This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-24397-3359eab09e634bf8298d3edbd2906c042c61791c in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit 9fdf1447ef9e797181f9b93e81cde937181093e3 Author: Nuno Faria <[email protected]> AuthorDate: Sun Aug 16 10:51:45 2026 +0000 feat: Add support for Map type in SQL (#24397) ## Which issue does this PR close? - Closes #24396. ## Rationale for this change Support the `Map` type directly in SQL, e.g., when creating tables. ## What changes are included in this PR? The sql-parser `DataType::Map` is now converted to the arrow type `DataType::Map`. ## Are these changes tested? Yes ## Are there any user-facing changes? New SQL type. --- datafusion/sql/src/planner.rs | 11 ++++++++- datafusion/sqllogictest/test_files/ddl.slt | 37 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/datafusion/sql/src/planner.rs b/datafusion/sql/src/planner.rs index 3a696811be..7bdeddf379 100644 --- a/datafusion/sql/src/planner.rs +++ b/datafusion/sql/src/planner.rs @@ -826,6 +826,16 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { .collect::<Result<Vec<_>>>()?; Ok(DataType::Struct(Fields::from(fields))) } + SQLDataType::Map(key_type, value_type) => { + let key_field = Arc::new(Field::new( + "key", self.convert_data_type_to_field(key_type)?.data_type().clone(), false + )); + let value_field = Arc::new(Field::new( + "value", self.convert_data_type_to_field(value_type)?.data_type().clone(), true) + ); + let entries = DataType::Struct(Fields::from([key_field, value_field])); + Ok(DataType::Map(Arc::new(Field::new("entries", entries, false)), false)) + } SQLDataType::Nvarchar(_) | SQLDataType::JSON | SQLDataType::Uuid @@ -870,7 +880,6 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | SQLDataType::Date32 | SQLDataType::Datetime64(_, _) | SQLDataType::FixedString(_) - | SQLDataType::Map(_, _) | SQLDataType::Tuple(_) | SQLDataType::Nested(_) | SQLDataType::Union(_) diff --git a/datafusion/sqllogictest/test_files/ddl.slt b/datafusion/sqllogictest/test_files/ddl.slt index 672bab5533..487786e3af 100644 --- a/datafusion/sqllogictest/test_files/ddl.slt +++ b/datafusion/sqllogictest/test_files/ddl.slt @@ -1001,3 +1001,40 @@ SELECT * INTO dup_into FROM dup_src LEFT JOIN dup_src y ON dup_src.column1 = y.c statement ok DROP TABLE dup_src; + + +# Table with Map types +statement ok +create table t (a map(int, int), b map(varchar, map(varchar, int))); + +query TTT +describe t; +---- +a Map("entries": non-null Struct("key": non-null Int32, "value": Int32), unsorted) YES +b Map("entries": non-null Struct("key": non-null Utf8View, "value": Map("entries": non-null Struct("key": non-null Utf8View, "value": Int32), unsorted)), unsorted) YES + +statement ok +insert into t values + (map{1: 10, 2: 20}, map{'a': map{'aa': 1, 'ab': 2}, 'b': map{'ba': 10, 'bb': 20}}), + (map{10: 100}, map{'c': map{'d': 100}}), + (map{}, map{'a': map{}}), + (null, map{'a': null}); + +query ?? rowsort +select * from t; +---- +NULL {a: NULL} +{10: 100} {c: {d: 100}} +{1: 10, 2: 20} {a: {aa: 1, ab: 2}, b: {ba: 10, bb: 20}} +{} {a: {}} + +# duplicate keys +statement error DataFusion error: Execution error: map key must be unique, duplicate key found: a +insert into t values (map{'a': 1, 'a': 10}, null); + +# key can't be null +statement error DataFusion error: Execution error: map key cannot be null +insert into t values (map{null: 1}, null); + +statement ok +drop table t; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
