Skip to content

Commit 00029de

Browse files
committed
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
1 parent f99870d commit 00029de

File tree

3 files changed

+35
-42
lines changed

3 files changed

+35
-42
lines changed

src/backend/commands/subscriptioncmds.c

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,16 @@ static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname,
9595
*
9696
* Since not all options can be specified in both commands, this function
9797
* will report an error if mutually exclusive options are specified.
98-
*
99-
* Caller is expected to have cleared 'opts'.
10098
*/
10199
static void
102100
parse_subscription_options(ParseState *pstate, List *stmt_options,
103101
bits32 supported_opts, SubOpts *opts)
104102
{
105103
ListCell *lc;
106104

105+
/* Start out with cleared opts. */
106+
memset(opts, 0, sizeof(SubOpts));
107+
107108
/* caller must expect some option */
108109
Assert(supported_opts != 0);
109110

@@ -262,7 +263,6 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
262263
{
263264
/* Check for incompatible options from the user. */
264265
if (opts->enabled &&
265-
IsSet(supported_opts, SUBOPT_ENABLED) &&
266266
IsSet(opts->specified_opts, SUBOPT_ENABLED))
267267
ereport(ERROR,
268268
(errcode(ERRCODE_SYNTAX_ERROR),
@@ -271,15 +271,13 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
271271
"connect = false", "enabled = true")));
272272

273273
if (opts->create_slot &&
274-
IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
275274
IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
276275
ereport(ERROR,
277276
(errcode(ERRCODE_SYNTAX_ERROR),
278277
errmsg("%s and %s are mutually exclusive options",
279278
"connect = false", "create_slot = true")));
280279

281280
if (opts->copy_data &&
282-
IsSet(supported_opts, SUBOPT_COPY_DATA) &&
283281
IsSet(opts->specified_opts, SUBOPT_COPY_DATA))
284282
ereport(ERROR,
285283
(errcode(ERRCODE_SYNTAX_ERROR),
@@ -297,44 +295,39 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
297295
* was used.
298296
*/
299297
if (!opts->slot_name &&
300-
IsSet(supported_opts, SUBOPT_SLOT_NAME) &&
301298
IsSet(opts->specified_opts, SUBOPT_SLOT_NAME))
302299
{
303-
if (opts->enabled &&
304-
IsSet(supported_opts, SUBOPT_ENABLED) &&
305-
IsSet(opts->specified_opts, SUBOPT_ENABLED))
306-
ereport(ERROR,
307-
(errcode(ERRCODE_SYNTAX_ERROR),
308-
/*- translator: both %s are strings of the form "option = value" */
309-
errmsg("%s and %s are mutually exclusive options",
310-
"slot_name = NONE", "enabled = true")));
311-
312-
if (opts->create_slot &&
313-
IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
314-
IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
315-
ereport(ERROR,
316-
(errcode(ERRCODE_SYNTAX_ERROR),
317-
/*- translator: both %s are strings of the form "option = value" */
318-
errmsg("%s and %s are mutually exclusive options",
319-
"slot_name = NONE", "create_slot = true")));
320-
321-
if (opts->enabled &&
322-
IsSet(supported_opts, SUBOPT_ENABLED) &&
323-
!IsSet(opts->specified_opts, SUBOPT_ENABLED))
324-
ereport(ERROR,
325-
(errcode(ERRCODE_SYNTAX_ERROR),
326-
/*- translator: both %s are strings of the form "option = value" */
327-
errmsg("subscription with %s must also set %s",
328-
"slot_name = NONE", "enabled = false")));
300+
if (opts->enabled)
301+
{
302+
if (IsSet(opts->specified_opts, SUBOPT_ENABLED))
303+
ereport(ERROR,
304+
(errcode(ERRCODE_SYNTAX_ERROR),
305+
/*- translator: both %s are strings of the form "option = value" */
306+
errmsg("%s and %s are mutually exclusive options",
307+
"slot_name = NONE", "enabled = true")));
308+
else
309+
ereport(ERROR,
310+
(errcode(ERRCODE_SYNTAX_ERROR),
311+
/*- translator: both %s are strings of the form "option = value" */
312+
errmsg("subscription with %s must also set %s",
313+
"slot_name = NONE", "enabled = false")));
314+
}
329315

330-
if (opts->create_slot &&
331-
IsSet(supported_opts, SUBOPT_CREATE_SLOT) &&
332-
!IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
333-
ereport(ERROR,
334-
(errcode(ERRCODE_SYNTAX_ERROR),
335-
/*- translator: both %s are strings of the form "option = value" */
336-
errmsg("subscription with %s must also set %s",
337-
"slot_name = NONE", "create_slot = false")));
316+
if (opts->create_slot)
317+
{
318+
if (IsSet(opts->specified_opts, SUBOPT_CREATE_SLOT))
319+
ereport(ERROR,
320+
(errcode(ERRCODE_SYNTAX_ERROR),
321+
/*- translator: both %s are strings of the form "option = value" */
322+
errmsg("%s and %s are mutually exclusive options",
323+
"slot_name = NONE", "create_slot = true")));
324+
else
325+
ereport(ERROR,
326+
(errcode(ERRCODE_SYNTAX_ERROR),
327+
/*- translator: both %s are strings of the form "option = value" */
328+
errmsg("subscription with %s must also set %s",
329+
"slot_name = NONE", "create_slot = false")));
330+
}
338331
}
339332
}
340333

src/test/regress/expected/subscription.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PU
5454
ERROR: connect = false and create_slot = true are mutually exclusive options
5555
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true);
5656
ERROR: slot_name = NONE and enabled = true are mutually exclusive options
57-
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true);
57+
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false, create_slot = true);
5858
ERROR: slot_name = NONE and create_slot = true are mutually exclusive options
5959
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE);
6060
ERROR: subscription with slot_name = NONE must also set enabled = false

src/test/regress/sql/subscription.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PU
4343
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true);
4444
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true);
4545
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true);
46-
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true);
46+
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false, create_slot = true);
4747
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE);
4848
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false);
4949
CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy