diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml index 9f2fb93..c89a016 100644 --- a/doc/src/sgml/ref/drop_subscription.sgml +++ b/doc/src/sgml/ref/drop_subscription.sgml @@ -21,7 +21,11 @@ PostgreSQL documentation -DROP SUBSCRIPTION [ IF EXISTS ] name [ DROP SLOT | NODROP SLOT ] + DROP SUBSCRIPTION [ IF EXISTS ] name [ WITH ( option [, ...] ) ] + + where option can be: + + | DROP SLOT | NODROP SLOT diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 0e08138..c5c8581 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -41,7 +41,8 @@ #include "utils/syscache.h" /* - * Common option parsing function for CREATE and ALTER SUBSCRIPTION commands. + * Common option parsing function for CREATE, DROP and ALTER SUBSCRIPTION + * commands. * * Since not all options can be specified in both commands, this function * will report an error on options if the target output pointer is NULL to @@ -50,10 +51,12 @@ static void parse_subscription_options(List *options, char **conninfo, List **publications, bool *enabled_given, - bool *enabled, bool *create_slot, char **slot_name) + bool *enabled, bool *create_slot, bool *drop_slot, + char **slot_name) { ListCell *lc; bool create_slot_given = false; + bool drop_slot_given = false; if (conninfo) *conninfo = NULL; @@ -66,6 +69,8 @@ parse_subscription_options(List *options, char **conninfo, } if (create_slot) *create_slot = true; + if (drop_slot) + *drop_slot = true; if (slot_name) *slot_name = NULL; @@ -132,6 +137,24 @@ parse_subscription_options(List *options, char **conninfo, create_slot_given = true; *create_slot = !defGetBoolean(defel); } + else if (strcmp(defel->defname, "drop slot") == 0 && drop_slot) + { + if (drop_slot_given) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + drop_slot_given = true; + *drop_slot = defGetBoolean(defel); + } + else if (strcmp(defel->defname, "nodrop slot") == 0 && drop_slot) + { + if (drop_slot_given) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + drop_slot_given = true; + *drop_slot = !defGetBoolean(defel); + } else if (strcmp(defel->defname, "slot name") == 0 && slot_name) { if (*slot_name) @@ -245,7 +268,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt) */ parse_subscription_options(stmt->options, NULL, NULL, &enabled_given, &enabled, - &create_slot, &slotname); + &create_slot, NULL, &slotname); if (slotname == NULL) slotname = stmt->subname; @@ -372,7 +395,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt) /* Parse options. */ parse_subscription_options(stmt->options, &conninfo, &publications, &enabled_given, &enabled, - NULL, &slot_name); + NULL, NULL, &slot_name); /* Form a new tuple. */ memset(values, 0, sizeof(values)); @@ -440,6 +463,15 @@ DropSubscription(DropSubscriptionStmt *stmt) RepOriginId originid; WalReceiverConn *wrconn = NULL; StringInfoData cmd; + bool drop_slot; + + /* + * Parse and check options. Other than drop slot option + * should not be specified here. + */ + parse_subscription_options(stmt->options, NULL, NULL, + NULL, NULL, NULL, &drop_slot, + NULL); rel = heap_open(SubscriptionRelationId, RowExclusiveLock); @@ -523,7 +555,7 @@ DropSubscription(DropSubscriptionStmt *stmt) replorigin_drop(originid); /* If the user asked to not drop the slot, we are done mow.*/ - if (!stmt->drop_slot) + if (!drop_slot) { heap_close(rel, NoLock); return; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 05d8538..b5396b1 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -4345,7 +4345,7 @@ _copyDropSubscriptionStmt(const DropSubscriptionStmt *from) DropSubscriptionStmt *newnode = makeNode(DropSubscriptionStmt); COPY_STRING_FIELD(subname); - COPY_SCALAR_FIELD(drop_slot); + COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(missing_ok); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index d595cd7..f99fab1 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2188,7 +2188,7 @@ _equalDropSubscriptionStmt(const DropSubscriptionStmt *a, const DropSubscriptionStmt *b) { COMPARE_STRING_FIELD(subname); - COMPARE_SCALAR_FIELD(drop_slot); + COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(missing_ok); return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6c6d21b..7804eee 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -413,7 +413,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type arg_class %type func_return func_type -%type opt_trusted opt_restart_seqs opt_drop_slot +%type opt_trusted opt_restart_seqs %type OptTemp %type OptNoLog %type OnCommitOption @@ -9165,44 +9165,28 @@ AlterSubscriptionStmt: /***************************************************************************** * - * DROP SUBSCRIPTION [ IF EXISTS ] name + * DROP SUBSCRIPTION [ IF EXISTS ] name [ WITH (options) ] * *****************************************************************************/ -DropSubscriptionStmt: DROP SUBSCRIPTION name opt_drop_slot +DropSubscriptionStmt: DROP SUBSCRIPTION name opt_definition { DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); n->subname = $3; - n->drop_slot = $4; + n->options = $4; n->missing_ok = false; $$ = (Node *) n; } - | DROP SUBSCRIPTION IF_P EXISTS name opt_drop_slot + | DROP SUBSCRIPTION IF_P EXISTS name opt_definition { DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); n->subname = $5; - n->drop_slot = $6; + n->options = $6; n->missing_ok = true; $$ = (Node *) n; } ; -opt_drop_slot: - IDENT SLOT - { - if (strcmp($1, "drop") == 0) - $$ = TRUE; - else if (strcmp($1, "nodrop") == 0) - $$ = FALSE; - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized option \"%s\"", $1), - parser_errposition(@1))); - } - | /*EMPTY*/ { $$ = TRUE; } - ; - /***************************************************************************** * * QUERY: Define Rewrite Rule diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 5afc3eb..8ef61fa 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -3296,7 +3296,7 @@ typedef struct DropSubscriptionStmt { NodeTag type; char *subname; /* Name of of the subscription */ - bool drop_slot; /* Should we drop the slot on remote side? */ + List *options; /* List of DefElem nodes */ bool missing_ok; /* Skip error if missing? */ } DropSubscriptionStmt; diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index ec5ada9..de0c86d 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -464,7 +464,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*, SET client_min_messages TO 'warning'; DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub NODROP SLOT; +DROP SUBSCRIPTION addr_sub WITH (NODROP SLOT); DROP SCHEMA addr_nsp CASCADE; DROP OWNED BY regress_addr_user; DROP USER regress_addr_user; diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 2ccec98..340180e 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -61,6 +61,6 @@ ALTER SUBSCRIPTION testsub DISABLE; (1 row) COMMIT; -DROP SUBSCRIPTION testsub NODROP SLOT; +DROP SUBSCRIPTION testsub WITH (NODROP SLOT); RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index e658ea3..06cf337 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -197,7 +197,7 @@ SET client_min_messages TO 'warning'; DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub NODROP SLOT; +DROP SUBSCRIPTION addr_sub WITH (NODROP SLOT); DROP SCHEMA addr_nsp CASCADE; diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index 68c17d5..e325b0a 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -38,7 +38,7 @@ ALTER SUBSCRIPTION testsub DISABLE; COMMIT; -DROP SUBSCRIPTION testsub NODROP SLOT; +DROP SUBSCRIPTION testsub WITH (NODROP SLOT); RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user;