You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by "imankhadiv (via GitHub)" <gi...@apache.org> on 2026/08/26 15:47:00 UTC

[PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

imankhadiv opened a new pull request, #29027:
URL: https://github.com/apache/flink/pull/29027

   ## What is the purpose of the change
   
   `OutputConversionOperator.processElement` dereferences the result of `RowData#getTimestamp(...)` without a null check, so converting a table with a `null` rowtime attribute into a `DataStream` fails the job with a `NullPointerException`. Both rowtime paths are affected: the rowtime metadata path and the rowtime column path.
   
   Adding null checks alone is not enough. `outRecord` is a single `StreamRecord` allocated once in `open()` and reused for every element, and `StreamRecord#replace(Object)` leaves the timestamp untouched. Merely skipping `setTimestamp()` would leave the *previous* record's timestamp on the record carrying the null rowtime, i.e. it would trade the `NullPointerException` for a silently wrong timestamp. The null case therefore erases the timestamp explicitly.
   
   ## Brief change log
   
     - Both rowtime lookups in `OutputConversionOperator` go through a new private `updateRowtime(RowData, int)` helper
     - The helper sets the output timestamp when the rowtime is present, and calls `StreamRecord#eraseTimestamp()` when it is null, so a record with a null rowtime cannot inherit the preceding record's timestamp
   
   ## Verifying this change
   
   This change added tests and can be verified as follows:
   
     - Added `OutputConversionOperatorTest` with four cases — a null rowtime is emitted without a timestamp, and a null rowtime does not inherit the timestamp of the preceding record — each covering the rowtime metadata path and the rowtime column path
     - All four tests were watched failing before the fix: first with the reported `NullPointerException`, and the two "does not inherit" cases again against a null-check-only variant of the fix, which is what motivated the explicit `eraseTimestamp()`
     - `flink-table-runtime` module test suite passes (1824 tests)
     - `DataStreamJavaITCase` passes (38 tests); it covers the non-null rowtime path end to end via `toDataStream` with event-time windows and a downstream assertion on `ctx.timestamp()`
   
   ## Does this pull request potentially affect one of the following parts:
   
     - Dependencies (does it add or upgrade a dependency): **no**
     - The public API, i.e., is any changed class annotated with `@Public(Evolving)`: **no**
     - The serializers: **no**
     - The runtime per-record code paths (performance sensitive): **yes** — one additional `isNullAt` check per record, in an operator that already read the rowtime field
     - Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: **no**
     - The S3 file system connector: **no**
   
   ## Documentation
   
     - Does this pull request introduce a new feature? **no**
     - If yes, how is the feature documented? **not applicable**
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Claude Code (Claude Opus 5)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "davidradl (via GitHub)" <gi...@apache.org>.
davidradl commented on code in PR #29027:
URL: https://github.com/apache/flink/pull/29027#discussion_r3879754695


##########
flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/operators/sink/OutputConversionOperator.java:
##########
@@ -71,12 +72,10 @@ public void processElement(StreamRecord<RowData> element) throws Exception {
 
         if (consumeRowtimeMetadata) {
             // timestamp is TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowData.getArity() - 1, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowData.getArity() - 1);
         } else if (rowtimeIndex != -1) {
             // timestamp might be TIMESTAMP or TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowtimeIndex, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowtimeIndex);

Review Comment:
   nit: you could move updateRowtime call outside the if else and set the index in the if else. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "imankhadiv (via GitHub)" <gi...@apache.org>.
imankhadiv commented on PR #29027:
URL: https://github.com/apache/flink/pull/29027#issuecomment-5443945780

   @nateab thanks for assigning me FLINK-40232 — Azure is green on this one, so it's ready for review.
   
   Both rowtime lookups in `OutputConversionOperator` now go through a small `updateRowtime(RowData, int)` helper that null-checks the rowtime. The one part that goes beyond the null checks suggested in the ticket is the `else` branch: `outRecord` is a single `StreamRecord` allocated in `open()` and reused for every element, and `StreamRecord#replace(Object)` leaves the timestamp untouched — so only skipping `setTimestamp()` would leave the *previous* record's timestamp on the record with the null rowtime, turning the NPE into a silently wrong timestamp. Hence the explicit `eraseTimestamp()`.
   
   Test coverage in `OutputConversionOperatorTest` follows that split: for both the rowtime metadata path and the rowtime column path, one case asserts the record is emitted without a timestamp, and one asserts it does not inherit the preceding record's timestamp. The latter two were confirmed failing against a null-checks-only version of the fix, which is what motivated the erase. Locally `flink-table-runtime` (1824 tests) and `DataStreamJavaITCase` (38 tests, covers the non-null rowtime path end to end) pass.
   
   Could you take a look, or point me to the right committer for table-runtime? Happy to rebase or adjust anything.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "snuyanzin (via GitHub)" <gi...@apache.org>.
snuyanzin commented on PR #29027:
URL: https://github.com/apache/flink/pull/29027#issuecomment-5779956279

   i see to much AI
   can we have short summary of problem what was the issue
   why this approach and etc
   
   please respect reviewer's time


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "imankhadiv (via GitHub)" <gi...@apache.org>.
imankhadiv commented on PR #29027:
URL: https://github.com/apache/flink/pull/29027#issuecomment-5780047297

   Sorry — fair, too much text. Short version:
   
   **Bug:** `toDataStream` on a table with a null rowtime throws NPE — `OutputConversionOperator` dereferences `getTimestamp(...)` unchecked, on both rowtime paths.
   
   **Fix:** null-check it. The null branch calls `eraseTimestamp()` rather than just skipping `setTimestamp()`, because `outRecord` is reused across records and would otherwise keep the previous record's timestamp.
   
   19 lines of src, the rest is tests. I have also trimmed the PR description.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "flinkbot (via GitHub)" <gi...@apache.org>.
flinkbot commented on PR #29027:
URL: https://github.com/apache/flink/pull/29027#issuecomment-5427733421

   <!--
   Meta data
   {
     "version" : 1,
     "metaDataEntries" : [ {
       "hash" : "1cd6354a375c1b0705838c3c64998ad0f3d7435e",
       "status" : "UNKNOWN",
       "url" : "TBD",
       "triggerID" : "1cd6354a375c1b0705838c3c64998ad0f3d7435e",
       "triggerType" : "PUSH"
     } ]
   }-->
   ## CI report:
   
   * 1cd6354a375c1b0705838c3c64998ad0f3d7435e UNKNOWN
   
   <details>
   <summary>Bot commands</summary>
     The @flinkbot bot supports the following commands:
   
    - `@flinkbot run azure` re-run the last Azure build
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "imankhadiv (via GitHub)" <gi...@apache.org>.
imankhadiv commented on code in PR #29027:
URL: https://github.com/apache/flink/pull/29027#discussion_r3883696968


##########
flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/operators/sink/OutputConversionOperator.java:
##########
@@ -71,12 +72,10 @@ public void processElement(StreamRecord<RowData> element) throws Exception {
 
         if (consumeRowtimeMetadata) {
             // timestamp is TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowData.getArity() - 1, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowData.getArity() - 1);
         } else if (rowtimeIndex != -1) {
             // timestamp might be TIMESTAMP or TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowtimeIndex, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowtimeIndex);

Review Comment:
   Azure is green on a0142a2. Since the nit is addressed and the change is confined to `OutputConversionOperator`, would you know which committer is the right one to tag for a table-runtime review?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "imankhadiv (via GitHub)" <gi...@apache.org>.
imankhadiv commented on code in PR #29027:
URL: https://github.com/apache/flink/pull/29027#discussion_r3882447338


##########
flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/operators/sink/OutputConversionOperator.java:
##########
@@ -71,12 +72,10 @@ public void processElement(StreamRecord<RowData> element) throws Exception {
 
         if (consumeRowtimeMetadata) {
             // timestamp is TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowData.getArity() - 1, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowData.getArity() - 1);
         } else if (rowtimeIndex != -1) {
             // timestamp might be TIMESTAMP or TIMESTAMP_LTZ
-            final long rowtime = rowData.getTimestamp(rowtimeIndex, 3).getMillisecond();
-            outRecord.setTimestamp(rowtime);
+            updateRowtime(rowData, rowtimeIndex);

Review Comment:
   Applied in a0142a2 — the position is now computed in the if/else and `updateRowtime` is called once, with the two type comments kept on their respective branches.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] [FLINK-40232][table-runtime] Handle null rowtime in OutputConversionOperator [flink]

Posted by "imankhadiv (via GitHub)" <gi...@apache.org>.
imankhadiv commented on PR #29027:
URL: https://github.com/apache/flink/pull/29027#issuecomment-5779785762

   Gentle ping — this has been green since Aug 28 (Azure build 78461 on `a0142a2`) and the review nit from @davidradl is addressed.
   
   @snuyanzin would you have a moment to take a look? It's a small `flink-table-runtime` change: both rowtime lookups in `OutputConversionOperator` are null-guarded via a shared `updateRowtime` helper, and the null branch calls `eraseTimestamp()` — `outRecord` is a single `StreamRecord` reused across elements and `replace(Object)` leaves the timestamp untouched, so skipping `setTimestamp()` alone would leak the previous record's timestamp rather than fix the NPE. FLINK-40232 is assigned to me and the test covers both the NPE and the stale-timestamp case (verified red before green).
   
   Happy to rebase or adjust if anything is needed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org