Ramin Gharib created FLINK-41279:
------------------------------------
Summary: Support the PostgreSQL-style :: cast operator
Key: FLINK-41279
URL: https://issues.apache.org/jira/browse/FLINK-41279
Project: Flink
Issue Type: New Feature
Components: Table SQL / API
Reporter: Ramin Gharib
Assignee: Ramin Gharib
Flink SQL only supports {{CAST(x AS type)}}. PostgreSQL, DuckDB and Snowflake
also accept the shorter infix form {{x::type}}, and Calcite supports it in its
Babel parser. These statements fail to parse in Flink today:
{code:sql}
SELECT '42'::INT + 1; -- CAST('42' AS INT) + 1
SELECT payload::VARIANT FROM t; -- CAST(payload AS VARIANT)
SELECT m['k']::INT FROM t; -- CAST(m['k'] AS INT)
SELECT s::INT::STRING FROM t; -- CAST(CAST(s AS INT) AS STRING)
{code}
h3. Proposal
Treat {{::}} as pure syntax for {{CAST}}. The parser turns {{x::type}} into a
plain {{CAST(x AS type)}} call, so validation, planning, code generation and
compiled plans stay unchanged.
* Add the {{::}} token and an {{InfixCast}} production through the existing
{{binaryOperatorsTokens}} and {{extraBinaryExpressions}} hooks in
{{Parser.tdd}} and {{parserImpls.ftl}}. {{Parser.jj}} stays untouched.
* The production emits a Flink-side binary operator whose {{createCall}}
returns a {{CAST}} call. It keeps Calcite's precedence for {{::}}: tighter than
arithmetic, looser than {{[]}} and {{.}}.
* The type after {{::}} goes through Flink's {{DataType()}} production, so
types like {{ARRAY<INT>}}, {{ROW<...>}} and {{VARIANT}} work.
h3. Why not reuse Calcite's SqlLibraryOperators.INFIX_CAST
Calcite's operator stays in the validated tree and unparses as {{a :: INT}}.
That text ends up in persisted catalog state, such as view expanded queries,
computed columns and materialized table definition queries, and older Flink
versions can't parse it. The unparse format also belongs to Calcite:
CALCITE-7475 changed it in Calcite 1.42. Desugaring in the parser keeps all
stored text as {{CAST(a AS INT)}} and leaves no new operator for later Calcite
upgrades to track.
h3. Out of scope
* Table API. {{BaseExpressions#cast}} already covers it.
* A {{TRY_CAST}} counterpart. PostgreSQL has none.
* Postfix access directly after the type, like {{x::ARRAY<INT>[1]}}, which
Calcite Babel added in CALCITE-7475.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)