mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Improve parsing of options of CREATE/ALTER SUBSCRIPTION
This simplifies the code so as it is not necessary anymore for the caller of parse_subscription_options() to zero SubOpts, holding a bitmaps of the provided options as well as the default/parsed option values. This also simplifies some checks related to the options supported by a command when checking for incompatibilities. While on it, the errors generated for unsupported combinations with "slot_name = NONE" are reordered. This may generate a different errors compared to the previous major versions, but users have to go through all those errors to get a correct command in this case when using incorrect values for options "enabled" and "create\slot", so at the end the resulting command would remain the same. Author: Peter Smith Reviewed-by: Nathan Bossart Discussion: https://postgr.es/m/CAHut+PtXHfLgLHDDJ8ZN5f5Be_37mJoxpEsRg8LNmm4XCr06Rw@mail.gmail.com
This commit is contained in:
		@@ -95,8 +95,6 @@ static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname,
 | 
			
		||||
 *
 | 
			
		||||
 * Since not all options can be specified in both commands, this function
 | 
			
		||||
 * will report an error if mutually exclusive options are specified.
 | 
			
		||||
 *
 | 
			
		||||
 * Caller is expected to have cleared 'opts'.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
@@ -104,6 +102,9 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
{
 | 
			
		||||
	ListCell   *lc;
 | 
			
		||||
 | 
			
		||||
	/* Start out with cleared opts. */
 | 
			
		||||
	memset(opts, 0, sizeof(SubOpts));
 | 
			
		||||
 | 
			
		||||
	/* caller must expect some option */
 | 
			
		||||
	Assert(supported_opts != 0);
 | 
			
		||||
 | 
			
		||||
@@ -262,7 +263,6 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
	{
 | 
			
		||||
		/* Check for incompatible options from the user. */
 | 
			
		||||
		if (opts->enabled &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_ENABLED) &&
 | 
			
		||||
			IsSet(opts->specified_opts, SUBOPT_ENABLED))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
@@ -271,7 +271,6 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
							"connect = false", "enabled = true")));
 | 
			
		||||
 | 
			
		||||
		if (opts->create_slot &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
 | 
			
		||||
			IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
@@ -279,7 +278,6 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
							"connect = false", "create_slot = true")));
 | 
			
		||||
 | 
			
		||||
		if (opts->copy_data &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_COPY_DATA) &&
 | 
			
		||||
			IsSet(opts->specified_opts, SUBOPT_COPY_DATA))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
@@ -297,44 +295,39 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 | 
			
		||||
	 * was used.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!opts->slot_name &&
 | 
			
		||||
		IsSet(supported_opts, SUBOPT_SLOT_NAME) &&
 | 
			
		||||
		IsSet(opts->specified_opts, SUBOPT_SLOT_NAME))
 | 
			
		||||
	{
 | 
			
		||||
		if (opts->enabled &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_ENABLED) &&
 | 
			
		||||
			IsSet(opts->specified_opts, SUBOPT_ENABLED))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
			/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
					 errmsg("%s and %s are mutually exclusive options",
 | 
			
		||||
							"slot_name = NONE", "enabled = true")));
 | 
			
		||||
		if (opts->enabled)
 | 
			
		||||
		{
 | 
			
		||||
			if (IsSet(opts->specified_opts, SUBOPT_ENABLED))
 | 
			
		||||
				ereport(ERROR,
 | 
			
		||||
						(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
				/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
						 errmsg("%s and %s are mutually exclusive options",
 | 
			
		||||
								"slot_name = NONE", "enabled = true")));
 | 
			
		||||
			else
 | 
			
		||||
				ereport(ERROR,
 | 
			
		||||
						(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
				/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
						 errmsg("subscription with %s must also set %s",
 | 
			
		||||
								"slot_name = NONE", "enabled = false")));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (opts->create_slot &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
 | 
			
		||||
			IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
			/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
					 errmsg("%s and %s are mutually exclusive options",
 | 
			
		||||
							"slot_name = NONE", "create_slot = true")));
 | 
			
		||||
 | 
			
		||||
		if (opts->enabled &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_ENABLED) &&
 | 
			
		||||
			!IsSet(opts->specified_opts, SUBOPT_ENABLED))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
			/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
					 errmsg("subscription with %s must also set %s",
 | 
			
		||||
							"slot_name = NONE", "enabled = false")));
 | 
			
		||||
 | 
			
		||||
		if (opts->create_slot &&
 | 
			
		||||
			IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
 | 
			
		||||
			!IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
 | 
			
		||||
			ereport(ERROR,
 | 
			
		||||
					(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
			/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
					 errmsg("subscription with %s must also set %s",
 | 
			
		||||
							"slot_name = NONE", "create_slot = false")));
 | 
			
		||||
		if (opts->create_slot)
 | 
			
		||||
		{
 | 
			
		||||
			if (IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
 | 
			
		||||
				ereport(ERROR,
 | 
			
		||||
						(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
				/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
						 errmsg("%s and %s are mutually exclusive options",
 | 
			
		||||
								"slot_name = NONE", "create_slot = true")));
 | 
			
		||||
			else
 | 
			
		||||
				ereport(ERROR,
 | 
			
		||||
						(errcode(ERRCODE_SYNTAX_ERROR),
 | 
			
		||||
				/*- translator: both %s are strings of the form "option = value" */
 | 
			
		||||
						 errmsg("subscription with %s must also set %s",
 | 
			
		||||
								"slot_name = NONE", "create_slot = false")));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user