@@ -34,14 +34,12 @@ use crate::execution_props::ExecutionProps;
34
34
use crate :: sort_properties:: SortProperties ;
35
35
use crate :: {
36
36
array_expressions, conditional_expressions, datetime_expressions,
37
- expressions:: { cast_column, nullif_func} ,
38
- math_expressions, string_expressions, struct_expressions, PhysicalExpr ,
39
- ScalarFunctionExpr ,
37
+ expressions:: nullif_func, math_expressions, string_expressions, struct_expressions,
38
+ PhysicalExpr , ScalarFunctionExpr ,
40
39
} ;
41
40
use arrow:: {
42
41
array:: ArrayRef ,
43
42
compute:: kernels:: length:: { bit_length, length} ,
44
- datatypes:: TimeUnit ,
45
43
datatypes:: { DataType , Int32Type , Int64Type , Schema } ,
46
44
} ;
47
45
use datafusion_common:: { internal_err, DataFusionError , Result , ScalarValue } ;
@@ -71,143 +69,8 @@ pub fn create_physical_expr(
71
69
72
70
let data_type = fun. return_type ( & input_expr_types) ?;
73
71
74
- let fun_expr: ScalarFunctionImplementation = match fun {
75
- // These functions need args and input schema to pick an implementation
76
- // Unlike the string functions, which actually figure out the function to use with each array,
77
- // here we return either a cast fn or string timestamp translation based on the expression data type
78
- // so we don't have to pay a per-array/batch cost.
79
- BuiltinScalarFunction :: ToTimestamp => {
80
- Arc :: new ( match input_phy_exprs[ 0 ] . data_type ( input_schema) {
81
- Ok ( DataType :: Int64 ) => |col_values : & [ ColumnarValue ] | {
82
- cast_column (
83
- & col_values[ 0 ] ,
84
- & DataType :: Timestamp ( TimeUnit :: Second , None ) ,
85
- None ,
86
- )
87
- } ,
88
- Ok ( DataType :: Timestamp ( _, None ) ) => |col_values : & [ ColumnarValue ] | {
89
- cast_column (
90
- & col_values[ 0 ] ,
91
- & DataType :: Timestamp ( TimeUnit :: Nanosecond , None ) ,
92
- None ,
93
- )
94
- } ,
95
- Ok ( DataType :: Utf8 ) => datetime_expressions:: to_timestamp,
96
- other => {
97
- return internal_err ! (
98
- "Unsupported data type {other:?} for function to_timestamp"
99
- ) ;
100
- }
101
- } )
102
- }
103
- BuiltinScalarFunction :: ToTimestampMillis => {
104
- Arc :: new ( match input_phy_exprs[ 0 ] . data_type ( input_schema) {
105
- Ok ( DataType :: Int64 ) | Ok ( DataType :: Timestamp ( _, None ) ) => {
106
- |col_values : & [ ColumnarValue ] | {
107
- cast_column (
108
- & col_values[ 0 ] ,
109
- & DataType :: Timestamp ( TimeUnit :: Millisecond , None ) ,
110
- None ,
111
- )
112
- }
113
- }
114
- Ok ( DataType :: Utf8 ) => datetime_expressions:: to_timestamp_millis,
115
- other => {
116
- return internal_err ! (
117
- "Unsupported data type {other:?} for function to_timestamp_millis"
118
- ) ;
119
- }
120
- } )
121
- }
122
- BuiltinScalarFunction :: ToTimestampMicros => {
123
- Arc :: new ( match input_phy_exprs[ 0 ] . data_type ( input_schema) {
124
- Ok ( DataType :: Int64 ) | Ok ( DataType :: Timestamp ( _, None ) ) => {
125
- |col_values : & [ ColumnarValue ] | {
126
- cast_column (
127
- & col_values[ 0 ] ,
128
- & DataType :: Timestamp ( TimeUnit :: Microsecond , None ) ,
129
- None ,
130
- )
131
- }
132
- }
133
- Ok ( DataType :: Utf8 ) => datetime_expressions:: to_timestamp_micros,
134
- other => {
135
- return internal_err ! (
136
- "Unsupported data type {other:?} for function to_timestamp_micros"
137
- ) ;
138
- }
139
- } )
140
- }
141
- BuiltinScalarFunction :: ToTimestampNanos => {
142
- Arc :: new ( match input_phy_exprs[ 0 ] . data_type ( input_schema) {
143
- Ok ( DataType :: Int64 ) | Ok ( DataType :: Timestamp ( _, None ) ) => {
144
- |col_values : & [ ColumnarValue ] | {
145
- cast_column (
146
- & col_values[ 0 ] ,
147
- & DataType :: Timestamp ( TimeUnit :: Nanosecond , None ) ,
148
- None ,
149
- )
150
- }
151
- }
152
- Ok ( DataType :: Utf8 ) => datetime_expressions:: to_timestamp_nanos,
153
- other => {
154
- return internal_err ! (
155
- "Unsupported data type {other:?} for function to_timestamp_nanos"
156
- ) ;
157
- }
158
- } )
159
- }
160
- BuiltinScalarFunction :: ToTimestampSeconds => Arc :: new ( {
161
- match input_phy_exprs[ 0 ] . data_type ( input_schema) {
162
- Ok ( DataType :: Int64 ) | Ok ( DataType :: Timestamp ( _, None ) ) => {
163
- |col_values : & [ ColumnarValue ] | {
164
- cast_column (
165
- & col_values[ 0 ] ,
166
- & DataType :: Timestamp ( TimeUnit :: Second , None ) ,
167
- None ,
168
- )
169
- }
170
- }
171
- Ok ( DataType :: Utf8 ) => datetime_expressions:: to_timestamp_seconds,
172
- other => {
173
- return internal_err ! (
174
- "Unsupported data type {other:?} for function to_timestamp_seconds"
175
- ) ;
176
- }
177
- }
178
- } ) ,
179
- BuiltinScalarFunction :: FromUnixtime => Arc :: new ( {
180
- match input_phy_exprs[ 0 ] . data_type ( input_schema) {
181
- Ok ( DataType :: Int64 ) => |col_values : & [ ColumnarValue ] | {
182
- cast_column (
183
- & col_values[ 0 ] ,
184
- & DataType :: Timestamp ( TimeUnit :: Second , None ) ,
185
- None ,
186
- )
187
- } ,
188
- other => {
189
- return internal_err ! (
190
- "Unsupported data type {other:?} for function from_unixtime"
191
- ) ;
192
- }
193
- }
194
- } ) ,
195
- BuiltinScalarFunction :: ArrowTypeof => {
196
- let input_data_type = input_phy_exprs[ 0 ] . data_type ( input_schema) ?;
197
- Arc :: new ( move |_| {
198
- Ok ( ColumnarValue :: Scalar ( ScalarValue :: Utf8 ( Some ( format ! (
199
- "{input_data_type}"
200
- ) ) ) ) )
201
- } )
202
- }
203
- BuiltinScalarFunction :: Abs => {
204
- let input_data_type = input_phy_exprs[ 0 ] . data_type ( input_schema) ?;
205
- let abs_fun = math_expressions:: create_abs_function ( & input_data_type) ?;
206
- Arc :: new ( move |args| make_scalar_function ( abs_fun) ( args) )
207
- }
208
- // These don't need args and input schema
209
- _ => create_physical_fun ( fun, execution_props) ?,
210
- } ;
72
+ let fun_expr: ScalarFunctionImplementation =
73
+ create_physical_fun ( fun, execution_props) ?;
211
74
212
75
let monotonicity = fun. monotonicity ( ) ;
213
76
@@ -397,6 +260,9 @@ pub fn create_physical_fun(
397
260
) -> Result < ScalarFunctionImplementation > {
398
261
Ok ( match fun {
399
262
// math functions
263
+ BuiltinScalarFunction :: Abs => {
264
+ Arc :: new ( |args| make_scalar_function ( math_expressions:: abs_invoke) ( args) )
265
+ }
400
266
BuiltinScalarFunction :: Acos => Arc :: new ( math_expressions:: acos) ,
401
267
BuiltinScalarFunction :: Asin => Arc :: new ( math_expressions:: asin) ,
402
268
BuiltinScalarFunction :: Atan => Arc :: new ( math_expressions:: atan) ,
@@ -625,6 +491,24 @@ pub fn create_physical_fun(
625
491
execution_props. query_execution_start_time ,
626
492
) )
627
493
}
494
+ BuiltinScalarFunction :: ToTimestamp => {
495
+ Arc :: new ( datetime_expressions:: to_timestamp_invoke)
496
+ }
497
+ BuiltinScalarFunction :: ToTimestampMillis => {
498
+ Arc :: new ( datetime_expressions:: to_timestamp_millis_invoke)
499
+ }
500
+ BuiltinScalarFunction :: ToTimestampMicros => {
501
+ Arc :: new ( datetime_expressions:: to_timestamp_micros_invoke)
502
+ }
503
+ BuiltinScalarFunction :: ToTimestampNanos => {
504
+ Arc :: new ( datetime_expressions:: to_timestamp_nanos_invoke)
505
+ }
506
+ BuiltinScalarFunction :: ToTimestampSeconds => {
507
+ Arc :: new ( datetime_expressions:: to_timestamp_seconds_invoke)
508
+ }
509
+ BuiltinScalarFunction :: FromUnixtime => {
510
+ Arc :: new ( datetime_expressions:: from_unixtime_invoke)
511
+ }
628
512
BuiltinScalarFunction :: InitCap => Arc :: new ( |args| match args[ 0 ] . data_type ( ) {
629
513
DataType :: Utf8 => {
630
514
make_scalar_function ( string_expressions:: initcap :: < i32 > ) ( args)
@@ -927,11 +811,19 @@ pub fn create_physical_fun(
927
811
} ) ,
928
812
BuiltinScalarFunction :: Upper => Arc :: new ( string_expressions:: upper) ,
929
813
BuiltinScalarFunction :: Uuid => Arc :: new ( string_expressions:: uuid) ,
930
- _ => {
931
- return internal_err ! (
932
- "create_physical_fun: Unsupported scalar function {fun:?}"
933
- ) ;
934
- }
814
+ BuiltinScalarFunction :: ArrowTypeof => Arc :: new ( move |args| {
815
+ if args. len ( ) != 1 {
816
+ return internal_err ! (
817
+ "arrow_typeof function requires 1 arguments, got {}" ,
818
+ args. len( )
819
+ ) ;
820
+ }
821
+
822
+ let input_data_type = args[ 0 ] . data_type ( ) ;
823
+ Ok ( ColumnarValue :: Scalar ( ScalarValue :: Utf8 ( Some ( format ! (
824
+ "{input_data_type}"
825
+ ) ) ) ) )
826
+ } ) ,
935
827
} )
936
828
}
937
829
0 commit comments