Skip to content

Mirror the source node's replication sets onto the node being added. - #559

Open
ibrarahmad wants to merge 1 commit into
mainfrom
spock-zodan-repset
Open

Mirror the source node's replication sets onto the node being added.#559
ibrarahmad wants to merge 1 commit into
mainfrom
spock-zodan-repset

Conversation

@ibrarahmad

Copy link
Copy Markdown
Contributor

Subscriptions named the three built-in sets literally, and nothing copied the source's sets to the new node, so tables in a user-created set were silently neither sent nor received. Membership was re-derived by AutoDDL during the structure restore rather than copied, losing column lists, row filters, and any table the user had removed from a set. Read the sets from the source instead, and copy the definitions and membership once the data sync has completed.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c91c41d7-9598-4590-8a3a-de41115bb812

📥 Commits

Reviewing files that changed from the base of the PR and between 4084ac3 and 8638338.

📒 Files selected for processing (1)
  • samples/Z0DAN/zodan.sql

📝 Walkthrough

Walkthrough

The Z0DAN SQL now discovers and mirrors provider replication sets during node addition. Subscription creation uses complete provider-specific replication-set lists. The workflow synchronizes sets after initial synchronization and before subscription enablement.

Changes

Replication-set synchronization

Layer / File(s) Summary
Source replication-set synchronization
samples/Z0DAN/zodan.sql
Adds provider replication-set discovery, drift comparison, and synchronization. The procedure copies definitions, memberships, column lists, row filters, and sequence memberships. It clears auto-derived memberships, removes stale sets, and rejects missing relations.
Dynamic subscription replication sets
samples/Z0DAN/zodan.sql
Updates subscription creation paths to use complete replication-set lists from the relevant provider or mirrored node instead of the fixed built-in sets.
Node-add orchestration
samples/Z0DAN/zodan.sql
Runs replication-set synchronization over dblink after initial synchronization and before subscription enablement. The workflow stores the result, reports post-sync drift, and updates subsequent phase numbering.

Poem

I’m a rabbit with sets in a row,
Mirroring the rules where records flow.
Stale sets hop away,
New memberships stay.
Subscriptions follow the list,
As nodes join the synchronized mist.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: mirroring source replication sets onto the new node.
Description check ✅ Passed The description accurately explains the replication-set synchronization problem and the changes that preserve custom sets and membership details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spock-zodan-repset

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
samples/Z0DAN/zodan.sql (2)

1237-1254: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Reuse one source set list instead of a second dblink query.

Line 1211 already reads the source set list. This loop reads it again over dblink. Two reads can return different results if a user changes sets on the source between the two queries. The membership drift check in step 5 does not cover set definitions, so a set created on the source between the two reads is created locally and then dropped again.

Collect the source set names into a local text[] once, then use it for both the create/alter loop and the drop loop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@samples/Z0DAN/zodan.sql` around lines 1237 - 1254, Reuse the source
replication-set list already fetched near line 1211 instead of issuing a second
dblink query in the drop loop. Store that result in a local text[] and use it
for both the create/alter processing and the NOT IN membership check before
spock.repset_drop, preserving consistent source-set membership across the
operation.

2166-2166: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Two procedures initialize repsets with a dblink call inside DECLARE. A variable initializer runs before the block body, so an EXCEPTION handler in the procedure cannot catch a remote-connection failure, and no phase notice is emitted before the error. The shared fix is to assign repsets as the first statement after BEGIN.

  • samples/Z0DAN/zodan.sql#L2166-L2166: in create_new_to_source_subscription, declare repsets text; without an initializer and assign repsets := spock.source_repset_list(src_dsn); after BEGIN.
  • samples/Z0DAN/zodan.sql#L2201-L2201: in create_source_to_new_subscription, apply the same change.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@samples/Z0DAN/zodan.sql` at line 2166, Move the dblink initializer out of the
DECLARE sections of create_new_to_source_subscription and
create_source_to_new_subscription: declare repsets as text, then assign
spock.source_repset_list(src_dsn) as the first statement after BEGIN so the
existing exception handlers and phase notices can handle connection failures.
Apply this change at samples/Z0DAN/zodan.sql lines 2166-2166 and 2201-2201.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@samples/Z0DAN/zodan.sql`:
- Around line 1327-1361: Replace the row-count comparisons in the add_node
membership recheck with ordered digests of the complete replication-set
definitions and memberships, including set attributes such as set_att_list and
set_row_filter. Apply the same digest comparison to table and sequence
memberships, declare src_digest and local_digest as text in the DECLARE block,
and retain the existing failure notice/exception when either digest differs.
- Around line 2787-2814: Update the hardcoded RAISE NOTICE phase labels in the
post-Phase 8 procedures to match add_node’s current ordering: enabling disabled
subscriptions is Phase 9, creating the subscription to the source is Phase 10,
and each subsequent procedure advances accordingly. Apply this consistently to
the procedures invoked after sync_repsets_from_source, without changing their
execution order.
- Around line 1262-1287: The row-filter handling in the dblink query must
preserve the catalog’s pg_node_tree value instead of deparsing set_row_filter
with pg_get_expr and passing text to spock.repset_add_table. Update the SELECT
and corresponding dblink record type to copy or restore the row filter through
the API’s representation-preserving mechanism, while keeping the existing table
and replication-set processing unchanged.
- Line 1897: Ensure every source-derived replication set in repsets is owned by
each provider referenced by rec.dsn before subscriptions are created. Validate
provider membership and add or mirror missing sets for other providers,
preserving all source replication sets so tables in them are included in
replication.

---

Nitpick comments:
In `@samples/Z0DAN/zodan.sql`:
- Around line 1237-1254: Reuse the source replication-set list already fetched
near line 1211 instead of issuing a second dblink query in the drop loop. Store
that result in a local text[] and use it for both the create/alter processing
and the NOT IN membership check before spock.repset_drop, preserving consistent
source-set membership across the operation.
- Line 2166: Move the dblink initializer out of the DECLARE sections of
create_new_to_source_subscription and create_source_to_new_subscription: declare
repsets as text, then assign spock.source_repset_list(src_dsn) as the first
statement after BEGIN so the existing exception handlers and phase notices can
handle connection failures. Apply this change at samples/Z0DAN/zodan.sql lines
2166-2166 and 2201-2201.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 646b67b0-afe4-442c-b1d3-705a93840996

📥 Commits

Reviewing files that changed from the base of the PR and between 90fd9ae and 0bea1e8.

📒 Files selected for processing (1)
  • samples/Z0DAN/zodan.sql

Comment thread samples/Z0DAN/zodan.sql
Comment thread samples/Z0DAN/zodan.sql Outdated
Comment thread samples/Z0DAN/zodan.sql Outdated
Comment thread samples/Z0DAN/zodan.sql
Comment thread samples/Z0DAN/zodan.sql Outdated
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
samples/Z0DAN/zodan.sql (1)

2844-2848: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Phase 8 progress notices never reach the user.

sync_repsets_from_source raises notices at lines 1189, 1219, 1282, 1350 and 1401. A notice raised inside a dblink session is not forwarded to the calling session, so all of them are discarded and only line 2847 is printed. Phase 8 is then the one phase that reports no counters, while the RAISE EXCEPTION paths still surface as dblink errors.

Return the counters from the remote call and print them locally, or accept the gap and drop the unreachable notices from the procedure.

Also refine the comment at lines 1164-1165. A single CALL over dblink_exec commits as one remote transaction, so the locks are released when that CALL returns, not after each statement. The deadlock-avoidance reason stays valid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@samples/Z0DAN/zodan.sql` around lines 2844 - 2848, Update Phase 8 around
sync_repsets_from_source and its dblink_exec call so the remote procedure
returns its counters and the caller prints them locally, preserving surfaced
exceptions. Revise the nearby lock comment to state that locks are released when
the single remote CALL transaction completes, while retaining the
deadlock-avoidance rationale.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@samples/Z0DAN/zodan.sql`:
- Line 2209: Confirm the add_node call order and update the Phase notice in
create_new_to_source_subscription so it uses the correct unique phase number,
avoiding the duplicate Phase 10 announcement from
create_sub_on_new_node_to_src_node. Keep the surrounding notice text and
procedure behavior unchanged.

---

Nitpick comments:
In `@samples/Z0DAN/zodan.sql`:
- Around line 2844-2848: Update Phase 8 around sync_repsets_from_source and its
dblink_exec call so the remote procedure returns its counters and the caller
prints them locally, preserving surfaced exceptions. Revise the nearby lock
comment to state that locks are released when the single remote CALL transaction
completes, while retaining the deadlock-avoidance rationale.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 06dfa929-eea3-4583-a1bc-157be3da362f

📥 Commits

Reviewing files that changed from the base of the PR and between 90fd9ae and 149b251.

📒 Files selected for processing (1)
  • samples/Z0DAN/zodan.sql

Comment thread samples/Z0DAN/zodan.sql Outdated
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@ibrarahmad ibrarahmad self-assigned this Aug 5, 2026
Subscriptions named the three built-in sets literally, and nothing copied the
source's sets to the new node, so tables in a user-created set were silently
neither sent nor received.  Membership was re-derived by AutoDDL during the
structure restore rather than copied, losing column lists, row filters, and any
table the user had removed from a set.  Read each subscription's sets from its
provider, and copy the definitions and membership once the data sync completes.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@danolivo
danolivo self-requested a review August 5, 2026 09:59

@danolivo danolivo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, it looks good and might serve as a quick intermediate fix. But before merging it, I'd like to see the reasoning:

  1. Why base machinery not inside the Spock. spock.repset_export(node_id) / spock.repset_import(jsonb) might serve better and be used in different situations. At least - no dblink needed, less round trips, locks, etc. spock.repset_diff() also might be a general tool and let users be sure if replication sets are symmetrical.
  2. AutoDDL on a next table will send it to default/default_insert_only repset even if user deliberately put it into a custom repset, isn't it?
  3. It seems to me that COPY machinery shouldn't rely on AutoDDL and we need to add one more stage after the SYNC_STATUS_CONSTRAINTS - SYNC_STATUS_REPSETS. It will explicitly guarantee that we mirror replication sets (it may be designed optional) and remove (potentially) the whole phase 8 from zodan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants