[
https://issues.apache.org/jira/browse/FLINK-40826?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ramin Gharib updated FLINK-40826:
---------------------------------
Description:
Adds {{CAST}} from primitive types to VARIANT. This ticket adds ARRAY, MAP,
ROW, and STRUCTURED sources.
h3. Rule
A constructed type casts to VARIANT only if every leaf type does. Each level
maps to its VARIANT shape, and each leaf is cast by the primitive rule. A leaf
without a VARIANT kind rejects the whole cast at validation time.
||Source type||Stored VARIANT shape||
|ARRAY<T>|array, each element cast from T|
|MAP<K, V>|object, K must be a character string, each value cast from V|
|ROW, STRUCTURED|object keyed by field name|
{code:sql}
CAST(ARRAY[1, 2, 3] AS VARIANT) -- [1,2,3]
CAST(ARRAY[1, NULL] AS VARIANT) -- [1,null], a NULL element
becomes a variant null
CAST(MAP['a', 1, 'b', 2] AS VARIANT) -- \{"a":1,"b":2}
CAST(r AS VARIANT) -- \{"id":7,"name":"ada"} for
r ROW<id INT, name STRING>
CAST(r AS VARIANT) -- \{"id":1,"tags":[1,2]} for
r ROW<id INT, tags VARIANT>
CAST(MAP[1, 'a'] AS VARIANT) -- fails at validation, keys
are not stringified
CAST(ARRAY[INTERVAL '1' DAY] AS VARIANT) -- fails at validation, the
leaf has no VARIANT kind
CAST(MULTISET[1, 1] AS VARIANT) -- fails at validation
{code}
* A NULL element, map value, or field becomes a variant null, so the array
length and the object shape are kept. A NULL top-level value stays SQL NULL.
* A nested VARIANT is embedded as is.
* Field order is not kept, since a variant object is ordered by key.
* An empty array, map, or row becomes an empty array or object.
This can be delivered in three PRs, ARRAY, then MAP, then ROW and STRUCTURED,
like the opposite direction in FLINK-37926.
h3. Open question
Which keys should an unnamed row get? The SQL row constructor {{ROW(7, 'ada')}}
carries planner-generated field names that are not user-facing.
was:
Adds {{CAST}} from primitive types to VARIANT. This ticket adds ARRAY, MAP,
ROW, and STRUCTURED sources.
h3. Rule
A constructed type casts to VARIANT only if every leaf type does. Each level
maps to its VARIANT shape, and each leaf is cast by the primitive rule. A leaf
without a VARIANT kind rejects the whole cast at validation time.
||Source type||Stored VARIANT shape||
|ARRAY<T>|array, each element cast from T|
|MAP<K, V>|object, K must be a character string, each value cast from V|
|ROW, STRUCTURED|object keyed by field name|
{code:sql}
CAST(ARRAY[1, 2, 3] AS VARIANT) -- [1,2,3]
CAST(ARRAY[1, NULL] AS VARIANT) -- [1,null], a NULL element
becomes a variant null
CAST(MAP['a', 1, 'b', 2] AS VARIANT) -- \{"a":1,"b":2}
CAST(r AS VARIANT) -- \{"id":7,"name":"ada"} for
r ROW<id INT, name STRING>
CAST(r AS VARIANT) -- \{"id":1,"tags":[1,2]} for
r ROW<id INT, tags VARIANT>
CAST(MAP[1, 'a'] AS VARIANT) -- fails at validation, keys
are not stringified
CAST(ARRAY[INTERVAL '1' DAY] AS VARIANT) -- fails at validation, the
leaf has no VARIANT kind
CAST(MULTISET[1, 1] AS VARIANT) -- fails at validation
{code}
* A NULL element, map value, or field becomes a variant null, so the array
length and the object shape are kept. A NULL top-level value stays SQL NULL.
* A nested VARIANT is embedded as is.
* Field order is not kept, since a variant object is ordered by key.
* An empty array, map, or row becomes an empty array or object.
This can be delivered in three PRs, ARRAY, then MAP, then ROW and STRUCTURED,
like the opposite direction in FLINK-37926.
h3. Open question
Which keys should an unnamed row get? The SQL row constructor \{{ROW(7,
'ada')}} carries planner-generated field names that are not user-facing.
> Support casting constructed types to VARIANT
> ---------------------------------------------
>
> Key: FLINK-40826
> URL: https://issues.apache.org/jira/browse/FLINK-40826
> Project: Flink
> Issue Type: Sub-task
> Components: Table SQL / API
> Reporter: Ramin Gharib
> Assignee: Ramin Gharib
> Priority: Major
>
> Adds {{CAST}} from primitive types to VARIANT. This ticket adds ARRAY, MAP,
> ROW, and STRUCTURED sources.
> h3. Rule
> A constructed type casts to VARIANT only if every leaf type does. Each level
> maps to its VARIANT shape, and each leaf is cast by the primitive rule. A
> leaf without a VARIANT kind rejects the whole cast at validation time.
> ||Source type||Stored VARIANT shape||
> |ARRAY<T>|array, each element cast from T|
> |MAP<K, V>|object, K must be a character string, each value cast from V|
> |ROW, STRUCTURED|object keyed by field name|
> {code:sql}
> CAST(ARRAY[1, 2, 3] AS VARIANT) -- [1,2,3]
> CAST(ARRAY[1, NULL] AS VARIANT) -- [1,null], a NULL element
> becomes a variant null
> CAST(MAP['a', 1, 'b', 2] AS VARIANT) -- \{"a":1,"b":2}
> CAST(r AS VARIANT) -- \{"id":7,"name":"ada"}
> for r ROW<id INT, name STRING>
> CAST(r AS VARIANT) -- \{"id":1,"tags":[1,2]}
> for r ROW<id INT, tags VARIANT>
> CAST(MAP[1, 'a'] AS VARIANT) -- fails at validation, keys
> are not stringified
> CAST(ARRAY[INTERVAL '1' DAY] AS VARIANT) -- fails at validation, the
> leaf has no VARIANT kind
> CAST(MULTISET[1, 1] AS VARIANT) -- fails at validation
> {code}
> * A NULL element, map value, or field becomes a variant null, so the array
> length and the object shape are kept. A NULL top-level value stays SQL NULL.
> * A nested VARIANT is embedded as is.
> * Field order is not kept, since a variant object is ordered by key.
> * An empty array, map, or row becomes an empty array or object.
> This can be delivered in three PRs, ARRAY, then MAP, then ROW and STRUCTURED,
> like the opposite direction in FLINK-37926.
> h3. Open question
> Which keys should an unnamed row get? The SQL row constructor {{ROW(7,
> 'ada')}} carries planner-generated field names that are not user-facing.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)