On Tue, May 11, 2021 at 2:47 AM Alvaro Herrera <alvhe...@alvh.no-ip.org> wrote: > > On 2021-May-10, vignesh C wrote: > > > That sounds fine to me, Attached v6 patch which has the changes for the > > same. > > What about defining a function (maybe a static inline function in > defrem.h) that is marked noreturn and receives the DefElem and > optionally pstate, and throws the error? I think that would avoid the > patch's need to have half a dozen copies of the "duplicate_error:" label > and ereport stanza.
Thanks for the comment, this reduces a significant amount of code. Attached patch has the changes incorporated. Regards, Vignesh
From 9b325d6d85fca39ec0ff3f39735281f8a9fa647c Mon Sep 17 00:00:00 2001 From: vignesh <vignesh21@gmail.com> Date: Mon, 26 Apr 2021 18:40:36 +0530 Subject: [PATCH v7] Enhance error message. Enhanced error message, so that the user can easily identify the error. --- contrib/file_fdw/file_fdw.c | 13 +-- src/backend/catalog/aclchk.c | 14 +-- src/backend/commands/copy.c | 57 +++------- src/backend/commands/dbcommands.c | 76 +++---------- src/backend/commands/extension.c | 23 +--- src/backend/commands/foreigncmds.c | 21 ++-- src/backend/commands/functioncmds.c | 59 ++++------ src/backend/commands/publicationcmds.c | 30 ++--- src/backend/commands/sequence.c | 48 ++------ src/backend/commands/subscriptioncmds.c | 66 +++++------ src/backend/commands/tablecmds.c | 4 +- src/backend/commands/typecmds.c | 34 ++---- src/backend/commands/user.c | 118 +++++--------------- src/backend/parser/parse_utilcmd.c | 4 +- src/backend/replication/pgoutput/pgoutput.c | 23 ++-- src/backend/replication/walsender.c | 15 +-- src/backend/tcop/utility.c | 20 ++-- src/include/commands/defrem.h | 20 +++- src/include/commands/publicationcmds.h | 4 +- src/include/commands/subscriptioncmds.h | 4 +- src/include/commands/typecmds.h | 2 +- src/include/commands/user.h | 2 +- src/test/regress/expected/copy2.out | 24 ++-- src/test/regress/expected/foreign_data.out | 8 +- src/test/regress/expected/publication.out | 4 +- 25 files changed, 239 insertions(+), 454 deletions(-) diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c index 2c2f149fb0..f49dd47930 100644 --- a/contrib/file_fdw/file_fdw.c +++ b/contrib/file_fdw/file_fdw.c @@ -200,6 +200,7 @@ file_fdw_validator(PG_FUNCTION_ARGS) char *filename = NULL; DefElem *force_not_null = NULL; DefElem *force_null = NULL; + DefElem *def; List *other_options = NIL; ListCell *cell; @@ -209,7 +210,7 @@ file_fdw_validator(PG_FUNCTION_ARGS) */ foreach(cell, options_list) { - DefElem *def = (DefElem *) lfirst(cell); + def = (DefElem *) lfirst(cell); if (!is_valid_option(def->defname, catalog)) { @@ -290,10 +291,7 @@ file_fdw_validator(PG_FUNCTION_ARGS) else if (strcmp(def->defname, "force_not_null") == 0) { 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."))); + ReportDuplicateOptionError(def, NULL); force_not_null = def; /* Don't care what the value is, as long as it's a legal boolean */ (void) defGetBoolean(def); @@ -302,10 +300,7 @@ file_fdw_validator(PG_FUNCTION_ARGS) else if (strcmp(def->defname, "force_null") == 0) { 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."))); + ReportDuplicateOptionError(def, NULL); force_null = def; (void) defGetBoolean(def); } diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index e1573eb398..3933aba716 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -59,6 +59,7 @@ #include "catalog/pg_ts_template.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" +#include "commands/defrem.h" #include "commands/event_trigger.h" #include "commands/extension.h" #include "commands/proclang.h" @@ -910,30 +911,25 @@ ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *s List *nspnames = NIL; DefElem *drolespecs = NULL; DefElem *dnspnames = NULL; + DefElem *defel; AclMode all_privileges; const char *errormsg; /* Deconstruct the "options" part of the statement */ foreach(cell, stmt->options) { - DefElem *defel = (DefElem *) lfirst(cell); + defel = (DefElem *) lfirst(cell); if (strcmp(defel->defname, "schemas") == 0) { if (dnspnames) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dnspnames = defel; } else if (strcmp(defel->defname, "roles") == 0) { if (drolespecs) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); drolespecs = defel; } else diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 8265b981eb..0d13daab4c 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -340,6 +340,7 @@ ProcessCopyOptions(ParseState *pstate, bool freeze_specified = false; bool header_specified = false; ListCell *option; + DefElem *defel; /* Support external use for option sanity checking */ if (opts_out == NULL) @@ -350,17 +351,14 @@ ProcessCopyOptions(ParseState *pstate, /* Extract options from the statement node tree */ foreach(option, options) { - DefElem *defel = lfirst_node(DefElem, option); + defel = lfirst_node(DefElem, option); if (strcmp(defel->defname, "format") == 0) { char *fmt = defGetString(defel); if (format_specified) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); format_specified = true; if (strcmp(fmt, "text") == 0) /* default format */ ; @@ -377,57 +375,39 @@ ProcessCopyOptions(ParseState *pstate, else if (strcmp(defel->defname, "freeze") == 0) { if (freeze_specified) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); freeze_specified = true; opts_out->freeze = defGetBoolean(defel); } else if (strcmp(defel->defname, "delimiter") == 0) { if (opts_out->delim) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->delim = defGetString(defel); } else if (strcmp(defel->defname, "null") == 0) { if (opts_out->null_print) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->null_print = defGetString(defel); } else if (strcmp(defel->defname, "header") == 0) { if (header_specified) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); header_specified = true; opts_out->header_line = defGetBoolean(defel); } else if (strcmp(defel->defname, "quote") == 0) { if (opts_out->quote) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->quote = defGetString(defel); } else if (strcmp(defel->defname, "escape") == 0) { if (opts_out->escape) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->escape = defGetString(defel); } else if (strcmp(defel->defname, "force_quote") == 0) @@ -451,10 +431,7 @@ ProcessCopyOptions(ParseState *pstate, else if (strcmp(defel->defname, "force_not_null") == 0) { if (opts_out->force_notnull) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); if (defel->arg && IsA(defel->arg, List)) opts_out->force_notnull = castNode(List, defel->arg); else @@ -467,9 +444,7 @@ ProcessCopyOptions(ParseState *pstate, else if (strcmp(defel->defname, "force_null") == 0) { if (opts_out->force_null) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); if (defel->arg && IsA(defel->arg, List)) opts_out->force_null = castNode(List, defel->arg); else @@ -487,10 +462,7 @@ ProcessCopyOptions(ParseState *pstate, * allowed for the column list to be NIL. */ if (opts_out->convert_selectively) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->convert_selectively = true; if (defel->arg == NULL || IsA(defel->arg, List)) opts_out->convert_select = castNode(List, defel->arg); @@ -504,10 +476,7 @@ ProcessCopyOptions(ParseState *pstate, else if (strcmp(defel->defname, "encoding") == 0) { if (opts_out->file_encoding >= 0) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); opts_out->file_encoding = pg_char_to_encoding(defGetString(defel)); if (opts_out->file_encoding < 0) ereport(ERROR, diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 2b159b60eb..0aa2311ad2 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -143,100 +143,71 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) int notherbackends; int npreparedxacts; createdb_failure_params fparms; + DefElem *defel; /* Extract options from the statement node tree */ foreach(option, stmt->options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "tablespace") == 0) { if (dtablespacename) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dtablespacename = defel; } else if (strcmp(defel->defname, "owner") == 0) { if (downer) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); downer = defel; } else if (strcmp(defel->defname, "template") == 0) { if (dtemplate) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dtemplate = defel; } else if (strcmp(defel->defname, "encoding") == 0) { if (dencoding) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dencoding = defel; } else if (strcmp(defel->defname, "locale") == 0) { if (dlocale) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dlocale = defel; } else if (strcmp(defel->defname, "lc_collate") == 0) { if (dcollate) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dcollate = defel; } else if (strcmp(defel->defname, "lc_ctype") == 0) { if (dctype) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dctype = defel; } else if (strcmp(defel->defname, "is_template") == 0) { if (distemplate) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); distemplate = defel; } else if (strcmp(defel->defname, "allow_connections") == 0) { if (dallowconnections) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dallowconnections = defel; } else if (strcmp(defel->defname, "connection_limit") == 0) { if (dconnlimit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dconnlimit = defel; } else if (strcmp(defel->defname, "location") == 0) @@ -1488,46 +1459,35 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) Datum new_record[Natts_pg_database]; bool new_record_nulls[Natts_pg_database]; bool new_record_repl[Natts_pg_database]; + DefElem *defel; /* Extract options from the statement node tree */ foreach(option, stmt->options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "is_template") == 0) { if (distemplate) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); distemplate = defel; } else if (strcmp(defel->defname, "allow_connections") == 0) { if (dallowconnections) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dallowconnections = defel; } else if (strcmp(defel->defname, "connection_limit") == 0) { if (dconnlimit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dconnlimit = defel; } else if (strcmp(defel->defname, "tablespace") == 0) { if (dtablespace) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dtablespace = defel; } else diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 19db329fe6..32941005bd 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -1682,6 +1682,7 @@ CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt) DefElem *d_schema = NULL; DefElem *d_new_version = NULL; DefElem *d_cascade = NULL; + DefElem *defel; char *schemaName = NULL; char *versionName = NULL; bool cascade = false; @@ -1725,35 +1726,26 @@ CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt) /* Deconstruct the statement option list */ foreach(lc, stmt->options) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); if (strcmp(defel->defname, "schema") == 0) { if (d_schema) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); d_schema = defel; schemaName = defGetString(d_schema); } else if (strcmp(defel->defname, "new_version") == 0) { if (d_new_version) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); d_new_version = defel; versionName = defGetString(d_new_version); } else if (strcmp(defel->defname, "cascade") == 0) { if (d_cascade) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); d_cascade = defel; cascade = defGetBoolean(d_cascade); } @@ -3050,10 +3042,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt) if (strcmp(defel->defname, "new_version") == 0) { if (d_new_version) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); d_new_version = defel; } else diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index eb7103fd3b..dd3db3627e 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -515,11 +515,12 @@ lookup_fdw_validator_func(DefElem *validator) * Process function options of CREATE/ALTER FDW */ static void -parse_func_options(List *func_options, +parse_func_options(ParseState *pstate, List *func_options, bool *handler_given, Oid *fdwhandler, bool *validator_given, Oid *fdwvalidator) { ListCell *cell; + DefElem *def; *handler_given = false; *validator_given = false; @@ -529,23 +530,19 @@ parse_func_options(List *func_options, foreach(cell, func_options) { - DefElem *def = (DefElem *) lfirst(cell); + def = (DefElem *) lfirst(cell); if (strcmp(def->defname, "handler") == 0) { if (*handler_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(def, pstate); *handler_given = true; *fdwhandler = lookup_fdw_handler_func(def); } else if (strcmp(def->defname, "validator") == 0) { if (*validator_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(def, pstate); *validator_given = true; *fdwvalidator = lookup_fdw_validator_func(def); } @@ -559,7 +556,7 @@ parse_func_options(List *func_options, * Create a foreign-data wrapper */ ObjectAddress -CreateForeignDataWrapper(CreateFdwStmt *stmt) +CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt) { Relation rel; Datum values[Natts_pg_foreign_data_wrapper]; @@ -611,7 +608,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId); /* Lookup handler and validator functions, if given */ - parse_func_options(stmt->func_options, + parse_func_options(pstate, stmt->func_options, &handler_given, &fdwhandler, &validator_given, &fdwvalidator); @@ -675,7 +672,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) * Alter foreign-data wrapper */ ObjectAddress -AlterForeignDataWrapper(AlterFdwStmt *stmt) +AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) { Relation rel; HeapTuple tp; @@ -717,7 +714,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) memset(repl_null, false, sizeof(repl_null)); memset(repl_repl, false, sizeof(repl_repl)); - parse_func_options(stmt->func_options, + parse_func_options(pstate, stmt->func_options, &handler_given, &fdwhandler, &validator_given, &fdwvalidator); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 9548287217..12af901f56 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -497,7 +497,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*volatility_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *volatility_item = defel; } @@ -506,14 +506,14 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*strict_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *strict_item = defel; } else if (strcmp(defel->defname, "security") == 0) { if (*security_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *security_item = defel; } @@ -522,7 +522,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*leakproof_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *leakproof_item = defel; } @@ -535,7 +535,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*cost_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *cost_item = defel; } @@ -544,7 +544,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*rows_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *rows_item = defel; } @@ -553,7 +553,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*support_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *support_item = defel; } @@ -562,7 +562,7 @@ compute_common_attribute(ParseState *pstate, if (is_procedure) goto procedure_error; if (*parallel_item) - goto duplicate_error; + ReportDuplicateOptionError(defel, pstate); *parallel_item = defel; } @@ -572,13 +572,6 @@ compute_common_attribute(ParseState *pstate, /* 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), @@ -731,45 +724,34 @@ compute_function_attributes(ParseState *pstate, DefElem *rows_item = NULL; DefElem *support_item = NULL; DefElem *parallel_item = NULL; + DefElem *defel; foreach(option, options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "as") == 0) { if (as_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); as_item = defel; } else if (strcmp(defel->defname, "language") == 0) { if (language_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); language_item = defel; } else if (strcmp(defel->defname, "transform") == 0) { if (transform_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); transform_item = defel; } else if (strcmp(defel->defname, "window") == 0) { if (windowfunc_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); if (is_procedure) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), @@ -2044,12 +2026,13 @@ IsThereFunctionInNamespace(const char *proname, int pronargs, * See at ExecuteCallStmt() about the atomic argument. */ void -ExecuteDoStmt(DoStmt *stmt, bool atomic) +ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic) { InlineCodeBlock *codeblock = makeNode(InlineCodeBlock); ListCell *arg; DefElem *as_item = NULL; DefElem *language_item = NULL; + DefElem *defel; char *language; Oid laninline; HeapTuple languageTuple; @@ -2058,22 +2041,18 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic) /* Process options we got from gram.y */ foreach(arg, stmt->args) { - DefElem *defel = (DefElem *) lfirst(arg); + defel = (DefElem *) lfirst(arg); if (strcmp(defel->defname, "as") == 0) { if (as_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); as_item = defel; } else if (strcmp(defel->defname, "language") == 0) { if (language_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); language_item = defel; } else diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 95c253c8e0..93ad657c02 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -55,13 +55,15 @@ static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, static void PublicationDropTables(Oid pubid, List *rels, bool missing_ok); static void -parse_publication_options(List *options, +parse_publication_options(ParseState *pstate, + List *options, bool *publish_given, PublicationActions *pubactions, bool *publish_via_partition_root_given, bool *publish_via_partition_root) { ListCell *lc; + DefElem *defel; *publish_given = false; *publish_via_partition_root_given = false; @@ -76,7 +78,7 @@ parse_publication_options(List *options, /* Parse options */ foreach(lc, options) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); if (strcmp(defel->defname, "publish") == 0) { @@ -85,9 +87,7 @@ parse_publication_options(List *options, ListCell *lc; if (*publish_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); /* * If publish option was given only the explicitly listed actions @@ -128,9 +128,7 @@ parse_publication_options(List *options, else if (strcmp(defel->defname, "publish_via_partition_root") == 0) { if (*publish_via_partition_root_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *publish_via_partition_root_given = true; *publish_via_partition_root = defGetBoolean(defel); } @@ -145,7 +143,7 @@ parse_publication_options(List *options, * Create new publication. */ ObjectAddress -CreatePublication(CreatePublicationStmt *stmt) +CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt) { Relation rel; ObjectAddress myself; @@ -192,7 +190,8 @@ CreatePublication(CreatePublicationStmt *stmt) DirectFunctionCall1(namein, CStringGetDatum(stmt->pubname)); values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId()); - parse_publication_options(stmt->options, + parse_publication_options(pstate, + stmt->options, &publish_given, &pubactions, &publish_via_partition_root_given, &publish_via_partition_root); @@ -256,8 +255,8 @@ CreatePublication(CreatePublicationStmt *stmt) * Change options of a publication. */ static void -AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel, - HeapTuple tup) +AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, + Relation rel, HeapTuple tup) { bool nulls[Natts_pg_publication]; bool replaces[Natts_pg_publication]; @@ -269,7 +268,8 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel, ObjectAddress obj; Form_pg_publication pubform; - parse_publication_options(stmt->options, + parse_publication_options(pstate, + stmt->options, &publish_given, &pubactions, &publish_via_partition_root_given, &publish_via_partition_root); @@ -434,7 +434,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, * AlterPublicationTables. */ void -AlterPublication(AlterPublicationStmt *stmt) +AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) { Relation rel; HeapTuple tup; @@ -459,7 +459,7 @@ AlterPublication(AlterPublicationStmt *stmt) stmt->pubname); if (stmt->options) - AlterPublicationOptions(stmt, rel, tup); + AlterPublicationOptions(pstate, stmt, rel, tup); else AlterPublicationTables(stmt, rel, tup); diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 0415df9ccb..155d332e43 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1247,6 +1247,7 @@ init_params(ParseState *pstate, List *options, bool for_identity, DefElem *min_value = NULL; DefElem *cache_value = NULL; DefElem *is_cycled = NULL; + DefElem *defel; ListCell *option; bool reset_max_value = false; bool reset_min_value = false; @@ -1256,95 +1257,68 @@ init_params(ParseState *pstate, List *options, bool for_identity, foreach(option, options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "as") == 0) { if (as_type) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); as_type = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "increment") == 0) { if (increment_by) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); increment_by = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "start") == 0) { if (start_value) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); start_value = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "restart") == 0) { if (restart_value) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); restart_value = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "maxvalue") == 0) { if (max_value) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); max_value = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "minvalue") == 0) { if (min_value) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); min_value = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "cache") == 0) { if (cache_value) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); cache_value = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "cycle") == 0) { if (is_cycled) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); is_cycled = defel; *need_seq_rewrite = true; } else if (strcmp(defel->defname, "owned_by") == 0) { if (*owned_by) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); *owned_by = defGetQualifiedName(defel); } else if (strcmp(defel->defname, "sequence_name") == 0) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index bbb2f5d029..4bae26e250 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -60,7 +60,8 @@ static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, * accommodate that. */ static void -parse_subscription_options(List *options, +parse_subscription_options(ParseState *pstate, + List *options, bool *connect, bool *enabled_given, bool *enabled, bool *create_slot, @@ -76,6 +77,7 @@ parse_subscription_options(List *options, bool create_slot_given = false; bool copy_data_given = false; bool refresh_given = false; + DefElem *defel; /* If connect is specified, the others also need to be. */ Assert(!connect || (enabled && create_slot && copy_data)); @@ -114,14 +116,12 @@ parse_subscription_options(List *options, /* Parse options */ foreach(lc, options) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); if (strcmp(defel->defname, "connect") == 0 && connect) { if (connect_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); connect_given = true; *connect = defGetBoolean(defel); @@ -129,9 +129,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "enabled") == 0 && enabled) { if (*enabled_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *enabled_given = true; *enabled = defGetBoolean(defel); @@ -139,9 +137,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "create_slot") == 0 && create_slot) { if (create_slot_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); create_slot_given = true; *create_slot = defGetBoolean(defel); @@ -149,9 +145,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "slot_name") == 0 && slot_name) { if (*slot_name_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *slot_name_given = true; *slot_name = defGetString(defel); @@ -163,9 +157,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "copy_data") == 0 && copy_data) { if (copy_data_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); copy_data_given = true; *copy_data = defGetBoolean(defel); @@ -174,9 +166,7 @@ parse_subscription_options(List *options, synchronous_commit) { if (*synchronous_commit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *synchronous_commit = defGetString(defel); @@ -188,9 +178,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "refresh") == 0 && refresh) { if (refresh_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); refresh_given = true; *refresh = defGetBoolean(defel); @@ -198,9 +186,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "binary") == 0 && binary) { if (*binary_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *binary_given = true; *binary = defGetBoolean(defel); @@ -208,9 +194,7 @@ parse_subscription_options(List *options, else if (strcmp(defel->defname, "streaming") == 0 && streaming) { if (*streaming_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); *streaming_given = true; *streaming = defGetBoolean(defel); @@ -322,7 +306,8 @@ publicationListToArray(List *publist) * Create new subscription. */ ObjectAddress -CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) +CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, + bool isTopLevel) { Relation rel; ObjectAddress myself; @@ -352,7 +337,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) * * Connection and publication should not be specified here. */ - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, &connect, &enabled_given, &enabled, &create_slot, @@ -750,7 +736,8 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data) * Alter the existing subscription. */ ObjectAddress -AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) +AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, + bool isTopLevel) { Relation rel; ObjectAddress myself; @@ -805,7 +792,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) bool streaming_given; bool streaming; - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, NULL, /* no "connect" */ NULL, NULL, /* no "enabled" */ NULL, /* no "create_slot" */ @@ -862,7 +850,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) bool enabled, enabled_given; - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, NULL, /* no "connect" */ &enabled_given, &enabled, NULL, /* no "create_slot" */ @@ -907,7 +896,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) bool copy_data; bool refresh; - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, NULL, /* no "connect" */ NULL, NULL, /* no "enabled" */ NULL, /* no "create_slot" */ @@ -953,7 +943,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) publist = merge_publications(sub->publications, stmt->publication, isadd, stmt->subname); - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, NULL, /* no "connect" */ NULL, NULL, /* no "enabled" */ NULL, /* no "create_slot" */ @@ -1000,7 +991,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) (errcode(ERRCODE_SYNTAX_ERROR), errmsg("ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions"))); - parse_subscription_options(stmt->options, + parse_subscription_options(pstate, + stmt->options, NULL, /* no "connect" */ NULL, NULL, /* no "enabled" */ NULL, /* no "create_slot" */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 591bf01189..852056366f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -7509,9 +7509,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod if (strcmp(defel->defname, "generated") == 0) { if (generatedEl) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); generatedEl = defel; } else diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 036fa69d17..051f23c009 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -330,10 +330,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) continue; } if (*defelp != NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); *defelp = defel; } @@ -1336,7 +1333,7 @@ checkEnumOwner(HeapTuple tup) * and users might have queries with that same assumption. */ ObjectAddress -DefineRange(CreateRangeStmt *stmt) +DefineRange(ParseState *pstate, CreateRangeStmt *stmt) { char *typeName; Oid typeNamespace; @@ -1366,6 +1363,7 @@ DefineRange(CreateRangeStmt *stmt) ObjectAddress address; ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY; Oid castFuncOid; + DefElem *defel; /* Convert list of names to a name and namespace */ typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, @@ -1406,55 +1404,43 @@ DefineRange(CreateRangeStmt *stmt) /* Extract the parameters from the parameter list */ foreach(lc, stmt->params) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); if (strcmp(defel->defname, "subtype") == 0) { if (OidIsValid(rangeSubtype)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); /* we can look up the subtype name immediately */ rangeSubtype = typenameTypeId(NULL, defGetTypeName(defel)); } else if (strcmp(defel->defname, "subtype_opclass") == 0) { if (rangeSubOpclassName != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); rangeSubOpclassName = defGetQualifiedName(defel); } else if (strcmp(defel->defname, "collation") == 0) { if (rangeCollationName != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); rangeCollationName = defGetQualifiedName(defel); } else if (strcmp(defel->defname, "canonical") == 0) { if (rangeCanonicalName != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); rangeCanonicalName = defGetQualifiedName(defel); } else if (strcmp(defel->defname, "subtype_diff") == 0) { if (rangeSubtypeDiffName != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); rangeSubtypeDiffName = defGetQualifiedName(defel); } else if (strcmp(defel->defname, "multirange_type_name") == 0) { if (multirangeTypeName != NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); /* 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..5045ae3daf 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -27,6 +27,7 @@ #include "catalog/pg_db_role_setting.h" #include "commands/comment.h" #include "commands/dbcommands.h" +#include "commands/defrem.h" #include "commands/seclabel.h" #include "commands/user.h" #include "libpq/crypt.h" @@ -106,6 +107,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) DefElem *dadminmembers = NULL; DefElem *dvalidUntil = NULL; DefElem *dbypassRLS = NULL; + DefElem *defel; /* The defaults can vary depending on the original statement type */ switch (stmt->stmt_type) @@ -123,15 +125,12 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) /* Extract options from the statement node tree */ foreach(option, stmt->options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "password") == 0) { if (dpassword) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dpassword = defel; } else if (strcmp(defel->defname, "sysid") == 0) @@ -142,109 +141,73 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) else if (strcmp(defel->defname, "superuser") == 0) { if (dissuper) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dissuper = defel; } else if (strcmp(defel->defname, "inherit") == 0) { if (dinherit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dinherit = defel; } else if (strcmp(defel->defname, "createrole") == 0) { if (dcreaterole) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dcreaterole = defel; } else if (strcmp(defel->defname, "createdb") == 0) { if (dcreatedb) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dcreatedb = defel; } else if (strcmp(defel->defname, "canlogin") == 0) { if (dcanlogin) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dcanlogin = defel; } else if (strcmp(defel->defname, "isreplication") == 0) { if (disreplication) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); disreplication = defel; } else if (strcmp(defel->defname, "connectionlimit") == 0) { if (dconnlimit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dconnlimit = defel; } else if (strcmp(defel->defname, "addroleto") == 0) { if (daddroleto) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); daddroleto = defel; } else if (strcmp(defel->defname, "rolemembers") == 0) { if (drolemembers) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); drolemembers = defel; } else if (strcmp(defel->defname, "adminmembers") == 0) { if (dadminmembers) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dadminmembers = defel; } else if (strcmp(defel->defname, "validUntil") == 0) { if (dvalidUntil) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dvalidUntil = defel; } else if (strcmp(defel->defname, "bypassrls") == 0) { if (dbypassRLS) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); + ReportDuplicateOptionError(defel, pstate); dbypassRLS = defel; } else @@ -528,7 +491,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) * "ALTER ROLE role ROLE rolenames", we don't document it. */ Oid -AlterRole(AlterRoleStmt *stmt) +AlterRole(ParseState *pstate, AlterRoleStmt *stmt) { Datum new_record[Natts_pg_authid]; bool new_record_nulls[Natts_pg_authid]; @@ -564,6 +527,7 @@ AlterRole(AlterRoleStmt *stmt) DefElem *drolemembers = NULL; DefElem *dvalidUntil = NULL; DefElem *dbypassRLS = NULL; + DefElem *defel; Oid roleid; check_rolespec_name(stmt->role, @@ -572,95 +536,73 @@ AlterRole(AlterRoleStmt *stmt) /* Extract options from the statement node tree */ foreach(option, stmt->options) { - DefElem *defel = (DefElem *) lfirst(option); + defel = (DefElem *) lfirst(option); if (strcmp(defel->defname, "password") == 0) { if (dpassword) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dpassword = defel; } else if (strcmp(defel->defname, "superuser") == 0) { if (dissuper) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dissuper = defel; } else if (strcmp(defel->defname, "inherit") == 0) { if (dinherit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dinherit = defel; } else if (strcmp(defel->defname, "createrole") == 0) { if (dcreaterole) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dcreaterole = defel; } else if (strcmp(defel->defname, "createdb") == 0) { if (dcreatedb) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dcreatedb = defel; } else if (strcmp(defel->defname, "canlogin") == 0) { if (dcanlogin) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dcanlogin = defel; } else if (strcmp(defel->defname, "isreplication") == 0) { if (disreplication) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); disreplication = defel; } else if (strcmp(defel->defname, "connectionlimit") == 0) { if (dconnlimit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dconnlimit = defel; } else if (strcmp(defel->defname, "rolemembers") == 0 && stmt->action != 0) { if (drolemembers) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); drolemembers = defel; } else if (strcmp(defel->defname, "validUntil") == 0) { if (dvalidUntil) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dvalidUntil = defel; } else if (strcmp(defel->defname, "bypassrls") == 0) { if (dbypassRLS) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, pstate); dbypassRLS = defel; } else diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 48cce4567b..832fe392cd 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -402,9 +402,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, if (strcmp(defel->defname, "sequence_name") == 0) { if (nameEl) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); 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..96131b4420 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -165,6 +165,7 @@ static void parse_output_parameters(List *options, PGOutputData *data) { ListCell *lc; + DefElem *defel; bool protocol_version_given = false; bool publication_names_given = false; bool binary_option_given = false; @@ -177,7 +178,7 @@ parse_output_parameters(List *options, PGOutputData *data) foreach(lc, options) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); Assert(defel->arg == NULL || IsA(defel->arg, String)); @@ -187,9 +188,7 @@ parse_output_parameters(List *options, PGOutputData *data) int64 parsed; if (protocol_version_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); protocol_version_given = true; if (!scanint8(strVal(defel->arg), true, &parsed)) @@ -208,9 +207,7 @@ parse_output_parameters(List *options, PGOutputData *data) else if (strcmp(defel->defname, "publication_names") == 0) { if (publication_names_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); publication_names_given = true; if (!SplitIdentifierString(strVal(defel->arg), ',', @@ -222,9 +219,7 @@ parse_output_parameters(List *options, PGOutputData *data) else if (strcmp(defel->defname, "binary") == 0) { if (binary_option_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); binary_option_given = true; data->binary = defGetBoolean(defel); @@ -232,9 +227,7 @@ parse_output_parameters(List *options, PGOutputData *data) else if (strcmp(defel->defname, "messages") == 0) { if (messages_option_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); messages_option_given = true; data->messages = defGetBoolean(defel); @@ -242,9 +235,7 @@ parse_output_parameters(List *options, PGOutputData *data) else if (strcmp(defel->defname, "streaming") == 0) { if (streaming_given) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); streaming_given = true; data->streaming = defGetBoolean(defel); diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 628c8d49d9..3e846981fc 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -868,18 +868,17 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, ListCell *lc; bool snapshot_action_given = false; bool reserve_wal_given = false; + DefElem *defel; /* Parse options */ foreach(lc, cmd->options) { - DefElem *defel = (DefElem *) lfirst(lc); + defel = (DefElem *) lfirst(lc); if (strcmp(defel->defname, "export_snapshot") == 0) { if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); snapshot_action_given = true; *snapshot_action = defGetBoolean(defel) ? CRS_EXPORT_SNAPSHOT : @@ -888,9 +887,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, else if (strcmp(defel->defname, "use_snapshot") == 0) { if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); snapshot_action_given = true; *snapshot_action = CRS_USE_SNAPSHOT; @@ -898,9 +895,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, else if (strcmp(defel->defname, "reserve_wal") == 0) { if (reserve_wal_given || cmd->kind != REPLICATION_KIND_PHYSICAL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + ReportDuplicateOptionError(defel, NULL); reserve_wal_given = true; *reserve_wal = true; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 1a8fc16773..865c59dfe4 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -693,7 +693,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case T_DoStmt: - ExecuteDoStmt((DoStmt *) parsetree, isAtomicContext); + ExecuteDoStmt(pstate, (DoStmt *) parsetree, isAtomicContext); break; case T_CreateTableSpaceStmt: @@ -873,7 +873,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, case T_AlterRoleStmt: /* no event triggers for global objects */ - AlterRole((AlterRoleStmt *) parsetree); + AlterRole(pstate, (AlterRoleStmt *) parsetree); break; case T_AlterRoleSetStmt: @@ -1536,11 +1536,11 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateFdwStmt: - address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree); + address = CreateForeignDataWrapper(pstate, (CreateFdwStmt *) parsetree); break; case T_AlterFdwStmt: - address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree); + address = AlterForeignDataWrapper(pstate, (AlterFdwStmt *) parsetree); break; case T_CreateForeignServerStmt: @@ -1585,7 +1585,7 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */ - address = DefineRange((CreateRangeStmt *) parsetree); + address = DefineRange(pstate, (CreateRangeStmt *) parsetree); break; case T_AlterEnumStmt: /* ALTER TYPE (enum) */ @@ -1786,11 +1786,11 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreatePublicationStmt: - address = CreatePublication((CreatePublicationStmt *) parsetree); + address = CreatePublication(pstate, (CreatePublicationStmt *) parsetree); break; case T_AlterPublicationStmt: - AlterPublication((AlterPublicationStmt *) parsetree); + AlterPublication(pstate, (AlterPublicationStmt *) parsetree); /* * AlterPublication calls EventTriggerCollectSimpleCommand @@ -1800,12 +1800,14 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateSubscriptionStmt: - address = CreateSubscription((CreateSubscriptionStmt *) parsetree, + address = CreateSubscription(pstate, + (CreateSubscriptionStmt *) parsetree, isTopLevel); break; case T_AlterSubscriptionStmt: - address = AlterSubscription((AlterSubscriptionStmt *) parsetree, + address = AlterSubscription(pstate, + (AlterSubscriptionStmt *) parsetree, isTopLevel); break; diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 6bce4d76fe..46823dab5e 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -56,7 +56,7 @@ extern ObjectAddress CreateCast(CreateCastStmt *stmt); extern ObjectAddress CreateTransform(CreateTransformStmt *stmt); extern void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid); -extern void ExecuteDoStmt(DoStmt *stmt, bool atomic); +extern void ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic); extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest); extern TupleDesc CallStmtResultDesc(CallStmt *stmt); extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok); @@ -121,8 +121,8 @@ extern ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId); extern void AlterForeignServerOwner_oid(Oid, Oid newOwnerId); extern ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId); extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId); -extern ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt); -extern ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt); +extern ObjectAddress CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt); +extern ObjectAddress AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt); extern ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt); extern ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt); extern ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt); @@ -154,4 +154,18 @@ extern TypeName *defGetTypeName(DefElem *def); extern int defGetTypeLength(DefElem *def); extern List *defGetStringList(DefElem *def); +static inline void +ReportDuplicateOptionError(DefElem *defel, ParseState *pstate) +{ + if (pstate) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" specified more than once", defel->defname), + parser_errposition(pstate, defel->location))); + + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" specified more than once", defel->defname))); +} + #endif /* DEFREM_H */ diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h index 00e2e626e6..efea01f2a9 100644 --- a/src/include/commands/publicationcmds.h +++ b/src/include/commands/publicationcmds.h @@ -18,8 +18,8 @@ #include "catalog/objectaddress.h" #include "nodes/parsenodes.h" -extern ObjectAddress CreatePublication(CreatePublicationStmt *stmt); -extern void AlterPublication(AlterPublicationStmt *stmt); +extern ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt); +extern void AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt); extern void RemovePublicationRelById(Oid proid); extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId); diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h index 3b926f35d7..8bf25ee66c 100644 --- a/src/include/commands/subscriptioncmds.h +++ b/src/include/commands/subscriptioncmds.h @@ -18,9 +18,9 @@ #include "catalog/objectaddress.h" #include "nodes/parsenodes.h" -extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt, +extern ObjectAddress CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, bool isTopLevel); -extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel); +extern ObjectAddress AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, bool isTopLevel); extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel); extern ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId); diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index 880679127b..d5e22811d0 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -25,7 +25,7 @@ extern ObjectAddress DefineType(ParseState *pstate, List *names, List *parameter extern void RemoveTypeById(Oid typeOid); extern ObjectAddress DefineDomain(CreateDomainStmt *stmt); extern ObjectAddress DefineEnum(CreateEnumStmt *stmt); -extern ObjectAddress DefineRange(CreateRangeStmt *stmt); +extern ObjectAddress DefineRange(ParseState *pstate, CreateRangeStmt *stmt); extern ObjectAddress AlterEnum(AlterEnumStmt *stmt); extern ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist); extern Oid AssignTypeArrayOid(void); diff --git a/src/include/commands/user.h b/src/include/commands/user.h index 028e0dde56..0b7a3cd65f 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -25,7 +25,7 @@ typedef void (*check_password_hook_type) (const char *username, const char *shad extern PGDLLIMPORT check_password_hook_type check_password_hook; extern Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt); -extern Oid AlterRole(AlterRoleStmt *stmt); +extern Oid AlterRole(ParseState *pstate, AlterRoleStmt *stmt); extern Oid AlterRoleSet(AlterRoleSetStmt *stmt); extern void DropRole(DropRoleStmt *stmt); extern void GrantRole(GrantRoleStmt *stmt); 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..03d6eca747 100644 --- a/src/test/regress/expected/foreign_data.out +++ b/src/test/regress/expected/foreign_data.out @@ -94,7 +94,9 @@ 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 +LINE 1: ...GN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER in... + ^ CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler; DROP FOREIGN DATA WRAPPER test_fdw; -- ALTER FOREIGN DATA WRAPPER @@ -200,7 +202,9 @@ 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 +LINE 1: ...FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER an... + ^ 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..0f5cbe2e99 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -26,7 +26,9 @@ 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 +LINE 1: ...ub_xxx WITH (publish_via_partition_root = 'true', publish_vi... + ^ \dRp List of publications Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root -- 2.25.1