On Fri, Apr 30, 2021 at 11:23 AM Dilip Kumar <dilipbal...@gmail.com> wrote:
>
> On Fri, Apr 30, 2021 at 11:09 AM Bharath Rupireddy
> <bharath.rupireddyforpostg...@gmail.com> wrote:
> >
> > On Fri, Apr 30, 2021 at 10:51 AM Dilip Kumar <dilipbal...@gmail.com> wrote:
> > >
> > > On Fri, Apr 30, 2021 at 10:43 AM Bharath Rupireddy
> > > <bharath.rupireddyforpostg...@gmail.com> wrote:
> > > >
> > > > On Fri, Apr 30, 2021 at 10:17 AM Dilip Kumar <dilipbal...@gmail.com> 
> > > > wrote:
> > > > > In this function, we already have the "defel" variable then I do not
> > > > > understand why you are using one extra variable and assigning defel to
> > > > > that?
> > > > > If the goal is to just improve the error message then you can simply
> > > > > use defel->defname?
> > > >
> > > > Yeah. I can do that. Thanks for the comment.
> > > >
> > > > While on this, I also removed  the duplicate_error and procedure_error
> > > > goto statements, because IMHO, using goto statements is not an elegant
> > > > way. I used boolean flags to do the job instead. See the attached and
> > > > let me know what you think.
> > >
> > > Okay, but I see one side effect of this, basically earlier on
> > > procedure_error and duplicate_error we were not assigning anything to
> > > output parameters, e.g. volatility_item,  but now those values will be
> > > assigned with defel even if there is an error.
> >
> > Yes, but on ereport(ERROR, we don't come back right? The txn gets
> > aborted and the control is not returned to the caller instead it will
> > go to sigjmp_buf of the backend.
> >
> > > So I think we should
> > > better avoid such change.  But even if you want to do then better
> > > check for any impacts on the caller.
> >
> > AFAICS, there will not be any impact on the caller, as the control
> > doesn't return to the caller on error.
>
> I see.
>
> other comments
>
>  if (strcmp(defel->defname, "volatility") == 0)
>   {
>   if (is_procedure)
> - goto procedure_error;
> + is_procedure_error =  true;
>   if (*volatility_item)
> - goto duplicate_error;
> + is_duplicate_error = true;
>
> Another side effect I see is, in the above check earlier if
> is_procedure was true it was directly goto procedure_error, but now it
> will also check the if (*volatility_item) and it may set
> is_duplicate_error also true, which seems wrong to me.  I think you
> can change it to
>
> if (is_procedure)
>    is_procedure_error =  true;
> else if (*volatility_item)
>   is_duplicate_error = true;

Thanks. Done that way, see the attached v3. Let's see what others has to say.

Also attaching Vignesh's v3 patch as-is, just for completion.

With Regards,
Bharath Rupireddy.
EnterpriseDB: http://www.enterprisedb.com
From 6ed153cdb45a0d41d3889dc7d80b3a743eb66725 Mon Sep 17 00:00:00 2001
From: vignesh <vignesh21@gmail.com>
Date: Mon, 26 Apr 2021 18:40:36 +0530
Subject: [PATCH v3] Enhance error message.

Enhanced error message, so that the user can easily identify the error.
---
 contrib/file_fdw/file_fdw.c                 |  6 +--
 src/backend/catalog/aclchk.c                |  4 +-
 src/backend/commands/copy.c                 | 23 +++++-----
 src/backend/commands/dbcommands.c           | 28 ++++++------
 src/backend/commands/extension.c            |  8 ++--
 src/backend/commands/foreigncmds.c          |  4 +-
 src/backend/commands/functioncmds.c         | 12 +++---
 src/backend/commands/publicationcmds.c      |  4 +-
 src/backend/commands/sequence.c             | 18 ++++----
 src/backend/commands/subscriptioncmds.c     | 18 ++++----
 src/backend/commands/tablecmds.c            |  2 +-
 src/backend/commands/typecmds.c             | 14 +++---
 src/backend/commands/user.c                 | 48 ++++++++++-----------
 src/backend/parser/parse_utilcmd.c          |  2 +-
 src/backend/replication/pgoutput/pgoutput.c | 10 ++---
 src/backend/replication/walsender.c         |  6 +--
 src/test/regress/expected/copy2.out         | 24 ++++++-----
 src/test/regress/expected/foreign_data.out  |  4 +-
 src/test/regress/expected/publication.out   |  2 +-
 19 files changed, 119 insertions(+), 118 deletions(-)

diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index 2c2f149fb0..10aa2fca28 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -292,8 +292,7 @@ file_fdw_validator(PG_FUNCTION_ARGS)
 			if (force_not_null)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
-						 errhint("Option \"force_not_null\" supplied more than once for a column.")));
+						 errmsg("option \"%s\" specified more than once", def->defname)));
 			force_not_null = def;
 			/* Don't care what the value is, as long as it's a legal boolean */
 			(void) defGetBoolean(def);
@@ -304,8 +303,7 @@ file_fdw_validator(PG_FUNCTION_ARGS)
 			if (force_null)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
-						 errhint("Option \"force_null\" supplied more than once for a column.")));
+						 errmsg("option \"%s\" specified more than once", def->defname)));
 			force_null = def;
 			(void) defGetBoolean(def);
 		}
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index e1573eb398..7885587bfc 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -923,7 +923,7 @@ ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *s
 			if (dnspnames)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dnspnames = defel;
 		}
@@ -932,7 +932,7 @@ ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *s
 			if (drolespecs)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			drolespecs = defel;
 		}
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 8265b981eb..2860f36f91 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -359,7 +359,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (format_specified)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			format_specified = true;
 			if (strcmp(fmt, "text") == 0)
@@ -379,7 +379,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (freeze_specified)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			freeze_specified = true;
 			opts_out->freeze = defGetBoolean(defel);
@@ -389,7 +389,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->delim)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->delim = defGetString(defel);
 		}
@@ -398,7 +398,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->null_print)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->null_print = defGetString(defel);
 		}
@@ -407,7 +407,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (header_specified)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			header_specified = true;
 			opts_out->header_line = defGetBoolean(defel);
@@ -417,7 +417,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->quote)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->quote = defGetString(defel);
 		}
@@ -426,7 +426,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->escape)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->escape = defGetString(defel);
 		}
@@ -453,7 +453,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->force_notnull)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			if (defel->arg && IsA(defel->arg, List))
 				opts_out->force_notnull = castNode(List, defel->arg);
@@ -469,7 +469,8 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->force_null)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname),
+						 parser_errposition(pstate, defel->location)));
 			if (defel->arg && IsA(defel->arg, List))
 				opts_out->force_null = castNode(List, defel->arg);
 			else
@@ -489,7 +490,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->convert_selectively)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->convert_selectively = true;
 			if (defel->arg == NULL || IsA(defel->arg, List))
@@ -506,7 +507,7 @@ ProcessCopyOptions(ParseState *pstate,
 			if (opts_out->file_encoding >= 0)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			opts_out->file_encoding = pg_char_to_encoding(defGetString(defel));
 			if (opts_out->file_encoding < 0)
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 2b159b60eb..15ca32c898 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -154,7 +154,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dtablespacename)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dtablespacename = defel;
 		}
@@ -163,7 +163,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (downer)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			downer = defel;
 		}
@@ -172,7 +172,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dtemplate)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dtemplate = defel;
 		}
@@ -181,7 +181,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dencoding)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dencoding = defel;
 		}
@@ -190,7 +190,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dlocale)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dlocale = defel;
 		}
@@ -199,7 +199,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dcollate)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dcollate = defel;
 		}
@@ -208,7 +208,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dctype)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dctype = defel;
 		}
@@ -217,7 +217,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (distemplate)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			distemplate = defel;
 		}
@@ -226,7 +226,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dallowconnections)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dallowconnections = defel;
 		}
@@ -235,7 +235,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 			if (dconnlimit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dconnlimit = defel;
 		}
@@ -1499,7 +1499,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 			if (distemplate)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			distemplate = defel;
 		}
@@ -1508,7 +1508,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 			if (dallowconnections)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dallowconnections = defel;
 		}
@@ -1517,7 +1517,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 			if (dconnlimit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dconnlimit = defel;
 		}
@@ -1526,7 +1526,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 			if (dtablespace)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dtablespace = defel;
 		}
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 19db329fe6..5525919735 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1732,7 +1732,7 @@ CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
 			if (d_schema)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			d_schema = defel;
 			schemaName = defGetString(d_schema);
@@ -1742,7 +1742,7 @@ CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
 			if (d_new_version)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			d_new_version = defel;
 			versionName = defGetString(d_new_version);
@@ -1752,7 +1752,7 @@ CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
 			if (d_cascade)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			d_cascade = defel;
 			cascade = defGetBoolean(d_cascade);
@@ -3052,7 +3052,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
 			if (d_new_version)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			d_new_version = defel;
 		}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index eb7103fd3b..d9cf3227fe 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -536,7 +536,7 @@ parse_func_options(List *func_options,
 			if (*handler_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", def->defname)));
 			*handler_given = true;
 			*fdwhandler = lookup_fdw_handler_func(def);
 		}
@@ -545,7 +545,7 @@ parse_func_options(List *func_options,
 			if (*validator_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", def->defname)));
 			*validator_given = true;
 			*fdwvalidator = lookup_fdw_validator_func(def);
 		}
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9548287217..ed13bf547c 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -741,7 +741,7 @@ compute_function_attributes(ParseState *pstate,
 			if (as_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			as_item = defel;
 		}
@@ -750,7 +750,7 @@ compute_function_attributes(ParseState *pstate,
 			if (language_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			language_item = defel;
 		}
@@ -759,7 +759,7 @@ compute_function_attributes(ParseState *pstate,
 			if (transform_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			transform_item = defel;
 		}
@@ -768,7 +768,7 @@ compute_function_attributes(ParseState *pstate,
 			if (windowfunc_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			if (is_procedure)
 				ereport(ERROR,
@@ -2065,7 +2065,7 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic)
 			if (as_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			as_item = defel;
 		}
 		else if (strcmp(defel->defname, "language") == 0)
@@ -2073,7 +2073,7 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic)
 			if (language_item)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			language_item = defel;
 		}
 		else
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 95c253c8e0..9dc2bfdd60 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -87,7 +87,7 @@ parse_publication_options(List *options,
 			if (*publish_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			/*
 			 * If publish option was given only the explicitly listed actions
@@ -130,7 +130,7 @@ parse_publication_options(List *options,
 			if (*publish_via_partition_root_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			*publish_via_partition_root_given = true;
 			*publish_via_partition_root = defGetBoolean(defel);
 		}
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 0415df9ccb..f2180cd29b 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1263,7 +1263,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (as_type)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			as_type = defel;
 			*need_seq_rewrite = true;
@@ -1273,7 +1273,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (increment_by)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			increment_by = defel;
 			*need_seq_rewrite = true;
@@ -1283,7 +1283,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (start_value)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			start_value = defel;
 			*need_seq_rewrite = true;
@@ -1293,7 +1293,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (restart_value)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			restart_value = defel;
 			*need_seq_rewrite = true;
@@ -1303,7 +1303,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (max_value)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			max_value = defel;
 			*need_seq_rewrite = true;
@@ -1313,7 +1313,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (min_value)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			min_value = defel;
 			*need_seq_rewrite = true;
@@ -1323,7 +1323,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (cache_value)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			cache_value = defel;
 			*need_seq_rewrite = true;
@@ -1333,7 +1333,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (is_cycled)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			is_cycled = defel;
 			*need_seq_rewrite = true;
@@ -1343,7 +1343,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
 			if (*owned_by)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			*owned_by = defGetQualifiedName(defel);
 		}
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 517c8edd3b..662191bc9e 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -121,7 +121,7 @@ parse_subscription_options(List *options,
 			if (connect_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			connect_given = true;
 			*connect = defGetBoolean(defel);
@@ -131,7 +131,7 @@ parse_subscription_options(List *options,
 			if (*enabled_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			*enabled_given = true;
 			*enabled = defGetBoolean(defel);
@@ -141,7 +141,7 @@ parse_subscription_options(List *options,
 			if (create_slot_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			create_slot_given = true;
 			*create_slot = defGetBoolean(defel);
@@ -151,7 +151,7 @@ parse_subscription_options(List *options,
 			if (*slot_name_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			*slot_name_given = true;
 			*slot_name = defGetString(defel);
@@ -165,7 +165,7 @@ parse_subscription_options(List *options,
 			if (copy_data_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			copy_data_given = true;
 			*copy_data = defGetBoolean(defel);
@@ -176,7 +176,7 @@ parse_subscription_options(List *options,
 			if (*synchronous_commit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			*synchronous_commit = defGetString(defel);
 
@@ -190,7 +190,7 @@ parse_subscription_options(List *options,
 			if (refresh_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			refresh_given = true;
 			*refresh = defGetBoolean(defel);
@@ -200,7 +200,7 @@ parse_subscription_options(List *options,
 			if (*binary_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			*binary_given = true;
 			*binary = defGetBoolean(defel);
@@ -210,7 +210,7 @@ parse_subscription_options(List *options,
 			if (*streaming_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			*streaming_given = true;
 			*streaming = defGetBoolean(defel);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d9ba87a2a3..26a1f16271 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -7524,7 +7524,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod
 			if (generatedEl)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			generatedEl = defel;
 		}
 		else
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 036fa69d17..84d654d5a5 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -332,7 +332,7 @@ DefineType(ParseState *pstate, List *names, List *parameters)
 		if (*defelp != NULL)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
-					 errmsg("conflicting or redundant options"),
+					 errmsg("option \"%s\" specified more than once", defel->defname),
 					 parser_errposition(pstate, defel->location)));
 		*defelp = defel;
 	}
@@ -1413,7 +1413,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (OidIsValid(rangeSubtype))
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			/* we can look up the subtype name immediately */
 			rangeSubtype = typenameTypeId(NULL, defGetTypeName(defel));
 		}
@@ -1422,7 +1422,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (rangeSubOpclassName != NIL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			rangeSubOpclassName = defGetQualifiedName(defel);
 		}
 		else if (strcmp(defel->defname, "collation") == 0)
@@ -1430,7 +1430,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (rangeCollationName != NIL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			rangeCollationName = defGetQualifiedName(defel);
 		}
 		else if (strcmp(defel->defname, "canonical") == 0)
@@ -1438,7 +1438,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (rangeCanonicalName != NIL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			rangeCanonicalName = defGetQualifiedName(defel);
 		}
 		else if (strcmp(defel->defname, "subtype_diff") == 0)
@@ -1446,7 +1446,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (rangeSubtypeDiffName != NIL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			rangeSubtypeDiffName = defGetQualifiedName(defel);
 		}
 		else if (strcmp(defel->defname, "multirange_type_name") == 0)
@@ -1454,7 +1454,7 @@ DefineRange(CreateRangeStmt *stmt)
 			if (multirangeTypeName != NULL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			/* we can look up the subtype name immediately */
 			multirangeNamespace = QualifiedNameGetCreationNamespace(defGetQualifiedName(defel),
 																	&multirangeTypeName);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 65bb733958..4c7af6252d 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -130,7 +130,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dpassword)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dpassword = defel;
 		}
@@ -144,7 +144,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dissuper)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dissuper = defel;
 		}
@@ -153,7 +153,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dinherit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dinherit = defel;
 		}
@@ -162,7 +162,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dcreaterole)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dcreaterole = defel;
 		}
@@ -171,7 +171,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dcreatedb)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dcreatedb = defel;
 		}
@@ -180,7 +180,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dcanlogin)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dcanlogin = defel;
 		}
@@ -189,7 +189,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (disreplication)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			disreplication = defel;
 		}
@@ -198,7 +198,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dconnlimit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dconnlimit = defel;
 		}
@@ -207,7 +207,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (daddroleto)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			daddroleto = defel;
 		}
@@ -216,7 +216,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (drolemembers)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			drolemembers = defel;
 		}
@@ -225,7 +225,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dadminmembers)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dadminmembers = defel;
 		}
@@ -234,7 +234,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dvalidUntil)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dvalidUntil = defel;
 		}
@@ -243,7 +243,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 			if (dbypassRLS)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
+						 errmsg("option \"%s\" specified more than once", defel->defname),
 						 parser_errposition(pstate, defel->location)));
 			dbypassRLS = defel;
 		}
@@ -579,7 +579,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dpassword)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dpassword = defel;
 		}
 		else if (strcmp(defel->defname, "superuser") == 0)
@@ -587,7 +587,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dissuper)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dissuper = defel;
 		}
 		else if (strcmp(defel->defname, "inherit") == 0)
@@ -595,7 +595,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dinherit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dinherit = defel;
 		}
 		else if (strcmp(defel->defname, "createrole") == 0)
@@ -603,7 +603,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dcreaterole)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dcreaterole = defel;
 		}
 		else if (strcmp(defel->defname, "createdb") == 0)
@@ -611,7 +611,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dcreatedb)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dcreatedb = defel;
 		}
 		else if (strcmp(defel->defname, "canlogin") == 0)
@@ -619,7 +619,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dcanlogin)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dcanlogin = defel;
 		}
 		else if (strcmp(defel->defname, "isreplication") == 0)
@@ -627,7 +627,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (disreplication)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			disreplication = defel;
 		}
 		else if (strcmp(defel->defname, "connectionlimit") == 0)
@@ -635,7 +635,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dconnlimit)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dconnlimit = defel;
 		}
 		else if (strcmp(defel->defname, "rolemembers") == 0 &&
@@ -644,7 +644,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (drolemembers)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			drolemembers = defel;
 		}
 		else if (strcmp(defel->defname, "validUntil") == 0)
@@ -652,7 +652,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dvalidUntil)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dvalidUntil = defel;
 		}
 		else if (strcmp(defel->defname, "bypassrls") == 0)
@@ -660,7 +660,7 @@ AlterRole(AlterRoleStmt *stmt)
 			if (dbypassRLS)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			dbypassRLS = defel;
 		}
 		else
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 9dd30370da..9e44885146 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -402,7 +402,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
 			if (nameEl)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			nameEl = defel;
 			nameEl_idx = foreach_current_index(option);
 		}
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index f68348dcf4..50995868db 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -189,7 +189,7 @@ parse_output_parameters(List *options, PGOutputData *data)
 			if (protocol_version_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			protocol_version_given = true;
 
 			if (!scanint8(strVal(defel->arg), true, &parsed))
@@ -210,7 +210,7 @@ parse_output_parameters(List *options, PGOutputData *data)
 			if (publication_names_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			publication_names_given = true;
 
 			if (!SplitIdentifierString(strVal(defel->arg), ',',
@@ -224,7 +224,7 @@ parse_output_parameters(List *options, PGOutputData *data)
 			if (binary_option_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			binary_option_given = true;
 
 			data->binary = defGetBoolean(defel);
@@ -234,7 +234,7 @@ parse_output_parameters(List *options, PGOutputData *data)
 			if (messages_option_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			messages_option_given = true;
 
 			data->messages = defGetBoolean(defel);
@@ -244,7 +244,7 @@ parse_output_parameters(List *options, PGOutputData *data)
 			if (streaming_given)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 			streaming_given = true;
 
 			data->streaming = defGetBoolean(defel);
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 6fefc3bedc..e79690a0f9 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -882,7 +882,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd,
 			if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			snapshot_action_given = true;
 			*snapshot_action = defGetBoolean(defel) ? CRS_EXPORT_SNAPSHOT :
@@ -893,7 +893,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd,
 			if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			snapshot_action_given = true;
 			*snapshot_action = CRS_USE_SNAPSHOT;
@@ -903,7 +903,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd,
 			if (reserve_wal_given || cmd->kind != REPLICATION_KIND_PHYSICAL)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options")));
+						 errmsg("option \"%s\" specified more than once", defel->defname)));
 
 			reserve_wal_given = true;
 			*reserve_wal = true;
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index c64f0719e7..92fe8a121a 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -30,31 +30,31 @@ COPY x (xyz) from stdin;
 ERROR:  column "xyz" of relation "x" does not exist
 -- redundant options
 COPY x from stdin (format CSV, FORMAT CSV);
-ERROR:  conflicting or redundant options
+ERROR:  option "format" specified more than once
 LINE 1: COPY x from stdin (format CSV, FORMAT CSV);
                                        ^
 COPY x from stdin (freeze off, freeze on);
-ERROR:  conflicting or redundant options
+ERROR:  option "freeze" specified more than once
 LINE 1: COPY x from stdin (freeze off, freeze on);
                                        ^
 COPY x from stdin (delimiter ',', delimiter ',');
-ERROR:  conflicting or redundant options
+ERROR:  option "delimiter" specified more than once
 LINE 1: COPY x from stdin (delimiter ',', delimiter ',');
                                           ^
 COPY x from stdin (null ' ', null ' ');
-ERROR:  conflicting or redundant options
+ERROR:  option "null" specified more than once
 LINE 1: COPY x from stdin (null ' ', null ' ');
                                      ^
 COPY x from stdin (header off, header on);
-ERROR:  conflicting or redundant options
+ERROR:  option "header" specified more than once
 LINE 1: COPY x from stdin (header off, header on);
                                        ^
 COPY x from stdin (quote ':', quote ':');
-ERROR:  conflicting or redundant options
+ERROR:  option "quote" specified more than once
 LINE 1: COPY x from stdin (quote ':', quote ':');
                                       ^
 COPY x from stdin (escape ':', escape ':');
-ERROR:  conflicting or redundant options
+ERROR:  option "escape" specified more than once
 LINE 1: COPY x from stdin (escape ':', escape ':');
                                        ^
 COPY x from stdin (force_quote (a), force_quote *);
@@ -62,17 +62,19 @@ ERROR:  conflicting or redundant options
 LINE 1: COPY x from stdin (force_quote (a), force_quote *);
                                             ^
 COPY x from stdin (force_not_null (a), force_not_null (b));
-ERROR:  conflicting or redundant options
+ERROR:  option "force_not_null" specified more than once
 LINE 1: COPY x from stdin (force_not_null (a), force_not_null (b));
                                                ^
 COPY x from stdin (force_null (a), force_null (b));
-ERROR:  conflicting or redundant options
+ERROR:  option "force_null" specified more than once
+LINE 1: COPY x from stdin (force_null (a), force_null (b));
+                                           ^
 COPY x from stdin (convert_selectively (a), convert_selectively (b));
-ERROR:  conflicting or redundant options
+ERROR:  option "convert_selectively" specified more than once
 LINE 1: COPY x from stdin (convert_selectively (a), convert_selectiv...
                                                     ^
 COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii');
-ERROR:  conflicting or redundant options
+ERROR:  option "encoding" specified more than once
 LINE 1: COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii...
                                                  ^
 -- too many columns in column list: should fail
diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out
index 5385f98a0f..0cdab88eed 100644
--- a/src/test/regress/expected/foreign_data.out
+++ b/src/test/regress/expected/foreign_data.out
@@ -94,7 +94,7 @@ CREATE FUNCTION invalid_fdw_handler() RETURNS int LANGUAGE SQL AS 'SELECT 1;';
 CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler;  -- ERROR
 ERROR:  function invalid_fdw_handler must return type fdw_handler
 CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler;  -- ERROR
-ERROR:  conflicting or redundant options
+ERROR:  option "handler" specified more than once
 CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler;
 DROP FOREIGN DATA WRAPPER test_fdw;
 -- ALTER FOREIGN DATA WRAPPER
@@ -200,7 +200,7 @@ ALTER FOREIGN DATA WRAPPER foo1 RENAME TO foo;
 ALTER FOREIGN DATA WRAPPER foo HANDLER invalid_fdw_handler;  -- ERROR
 ERROR:  function invalid_fdw_handler must return type fdw_handler
 ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER anything;  -- ERROR
-ERROR:  conflicting or redundant options
+ERROR:  option "handler" specified more than once
 ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler;
 WARNING:  changing the foreign-data wrapper handler can change behavior of existing foreign tables
 DROP FUNCTION invalid_fdw_handler();
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index 63d6ab7a4e..7887dada21 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -26,7 +26,7 @@ ERROR:  unrecognized publication parameter: "foo"
 CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum');
 ERROR:  unrecognized "publish" value: "cluster"
 CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0');
-ERROR:  conflicting or redundant options
+ERROR:  option "publish_via_partition_root" specified more than once
 \dRp
                                               List of publications
         Name        |          Owner           | All tables | Inserts | Updates | Deletes | Truncates | Via root 
-- 
2.25.1

From eee10389a5d2071e564ba174bb462f7500be33d4 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddy@enterprisedb.com>
Date: Fri, 30 Apr 2021 11:35:05 +0530
Subject: [PATCH v3] compute_common_attribute

---
 src/backend/commands/functioncmds.c | 73 +++++++++++++++--------------
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9548287217..7bd97f5fad 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -492,37 +492,40 @@ compute_common_attribute(ParseState *pstate,
 						 DefElem **support_item,
 						 DefElem **parallel_item)
 {
+	bool	is_duplicate_error = false;
+	bool	is_procedure_error = false;
+
 	if (strcmp(defel->defname, "volatility") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*volatility_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*volatility_item)
+			is_duplicate_error = true;
 
 		*volatility_item = defel;
 	}
 	else if (strcmp(defel->defname, "strict") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*strict_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*strict_item)
+			is_duplicate_error = true;
 
 		*strict_item = defel;
 	}
 	else if (strcmp(defel->defname, "security") == 0)
 	{
 		if (*security_item)
-			goto duplicate_error;
+			is_duplicate_error = true;
 
 		*security_item = defel;
 	}
 	else if (strcmp(defel->defname, "leakproof") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*leakproof_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*leakproof_item)
+			is_duplicate_error = true;
 
 		*leakproof_item = defel;
 	}
@@ -533,58 +536,56 @@ compute_common_attribute(ParseState *pstate,
 	else if (strcmp(defel->defname, "cost") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*cost_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*cost_item)
+			is_duplicate_error = true;
 
 		*cost_item = defel;
 	}
 	else if (strcmp(defel->defname, "rows") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*rows_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*rows_item)
+			is_duplicate_error = true;
 
 		*rows_item = defel;
 	}
 	else if (strcmp(defel->defname, "support") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*support_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*support_item)
+			is_duplicate_error = true;
 
 		*support_item = defel;
 	}
 	else if (strcmp(defel->defname, "parallel") == 0)
 	{
 		if (is_procedure)
-			goto procedure_error;
-		if (*parallel_item)
-			goto duplicate_error;
+			is_procedure_error =  true;
+		else if (*parallel_item)
+			is_duplicate_error = true;
 
 		*parallel_item = defel;
 	}
 	else
 		return false;
 
+	if (is_procedure_error)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+				 errmsg("invalid attribute in procedure definition"),
+				 parser_errposition(pstate, defel->location)));
+
+	if (is_duplicate_error)
+		ereport(ERROR,
+				(errcode(ERRCODE_SYNTAX_ERROR),
+				 errmsg("option \"%s\" specified more than once", defel->defname),
+				 parser_errposition(pstate, defel->location)));
+
 	/* Recognized an option */
 	return true;
-
-duplicate_error:
-	ereport(ERROR,
-			(errcode(ERRCODE_SYNTAX_ERROR),
-			 errmsg("conflicting or redundant options"),
-			 parser_errposition(pstate, defel->location)));
-	return false;				/* keep compiler quiet */
-
-procedure_error:
-	ereport(ERROR,
-			(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-			 errmsg("invalid attribute in procedure definition"),
-			 parser_errposition(pstate, defel->location)));
-	return false;
 }
 
 static char
-- 
2.25.1

Reply via email to