Skip to content

Commit

Permalink
fix(expr): fix casting rules for struct (#7202)
Browse files Browse the repository at this point in the history
Fix row type alignment. As mentioned by @xiangjinwu [here](#7189 (comment)):
> It is due to the fact that we do not allow casting between the same type, so the 2nd field fails to match interval to interval 😂

Thanks to @xiangjinwu for pointing out the quick fix.

Approved-By: xiangjinwu
  • Loading branch information
kwannoel authored Jan 5, 2023
1 parent 80abae3 commit 77534a9
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
12 changes: 12 additions & 0 deletions e2e_test/batch/types/struct/struct_cast_2.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ select row(1) < row(true);

statement error
select row(1) < row(1, 1);

# Align row types
query I
select CASE WHEN false THEN ROW(1.1, INTERVAL '1') ELSE ROW(0, INTERVAL '1') END;
----
(0,00:00:01)

# Align row types
query I
select CASE WHEN false THEN ROW(0, INTERVAL '1') ELSE ROW(1.1, INTERVAL '1') END;
----
(1.1,00:00:01)
6 changes: 6 additions & 0 deletions src/frontend/planner_test/tests/testdata/struct_query.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,9 @@
CREATE TABLE a (c STRUCT<i STRUCT<a INTEGER>, j INTEGER>);
INSERT INTO a VALUES (1);
binder_error: 'Bind error: cannot cast type "integer" to "struct<i struct<a integer>,j integer>" in Assign context'
- name: test struct type alignment in CASE expression
sql: |
select CASE WHEN false THEN ROW(0, INTERVAL '1') WHEN true THEN ROW(1.1, INTERVAL '1') ELSE ROW(1, INTERVAL '1') END;
logical_plan: |
LogicalProject { exprs: [Case(false:Boolean, Row(0:Int32::Decimal, '00:00:01':Interval), true:Boolean, Row(1.1:Decimal, '00:00:01':Interval), Row(1:Int32::Decimal, '00:00:01':Interval))] }
└─LogicalValues { rows: [[]], schema: Schema { fields: [] } }
2 changes: 1 addition & 1 deletion src/frontend/src/expr/type_inference/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ fn cast_ok_struct(source: &DataType, target: &DataType, allows: CastContext) ->
lty.fields
.iter()
.zip_eq(rty.fields.iter())
.all(|(src, dst)| cast_ok(src, dst, allows))
.all(|(src, dst)| src == dst || cast_ok(src, dst, allows))
}
// The automatic casts to string types are treated as assignment casts, while the automatic
// casts from string types are explicit-only.
Expand Down

0 comments on commit 77534a9

Please sign in to comment.