From 1bf7d13b1b835f6658695999bd10b23496c177b8 Mon Sep 17 00:00:00 2001 From: Vigneshwaran C Date: Mon, 30 Aug 2021 19:23:27 +0530 Subject: [PATCH v23 4/4] Alter publication syntax enhancement to keep it similar to create publication. Alter publication syntax enhancement to keep it similar to create publication to support FOR TABLE, FOR ALL TABLES IN SCHEMA syntax. --- doc/src/sgml/ref/alter_publication.sgml | 26 +++++++-- src/backend/commands/publicationcmds.c | 70 ++++++----------------- src/backend/nodes/copyfuncs.c | 3 +- src/backend/nodes/equalfuncs.c | 3 +- src/backend/parser/gram.y | 75 +++---------------------- src/include/nodes/nodes.h | 1 - src/include/nodes/parsenodes.h | 20 +------ src/tools/pgindent/typedefs.list | 2 - 8 files changed, 46 insertions(+), 154 deletions(-) diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 21788f7176..7722550f19 100644 --- a/doc/src/sgml/ref/alter_publication.sgml +++ b/doc/src/sgml/ref/alter_publication.sgml @@ -21,12 +21,12 @@ PostgreSQL documentation -ALTER PUBLICATION name ADD TABLE [ ONLY ] table_name [ * ] [, ...] -ALTER PUBLICATION name SET TABLE [ ONLY ] table_name [ * ] [, ...] -ALTER PUBLICATION name DROP TABLE [ ONLY ] table_name [ * ] [, ...] -ALTER PUBLICATION name ADD ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] -ALTER PUBLICATION name SET ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] -ALTER PUBLICATION name DROP ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] +ALTER PUBLICATION name ADD { TABLE [ ONLY ] table_name [ * ] [, ...] } + | { ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] } +ALTER PUBLICATION name SET { TABLE [ ONLY ] table_name [ * ] [, ...] } + | { ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] } +ALTER PUBLICATION name DROP { TABLE [ ONLY ] table_name [ * ] [, ...] } + | { ALL TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ...] } ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] ) ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER PUBLICATION name RENAME TO new_name @@ -175,6 +175,20 @@ ALTER PUBLICATION sales_publication ADD ALL TABLES IN SCHEMA marketing_june, sal + + ADD some tables and schemas to the publication: + +ALTER PUBLICATION production_publication ADD TABLE users, departments, ALL TABLES IN SCHEMA production; + + + + + Add some schemas to the publication: + +ALTER PUBLICATION sales_publication ADD ALL TABLES IN SCHEMA marketing_june, sales_june; + + + Drop some schema from the publication: diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 438bfc4b02..c26261f9ab 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -141,49 +141,6 @@ parse_publication_options(ParseState *pstate, } } -/* - * Convert the SchemaSpec list into an Oid list. - */ -static List * -ConvertSchemaSpecListToOidList(List *schemas) -{ - List *schemaoidlist = NIL; - ListCell *cell; - - foreach(cell, schemas) - { - SchemaSpec *schema = (SchemaSpec *) lfirst(cell); - Oid schemaoid; - List *search_path; - char *nspname; - - if (schema->schematype == SCHEMASPEC_CURRENT_SCHEMA) - { - search_path = fetch_search_path(false); - if (search_path == NIL) /* nothing valid in search_path? */ - ereport(ERROR, - errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("no schema has been selected")); - - schemaoid = linitial_oid(search_path); - nspname = get_namespace_name(schemaoid); - if (nspname == NULL) /* recently-deleted namespace? */ - ereport(ERROR, - errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("no schema has been selected")); - - list_free(search_path); - } - else - schemaoid = get_namespace_oid(schema->schemaname, false); - - /* Filter out duplicates if user specifies "sch1, sch1" */ - schemaoidlist = list_append_unique_oid(schemaoidlist, schemaoid); - } - - return schemaoidlist; -} - /* * Convert the PublicationObjSpecType list into schema oid list and rangevar * list. @@ -510,7 +467,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, */ static void AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, - HeapTuple tup) + HeapTuple tup, List *tables) { List *rels = NIL; Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); @@ -524,9 +481,9 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, NameStr(pubform->pubname)), errdetail("Tables cannot be added to, dropped from, or set on FOR ALL TABLES publications."))); - Assert(list_length(stmt->tables) > 0); + Assert(list_length(tables) > 0); - rels = OpenTableList(stmt->tables); + rels = OpenTableList(tables); if (stmt->action == DEFELEM_ADD) PublicationAddTables(pubid, rels, false, stmt); @@ -587,9 +544,9 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, * Add/Remove/Set the schemas to/from publication. */ static void -AlterPublicationSchemas(AlterPublicationStmt *stmt, Relation rel, HeapTuple tup) +AlterPublicationSchemas(AlterPublicationStmt *stmt, Relation rel, + HeapTuple tup, List *schemaoidlist) { - List *schemaoidlist = NIL; Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); /* Check that user is allowed to manipulate the publication tables */ @@ -606,9 +563,6 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt, Relation rel, HeapTuple tup) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to add or set schemas"))); - /* Convert the text list into oid list */ - schemaoidlist = ConvertSchemaSpecListToOidList(stmt->schemas); - /* * Schema lock is held until the publication is altered to prevent * concurrent schema deletion. No need to unlock the schemas, the locks @@ -652,6 +606,8 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) Relation rel; HeapTuple tup; Form_pg_publication pubform; + List *relations = NIL; + List *schemaoidlist = NIL; rel = table_open(PublicationRelationId, RowExclusiveLock); @@ -671,12 +627,18 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION, stmt->pubname); + ConvertPubObjSpecListToOidList(stmt->pubobjects, pstate, &relations, + &schemaoidlist); + if (stmt->options) AlterPublicationOptions(pstate, stmt, rel, tup); - else if (stmt->schemas) - AlterPublicationSchemas(stmt, rel, tup); else - AlterPublicationTables(stmt, rel, tup); + { + if (schemaoidlist) + AlterPublicationSchemas(stmt, rel, tup, schemaoidlist); + if (relations) + AlterPublicationTables(stmt, rel, tup, relations); + } /* Cleanup. */ heap_freetuple(tup); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index bcb937c7be..4f15214d8c 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -4821,8 +4821,7 @@ _copyAlterPublicationStmt(const AlterPublicationStmt *from) COPY_STRING_FIELD(pubname); COPY_NODE_FIELD(options); - COPY_NODE_FIELD(tables); - COPY_NODE_FIELD(schemas); + COPY_NODE_FIELD(pubobjects); COPY_SCALAR_FIELD(for_all_tables); COPY_SCALAR_FIELD(action); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 05ca195af8..14af6b9937 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2307,8 +2307,7 @@ _equalAlterPublicationStmt(const AlterPublicationStmt *a, { COMPARE_STRING_FIELD(pubname); COMPARE_NODE_FIELD(options); - COMPARE_NODE_FIELD(tables); - COMPARE_NODE_FIELD(schemas); + COMPARE_NODE_FIELD(pubobjects); COMPARE_SCALAR_FIELD(for_all_tables); COMPARE_SCALAR_FIELD(action); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index e408acfce3..53b5d012d2 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -169,7 +169,6 @@ static Node *makeNullAConst(int location); static Node *makeAConst(Value *v, int location); static Node *makeBoolAConst(bool state, int location); static RoleSpec *makeRoleSpec(RoleSpecType type, int location); -static SchemaSpec *makeSchemaSpec(SchemaSpecType type, int location); static void check_qualified_name(List *names, core_yyscan_t yyscanner); static List *check_func_name(List *names, core_yyscan_t yyscanner); static List *check_indirection(List *indirection, core_yyscan_t yyscanner); @@ -258,7 +257,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionSpec *partspec; PartitionBoundSpec *partboundspec; RoleSpec *rolespec; - SchemaSpec *schemaspec; PublicationObjSpec *publicationobjectspec; struct SelectLimit *selectlimit; SetQuantifier setquantifier; @@ -429,7 +427,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); transform_element_list transform_type_list TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list - drop_option_list schema_list pub_obj_list + drop_option_list pub_obj_list %type opt_routine_body %type group_clause @@ -556,7 +554,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type createdb_opt_name plassign_target %type var_value zone_value %type auth_ident RoleSpec opt_granted_by -%type SchemaSpec %type PublicationObjSpec %type pubobj_expr %type unreserved_keyword type_func_name_keyword @@ -9705,26 +9702,6 @@ pub_obj_list: PublicationObjSpec { $$ = lappend($1, $3); } ; -/* Schema specifications */ -SchemaSpec: ColId - { - SchemaSpec *n; - n = makeSchemaSpec(SCHEMASPEC_CSTRING, @1); - n->schemaname = pstrdup($1); - $$ = n; - } - | CURRENT_SCHEMA - { - $$ = makeSchemaSpec(SCHEMASPEC_CURRENT_SCHEMA, @1); - } - ; - -schema_list: SchemaSpec - { $$ = list_make1($1); } - | schema_list ',' SchemaSpec - { $$ = lappend($1, $3); } - ; - /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) @@ -9750,51 +9727,27 @@ AlterPublicationStmt: n->options = $5; $$ = (Node *)n; } - | ALTER PUBLICATION name ADD_P TABLE relation_expr_list + | ALTER PUBLICATION name ADD_P pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); n->pubname = $3; - n->tables = $6; + n->pubobjects = $5; n->action = DEFELEM_ADD; $$ = (Node *)n; } - | ALTER PUBLICATION name SET TABLE relation_expr_list + | ALTER PUBLICATION name SET pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); n->pubname = $3; - n->tables = $6; + n->pubobjects = $5; n->action = DEFELEM_SET; $$ = (Node *)n; } - | ALTER PUBLICATION name DROP TABLE relation_expr_list + | ALTER PUBLICATION name DROP pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); n->pubname = $3; - n->tables = $6; - n->action = DEFELEM_DROP; - $$ = (Node *)n; - } - | ALTER PUBLICATION name ADD_P ALL TABLES IN_P SCHEMA schema_list - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = $3; - n->schemas = $9; - n->action = DEFELEM_ADD; - $$ = (Node *)n; - } - | ALTER PUBLICATION name SET ALL TABLES IN_P SCHEMA schema_list - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = $3; - n->schemas = $9; - n->action = DEFELEM_SET; - $$ = (Node *)n; - } - | ALTER PUBLICATION name DROP ALL TABLES IN_P SCHEMA schema_list - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = $3; - n->schemas = $9; + n->pubobjects = $5; n->action = DEFELEM_DROP; $$ = (Node *)n; } @@ -16744,20 +16697,6 @@ makeRoleSpec(RoleSpecType type, int location) return spec; } -/* - * makeSchemaSpec - Create a SchemaSpec with the given type and location - */ -static SchemaSpec * -makeSchemaSpec(SchemaSpecType type, int location) -{ - SchemaSpec *spec = makeNode(SchemaSpec); - - spec->schematype = type; - spec->location = location; - - return spec; -} - /* check_qualified_name --- check the result of qualified_name production * * It's easiest to let the grammar production for qualified_name allow diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index af82a2fd7f..bec18e978a 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -484,7 +484,6 @@ typedef enum NodeTag T_CommonTableExpr, T_PublicationObjSpec, T_RoleSpec, - T_SchemaSpec, T_TriggerTransition, T_PartitionElem, T_PartitionSpec, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 495f7453ea..a2d3990054 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -341,23 +341,6 @@ typedef struct RoleSpec int location; /* token location, or -1 if unknown */ } RoleSpec; -/* - * SchemaSpec - a schema name or CURRENT_SCHEMA - */ -typedef enum SchemaSpecType -{ - SCHEMASPEC_CSTRING, /* schema name is stored as a C string */ - SCHEMASPEC_CURRENT_SCHEMA /* schema spec is CURRENT_SCHEMA */ -} SchemaSpecType; - -typedef struct SchemaSpec -{ - NodeTag type; - SchemaSpecType schematype; /* type of this schemaspec */ - char *schemaname; /* filled only for SCHEMASPEC_CSTRING */ - int location; /* token location, or -1 if unknown */ -} SchemaSpec; - /* * Publication object type */ @@ -3683,8 +3666,7 @@ typedef struct AlterPublicationStmt List *options; /* List of DefElem nodes */ /* parameters used for ALTER PUBLICATION ... ADD/DROP TABLE/SCHEMA */ - List *tables; /* List of tables to add/drop */ - List *schemas; /* List of schemas to add/drop/set */ + List *pubobjects; /* Optional list of publication objects */ bool for_all_tables; /* Special publication for all tables in db */ DefElemAction action; /* What action to perform with the * tables/schemas */ diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index fc0deec206..2d24e72329 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2336,8 +2336,6 @@ ScanState ScanTypeControl ScannerCallbackState SchemaQuery -SchemaSpec -SchemaSpecType SecBuffer SecBufferDesc SecLabelItem -- 2.30.2