@@ -122,7 +122,8 @@ pub enum TypeSignature {
122122 /// is `OneOf(vec![Any(0), VariadicAny])`.
123123 OneOf ( Vec < TypeSignature > ) ,
124124 /// Specifies Signatures for array functions
125- ArraySignature ( ArrayFunctionSignature ) ,
125+ /// Boolean value specifies whether null type coercion is allowed
126+ ArraySignature ( ArrayFunctionSignature , bool ) ,
126127}
127128
128129#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
@@ -144,13 +145,19 @@ pub enum ArrayFunctionSignature {
144145}
145146
146147impl ArrayFunctionSignature {
148+ /// Arguments to ArrayFunctionSignature
149+ /// `current_types` - The data types of the arguments
150+ /// `coercion` - Whether null type coercion is allowed
151+ /// Returns the valid types for the function signature
147152 pub fn get_type_signature (
148153 & self ,
149154 current_types : & [ DataType ] ,
155+ allow_null_coercion : bool ,
150156 ) -> Result < Vec < Vec < DataType > > > {
151157 fn array_append_or_prepend_valid_types (
152158 current_types : & [ DataType ] ,
153159 is_append : bool ,
160+ allow_null_coercion : bool ,
154161 ) -> Result < Vec < Vec < DataType > > > {
155162 if current_types. len ( ) != 2 {
156163 return Ok ( vec ! [ vec![ ] ] ) ;
@@ -163,7 +170,7 @@ impl ArrayFunctionSignature {
163170 } ;
164171
165172 // We follow Postgres on `array_append(Null, T)`, which is not valid.
166- if array_type. eq ( & DataType :: Null ) {
173+ if array_type. eq ( & DataType :: Null ) && !allow_null_coercion {
167174 return Ok ( vec ! [ vec![ ] ] ) ;
168175 }
169176
@@ -215,8 +222,13 @@ impl ArrayFunctionSignature {
215222 _ => Ok ( vec ! [ vec![ ] ] ) ,
216223 }
217224 }
218- fn array ( current_types : & [ DataType ] ) -> Result < Vec < Vec < DataType > > > {
219- if current_types. len ( ) != 1 {
225+ fn array (
226+ current_types : & [ DataType ] ,
227+ allow_null_coercion : bool ,
228+ ) -> Result < Vec < Vec < DataType > > > {
229+ if current_types. len ( ) != 1
230+ || ( current_types[ 0 ] . is_null ( ) && !allow_null_coercion)
231+ {
220232 return Ok ( vec ! [ vec![ ] ] ) ;
221233 }
222234
@@ -229,7 +241,7 @@ impl ArrayFunctionSignature {
229241 let array_type = coerced_fixed_size_list_to_list ( array_type) ;
230242 Ok ( vec ! [ vec![ array_type] ] )
231243 }
232- DataType :: Null => Ok ( vec ! [ vec![ array_type. to_owned ( ) ] ] ) ,
244+ DataType :: Null => Ok ( vec ! [ vec![ array_type. clone ( ) ] ] ) ,
233245 _ => Ok ( vec ! [ vec![ DataType :: List ( Arc :: new( Field :: new(
234246 "item" ,
235247 array_type. to_owned( ) ,
@@ -239,13 +251,21 @@ impl ArrayFunctionSignature {
239251 }
240252 match self {
241253 ArrayFunctionSignature :: ArrayAndElement => {
242- array_append_or_prepend_valid_types ( current_types, true )
254+ array_append_or_prepend_valid_types (
255+ current_types,
256+ true ,
257+ allow_null_coercion,
258+ )
243259 }
244260 ArrayFunctionSignature :: ElementAndArray => {
245- array_append_or_prepend_valid_types ( current_types, false )
261+ array_append_or_prepend_valid_types (
262+ current_types,
263+ false ,
264+ allow_null_coercion,
265+ )
246266 }
247267 ArrayFunctionSignature :: ArrayAndIndex => array_and_index ( current_types) ,
248- ArrayFunctionSignature :: Array => array ( current_types) ,
268+ ArrayFunctionSignature :: Array => array ( current_types, allow_null_coercion ) ,
249269 }
250270 }
251271}
@@ -297,7 +317,7 @@ impl TypeSignature {
297317 TypeSignature :: OneOf ( sigs) => {
298318 sigs. iter ( ) . flat_map ( |s| s. to_string_repr ( ) ) . collect ( )
299319 }
300- TypeSignature :: ArraySignature ( array_signature) => {
320+ TypeSignature :: ArraySignature ( array_signature, _ ) => {
301321 vec ! [ array_signature. to_string( ) ]
302322 }
303323 }
@@ -402,36 +422,42 @@ impl Signature {
402422 }
403423 }
404424 /// Specialized Signature for ArrayAppend and similar functions
405- pub fn array_and_element ( volatility : Volatility ) -> Self {
425+ pub fn array_and_element ( allow_null_coercion : bool , volatility : Volatility ) -> Self {
406426 Signature {
407427 type_signature : TypeSignature :: ArraySignature (
408428 ArrayFunctionSignature :: ArrayAndElement ,
429+ allow_null_coercion,
409430 ) ,
410431 volatility,
411432 }
412433 }
413434 /// Specialized Signature for ArrayPrepend and similar functions
414- pub fn element_and_array ( volatility : Volatility ) -> Self {
435+ pub fn element_and_array ( allow_null_coercion : bool , volatility : Volatility ) -> Self {
415436 Signature {
416437 type_signature : TypeSignature :: ArraySignature (
417438 ArrayFunctionSignature :: ElementAndArray ,
439+ allow_null_coercion,
418440 ) ,
419441 volatility,
420442 }
421443 }
422444 /// Specialized Signature for ArrayElement and similar functions
423- pub fn array_and_index ( volatility : Volatility ) -> Self {
445+ pub fn array_and_index ( allow_null_coercion : bool , volatility : Volatility ) -> Self {
424446 Signature {
425447 type_signature : TypeSignature :: ArraySignature (
426448 ArrayFunctionSignature :: ArrayAndIndex ,
449+ allow_null_coercion,
427450 ) ,
428451 volatility,
429452 }
430453 }
431454 /// Specialized Signature for ArrayEmpty and similar functions
432- pub fn array ( volatility : Volatility ) -> Self {
455+ pub fn array ( allow_null_coercion : bool , volatility : Volatility ) -> Self {
433456 Signature {
434- type_signature : TypeSignature :: ArraySignature ( ArrayFunctionSignature :: Array ) ,
457+ type_signature : TypeSignature :: ArraySignature (
458+ ArrayFunctionSignature :: Array ,
459+ allow_null_coercion,
460+ ) ,
435461 volatility,
436462 }
437463 }
0 commit comments