From bcee1a20adbd31b1af78bdd2c5b9671e948421e2 Mon Sep 17 00:00:00 2001 From: Vigneshwaran C Date: Fri, 27 Aug 2021 09:23:47 +0530 Subject: [PATCH v22 3/3] 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. --- src/backend/commands/publicationcmds.c | 68 ++++++----------------- src/backend/nodes/copyfuncs.c | 3 +- src/backend/nodes/equalfuncs.c | 3 +- src/backend/parser/gram.y | 75 +++----------------------- src/include/nodes/parsenodes.h | 20 +------ src/tools/pgindent/typedefs.list | 2 - 6 files changed, 26 insertions(+), 145 deletions(-) diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index e694c67369..0f2ee6173e 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -141,47 +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")); - } - 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. @@ -507,7 +466,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); @@ -521,9 +480,9 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, NameStr(pubform->pubname)), errdetail("Tables cannot be added, dropped 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) { @@ -586,9 +545,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 */ @@ -605,9 +564,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 @@ -651,6 +607,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); @@ -670,12 +628,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/parsenodes.h b/src/include/nodes/parsenodes.h index 7175ae1fe5..9153466f2c 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 */ @@ -3684,8 +3667,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 7f5d0e16df..d0e3179519 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2335,8 +2335,6 @@ ScanState ScanTypeControl ScannerCallbackState SchemaQuery -SchemaSpec -SchemaSpecType SecBuffer SecBufferDesc SecLabelItem -- 2.30.2