Moritz Manner created FLINK-40410:
-------------------------------------
Summary: ClassCastException when constant-folding a VARIANT
expression before another constant expression
Key: FLINK-40410
URL: https://issues.apache.org/jira/browse/FLINK-40410
Project: Flink
Issue Type: Bug
Components: Table SQL / Planner
Affects Versions: 2.4.0
Reporter: Moritz Manner
When running the query:
{code:java}
SELECT JSON_STRING(PARSE_JSON('{}')), PARSE_JSON('{}');{code}
the output is correct with a single row containing _*{}*_ and _*{}*_ (first of
type VARCHAR, second of type VARIANT).
However, by just switching the order of the values to
{code:java}
SELECT PARSE_JSON('{}'), JSON_STRING(PARSE_JSON('{}'));{code}
a ClassCastException is thrown:
{code:java}
[ERROR] Could not execute SQL statement. Reason:
java.lang.ClassCastException: class
org.apache.flink.types.variant.BinaryVariant cannot be cast to class
org.apache.flink.table.data.binary.BinaryStringData
(org.apache.flink.types.variant.BinaryVariant and
org.apache.flink.table.data.binary.BinaryStringData are in unnamed module of
loader 'app') {code}
*Root cause*
The ExpressionReducer.scala in *_flink-table-planner_* evaluates constant
sub-expressions, so they get computed during compile-time and not during query
run-time.
It runs in two passes that must agree on which types get a slot in the
intermediate (compile-time) result:
* Phase 1 excludes unsupported "object literal" types
(ROW/ARRAY/MAP/MULTISET/...) from compile-time evaluation. VARIANT is missing
from this list and is therefore evaluated at compile-time and added to the
intermediate result list.
* Phase 2 has an specific case for VARIANT and treats VARIANT as excluded from
compile-time evaluation. So a VARIANT constant gets evaluated and occupies a
real slot in phase 1, but phase 2 doesn't know that and never advances its slot
index. Then the next reduced expression reads the stale slot containing the
VARIANT data and crashes on the bad cast.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)