Re: Conflict Detection and Resolution - Mailing list pgsql-hackers
From | shveta malik |
---|---|
Subject | Re: Conflict Detection and Resolution |
Date | |
Msg-id | CAJpy0uCqZjpz=MnfyrHQrzw0rDuuOTWGNDsyy_=2zpTJ6dx2Tg@mail.gmail.com Whole thread Raw |
In response to | Re: Conflict Detection and Resolution (shveta malik <shveta.malik@gmail.com>) |
List | pgsql-hackers |
On Fri, Sep 27, 2024 at 2:33 PM shveta malik <shveta.malik@gmail.com> wrote: > > On Fri, Sep 27, 2024 at 10:44 AM shveta malik <shveta.malik@gmail.com> wrote: > > > > > > > > > > Thanks for the review. > > > > Here is the v14 patch-set fixing review comments in [1] and [2]. > > > > > > > > > > Thanks for the patches. I am reviewing patch001, it is WIP, but please > > > find initial set of comments: > > > > > Please find next set of comments: 1) parse_subscription_conflict_resolvers() Shall we free 'SeenTypes' list at the end? 2) General logic comment: I think SetSubConflictResolver should also accept a list similar to UpdateSubConflictResolvers() instead of array. Then we can even try merging these 2 functions later (once we do this change, it will be more clear). For SetSubConflictResolver to accept a list, SetDefaultResolvers should give a list as output instead of an array currently. 3) Existing logic: case ALTER_SUBSCRIPTION_RESET_ALL_CONFLICT_RESOLVERS: { ConflictTypeResolver conflictResolvers[CONFLICT_NUM_TYPES]; /* Remove the existing conflict resolvers. */ RemoveSubscriptionConflictResolvers(subid); /* * Create list of conflict resolvers and set them in the * catalog. */ SetDefaultResolvers(conflictResolvers); SetSubConflictResolver(subid, conflictResolvers, CONFLICT_NUM_TYPES); } Suggestion: If we fix comment #2 and make SetSubConflictResolver and SetDefaultResolvers to deal with list, then here we can get rid of RemoveSubscriptionConflictResolvers(), we can simply make a default list using SetDefaultResolvers and call UpdateSubConflictResolvers(). No need for 2 separate calls for delete and insert/set. 4) Shall ResetConflictResolver() function also call UpdateSubConflictResolvers internally? It will get rid of a lot code duplication. ResetConflictResolver()'s new approach could be: a) validate conflict type and get enum value. To do this job, make a sub-function validate_conflict_type() which will be called both from here and from validate_conflict_type_and_resolver(). b) get default resolver for given conflict-type enum and then get resolver string for that to help step c. c) create a list of single element of ConflictTypeResolver and call UpdateSubConflictResolvers. 5) typedefs.list ConflictResolver is missed? 6) subscriptioncmds.c /* Get the list of conflict types and resolvers and validate them. */ conflict_resolvers = GetAndValidateSubsConflictResolverList(stmt->resolvers); No full stop needed in one line comment. But since it is >80 chars, it is good to split it to multiple lines and then full stop can be retained. 7) Shall we move the call to conf_detection_check_prerequisites() to GetAndValidateSubsConflictResolverList() similar to how we do it for parse_subscription_conflict_resolvers()? (I still prefer that GetAndValidateSubsConflictResolverList and parse_subscription_conflict_resolvers should be merged in the first place. Array to list conversion as suggested in comment #2 will make these two functions more similar, and then we can review to merge them.) 8) Shall parse_subscription_conflict_resolvers() be moved to conflict.c as well? Or since it is subscription options' parsing, is it more suited in the current file? Thoughts? 9) Existing: /* * Parsing function for conflict resolvers in CREATE SUBSCRIPTION command. * This function will report an error if mutually exclusive or duplicate * options are specified. */ Suggestion: /* * Parsing function for conflict resolvers in CREATE SUBSCRIPTION command. * * In addition to parsing and validating the resolvers' configuration, this function * also reports an error if mutually exclusive options are specified. */ 10) Test comments (subscription.sql): ------ a) -- fail - invalid conflict resolvers CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub CONFLICT RESOLVER (insert_exists = foo) WITH (connect = false); -- fail - invalid conflict types CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub CONFLICT RESOLVER (foo = 'keep_local') WITH (connect = false); We should swap the order of these 2 tests. Make it similar to ALTER tests. b) -- fail - invalid conflict resolvers resolvers-->resolver -- fail - invalid conflict types types-->type -- fail - duplicate conflict types types->type c) -- creating subscription should create default conflict resolvers Suggestion: -- creating subscription with no explicit conflict resolvers should configure default conflict resolvers d) -- ok - valid conflict type and resolvers type-->types e) -- fail - altering with duplicate conflict types types --> type ------ thanks Shveta
pgsql-hackers by date: