From fbf56a37afd3e92d4fa4da30d49cd3f8d13635de Mon Sep 17 00:00:00 2001 From: Shveta Malik Date: Mon, 24 Jun 2024 09:55:15 +0530 Subject: [PATCH v3 2/5] DDL command to configure Global Conflict Resolvers This patch adds new DDL commands to configure resolvers at global level: a) To set global resolver for a given conflict_type: SET CONFLICT RESOLVER 'conflict_resolver' FOR 'conflict_type' b) To reset to default: RESET CONFLICT RESOLVER FOR 'conflict_type' A new catalog table pg_conflict has been created to store global conflict_type and conflict_resolver configurations given by above DDL command. Initially, this catalog table holds default configuration for resolvers which is overwritten by the ones given by the user in 'SET CONFLICT RESOLVER' command. 'RESET CONFLICT RESOLVER' command will reset the resolver to default. This patch provides support to configure resolvers for below conflict types: - insert_exists - update_differ - update_missing - delete_missing --- src/backend/parser/gram.y | 42 +++- src/backend/replication/logical/conflict.c | 215 +++++++++++++++++- src/backend/tcop/utility.c | 15 ++ src/include/catalog/Makefile | 4 +- src/include/catalog/meson.build | 2 + src/include/catalog/pg_conflict.dat | 20 ++ src/include/catalog/pg_conflict.h | 43 ++++ src/include/nodes/parsenodes.h | 12 + src/include/parser/kwlist.h | 1 + src/include/replication/conflict.h | 38 +++- src/include/tcop/cmdtaglist.h | 1 + .../regress/expected/conflict_resolver.out | 50 ++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/conflict_resolver.sql | 27 +++ src/tools/pgindent/typedefs.list | 2 + 15 files changed, 467 insertions(+), 7 deletions(-) create mode 100644 src/include/catalog/pg_conflict.dat create mode 100644 src/include/catalog/pg_conflict.h create mode 100644 src/test/regress/expected/conflict_resolver.out create mode 100644 src/test/regress/sql/conflict_resolver.sql diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index a043fd4c66..42726fe3a6 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -292,7 +292,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt - ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt + ConflictResolverStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt @@ -613,6 +613,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type opt_check_option %type opt_provider security_label +%type conflict_type conflict_resolver %type xml_attribute_el %type xml_attribute_list xml_attributes @@ -772,7 +773,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); RANGE READ REAL REASSIGN RECHECK RECURSIVE REF_P REFERENCES REFERENCING REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + RESET RESOLVER RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT @@ -1039,6 +1040,7 @@ stmt: | ClosePortalStmt | ClusterStmt | CommentStmt + | ConflictResolverStmt | ConstraintsSetStmt | CopyStmt | CreateAmStmt @@ -7266,7 +7268,41 @@ comment_text: | NULL_P { $$ = NULL; } ; +/***************************************************************************** + * + * SET CONFLICT RESOLVER FOR + * RESET CONFLICT RESOLVER FOR + * + *****************************************************************************/ + +ConflictResolverStmt: + SET CONFLICT RESOLVER conflict_resolver FOR conflict_type + { + ConflictResolverStmt *n = makeNode(ConflictResolverStmt); + + n->conflict_resolver = $4; + n->conflict_type = $6; + n->isReset = false; + $$ = (Node *) n; + } + | RESET CONFLICT RESOLVER FOR conflict_type + { + ConflictResolverStmt *n = makeNode(ConflictResolverStmt); + n->conflict_type = $5; + n->isReset = true; + $$ = (Node *) n; + } + ; +conflict_type: + Sconst { $$ = $1; } + | NULL_P { $$ = NULL; } + ; + +conflict_resolver: + Sconst { $$ = $1; } + | NULL_P { $$ = NULL; } + ; /***************************************************************************** * * SECURITY LABEL [FOR ] ON IS