Skip to content

Commit 6efdbe6

Browse files
authored
Enforce uniqueness of named_struct field names (#11614)
* check struct field names for uniqueness * add logic test * improve error log
1 parent 8945462 commit 6efdbe6

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

datafusion/functions/src/core/named_struct.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use arrow::datatypes::{DataType, Field, Fields};
2020
use datafusion_common::{exec_err, internal_err, Result, ScalarValue};
2121
use datafusion_expr::{ColumnarValue, Expr, ExprSchemable};
2222
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
23+
use hashbrown::HashSet;
2324
use std::any::Any;
2425
use std::sync::Arc;
2526

@@ -45,7 +46,6 @@ fn named_struct_expr(args: &[ColumnarValue]) -> Result<ColumnarValue> {
4546
.map(|(i, chunk)| {
4647

4748
let name_column = &chunk[0];
48-
4949
let name = match name_column {
5050
ColumnarValue::Scalar(ScalarValue::Utf8(Some(name_scalar))) => name_scalar,
5151
_ => return exec_err!("named_struct even arguments must be string literals, got {name_column:?} instead at position {}", i * 2)
@@ -57,6 +57,19 @@ fn named_struct_expr(args: &[ColumnarValue]) -> Result<ColumnarValue> {
5757
.into_iter()
5858
.unzip();
5959

60+
{
61+
// Check to enforce the uniqueness of struct field name
62+
let mut unique_field_names = HashSet::new();
63+
for name in names.iter() {
64+
if unique_field_names.contains(name) {
65+
return exec_err!(
66+
"named_struct requires unique field names. Field {name} is used more than once."
67+
);
68+
}
69+
unique_field_names.insert(name);
70+
}
71+
}
72+
6073
let arrays = ColumnarValue::values_to_arrays(&values)?;
6174

6275
let fields = names

datafusion/sqllogictest/test_files/struct.slt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ physical_plan
122122
query error
123123
select named_struct();
124124

125+
# error on duplicate field names
126+
query error
127+
select named_struct('c0': 1, 'c1': 2, 'c1': 3);
128+
125129
# error on odd number of arguments #1
126130
query error DataFusion error: Execution error: named_struct requires an even number of arguments, got 1 instead
127131
select named_struct('a');

0 commit comments

Comments
 (0)