@@ -237,7 +237,7 @@ impl<'a> BinaryTypeCoercer<'a> {
237237 } )
238238 }
239239 StringConcat => {
240- string_concat_coercion ( lhs, rhs) . map ( Signature :: uniform ) . ok_or_else ( || {
240+ string_concat_coercion ( lhs, rhs) . ok_or_else ( || {
241241 plan_datafusion_err ! (
242242 "Cannot infer common string type for string concat operation {} {} {}" , self . lhs, self . op, self . rhs
243243 )
@@ -1635,50 +1635,63 @@ fn ree_coercion(
16351635/// 1. At least one side of lhs and rhs should be string type (Utf8 / LargeUtf8)
16361636/// 2. Data type of the other side should be able to cast to string type
16371637/// 3. Binary and string types cannot be mixed
1638- fn string_concat_coercion ( lhs_type : & DataType , rhs_type : & DataType ) -> Option < DataType > {
1638+ fn string_concat_coercion ( lhs_type : & DataType , rhs_type : & DataType ) -> Option < Signature > {
16391639 use arrow:: datatypes:: DataType :: * ;
1640- string_coercion ( lhs_type, rhs_type) . or_else ( || match ( lhs_type, rhs_type) {
1641- // Allow pure binary + binary
1642- (
1643- Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1644- Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1645- ) => {
1646- // Coerce fixed-sized binary to variable-sized `Binary` to make uniform signature
1647- // with the `Binary` result
1648- let lhs_type = match lhs_type {
1649- FixedSizeBinary ( _) => & Binary ,
1650- val => val,
1651- } ;
1652- let rhs_type = match rhs_type {
1653- FixedSizeBinary ( _) => & Binary ,
1654- val => val,
1655- } ;
1656- binary_coercion ( lhs_type, rhs_type)
1657- }
1658- // Deny other mixed binary + string combinations
1659- (
1660- Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1661- Utf8 | LargeUtf8 | Utf8View ,
1662- ) => None ,
1663- (
1664- Utf8 | LargeUtf8 | Utf8View ,
1665- Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1666- ) => None ,
1667- // Predicate-based coercion rules are following
1668- ( Utf8View , from_type) | ( from_type, Utf8View ) => {
1669- string_concat_internal_coercion ( from_type, & Utf8View )
1670- }
1671- ( Utf8 , from_type) | ( from_type, Utf8 ) => {
1672- string_concat_internal_coercion ( from_type, & Utf8 )
1673- }
1674- ( LargeUtf8 , from_type) | ( from_type, LargeUtf8 ) => {
1675- string_concat_internal_coercion ( from_type, & LargeUtf8 )
1676- }
1677- ( Dictionary ( _, lhs_value_type) , Dictionary ( _, rhs_value_type) ) => {
1678- string_coercion ( lhs_value_type, rhs_value_type) . or ( None )
1679- }
1680- _ => None ,
1681- } )
1640+
1641+ string_coercion ( lhs_type, rhs_type)
1642+ . map ( Signature :: uniform)
1643+ . or_else ( || match ( lhs_type, rhs_type) {
1644+ // Allow concatenation of mixed fixed size binary
1645+ ( FixedSizeBinary ( l) , FixedSizeBinary ( r) ) => Some ( Signature {
1646+ lhs : lhs_type. clone ( ) ,
1647+ rhs : rhs_type. clone ( ) ,
1648+ ret : FixedSizeBinary ( l + r) ,
1649+ } ) ,
1650+ // Allow pure binary + binary
1651+ (
1652+ Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1653+ Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1654+ ) => {
1655+ // Coerce fixed-sized binary to variable-sized `Binary` to make uniform signature
1656+ // with the `Binary` result
1657+ let lhs_type = match lhs_type {
1658+ FixedSizeBinary ( _) => & Binary ,
1659+ val => val,
1660+ } ;
1661+ let rhs_type = match rhs_type {
1662+ FixedSizeBinary ( _) => & Binary ,
1663+ val => val,
1664+ } ;
1665+ binary_coercion ( lhs_type, rhs_type) . map ( Signature :: uniform)
1666+ }
1667+ // Deny other mixed binary + string combinations
1668+ (
1669+ Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1670+ Utf8 | LargeUtf8 | Utf8View ,
1671+ ) => None ,
1672+ (
1673+ Utf8 | LargeUtf8 | Utf8View ,
1674+ Binary | LargeBinary | BinaryView | FixedSizeBinary ( _) ,
1675+ ) => None ,
1676+ // Predicate-based coercion rules are following
1677+ ( Utf8View , from_type) | ( from_type, Utf8View ) => {
1678+ string_concat_internal_coercion ( from_type, & Utf8View )
1679+ . map ( Signature :: uniform)
1680+ }
1681+ ( Utf8 , from_type) | ( from_type, Utf8 ) => {
1682+ string_concat_internal_coercion ( from_type, & Utf8 ) . map ( Signature :: uniform)
1683+ }
1684+ ( LargeUtf8 , from_type) | ( from_type, LargeUtf8 ) => {
1685+ string_concat_internal_coercion ( from_type, & LargeUtf8 )
1686+ . map ( Signature :: uniform)
1687+ }
1688+ ( Dictionary ( _, lhs_value_type) , Dictionary ( _, rhs_value_type) ) => {
1689+ string_coercion ( lhs_value_type, rhs_value_type)
1690+ . or ( None )
1691+ . map ( Signature :: uniform)
1692+ }
1693+ _ => None ,
1694+ } )
16821695}
16831696
16841697fn array_coercion ( lhs_type : & DataType , rhs_type : & DataType ) -> Option < DataType > {
0 commit comments