Skip to main content

datafusion_functions/core/
mod.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! "core" DataFusion functions
19
20use datafusion_expr::ScalarUDF;
21use std::sync::Arc;
22
23pub mod arrow_cast;
24pub mod arrow_field;
25pub mod arrow_metadata;
26pub mod arrow_try_cast;
27pub mod arrowtypeof;
28pub mod cast_to_type;
29pub mod coalesce;
30pub mod expr_ext;
31pub mod file_row_index;
32pub mod getfield;
33pub mod greatest;
34mod greatest_least_utils;
35pub mod input_file_name;
36pub mod least;
37pub mod named_struct;
38pub mod nullif;
39pub mod nvl;
40pub mod nvl2;
41pub mod overlay;
42pub mod planner;
43pub mod r#struct;
44pub mod try_cast_to_type;
45pub mod union_extract;
46pub mod union_tag;
47pub mod version;
48pub mod with_metadata;
49
50// create UDFs
51make_udf_function!(arrow_cast::ArrowCastFunc, arrow_cast);
52make_udf_function!(arrow_try_cast::ArrowTryCastFunc, arrow_try_cast);
53make_udf_function!(cast_to_type::CastToTypeFunc, cast_to_type);
54make_udf_function!(try_cast_to_type::TryCastToTypeFunc, try_cast_to_type);
55make_udf_function!(nullif::NullIfFunc, nullif);
56make_udf_function!(nvl::NVLFunc, nvl);
57make_udf_function!(nvl2::NVL2Func, nvl2);
58make_udf_function!(overlay::OverlayFunc, overlay);
59make_udf_function!(arrowtypeof::ArrowTypeOfFunc, arrow_typeof);
60make_udf_function!(r#struct::StructFunc, r#struct);
61make_udf_function!(named_struct::NamedStructFunc, named_struct);
62make_udf_function!(getfield::GetFieldFunc, get_field);
63make_udf_function!(coalesce::CoalesceFunc, coalesce);
64make_udf_function!(greatest::GreatestFunc, greatest);
65make_udf_function!(least::LeastFunc, least);
66make_udf_function!(union_extract::UnionExtractFun, union_extract);
67make_udf_function!(union_tag::UnionTagFunc, union_tag);
68make_udf_function!(version::VersionFunc, version);
69make_udf_function!(arrow_metadata::ArrowMetadataFunc, arrow_metadata);
70make_udf_function!(with_metadata::WithMetadataFunc, with_metadata);
71make_udf_function!(arrow_field::ArrowFieldFunc, arrow_field);
72make_udf_function!(file_row_index::FileRowIndexFunc, file_row_index);
73make_udf_function!(input_file_name::InputFileNameFunc, input_file_name);
74
75pub mod expr_fn {
76    use datafusion_expr::{Expr, Literal};
77
78    export_functions!((
79        nullif,
80        "Returns NULL if value1 equals value2; otherwise it returns value1. This can be used to perform the inverse operation of the COALESCE expression",
81        arg1 arg2
82    ),(
83        arrow_cast,
84        "Casts a value to a specific Arrow data type",
85        arg1 arg2
86    ),(
87        arrow_try_cast,
88        "Casts a value to a specific Arrow data type, returning NULL if the cast fails",
89        arg1 arg2
90    ),(
91        cast_to_type,
92        "Casts the first argument to the data type of the second argument",
93        arg1 arg2
94    ),(
95        try_cast_to_type,
96        "Casts the first argument to the data type of the second argument, returning NULL on failure",
97        arg1 arg2
98    ),(
99        nvl,
100        "Returns value2 if value1 is NULL; otherwise it returns value1",
101        arg1 arg2
102    ),(
103        nvl2,
104        "Returns value2 if value1 is not NULL; otherwise, it returns value3.",
105        arg1 arg2 arg3
106    ),(
107        overlay,
108        "replace the substring of string that starts at the start'th character and extends for count characters with new substring",
109        args,
110    ),(
111        arrow_typeof,
112        "Returns the Arrow type of the input expression.",
113        arg1
114    ),(
115        arrow_field,
116        "Returns the Arrow field info (name, data_type, nullable, metadata) of the input expression.",
117        arg1
118    ),(
119        arrow_metadata,
120        "Returns the metadata of the input expression",
121        args,
122    ),
123    (
124        input_file_name,
125        "Returns the path of the input file that produced the current row",
126    ),
127    (
128        with_metadata,
129        "Attaches Arrow field metadata (key/value pairs) to the input expression",
130        args,
131    ),(
132        r#struct,
133        "Returns a struct with the given arguments",
134        args,
135    ),(
136        named_struct,
137        "Returns a struct with the given names and arguments pairs",
138        args,
139    ),(
140        coalesce,
141        "Returns `coalesce(args...)`, which evaluates to the value of the first expr which is not NULL",
142        args,
143    ),(
144        greatest,
145        "Returns `greatest(args...)`, which evaluates to the greatest value in the list of expressions or NULL if all the expressions are NULL",
146        args,
147    ),(
148        least,
149        "Returns `least(args...)`, which evaluates to the smallest value in the list of expressions or NULL if all the expressions are NULL",
150        args,
151    ),(
152        union_tag,
153        "Returns the name of the currently selected field in the union",
154        arg1
155    ),(
156        file_row_index,
157        "Returns the offset of the row within its source file",
158    ));
159
160    #[doc = "Returns the value of the field with the given name from the struct"]
161    #[expect(clippy::needless_pass_by_value)]
162    pub fn get_field(arg1: Expr, arg2: impl Literal) -> Expr {
163        super::get_field().call(vec![arg1, arg2.lit()])
164    }
165
166    #[doc = "Returns the value of nested fields by traversing multiple field names"]
167    pub fn get_field_path(base: Expr, field_names: Vec<Expr>) -> Expr {
168        let mut args = vec![base];
169        args.extend(field_names);
170        super::get_field().call(args)
171    }
172
173    #[doc = "Returns the value of the field with the given name from the union when it's selected, or NULL otherwise"]
174    #[expect(clippy::needless_pass_by_value)]
175    pub fn union_extract(arg1: Expr, arg2: impl Literal) -> Expr {
176        super::union_extract().call(vec![arg1, arg2.lit()])
177    }
178}
179
180/// Returns all DataFusion functions defined in this package
181pub fn functions() -> Vec<Arc<ScalarUDF>> {
182    vec![
183        nullif(),
184        arrow_cast(),
185        arrow_field(),
186        arrow_try_cast(),
187        cast_to_type(),
188        try_cast_to_type(),
189        arrow_metadata(),
190        with_metadata(),
191        nvl(),
192        nvl2(),
193        overlay(),
194        arrow_typeof(),
195        named_struct(),
196        // Note: most users invoke `get_field` indirectly via field access
197        // syntax like `my_struct_col['field_name']`, which results in a call to
198        // `get_field(my_struct_col, "field_name")`.
199        //
200        // However, it is also exposed directly for use cases such as
201        // serializing / deserializing plans with the field access desugared to
202        // calls to [`get_field`]
203        get_field(),
204        coalesce(),
205        greatest(),
206        least(),
207        union_extract(),
208        union_tag(),
209        version(),
210        input_file_name(),
211        r#struct(),
212        file_row_index(),
213    ]
214}