datafusion_functions_nested/
map_keys.rs1use crate::utils::{get_map_entry_field, make_scalar_function};
21use arrow::array::{Array, ArrayRef, ListArray};
22use arrow::datatypes::{DataType, Field};
23use datafusion_common::utils::take_function_args;
24use datafusion_common::{Result, cast::as_map_array, exec_err};
25use datafusion_expr::{
26 ArrayFunctionSignature, ColumnarValue, Documentation, ScalarFunctionArgs,
27 ScalarUDFImpl, Signature, TypeSignature, Volatility,
28};
29use datafusion_macros::user_doc;
30use std::sync::Arc;
31
32make_udf_expr_and_func!(
33 MapKeysFunc,
34 map_keys,
35 map,
36 "Return a list of all keys in the map.",
37 map_keys_udf
38);
39
40#[user_doc(
41 doc_section(label = "Map Functions"),
42 description = "Returns a list of all keys in the map.",
43 syntax_example = "map_keys(map)",
44 sql_example = r#"```sql
45SELECT map_keys(MAP {'a': 1, 'b': NULL, 'c': 3});
46----
47[a, b, c]
48
49SELECT map_keys(map([100, 5], [42, 43]));
50----
51[100, 5]
52```"#,
53 argument(
54 name = "map",
55 description = "Map expression. Can be a constant, column, or function, and any combination of map operators."
56 )
57)]
58#[derive(Debug, PartialEq, Eq, Hash)]
59pub struct MapKeysFunc {
60 signature: Signature,
61}
62
63impl Default for MapKeysFunc {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69impl MapKeysFunc {
70 pub fn new() -> Self {
71 Self {
72 signature: Signature::new(
73 TypeSignature::ArraySignature(ArrayFunctionSignature::MapArray),
74 Volatility::Immutable,
75 ),
76 }
77 }
78}
79
80impl ScalarUDFImpl for MapKeysFunc {
81 fn name(&self) -> &str {
82 "map_keys"
83 }
84
85 fn signature(&self) -> &Signature {
86 &self.signature
87 }
88
89 fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
90 let [map_type] = take_function_args(self.name(), arg_types)?;
91 let map_fields = get_map_entry_field(map_type)?;
92 Ok(DataType::List(Arc::new(Field::new_list_field(
94 map_fields.first().unwrap().data_type().clone(),
95 true,
96 ))))
97 }
98
99 fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
100 make_scalar_function(map_keys_inner)(&args.args)
101 }
102
103 fn documentation(&self) -> Option<&Documentation> {
104 self.doc()
105 }
106}
107
108fn map_keys_inner(args: &[ArrayRef]) -> Result<ArrayRef> {
109 let [map_arg] = take_function_args("map_keys", args)?;
110
111 let map_array = match map_arg.data_type() {
112 DataType::Map(_, _) => as_map_array(&map_arg)?,
113 _ => return exec_err!("Argument for map_keys should be a map"),
114 };
115
116 Ok(Arc::new(ListArray::new(
117 Arc::new(Field::new_list_field(map_array.key_type().clone(), true)),
119 map_array.offsets().clone(),
120 Arc::clone(map_array.keys()),
121 map_array.nulls().cloned(),
122 )))
123}