You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2026/09/24 15:24:00 UTC

[jira] [Updated] (FLINK-40794) CAST in Table API ignores input nullability when the target type is NOT NULL

     [ https://issues.apache.org/jira/browse/FLINK-40794?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

ASF GitHub Bot updated FLINK-40794:
-----------------------------------
    Labels: pull-request-available  (was: )

> CAST in Table API ignores input nullability when the target type is NOT NULL
> ----------------------------------------------------------------------------
>
>                 Key: FLINK-40794
>                 URL: https://issues.apache.org/jira/browse/FLINK-40794
>             Project: Flink
>          Issue Type: Bug
>          Components: Table SQL / Planner
>            Reporter: Ramin Gharib
>            Assignee: Ramin Gharib
>            Priority: Major
>              Labels: pull-request-available
>
> In the Table API, a CAST to a target written with .notNull() is planned as NOT NULL even when the input may be null. The CAST type strategy already derives the result as nullable, but CastConverter builds the RexNode from the literal target type. The optimizer trusts the wrong NOT NULL and can fold null checks away, which drops rows or produces wrong values.
> h3. Reproduce
> {code:java}
> Table t = tEnv.fromValues(
>         ROW(FIELD("i", INT())),
>         Row.of((Object) null),
>         Row.of(1));
> t.select($("i").cast(BIGINT().notNull()).as("c"))
>         .filter($("c").isNull())
>         .execute()
>         .print();
> {code}
> Expected: one row with c = NULL.
> Actual: empty result. The plan collapses to an empty Values because IS NULL is folded to FALSE.
> The same happens for a nested VARIANT input, e.g. parseJson(s).cast(ARRAY(VARIANT())).cast(ARRAY(INT()).notNull()). FLINK-40672 only covered a top-level VARIANT input.
> SQL is not affected. A SQL CAST cannot declare NOT NULL on the target, and SqlCastFunction.deriveType takes the nullability from the input.
> h3. Proposed fix
> CastConverter should use the resolved output type of the call, which the type strategy derives from the input, instead of the literal target type. This aligns the Table API with SQL for all casts. As a side effect, casting a NOT NULL input to a nullable target now yields NOT NULL, as it already does in SQL.
> Also document on cast() that the top-level nullability of the target type is ignored.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)