@@ -26,6 +26,7 @@ use datafusion_common::cast::as_list_array;
2626use datafusion_common:: ScalarValue ;
2727use datafusion_common:: { DataFusionError , Result } ;
2828use datafusion_expr:: ColumnarValue ;
29+ use itertools:: Itertools ;
2930use std:: sync:: Arc ;
3031
3132macro_rules! downcast_vec {
@@ -1070,6 +1071,70 @@ pub fn array_ndims(args: &[ColumnarValue]) -> Result<ColumnarValue> {
10701071 ] ) ) ) )
10711072}
10721073
1074+ macro_rules! contains {
1075+ ( $FIRST_ARRAY: expr, $SECOND_ARRAY: expr, $ARRAY_TYPE: ident) => { {
1076+ let first_array = downcast_arg!( $FIRST_ARRAY, $ARRAY_TYPE) ;
1077+ let second_array = downcast_arg!( $SECOND_ARRAY, $ARRAY_TYPE) ;
1078+ let mut res = true ;
1079+ for x in second_array. values( ) . iter( ) . dedup( ) {
1080+ if !first_array. values( ) . contains( x) {
1081+ res = false ;
1082+ }
1083+ }
1084+
1085+ res
1086+ } } ;
1087+ }
1088+
1089+ /// Array_contains SQL function
1090+ pub fn array_contains ( args : & [ ArrayRef ] ) -> Result < ArrayRef > {
1091+ fn concat_inner_lists ( arg : ArrayRef ) -> Result < ArrayRef > {
1092+ match arg. data_type ( ) {
1093+ DataType :: List ( field) => match field. data_type ( ) {
1094+ DataType :: List ( ..) => {
1095+ concat_inner_lists ( array_concat ( & [ as_list_array ( & arg) ?
1096+ . values ( )
1097+ . clone ( ) ] ) ?)
1098+ }
1099+ _ => Ok ( as_list_array ( & arg) ?. values ( ) . clone ( ) ) ,
1100+ } ,
1101+ data_type => Err ( DataFusionError :: NotImplemented ( format ! (
1102+ "Array is not type '{data_type:?}'."
1103+ ) ) ) ,
1104+ }
1105+ }
1106+
1107+ let concat_first_array = concat_inner_lists ( args[ 0 ] . clone ( ) ) ?. clone ( ) ;
1108+ let concat_second_array = concat_inner_lists ( args[ 1 ] . clone ( ) ) ?. clone ( ) ;
1109+
1110+ let res = match ( concat_first_array. data_type ( ) , concat_second_array. data_type ( ) ) {
1111+ ( DataType :: Utf8 , DataType :: Utf8 ) => contains ! ( concat_first_array, concat_second_array, StringArray ) ,
1112+ ( DataType :: LargeUtf8 , DataType :: LargeUtf8 ) => contains ! ( concat_first_array, concat_second_array, LargeStringArray ) ,
1113+ ( DataType :: Boolean , DataType :: Boolean ) => {
1114+ let first_array = downcast_arg ! ( concat_first_array, BooleanArray ) ;
1115+ let second_array = downcast_arg ! ( concat_second_array, BooleanArray ) ;
1116+ compute:: bool_or ( first_array) == compute:: bool_or ( second_array)
1117+ }
1118+ ( DataType :: Float32 , DataType :: Float32 ) => contains ! ( concat_first_array, concat_second_array, Float32Array ) ,
1119+ ( DataType :: Float64 , DataType :: Float64 ) => contains ! ( concat_first_array, concat_second_array, Float64Array ) ,
1120+ ( DataType :: Int8 , DataType :: Int8 ) => contains ! ( concat_first_array, concat_second_array, Int8Array ) ,
1121+ ( DataType :: Int16 , DataType :: Int16 ) => contains ! ( concat_first_array, concat_second_array, Int16Array ) ,
1122+ ( DataType :: Int32 , DataType :: Int32 ) => contains ! ( concat_first_array, concat_second_array, Int32Array ) ,
1123+ ( DataType :: Int64 , DataType :: Int64 ) => contains ! ( concat_first_array, concat_second_array, Int64Array ) ,
1124+ ( DataType :: UInt8 , DataType :: UInt8 ) => contains ! ( concat_first_array, concat_second_array, UInt8Array ) ,
1125+ ( DataType :: UInt16 , DataType :: UInt16 ) => contains ! ( concat_first_array, concat_second_array, UInt16Array ) ,
1126+ ( DataType :: UInt32 , DataType :: UInt32 ) => contains ! ( concat_first_array, concat_second_array, UInt32Array ) ,
1127+ ( DataType :: UInt64 , DataType :: UInt64 ) => contains ! ( concat_first_array, concat_second_array, UInt64Array ) ,
1128+ ( first_array_data_type, second_array_data_type) => {
1129+ return Err ( DataFusionError :: NotImplemented ( format ! (
1130+ "Array_contains is not implemented for types '{first_array_data_type:?}' and '{second_array_data_type:?}'."
1131+ ) ) )
1132+ }
1133+ } ;
1134+
1135+ Ok ( Arc :: new ( BooleanArray :: from ( vec ! [ res] ) ) )
1136+ }
1137+
10731138#[ cfg( test) ]
10741139mod tests {
10751140 use super :: * ;
@@ -1588,7 +1653,7 @@ mod tests {
15881653
15891654 #[ test]
15901655 fn test_array_ndims ( ) {
1591- // array_ndims([1, 2]) = 1
1656+ // array_ndims([1, 2, 3, 4 ]) = 1
15921657 let list_array = return_array ( ) ;
15931658
15941659 let array = array_ndims ( & [ list_array] )
@@ -1602,7 +1667,7 @@ mod tests {
16021667
16031668 #[ test]
16041669 fn test_nested_array_ndims ( ) {
1605- // array_ndims([[1, 2], [ 3, 4]]) = 2
1670+ // array_ndims([[1, 2, 3, 4], [5, 6, 7, 8 ]]) = 2
16061671 let list_array = return_nested_array ( ) ;
16071672
16081673 let array = array_ndims ( & [ list_array] )
@@ -1614,6 +1679,63 @@ mod tests {
16141679 assert_eq ! ( result, & UInt8Array :: from( vec![ 2 ] ) ) ;
16151680 }
16161681
1682+ #[ test]
1683+ fn test_array_contains ( ) {
1684+ // array_contains([1, 2, 3, 4], array_append([1, 2, 3, 4], 3)) = t
1685+ let first_array = return_array ( ) . into_array ( 1 ) ;
1686+ let second_array = array_append ( & [
1687+ first_array. clone ( ) ,
1688+ Arc :: new ( Int64Array :: from ( vec ! [ Some ( 3 ) ] ) ) ,
1689+ ] )
1690+ . expect ( "failed to initialize function array_contains" ) ;
1691+
1692+ let arr = array_contains ( & [ first_array. clone ( ) , second_array] )
1693+ . expect ( "failed to initialize function array_contains" ) ;
1694+ let result = as_boolean_array ( & arr) ;
1695+
1696+ assert_eq ! ( result, & BooleanArray :: from( vec![ true ] ) ) ;
1697+
1698+ // array_contains([1, 2, 3, 4], array_append([1, 2, 3, 4], 5)) = f
1699+ let second_array = array_append ( & [
1700+ first_array. clone ( ) ,
1701+ Arc :: new ( Int64Array :: from ( vec ! [ Some ( 5 ) ] ) ) ,
1702+ ] )
1703+ . expect ( "failed to initialize function array_contains" ) ;
1704+
1705+ let arr = array_contains ( & [ first_array. clone ( ) , second_array] )
1706+ . expect ( "failed to initialize function array_contains" ) ;
1707+ let result = as_boolean_array ( & arr) ;
1708+
1709+ assert_eq ! ( result, & BooleanArray :: from( vec![ false ] ) ) ;
1710+ }
1711+
1712+ #[ test]
1713+ fn test_nested_array_contains ( ) {
1714+ // array_contains([[1, 2, 3, 4], [5, 6, 7, 8]], array_append([1, 2, 3, 4], 3)) = t
1715+ let first_array = return_nested_array ( ) . into_array ( 1 ) ;
1716+ let array = return_array ( ) . into_array ( 1 ) ;
1717+ let second_array =
1718+ array_append ( & [ array. clone ( ) , Arc :: new ( Int64Array :: from ( vec ! [ Some ( 3 ) ] ) ) ] )
1719+ . expect ( "failed to initialize function array_contains" ) ;
1720+
1721+ let arr = array_contains ( & [ first_array. clone ( ) , second_array] )
1722+ . expect ( "failed to initialize function array_contains" ) ;
1723+ let result = as_boolean_array ( & arr) ;
1724+
1725+ assert_eq ! ( result, & BooleanArray :: from( vec![ true ] ) ) ;
1726+
1727+ // array_contains([[1, 2, 3, 4], [5, 6, 7, 8]], array_append([1, 2, 3, 4], 9)) = f
1728+ let second_array =
1729+ array_append ( & [ array. clone ( ) , Arc :: new ( Int64Array :: from ( vec ! [ Some ( 9 ) ] ) ) ] )
1730+ . expect ( "failed to initialize function array_contains" ) ;
1731+
1732+ let arr = array_contains ( & [ first_array. clone ( ) , second_array] )
1733+ . expect ( "failed to initialize function array_contains" ) ;
1734+ let result = as_boolean_array ( & arr) ;
1735+
1736+ assert_eq ! ( result, & BooleanArray :: from( vec![ false ] ) ) ;
1737+ }
1738+
16171739 fn return_array ( ) -> ColumnarValue {
16181740 let args = [
16191741 ColumnarValue :: Scalar ( ScalarValue :: Int64 ( Some ( 1 ) ) ) ,
0 commit comments