Skip to content

[GLUTEN-12426][FLINK] Feat: Add columnar StreamRecordTimestampInserter operator#12428

Open
ggjh-159 wants to merge 7 commits into
apache:mainfrom
ggjh-159:feat/stateful-stream-record-timestamp-inserter
Open

[GLUTEN-12426][FLINK] Feat: Add columnar StreamRecordTimestampInserter operator#12428
ggjh-159 wants to merge 7 commits into
apache:mainfrom
ggjh-159:feat/stateful-stream-record-timestamp-inserter

Conversation

@ggjh-159

@ggjh-159 ggjh-159 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Issue: #12426

What changes are proposed in this pull request?

Adds a Gluten columnar replacement for Flink's row-mode StreamRecordTimestampInserter, so the sink input chain stays columnar end-to-end when the sink is offloaded to Velox.

The native Flink inserter (per-row timestamp) is replaced by GlutenStreamRecordTimestampInserter, whose underlying Velox operator computes the batch-max timestamp and forwards it via StatefulRecord.timestamp. The downstream TimestampSettingStatefulRecordOutputBridge then stamps the Flink StreamRecord in Java without re-entering C++.

Changes:

  • GlutenRowtimeInserterHelper — entry point invoked by each sink factory's buildVeloxSink; detects a native inserter on the input chain and rebuilds it as the Gluten columnar inserter
  • GlutenStreamRecordTimestampInserter — new columnar operator (<StatefulRecord, StatefulRecord>)
  • TimestampSettingStatefulRecordOutputBridge — collects with record.getTimestamp(), no JNI timestamp extraction
  • PrintSinkFactory, FuzzerSourceSinkFactory, FileSystemSinkFactory — invoke the helper on their input streams

Depends on the corresponding velox PR <bigo-sg/velox#64> and velox4j PR <bigo-sg/velox4j#52>.

How was this patch tested?

  • GlutenRowtimeInserterHelperTest — 3 unit tests (non-OneInputTransformation no-op, non-inserter operator no-op, full replacement path): mvn -pl gluten-flink/ut test -Dtest=GlutenRowtimeInserterHelperTest
  • End-to-end validation via gluten-flink nexmark q0

@github-actions github-actions Bot added the FLINK label Jul 2, 2026
@ggjh-159 ggjh-159 marked this pull request as draft July 2, 2026 09:11
@ggjh-159 ggjh-159 force-pushed the feat/stateful-stream-record-timestamp-inserter branch from 47c85b5 to c2fd991 Compare July 2, 2026 09:59
@github-actions github-actions Bot added the INFRA label Jul 2, 2026
@ggjh-159 ggjh-159 marked this pull request as ready for review July 2, 2026 10:01
import static org.junit.jupiter.api.Assertions.assertTrue;

class GlutenRowtimeInserterHelperTest {

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.

We use max timestamp in a batch record to replace the per-row timestamp, which is a different semantics,can we add a test for this?

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.

All three sink factories (Print, Fuzzer/Discard, FileSystem) wire requiresTimestamp = false, so the inserter is removed from the op chain and the batch-max path in GlutenRowtimeInserterHelper has no runtime caller in this PR. A test here would exercise a path no real sink reaches.

Batch-max computation itself is covered by velox C++ UT StreamRecordTimestampInserterTest.emitsBatchMaxTimestamp (PR bigo-sg/velox#64). The replacement/removal branches are covered by GlutenRowtimeInserterHelperTest.

// inserter so the chain stays columnar end-to-end; otherwise this is a no-op.
Transformation<RowData> veloxFileWriterInput =
GlutenRowtimeInserterHelper.processTransformation(
(Transformation<RowData>) fileWriterTransformation.getInputs().get(0));

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.

In gluten-flink,operator StreamingFileWriter will totally offload to velox, and velox's file writer will not rely on the StreamRecord.timestamp to determine partition, roll file, or commit partition, therefore, StreamRecordTimestampInserter is just a useless operator, we should just remove it from the op chain.

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.

Agreed. Updated FileSystemSinkFactory to call GlutenRowtimeInserterHelper.processTransformation(input, /*requiresTimestamp=*/false), which removes any native StreamRecordTimestampInserter from the input chain instead of replacing it with the columnar one. Same treatment applied to PrintSinkFactory and FuzzerSourceSinkFactory.

ggjh-159 added 4 commits July 6, 2026 15:57
…stamp-inserter' into feat/stateful-stream-record-timestamp-inserter
…m-record-timestamp-inserter

# Conflicts:
#	.github/workflows/flink.yml
#	gluten-flink/planner/src/main/java/org/apache/gluten/velox/FileSystemSinkFactory.java
@ggjh-159 ggjh-159 requested a review from KevinyhZou July 6, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants