Skip to content

Conversation

@wlwilliamx
Copy link
Collaborator

@wlwilliamx wlwilliamx commented Jan 28, 2026

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

    • Enhanced JSON serialization capabilities for improved data handling and compatibility.
  • Tests

    • Added comprehensive unit tests for JSON serialization functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@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
@ti-chi-bot
Copy link

ti-chi-bot bot commented Jan 28, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign asddongmen for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found 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

@gemini-code-assist
Copy link

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
Copy link

coderabbitai bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

Adds JSON marshaling and unmarshaling support to ChangeFeedDisplayName to handle backward and forward compatibility. MarshalJSON outputs both "keyspace" and "namespace" fields; UnmarshalJSON accepts either or both, with "keyspace" taking precedence.

Changes

Cohort / File(s) Change Summary
JSON Serialization
pkg/common/types.go
Implements custom JSON (un)marshaling for ChangeFeedDisplayName. MarshalJSON emits both "keyspace" (current) and "namespace" (legacy) fields for dual compatibility; UnmarshalJSON accepts both and prioritizes "keyspace" when present. Adds encoding/json import.
Serialization Tests
pkg/common/types_test.go
Adds unit tests covering legacy "namespace"-only JSON, new "keyspace"-only JSON, precedence when both fields exist, and marshaling output validation for backward/forward compatibility. Uses subtests with parallel execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A tale of two fields, now dancing as one,
Namespace and keyspace in JSON fun!
Legacy readers hop forward with grace,
While new ones embrace the keyspace embrace.
Backward, then forward—the upgrade's no race! 🐇✨

🚥 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 clearly and specifically describes the main change: accepting legacy namespace field in changefeed ID JSON for backward compatibility.
Description check ✅ Passed The description follows the template structure with linked issue, clear explanation of changes, test coverage, compatibility assessment, and release note.
Linked Issues check ✅ Passed Code changes fully address linked issue #4079 by implementing JSON compatibility for both legacy namespace and new keyspace fields, with comprehensive test coverage.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the linked issue objective: JSON compatibility for ChangeFeedDisplayName with no extraneous modifications.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

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 on lines +195 to +199
if decoded.Keyspace != "" {
r.Keyspace = decoded.Keyspace
return nil
}
r.Keyspace = decoded.Namespace

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
}

Copy link

@coderabbitai coderabbitai bot left a comment

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 on lines +1 to +8
package common

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add the required copyright header to fix CI.

The pipeline reports check-copyright failure for this file. Please add the standard header at the top.

🛠️ Proposed fix
+// Copyright 2025 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package common
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
package common
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
// Copyright 2025 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package common
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
🧰 Tools
🪛 GitHub Actions: PR Build and Unit Test

[error] 1-1: check-copyright: The copyright information of following files is incorrect: ./pkg/common/types_test.go

🤖 Prompt for AI Agents
In `@pkg/common/types_test.go` around lines 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.

// 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
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.

Copy link
Collaborator Author

@wlwilliamx wlwilliamx Feb 12, 2026

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.

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

Labels

do-not-merge/needs-triage-completed 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

2 participants