This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 9fdf1447ef feat: Add support for Map type in SQL (#24397)
9fdf1447ef is described below
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]