Skip to content

Commit 9d89bfb

Browse files
manuzhangcodex
andcommitted
test: add complex cast SQL coverage
Add a SQL test resource that exercises nested struct, array, and array-of-struct casts. Co-authored-by: Codex <codex@openai.com>
1 parent 9b10e99 commit 9d89bfb

2 files changed

Lines changed: 151 additions & 85 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one
2+
-- or more contributor license agreements. See the NOTICE file
3+
-- distributed with this work for additional information
4+
-- regarding copyright ownership. The ASF licenses this file
5+
-- to you under the Apache License, Version 2.0 (the
6+
-- "License"); you may not use this file except in compliance
7+
-- with the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing,
12+
-- software distributed under the License is distributed on an
13+
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
-- KIND, either express or implied. See the License for the
15+
-- specific language governing permissions and limitations
16+
-- under the License.
17+
18+
statement
19+
CREATE TABLE test_cast_complex(
20+
id int,
21+
struct_arr struct<items:array<int>,label:string>,
22+
deep struct<outer:struct<middle:struct<value:string,flag:boolean>,numbers:array<string>>,note:string>,
23+
arr_struct array<struct<id:int,score:string>>
24+
) USING parquet
25+
26+
statement
27+
INSERT INTO test_cast_complex VALUES
28+
(
29+
1,
30+
named_struct(
31+
'items', array(1, 2, cast(null as int)),
32+
'label', 'first'),
33+
named_struct(
34+
'outer',
35+
named_struct(
36+
'middle', named_struct('value', '1', 'flag', true),
37+
'numbers', array('2', '3')),
38+
'note', 'alpha'),
39+
array(
40+
named_struct('id', 1, 'score', '10'),
41+
named_struct('id', 2, 'score', cast(null as string)))
42+
),
43+
(
44+
2,
45+
named_struct(
46+
'items', cast(array() as array<int>),
47+
'label', cast(null as string)),
48+
named_struct(
49+
'outer',
50+
named_struct(
51+
'middle', named_struct('value', cast(null as string), 'flag', false),
52+
'numbers', array(cast(null as string))),
53+
'note', cast(null as string)),
54+
array(named_struct('id', cast(null as int), 'score', '30'))
55+
),
56+
(
57+
3,
58+
cast(null as struct<items:array<int>,label:string>),
59+
cast(null as
60+
struct<outer:struct<middle:struct<value:string,flag:boolean>,numbers:array<string>>,
61+
note:string>),
62+
cast(array() as array<struct<id:int,score:string>>)
63+
),
64+
(
65+
4,
66+
named_struct(
67+
'items', array(-1, 0, 2147483647),
68+
'label', 'edge'),
69+
named_struct(
70+
'outer',
71+
named_struct(
72+
'middle', named_struct('value', '-4', 'flag', true),
73+
'numbers', array('-5', '0')),
74+
'note', 'omega'),
75+
cast(null as array<struct<id:int,score:string>>)
76+
)
77+
78+
-- struct field containing an array
79+
query
80+
SELECT cast(struct_arr as struct<items:array<string>,label:string>), id
81+
FROM test_cast_complex
82+
ORDER BY id
83+
84+
-- struct fields can be renamed by the target type
85+
query
86+
SELECT cast(struct_arr as struct<numbers:array<string>,name:string>), id
87+
FROM test_cast_complex
88+
ORDER BY id
89+
90+
-- struct target field names are applied positionally
91+
query
92+
SELECT cast(struct_arr as struct<label:array<string>,items:string>), id
93+
FROM test_cast_complex
94+
ORDER BY id
95+
96+
-- missing struct fields are rejected
97+
query expect_error(DATATYPE_MISMATCH)
98+
SELECT cast(struct_arr as struct<items:array<string>>)
99+
FROM test_cast_complex
100+
101+
-- extra struct fields are rejected
102+
query expect_error(DATATYPE_MISMATCH)
103+
SELECT cast(struct_arr as struct<items:array<string>,label:string,extra:int>)
104+
FROM test_cast_complex
105+
106+
-- deeply nested struct to struct
107+
query
108+
SELECT cast(deep as
109+
struct<outer:struct<middle:struct<value:int,flag:string>,numbers:array<int>>,note:string>), id
110+
FROM test_cast_complex
111+
ORDER BY id
112+
113+
-- deeply nested struct to string
114+
query
115+
SELECT cast(deep as string), id
116+
FROM test_cast_complex
117+
ORDER BY id
118+
119+
-- array of structs to array of structs
120+
query
121+
SELECT cast(arr_struct as array<struct<id:bigint,score:int>>), id
122+
FROM test_cast_complex
123+
ORDER BY id
124+
125+
-- array of structs with renamed fields
126+
query
127+
SELECT cast(arr_struct as array<struct<item_id:bigint,total:int>>), id
128+
FROM test_cast_complex
129+
ORDER BY id
130+
131+
-- array of structs with target field names applied positionally
132+
query
133+
SELECT cast(arr_struct as array<struct<score:bigint,id:int>>), id
134+
FROM test_cast_complex
135+
ORDER BY id
136+
137+
-- array of structs with missing nested fields is rejected
138+
query expect_error(DATATYPE_MISMATCH)
139+
SELECT cast(arr_struct as array<struct<id:bigint>>)
140+
FROM test_cast_complex
141+
142+
-- array of structs with extra nested fields is rejected
143+
query expect_error(DATATYPE_MISMATCH)
144+
SELECT cast(arr_struct as array<struct<id:bigint,score:int,extra:string>>)
145+
FROM test_cast_complex
146+
147+
-- array of structs to string
148+
query
149+
SELECT cast(arr_struct as string), id
150+
FROM test_cast_complex
151+
ORDER BY id

spark/src/test/scala/org/apache/comet/CometCastSuite.scala

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,57 +1493,6 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
14931493
}
14941494
}
14951495

1496-
test("cast StructType with ArrayType field to StructType") {
1497-
testSingleLineQuery(
1498-
"""
1499-
|SELECT named_struct(
1500-
| 'items', array(1, 2, cast(null as int)),
1501-
| 'label', 'first') AS s
1502-
|UNION ALL
1503-
|SELECT named_struct(
1504-
| 'items', cast(array() as array<int>),
1505-
| 'label', cast(null as string)) AS s
1506-
|UNION ALL
1507-
|SELECT cast(null as struct<items:array<int>,label:string>) AS s
1508-
|""".stripMargin,
1509-
"SELECT CAST(s AS struct<items:array<string>,label:string>) FROM tbl",
1510-
testName = "cast_struct_array_field_to_struct")
1511-
}
1512-
1513-
test("cast deeply nested StructType to StructType and StringType") {
1514-
val input =
1515-
"""
1516-
|SELECT named_struct(
1517-
| 'outer',
1518-
| named_struct(
1519-
| 'middle', named_struct('value', '1', 'flag', true),
1520-
| 'numbers', array('2', '3')),
1521-
| 'note', 'alpha') AS s
1522-
|UNION ALL
1523-
|SELECT named_struct(
1524-
| 'outer',
1525-
| named_struct(
1526-
| 'middle', named_struct('value', cast(null as string), 'flag', false),
1527-
| 'numbers', array(cast(null as string))),
1528-
| 'note', cast(null as string)) AS s
1529-
|UNION ALL
1530-
|SELECT cast(null as
1531-
| struct<outer:struct<middle:struct<value:string,flag:boolean>,numbers:array<string>>,
1532-
| note:string>) AS s
1533-
|""".stripMargin
1534-
1535-
testSingleLineQuery(
1536-
input,
1537-
"SELECT CAST(s AS " +
1538-
"struct<outer:struct<middle:struct<value:int,flag:string>,numbers:array<int>>," +
1539-
"note:string>) FROM tbl",
1540-
testName = "cast_deep_struct_to_struct")
1541-
testSingleLineQuery(
1542-
input,
1543-
"SELECT CAST(s AS string) FROM tbl",
1544-
testName = "cast_deep_struct_to_string")
1545-
}
1546-
15471496
test("cast between decimals with different precision and scale") {
15481497
val rowData = Seq(
15491498
Row(BigDecimal("12345.6789")),
@@ -1658,23 +1607,6 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
16581607
StringType)
16591608
}
16601609

1661-
test("cast ArrayType(StructType) to StringType") {
1662-
testSingleLineQuery(
1663-
"""
1664-
|SELECT array(
1665-
| named_struct('id', 1, 'score', '10'),
1666-
| named_struct('id', 2, 'score', cast(null as string))) AS a
1667-
|UNION ALL
1668-
|SELECT array(named_struct('id', cast(null as int), 'score', '30')) AS a
1669-
|UNION ALL
1670-
|SELECT cast(array() as array<struct<id:int,score:string>>) AS a
1671-
|UNION ALL
1672-
|SELECT cast(null as array<struct<id:int,score:string>>) AS a
1673-
|""".stripMargin,
1674-
"SELECT CAST(a AS string) FROM tbl",
1675-
testName = "cast_array_struct_to_string")
1676-
}
1677-
16781610
test("cast ArrayType to ArrayType") {
16791611
val types = Seq(
16801612
BooleanType,
@@ -1700,23 +1632,6 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
17001632
testArrayCastMatrix(types, ArrayType(_), generateArrays(100, _))
17011633
}
17021634

1703-
test("cast ArrayType(StructType) to ArrayType(StructType)") {
1704-
testSingleLineQuery(
1705-
"""
1706-
|SELECT array(
1707-
| named_struct('id', 1, 'score', '10'),
1708-
| named_struct('id', 2, 'score', cast(null as string))) AS a
1709-
|UNION ALL
1710-
|SELECT array(named_struct('id', cast(null as int), 'score', '30')) AS a
1711-
|UNION ALL
1712-
|SELECT cast(array() as array<struct<id:int,score:string>>) AS a
1713-
|UNION ALL
1714-
|SELECT cast(null as array<struct<id:int,score:string>>) AS a
1715-
|""".stripMargin,
1716-
"SELECT CAST(a AS array<struct<id:bigint,score:int>>) FROM tbl",
1717-
testName = "cast_array_struct_to_array_struct")
1718-
}
1719-
17201635
test("cast ArrayType(DateType) to unsupported ArrayType falls back") {
17211636
val fromType = ArrayType(DateType)
17221637
val unsupportedElementTypes =

0 commit comments

Comments
 (0)