Skip to content

Add a connection-independent pgoutput to ChangeEvent decoder#102

Open
LucaCappelletti94 wants to merge 1 commit into
isdaniel:mainfrom
LucaCappelletti94:feat/pgoutput-decoder
Open

Add a connection-independent pgoutput to ChangeEvent decoder#102
LucaCappelletti94 wants to merge 1 commit into
isdaniel:mainfrom
LucaCappelletti94:feat/pgoutput-decoder

Conversation

@LucaCappelletti94

Copy link
Copy Markdown
Contributor

The step that turns a parsed pgoutput message into a ChangeEvent lived as a private method on the network-only LogicalReplicationStream, inside a module gated behind a network backend. The only way to obtain a ChangeEvent was to open a live replication connection and drive the high-level EventStream. That is a poor fit for consumers that hold no connection, such as a tests or a fuzz harness. This change lifts the assembly into the unconditional protocol module so those consumers can decode with only bytes in hand.

This is a pure refactor with no decode behavior change. The large code changes are just shifting the necessary method between two modules.

@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 refactors the logical replication message decoding logic by moving the core translation function message_to_change_event and its helpers from src/stream.rs to src/protocol.rs. It also introduces PgOutputDecoder to enable connection-independent decoding of pgoutput messages. The review feedback points out several opportunities to optimize performance and avoid unnecessary string allocations by passing owned String variables (prefix and gid) directly into functions that accept Into<Arc<str>>.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/protocol.rs Outdated
ChangeEvent::message(
flags,
Lsn::new(msg_lsn),
Arc::<str>::from(prefix.as_str()),

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

Since prefix is an owned String and ChangeEvent::message accepts any type implementing Into<Arc<str>>, you can pass prefix directly instead of creating a new Arc from a borrowed string slice. This avoids an unnecessary reallocation and string copy on the message decoding path.

Suggested change
Arc::<str>::from(prefix.as_str()),
prefix,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

Comment thread src/protocol.rs Outdated
Lsn::new(prepare_lsn),
Lsn::new(end),
postgres_timestamp_to_chrono(timestamp),
Arc::<str>::from(gid.as_str()),

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

Since gid is an owned String and ChangeEvent::begin_prepare accepts impl Into<Arc<str>>, you can pass gid directly to avoid an unnecessary reallocation and string copy.

Suggested change
Arc::<str>::from(gid.as_str()),
gid,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

Comment thread src/protocol.rs Outdated
Lsn::new(prepare_lsn),
Lsn::new(end),
postgres_timestamp_to_chrono(timestamp),
Arc::<str>::from(gid.as_str()),

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

Since gid is an owned String and ChangeEvent::prepare accepts impl Into<Arc<str>>, you can pass gid directly to avoid an unnecessary reallocation and string copy.

Suggested change
Arc::<str>::from(gid.as_str()),
gid,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

Comment thread src/protocol.rs Outdated
Lsn::new(commit_lsn),
Lsn::new(end),
postgres_timestamp_to_chrono(timestamp),
Arc::<str>::from(gid.as_str()),

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

Since gid is an owned String and ChangeEvent::commit_prepared accepts impl Into<Arc<str>>, you can pass gid directly to avoid an unnecessary reallocation and string copy.

Suggested change
Arc::<str>::from(gid.as_str()),
gid,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

Comment thread src/protocol.rs Outdated
Lsn::new(rollback_end_lsn),
postgres_timestamp_to_chrono(prepare_timestamp),
postgres_timestamp_to_chrono(rollback_timestamp),
Arc::<str>::from(gid.as_str()),

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

Since gid is an owned String and ChangeEvent::rollback_prepared accepts impl Into<Arc<str>>, you can pass gid directly to avoid an unnecessary reallocation and string copy.

Suggested change
Arc::<str>::from(gid.as_str()),
gid,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

Comment thread src/protocol.rs Outdated
Lsn::new(prepare_lsn),
Lsn::new(end),
postgres_timestamp_to_chrono(timestamp),
Arc::<str>::from(gid.as_str()),

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

Since gid is an owned String and ChangeEvent::stream_prepare accepts impl Into<Arc<str>>, you can pass gid directly to avoid an unnecessary reallocation and string copy.

Suggested change
Arc::<str>::from(gid.as_str()),
gid,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the proposed cleanup

@codspeed-hq

codspeed-hq Bot commented Jul 17, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.51%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 49 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
copy_from_slice[64] 1.7 µs 1.6 µs +5.51%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing LucaCappelletti94:feat/pgoutput-decoder (4ebcb96) with main (784e644)

Open in CodSpeed

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.32035% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.55%. Comparing base (784e644) to head (4ebcb96).

Files with missing lines Patch % Lines
src/protocol.rs 96.23% 17 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #102      +/-   ##
==========================================
+ Coverage   94.53%   94.55%   +0.01%     
==========================================
  Files          27       27              
  Lines       20179    20278      +99     
==========================================
+ Hits        19077    19174      +97     
- Misses       1102     1104       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@LucaCappelletti94
LucaCappelletti94 marked this pull request as ready for review July 17, 2026 13:16
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.

1 participant