Skip to content

Commit be19afc

Browse files
authored
Fix ExprSchema extraction of metadata for Cast expressions. (#13305)
* test(12733): reproducers for schema bugs * fix(12733): properly extract field metadata from Cast expr * test(12733): update metadata preservation test, for new contract (a.k.a. cast preserves field metadata)
1 parent 7ebd993 commit be19afc

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

datafusion/expr/src/expr_schema.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ impl ExprSchemable for Expr {
347347
match self {
348348
Expr::Column(c) => Ok(schema.metadata(c)?.clone()),
349349
Expr::Alias(Alias { expr, .. }) => expr.metadata(schema),
350+
Expr::Cast(Cast { expr, .. }) => expr.metadata(schema),
350351
_ => Ok(HashMap::new()),
351352
}
352353
}
@@ -681,13 +682,11 @@ mod tests {
681682
.with_data_type(DataType::Int32)
682683
.with_metadata(meta.clone());
683684

684-
// col and alias should be metadata-preserving
685+
// col, alias, and cast should be metadata-preserving
685686
assert_eq!(meta, expr.metadata(&schema).unwrap());
686687
assert_eq!(meta, expr.clone().alias("bar").metadata(&schema).unwrap());
687-
688-
// cast should drop input metadata since the type has changed
689688
assert_eq!(
690-
HashMap::new(),
689+
meta,
691690
expr.clone()
692691
.cast_to(&DataType::Int64, &schema)
693692
.unwrap()

datafusion/sqllogictest/test_files/metadata.slt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,74 @@ LIMIT 1;
168168
2020-09-08T13:42:29.190855123Z
169169

170170

171+
172+
# distinct (aggregate) alone
173+
query P
174+
SELECT
175+
DISTINCT ts as dist
176+
FROM table_with_metadata;
177+
----
178+
2020-09-08T13:42:29.190855123
179+
180+
# cast alone
181+
query D
182+
SELECT
183+
ts::DATE as casted
184+
FROM table_with_metadata;
185+
----
186+
2020-09-08
187+
2020-09-08
188+
2020-09-08
189+
190+
# Regression test: distinct with cast
191+
query D
192+
SELECT DISTINCT (ts::DATE) AS dist
193+
FROM table_with_metadata;
194+
----
195+
2020-09-08
196+
197+
198+
199+
# count distinct with group by
200+
query II
201+
SELECT
202+
id AS grp,
203+
COUNT(DISTINCT nonnull_name) as dist
204+
FROM table_with_metadata
205+
GROUP BY grp
206+
order by 1 asc nulls last;
207+
----
208+
1 1
209+
3 1
210+
NULL 1
211+
212+
# count (not distinct) & cast, with group by
213+
query TI
214+
SELECT
215+
CAST(id AS TEXT) AS grp,
216+
COUNT(nonnull_name) as dist
217+
FROM table_with_metadata
218+
GROUP BY grp
219+
order by 1 asc nulls last;
220+
----
221+
1 1
222+
3 1
223+
NULL 1
224+
225+
# Regression test: count distinct & cast, with group by
226+
query TI
227+
SELECT
228+
CAST(id AS TEXT) AS grp,
229+
COUNT(DISTINCT nonnull_name) as dist
230+
FROM table_with_metadata
231+
GROUP BY grp
232+
order by 1 asc nulls last;
233+
----
234+
1 1
235+
3 1
236+
NULL 1
237+
238+
239+
171240
statement ok
172241
drop table table_with_metadata;

0 commit comments

Comments
 (0)