Skip to content

Commit

Permalink
Support explicit type and name during table creation (apache#10273)
Browse files Browse the repository at this point in the history
* temp cargo commit

* chore: update test

* fmt

* update cli  cargo lock
  • Loading branch information
duongcongtoai authored and findepi committed Jul 16, 2024
1 parent 9b626c1 commit 10f922d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
20 changes: 19 additions & 1 deletion datafusion/sql/src/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,25 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
}
SQLDataType::Bytea => Ok(DataType::Binary),
SQLDataType::Interval => Ok(DataType::Interval(IntervalUnit::MonthDayNano)),
SQLDataType::Struct(fields) => {
let fields = fields
.iter()
.enumerate()
.map(|(idx, field)| {
let data_type = self.convert_data_type(&field.field_type)?;
let field_name = match &field.field_name{
Some(ident) => ident.clone(),
None => Ident::new(format!("c{idx}"))
};
Ok(Arc::new(Field::new(
self.normalizer.normalize(field_name),
data_type,
true,
)))
})
.collect::<Result<Vec<_>>>()?;
Ok(DataType::Struct(Fields::from(fields)))
}
// Explicitly list all other types so that if sqlparser
// adds/changes the `SQLDataType` the compiler will tell us on upgrade
// and avoid bugs like https://github.com/apache/datafusion/issues/3059
Expand Down Expand Up @@ -472,7 +491,6 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
| SQLDataType::Bytes(_)
| SQLDataType::Int64
| SQLDataType::Float64
| SQLDataType::Struct(_)
| SQLDataType::JSONB
| SQLDataType::Unspecified
=> not_impl_err!(
Expand Down
27 changes: 27 additions & 0 deletions datafusion/sqllogictest/test_files/struct.slt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,33 @@ CREATE TABLE values(
(3, 3.3, 'c', NULL)
;


# named and named less struct fields
statement ok
CREATE TABLE struct_values (
s1 struct<INT>,
s2 struct<a INT,b VARCHAR>
) AS VALUES
(struct(1), struct(1, 'string1')),
(struct(2), struct(2, 'string2')),
(struct(3), struct(3, 'string3'))
;

query ??
select * from struct_values;
----
{c0: 1} {a: 1, b: string1}
{c0: 2} {a: 2, b: string2}
{c0: 3} {a: 3, b: string3}

query TT
select arrow_typeof(s1), arrow_typeof(s2) from struct_values;
----
Struct([Field { name: "c0", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }]) Struct([Field { name: "a", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "b", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
Struct([Field { name: "c0", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }]) Struct([Field { name: "a", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "b", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
Struct([Field { name: "c0", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }]) Struct([Field { name: "a", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "b", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])


# struct[i]
query IRT
select struct(1, 3.14, 'h')['c0'], struct(3, 2.55, 'b')['c1'], struct(2, 6.43, 'a')['c2'];
Expand Down

0 comments on commit 10f922d

Please sign in to comment.