Skip to content

debezium: output start_ts in the source block of DML messages - #5903

Open
ekexium wants to merge 4 commits into
pingcap:masterfrom
ekexium:feat/debezium-start-ts
Open

debezium: output start_ts in the source block of DML messages#5903
ekexium wants to merge 4 commits into
pingcap:masterfrom
ekexium:feat/debezium-start-ts

Conversation

@ekexium

@ekexium ekexium commented Aug 7, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: close #5904

What is changed and how it works?

Add a new changefeed-level option for Debezium JSON output (default false). Configure it with the sink URI parameter debezium-include-start-ts=true or in the changefeed config:

[sink.debezium]
include-start-ts = true

When enabled, the Debezium JSON value message carries the start TSO of the transaction that made the change as source.start_ts, next to commit_ts:

"source": {
  ...
  "commit_ts": 1,
  "start_ts": 5,      // new (only with debezium-include-start-ts=true)
  "cluster_id": "..."
}
  • EncodeValue: write source.start_ts = e.StartTs when DebeziumIncludeStartTs is enabled.
  • writeSourceSchema: declare start_ts under the same option (JSON only), so schema-validated consumers (e.g. Kafka Connect) can see the field without enable-tidb-extension. The JSON source-schema writer is shared with Avro, so the declaration is guarded against Avro — the Avro payload does not carry the field and its schema must not declare it.
  • decoder: read source.start_ts and use it as the decoded event's StartTs (previously StartTs = CommitTs). Messages without the field (pre-feature format) fall back to CommitTs, preserving existing behavior. Present but invalid values (non-positive, out of int64 range, or not an integer) emit an error log and fall back to CommitTs so consumption can continue.
  • config: use debezium-include-start-ts in the sink URI, or include-start-ts under [sink.debezium] / the nested API v2 Debezium config. Explicit URI values (including false) override the config file — applied after the mergo merge because mergo cannot override a *bool true with false. Validation rejects the option for non-debezium protocols.

Check List

Tests

Questions

Will it cause performance regression or break compatibility?

No measurable performance impact (one extra uint64 field per DML message, only when the option is enabled). With the default config (option off) nothing changes at all; with the option on, the source block gains one field and the schema declares it consistently, so schema-validated consumers see a matching declaration. DDL/checkpoint messages, key messages, row checksums and the Avro protocol are unchanged. The decoder falls back to CommitTs when start_ts is absent, so messages produced before this change decode exactly as before. Invalid present values are logged at error level and also fall back to keep production consumption running.

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

Yes — the TiCDC Debezium protocol and changefeed configuration documentation will be updated in a follow-up PR to describe both forms: the URI parameter debezium-include-start-ts and [sink.debezium] include-start-ts.

Release note

Add an option to include the transaction start TSO in Debezium JSON messages. Configure it with the URI parameter `debezium-include-start-ts` or `[sink.debezium] include-start-ts`; when enabled, messages carry `source.start_ts`.

Summary by CodeRabbit

  • New Features

    • Added an option to include transaction start timestamps (start_ts) in Debezium JSON events.
    • Configure the option through sink settings or connection parameters.
    • Decoding supports start_ts and falls back to the commit timestamp when unavailable.
  • Improvements

    • The option is validated for Debezium JSON only.
    • Avro, DDL, and checkpoint events continue to omit transaction start timestamps.

@ti-chi-bot

ti-chi-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 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 Plus

Run ID: 676591fc-f4d9-451b-ab67-8bb594bbf626

📥 Commits

Reviewing files that changed from the base of the PR and between bc7c56b and 492dbbc.

📒 Files selected for processing (8)
  • api/v2/changefeed_toml_test.go
  • api/v2/model.go
  • api/v2/model_test.go
  • pkg/config/sink.go
  • pkg/sink/codec/common/config.go
  • pkg/sink/codec/common/config_test.go
  • pkg/sink/codec/debezium/debezium_test.go
  • pkg/sink/codec/debezium/decoder.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • api/v2/changefeed_toml_test.go
  • pkg/sink/codec/common/config_test.go
  • pkg/sink/codec/debezium/decoder.go
  • api/v2/model.go
  • pkg/sink/codec/common/config.go

📝 Walkthrough

Walkthrough

Adds optional start_ts output to Debezium JSON messages. Sink settings and URL parameters configure the option. JSON encoding declares and emits the field. Decoding restores it and falls back to commit_ts. Avro, DDL, and checkpoint output omit the field.

Changes

Debezium start timestamp

Layer / File(s) Summary
Start timestamp configuration
pkg/config/sink.go, pkg/sink/codec/common/config.go, api/v2/model.go, pkg/sink/codec/common/config_test.go, api/v2/changefeed_toml_test.go, api/v2/model_test.go
Adds sink and API configuration for IncludeStartTs. URL values override sink configuration, including explicit false. Validation permits the option only for the Debezium protocol.
Debezium JSON encoding
pkg/sink/codec/debezium/codec.go, pkg/sink/codec/debezium/avro.go, pkg/sink/codec/debezium/avro_test.go, pkg/sink/codec/debezium/codec_test.go, pkg/sink/codec/debezium/debezium_test.go
Declares and emits source.start_ts for enabled JSON row events. Avro, DDL, and checkpoint schemas exclude the field.
Debezium decoding
pkg/sink/codec/debezium/decoder.go, pkg/sink/codec/debezium/debezium_test.go
Reads valid positive start_ts values into StartTs. Missing, invalid, zero, and negative values fall back to commit_ts.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SinkConfig
  participant DebeziumCodec
  participant DebeziumMessage
  participant DebeziumDecoder
  participant DMLEvent
  SinkConfig->>DebeziumCodec: enable DebeziumIncludeStartTs
  DebeziumCodec->>DebeziumMessage: encode RowEvent.StartTs as source.start_ts
  DebeziumMessage->>DebeziumDecoder: provide source.start_ts
  DebeziumDecoder->>DMLEvent: restore StartTs
  DebeziumDecoder->>DMLEvent: use commit_ts when start_ts is absent or invalid
Loading

Possibly related PRs

  • pingcap/ticdc#5475: Both changes modify Debezium source-schema generation and timestamp handling.

Suggested reviewers: wk989898

Poem

A rabbit checks the source field bright,
start_ts hops through JSON light.
The decoder reads its trail,
Or uses commit_ts on failure.
Avro keeps its schema pale.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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
Linked Issues check ✅ Passed The changes satisfy issue #5904 by encoding and decoding start_ts, preserving fallbacks, and leaving Avro, DDL, and checkpoint messages unchanged.
Out of Scope Changes check ✅ Passed The configuration, API, codec, decoder, and test changes directly support the linked issue and stated PR objectives.
Title check ✅ Passed The title clearly and concisely describes the primary change: including transaction start_ts in Debezium source blocks.
Description check ✅ Passed The description includes the issue, implementation details, tests, compatibility assessment, documentation plan, and release note.
✨ Finishing Touches 💡 2
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch feat/debezium-start-ts
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

@pingcap-cla-assistant

pingcap-cla-assistant Bot commented Aug 7, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@ti-chi-bot ti-chi-bot Bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 7, 2026
@ekexium
ekexium force-pushed the feat/debezium-start-ts branch 2 times, most recently from 1b27000 to dc43cf0 Compare August 7, 2026 04:07
@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. and removed do-not-merge/needs-linked-issue do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Aug 7, 2026
@ekexium
ekexium force-pushed the feat/debezium-start-ts branch from dc43cf0 to f3a3988 Compare August 7, 2026 04:25
@ekexium

ekexium commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

/check-issue-triage-complete

@ekexium
ekexium force-pushed the feat/debezium-start-ts branch 3 times, most recently from a569d07 to c364a44 Compare August 10, 2026 09:46
@ti-chi-bot

ti-chi-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

[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 lidezhu 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

@ekexium
ekexium marked this pull request as ready for review August 10, 2026 10:01
Copilot AI lite review requested due to automatic review settings August 10, 2026 10:01
@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 10, 2026

Copilot AI 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.

Pull request overview

Adds an opt-in Debezium (JSON) output enhancement to include a transaction’s start_ts in the source block of DML messages, and updates decoding/config to support the new field while preserving backward compatibility for older messages.

Changes:

  • Add debezium-output-start-ts sink option/config to emit source.start_ts in Debezium JSON DML value messages.
  • Update Debezium JSON schema generation (JSON-only; guarded for Avro) and decoder logic to read start_ts with fallback to commit_ts when absent.
  • Add unit tests covering JSON emission/schema, decoder fallback, Avro non-impact, and config parsing/validation.

Validation:

  • Not run here (no CI access in this environment). Suggested: go test -tags intest ./pkg/sink/codec/debezium/... ./pkg/sink/codec/common/... ./pkg/config/... ./cmd/kafka-consumer/...

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/sink/codec/debezium/decoder.go Decode source.start_ts when present; fall back to commit_ts for older messages.
pkg/sink/codec/debezium/debezium_test.go Add unit tests for start_ts emission/schema and decoder fallback behavior.
pkg/sink/codec/debezium/codec.go Emit source.start_ts in JSON payload + declare in JSON schema; guard against Avro schema/payload changes.
pkg/sink/codec/debezium/avro_test.go Assert Avro payload/schema do not include start_ts even when option is enabled.
pkg/sink/codec/common/config.go Add DebeziumOutputStartTs config field, URI parsing, and validation gating by protocol.
pkg/sink/codec/common/config_test.go Test URI/config-file parsing and protocol validation for debezium-output-start-ts.
pkg/config/sink.go Add [sink.debezium].output-start-ts config field to Debezium sink config.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +273 to +293
encoder := NewBatchEncoder(cfg, "dbserver1")
rowEvent := common.NewRoutedRowEvent4Test()
rowEvent.StartTs = 5
require.NoError(t, encoder.AppendRowChangedEvent(context.Background(), "", rowEvent))

messages := encoder.Build()
require.Len(t, messages, 1)

// Simulate a pre-feature message: drop start_ts from the source block.
dec := json.NewDecoder(bytes.NewReader(messages[0].Value))
dec.UseNumber()
var value map[string]any
require.NoError(t, dec.Decode(&value))
source := value["payload"].(map[string]any)["source"].(map[string]any)
require.Equal(t, json.Number("5"), source["start_ts"])
delete(source, "start_ts")
valueBytes, err := json.Marshal(value)
require.NoError(t, err)

decoder := NewDecoder(cfg, 0, nil)
decoder.AddKeyValue(messages[0].Key, valueBytes)
Comment on lines +244 to +246
// round-trip: decoding restores the true start ts. The TiCDC-side decoder
// requires enable-tidb-extension (to read commit_ts and tidb_type), so the
// encoded message must carry the extension fields as well.

@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: 2

🧹 Nitpick comments (1)
pkg/sink/codec/common/config_test.go (1)

162-179: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a URI precedence test.

The separate tests do not verify the override contract when both configuration sources set debezium-output-start-ts.

Add cases where the sink configuration and URI parameter have opposite values. Assert that the URI value wins.

🤖 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 `@pkg/sink/codec/common/config_test.go` around lines 162 - 179, Extend
TestDebeziumOutputStartTsConfig with cases where
sinkConfig.Debezium.OutputStartTs and the debezium-output-start-ts URI parameter
are set to opposite boolean values. Apply each configuration and assert
cfg.DebeziumOutputStartTs matches the URI value, covering both true-over-false
and false-over-true precedence.
🤖 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 `@pkg/sink/codec/debezium/codec.go`:
- Around line 1097-1101: Update the start_ts payload write in the Debezium
encoding flow to require DebeziumOutputStartTs and a non-Avro output, matching
the schema exclusion logic. Use c.isDebeziumAvro() in the condition around
jWriter.WriteUint64Field("start_ts", e.StartTs), preserving start_ts for
non-Avro payloads.

In `@pkg/sink/codec/debezium/decoder.go`:
- Around line 267-272: Update the startTs conversion logic in the decoder to
reject negative signed values before converting to uint64, ensuring negative
start_ts values return 0 and trigger the existing commit_ts fallback. Add a
decoder test covering negative start_ts and verify the resulting timestamp
equals commit_ts.

---

Nitpick comments:
In `@pkg/sink/codec/common/config_test.go`:
- Around line 162-179: Extend TestDebeziumOutputStartTsConfig with cases where
sinkConfig.Debezium.OutputStartTs and the debezium-output-start-ts URI parameter
are set to opposite boolean values. Apply each configuration and assert
cfg.DebeziumOutputStartTs matches the URI value, covering both true-over-false
and false-over-true precedence.
🪄 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: 510e587e-ef39-4457-aef6-1f5226a3180e

📥 Commits

Reviewing files that changed from the base of the PR and between 2b82c06 and c364a44.

📒 Files selected for processing (7)
  • pkg/config/sink.go
  • pkg/sink/codec/common/config.go
  • pkg/sink/codec/common/config_test.go
  • pkg/sink/codec/debezium/avro_test.go
  • pkg/sink/codec/debezium/codec.go
  • pkg/sink/codec/debezium/debezium_test.go
  • pkg/sink/codec/debezium/decoder.go

Comment on lines +1097 to +1101
// start_ts: the start TSO of the transaction that made this change,
// exposed for downstream consumers that need transaction correlation.
if c.config.DebeziumOutputStartTs {
jWriter.WriteUint64Field("start_ts", e.StartTs)
}

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Exclude start_ts from Debezium Avro payloads.

Line 1099 does not check !c.isDebeziumAvro(). When DebeziumOutputStartTs is true, this writes source.start_ts into an Avro record although Lines 990-999 exclude it from the Avro schema.

This breaks the Avro payload/schema contract and fails the Avro exclusion test. Gate the payload write with the same Avro condition as the schema.

Proposed fix
-				if c.config.DebeziumOutputStartTs {
+				if c.config.DebeziumOutputStartTs && !c.isDebeziumAvro() {
 					jWriter.WriteUint64Field("start_ts", e.StartTs)
 				}
📝 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
// start_ts: the start TSO of the transaction that made this change,
// exposed for downstream consumers that need transaction correlation.
if c.config.DebeziumOutputStartTs {
jWriter.WriteUint64Field("start_ts", e.StartTs)
}
// start_ts: the start TSO of the transaction that made this change,
// exposed for downstream consumers that need transaction correlation.
if c.config.DebeziumOutputStartTs && !c.isDebeziumAvro() {
jWriter.WriteUint64Field("start_ts", e.StartTs)
}
🤖 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 `@pkg/sink/codec/debezium/codec.go` around lines 1097 - 1101, Update the
start_ts payload write in the Debezium encoding flow to require
DebeziumOutputStartTs and a non-Avro output, matching the schema exclusion
logic. Use c.isDebeziumAvro() in the condition around
jWriter.WriteUint64Field("start_ts", e.StartTs), preserving start_ts for
non-Avro payloads.

Comment thread pkg/sink/codec/debezium/decoder.go Outdated
Comment thread pkg/sink/codec/common/config_test.go Outdated
func TestDebeziumOutputStartTsConfig(t *testing.T) {
// URI parameter
cfg := NewConfig(config.ProtocolDebezium)
sinkURI, err := url.Parse("kafka://127.0.0.1:9092/topic?protocol=debezium&debezium-output-start-ts=true")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we rename to debezium-include-start-ts? I remember we have avro-include-before-value, so I think to keep it consistent. #5154

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In the changefeed config, do you prefer [sink] debezium-include-start-ts or [sink.debezium] include-start-ts = true? #5154 is the in the former form, but I think the latter is more reasonable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agree, please go with the latter one.

@ekexium
ekexium force-pushed the feat/debezium-start-ts branch from c364a44 to 039dffa Compare August 11, 2026 02:39

@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

🤖 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 `@pkg/config/sink.go`:
- Around line 203-205: Move DebeziumIncludeStartTs from SinkConfig into
DebeziumConfig, or explicitly map it through the existing SinkConfig.Debezium
field so the [sink.debezium] path populates it. Update mergeConfig to read the
nested value and extend the configuration test to verify DebeziumIncludeStartTs
is enabled through the nested form.
🪄 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: 909e3c37-18f3-47fb-820c-b9a1e2a52dbc

📥 Commits

Reviewing files that changed from the base of the PR and between c364a44 and 039dffa.

📒 Files selected for processing (6)
  • pkg/config/sink.go
  • pkg/sink/codec/common/config.go
  • pkg/sink/codec/common/config_test.go
  • pkg/sink/codec/debezium/avro_test.go
  • pkg/sink/codec/debezium/codec.go
  • pkg/sink/codec/debezium/debezium_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/sink/codec/debezium/codec.go
  • pkg/sink/codec/debezium/debezium_test.go
  • pkg/sink/codec/debezium/avro_test.go

Comment thread pkg/config/sink.go Outdated
@ekexium
ekexium force-pushed the feat/debezium-start-ts branch from 039dffa to 2d4e12c Compare August 11, 2026 02:59
Add a new changefeed-level option debezium-include-start-ts (sink URI
parameter or changefeed config, default false). When enabled, the
Debezium JSON value message carries source.start_ts — the start TSO
of the transaction that made the change — and the source schema
declares it, so schema-validated consumers (e.g. Kafka Connect) can
see the field without enable-tidb-extension. The option only takes
effect with protocol debezium; the Avro protocol is unaffected (its
payload does not carry the field and its schema does not declare it).
Explicit sink URI values (including false) override the config file.

- EncodeValue / writeSourceSchema: emit and declare start_ts under
  debezium-include-start-ts (JSON only, guarded for Avro).
- decoder: read source.start_ts as the decoded event's StartTs,
  falling back to commit_ts for messages without the field
  (pre-feature format), preserving old behavior.
- config: add the option (URI param + changefeed config) with
  protocol validation; apply explicit URI values after the mergo
  merge because mergo cannot override a *bool true with false.
- tests: encode/schema/round-trip coverage, pre-feature fallback
  coverage, Avro negative coverage, and config parse/precedence/
  validation coverage. Existing golden tests pass unchanged (default
  config does not emit the field).
@ekexium
ekexium force-pushed the feat/debezium-start-ts branch from 2d4e12c to 90947b6 Compare August 11, 2026 03:16
writeSourceSchema is shared by DML, DDL and checkpoint (watermark)
messages. Declaring start_ts for all of them while only DML payloads
carry the field breaks schema-validating consumers (declared
non-optional field missing from payload). Parameterize
writeSourceSchema with includeStartTs and declare start_ts only for
DML row events. Add a regression test covering DDL and checkpoint
messages with debezium-include-start-ts enabled.
@ti-chi-bot ti-chi-bot Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 11, 2026

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

🧹 Nitpick comments (1)
api/v2/changefeed_toml_test.go (1)

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

Assert the decoded sink value.

Line 119 only verifies text serialization. Assert wrapper.Config.Sink.DebeziumIncludeStartTs after TOML decoding. This verifies the TOML path and the internal field mapping.

Proposed test addition
 	_, err := toml.Decode(out, &wrapper)
 	require.NoError(t, err)
+	require.NotNil(t, wrapper.Config.Sink)
+	require.True(t, util.GetOrZero(wrapper.Config.Sink.DebeziumIncludeStartTs))
 	require.Equal(t, uint64(1024), util.GetOrZero(wrapper.Config.MemoryQuota))
🤖 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 `@api/v2/changefeed_toml_test.go` at line 119, Extend the TOML decoding test
around the existing serialization assertion to also validate
wrapper.Config.Sink.DebeziumIncludeStartTs after decoding, confirming the sink
field mapping and decoded value rather than only checking serialized text.
🤖 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.

Nitpick comments:
In `@api/v2/changefeed_toml_test.go`:
- Line 119: Extend the TOML decoding test around the existing serialization
assertion to also validate wrapper.Config.Sink.DebeziumIncludeStartTs after
decoding, confirming the sink field mapping and decoded value rather than only
checking serialized text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c4bde877-ddc6-4c92-935f-f66f34a75c7e

📥 Commits

Reviewing files that changed from the base of the PR and between 039dffa and bc7c56b.

📒 Files selected for processing (5)
  • api/v2/changefeed_toml_test.go
  • api/v2/model.go
  • pkg/sink/codec/debezium/avro.go
  • pkg/sink/codec/debezium/codec.go
  • pkg/sink/codec/debezium/codec_test.go

@ti-chi-bot

ti-chi-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

@ekexium: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-error-log-review 56d0dc5 link true /test pull-error-log-review

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ekexium

ekexium commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

@wk989898 PTAL

// includeStartTs should only be true for DML row events: DDL and checkpoint
// (watermark) messages have no per-row transaction, so their payloads never
// carry start_ts and their schemas must not declare it.
func (c *dbzCodec) writeSourceSchema(writer *util.JSONWriter, schemaName string, includeStartTs bool) {

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.

It looks like only dml will carry the start ts field?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, only DML events

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

Labels

release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

debezium: output the transaction start_ts in Debezium JSON messages

4 participants