Skip to content

common: accept legacy namespace in changefeed ID JSON#4080

Merged
ti-chi-bot[bot] merged 2 commits into
pingcap:masterfrom
wlwilliamx:fix/changefeed-displayname-json-compat
Jun 8, 2026
Merged

common: accept legacy namespace in changefeed ID JSON#4080
ti-chi-bot[bot] merged 2 commits into
pingcap:masterfrom
wlwilliamx:fix/changefeed-displayname-json-compat

Conversation

@wlwilliamx

@wlwilliamx wlwilliamx commented Jan 28, 2026

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Issue Number: close #4079

What is changed and how it works?

  • Accept legacy namespace field when unmarshalling ChangeFeedDisplayName JSON (treat it as an alias of keyspace).
  • Marshal ChangeFeedDisplayName with both keyspace and legacy namespace to keep metadata readable across versions.
  • Add a unit test to cover both formats.

Check List

Tests

  • Unit test
  • Manual test (add detailed scripts or steps below)

Manual test: N/A

Questions

Will it cause performance regression or break compatibility?

No. This only changes JSON encoding/decoding for changefeed display name metadata and improves cross-version compatibility.

Do you need to update user documentation, design documentation or monitoring documentation?

No.

Release note

Fix changefeed metadata compatibility when upgrading between TiCDC versions that used "namespace" vs "keyspace" in changefeed ID JSON.

Summary by CodeRabbit

  • Improvements

    • Improved JSON compatibility for display names: serialized output now includes both legacy and current field names so older and newer consumers can read data without migration; deserialization accepts either field and prefers the current one when both exist.
  • Tests

    • Added unit tests covering forward/backward compatibility and serialization behavior.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-triage-completed release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Jan 28, 2026
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @wlwilliamx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical compatibility issue in TiCDC's changefeed metadata handling. It ensures seamless operation during mixed-version upgrades or rollbacks by making the ChangeFeedDisplayName structure resilient to changes in JSON field names (from 'namespace' to 'keyspace'). By intelligently handling both old and new field names during serialization and deserialization, the PR prevents potential data interpretation errors and ensures that changefeeds remain discoverable and manageable across different TiCDC versions.

Highlights

  • Backward and Forward Compatibility: The pull request introduces custom JSON marshaling and unmarshaling logic for ChangeFeedDisplayName to ensure compatibility across TiCDC versions that used 'namespace' versus 'keyspace' for a key identifier.
  • Legacy Namespace Acceptance: The UnmarshalJSON method for ChangeFeedDisplayName now accepts the legacy namespace field, treating it as an alias for keyspace. If both keyspace and namespace are present, keyspace takes precedence.
  • Dual Field Marshalling: The MarshalJSON method for ChangeFeedDisplayName now emits both the keyspace and the legacy namespace fields (with the value of keyspace) to ensure that metadata remains readable by both older and newer TiCDC versions without explicit migration.
  • Comprehensive Unit Tests: A new unit test file, types_test.go, has been added with TestChangeFeedDisplayNameJSONCompatibility to cover scenarios for unmarshalling legacy namespace, new keyspace, handling precedence when both exist, and verifying dual field emission during marshalling.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ti-chi-bot ti-chi-bot Bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jan 28, 2026
@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

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

Run ID: 933da9fd-862b-4803-be0d-5c6b064a9714

📥 Commits

Reviewing files that changed from the base of the PR and between 3ba4614 and 01d4003.

📒 Files selected for processing (1)
  • pkg/common/types_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/common/types_test.go

📝 Walkthrough

Walkthrough

Adds custom JSON MarshalJSON/UnmarshalJSON for ChangeFeedDisplayName so it accepts legacy "namespace" and new "keyspace" (keyspace wins if both present). Tests validate legacy-only, new-only, both-present precedence, and that marshaling outputs both fields plus name.

Changes

JSON Serialization

Layer / File(s) Summary
Marshal/Unmarshal implementation
pkg/common/types.go
Implements custom MarshalJSON and UnmarshalJSON for ChangeFeedDisplayName to emit and accept both keyspace (current) and namespace (legacy), with keyspace taking precedence.
Serialization tests
pkg/common/types_test.go
Adds TestChangeFeedDisplayNameJSONCompatibility covering legacy-only (namespace), new-only (keyspace), precedence when both exist, and that marshaled output contains both fields; uses subtests and t.Parallel.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Two fields in a burrow, one old and one new,
I nibble the JSON and choose what is true.
If both fields appear, the keyspace I keep,
For forks and for upgrades, no tumble or leap.
Hooray for the change — now both readers may chew!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: accepting legacy 'namespace' field in changefeed display name JSON for backward compatibility.
Description check ✅ Passed The description follows the template with all required sections: issue number, change explanation, test coverage, compatibility assessment, and release notes.
Linked Issues check ✅ Passed The PR fully addresses issue #4079 by implementing bidirectional JSON compatibility for ChangeFeedDisplayName, allowing unmarshaling of legacy 'namespace' field and marshaling both 'keyspace' and 'namespace' for version compatibility.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to the stated objective: JSON marshaling/unmarshaling for ChangeFeedDisplayName with backward compatibility, plus supporting unit tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a compatibility layer for ChangeFeedDisplayName to handle both the new keyspace field and the legacy namespace field during JSON serialization and deserialization. This is a solid approach to ensure smooth upgrades and rollbacks between different TiCDC versions. The implementation using custom MarshalJSON and UnmarshalJSON methods is clean, and the accompanying unit tests are thorough, covering all relevant scenarios. I have one minor suggestion to improve code conciseness.

Comment thread pkg/common/types.go
Comment on lines +195 to +199
if decoded.Keyspace != "" {
r.Keyspace = decoded.Keyspace
return nil
}
r.Keyspace = decoded.Namespace

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for setting r.Keyspace can be made more concise and arguably more readable by removing the conditional early return.

Suggested change
if decoded.Keyspace != "" {
r.Keyspace = decoded.Keyspace
return nil
}
r.Keyspace = decoded.Namespace
r.Keyspace = decoded.Keyspace
if decoded.Keyspace == "" {
r.Keyspace = decoded.Namespace
}

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pkg/common/types_test.go`:
- Around line 1-8: Add the project's standard copyright header to the top of the
file before the package common declaration; insert the exact header used across
the repo (including year and copyright owner and license notice) above the line
"package common" in types_test.go so the check-copyright CI passes.

Comment thread pkg/common/types_test.go
Comment thread pkg/common/types.go
// not make changefeeds "disappear" (e.g., keyspace becomes empty and gets filtered out)
// or become un-recreatable due to occupied meta keys. To keep metadata compatible across
// versions, we accept both field names on unmarshal and emit both on marshal.
type changeFeedDisplayNameJSON struct {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Rewriting the UnmarshalJSON method is significantly better than defining a new struct.

@wlwilliamx wlwilliamx Feb 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I already rewrited UnmarshalJSON on ChangeFeedDisplayName. We keep the unexported changeFeedDisplayNameJSON shim only to share the JSON tags between MarshalJSON/UnmarshalJSON (to keep them symmetric and avoid duplication/drift) and to avoid unmarshalling twice.

Comment thread pkg/common/types.go
return json.Marshal(changeFeedDisplayNameJSON{
Name: r.Name,
Keyspace: r.Keyspace,
Namespace: r.Keyspace,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we don't need to Marshal the Namespace field

@ti-chi-bot ti-chi-bot Bot added needs-1-more-lgtm Indicates a PR needs 1 more LGTM. approved labels Feb 14, 2026
@wlwilliamx

Copy link
Copy Markdown
Collaborator Author

/test all

@ti-chi-bot

ti-chi-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lidezhu, tenfyzhong

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jun 8, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-02-14 03:33:10.074342512 +0000 UTC m=+66557.820736544: ☑️ agreed by tenfyzhong.
  • 2026-06-08 03:55:51.834084837 +0000 UTC m=+759452.904402377: ☑️ agreed by lidezhu.

@ti-chi-bot ti-chi-bot Bot merged commit 8262732 into pingcap:master Jun 8, 2026
23 of 25 checks passed
@wlwilliamx wlwilliamx added the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Jun 11, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #5332.

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

Labels

approved lgtm needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changefeed may disappear after upgrade due to legacy "namespace" field in changefeed ID JSON

4 participants