@@ -31,19 +31,23 @@ use arrow::array::{
3131 cast:: AsArray ,
3232} ;
3333use arrow:: array:: {
34- Datum , GenericListArray , Int32Array , Int64Array , MutableArrayData , make_array,
34+ ArrowPrimitiveType , Datum , GenericListArray , Int32Array , Int64Array ,
35+ MutableArrayData , PrimitiveArray , make_array,
3536} ;
3637use arrow:: array:: { LargeListViewArray , ListViewArray } ;
3738use arrow:: buffer:: { OffsetBuffer , ScalarBuffer } ;
3839use arrow:: compute:: kernels:: cmp:: neq;
3940use arrow:: compute:: kernels:: length:: length;
4041use arrow:: compute:: { SortColumn , SortOptions , partition} ;
41- use arrow:: datatypes:: { DataType , Field , SchemaRef } ;
42+ use arrow:: datatypes:: {
43+ ArrowNativeType , DataType , Field , Int32Type , Int64Type , SchemaRef ,
44+ } ;
4245#[ cfg( feature = "sql" ) ]
4346use sqlparser:: { ast:: Ident , dialect:: GenericDialect , parser:: Parser } ;
4447use std:: borrow:: { Borrow , Cow } ;
4548use std:: cmp:: { Ordering , min} ;
4649use std:: collections:: HashSet ;
50+ use std:: iter:: repeat_n;
4751use std:: num:: NonZero ;
4852use std:: ops:: Range ;
4953use std:: sync:: { Arc , LazyLock } ;
@@ -1181,6 +1185,74 @@ fn truncate_list_nulls<O: OffsetSizeTrait>(
11811185 Ok ( list. clone ( ) )
11821186}
11831187
1188+ /// If `array` is a list or a map, returns a new array of the same length as it's inner values
1189+ /// where each value is the 1-based index of the sublist it's contained. Example:
1190+ ///
1191+ /// `[[1], [2, 3], [4, 5, 6]] => [1, 2, 2, 3, 3, 3]`
1192+ ///
1193+ /// Otherwise returns an error
1194+ pub fn list_values_row_number ( array : & dyn Array ) -> Result < ArrayRef > {
1195+ match array. data_type ( ) {
1196+ DataType :: List ( _) => Ok ( Arc :: new ( variable_size_list_values_row_number :: <
1197+ Int32Type ,
1198+ > ( array. as_list ( ) . offsets ( ) ) ) ) ,
1199+ DataType :: LargeList ( _) => Ok ( Arc :: new ( variable_size_list_values_row_number :: <
1200+ Int64Type ,
1201+ > ( array. as_list ( ) . offsets ( ) ) ) ) ,
1202+ DataType :: ListView ( _) => Ok ( Arc :: new ( variable_size_list_values_row_number :: <
1203+ Int32Type ,
1204+ > ( array. as_list_view ( ) . offsets ( ) ) ) ) ,
1205+ DataType :: LargeListView ( _) => {
1206+ Ok ( Arc :: new ( variable_size_list_values_row_number :: < Int64Type > (
1207+ array. as_list_view ( ) . offsets ( ) ,
1208+ ) ) )
1209+ }
1210+ DataType :: FixedSizeList ( _, _) => {
1211+ let fixed_size_list = array. as_fixed_size_list ( ) ;
1212+
1213+ Ok ( Arc :: new ( fsl_values_row_number (
1214+ fixed_size_list. value_length ( ) ,
1215+ fixed_size_list. len ( ) ,
1216+ ) ?) )
1217+ }
1218+ DataType :: Map ( _, _) => Ok ( Arc :: new ( variable_size_list_values_row_number :: <
1219+ Int32Type ,
1220+ > ( array. as_map ( ) . offsets ( ) ) ) ) ,
1221+ other => _exec_err ! ( "expected list, got {other}" ) ,
1222+ }
1223+ }
1224+
1225+ /// [0, 2, 2, 5, 6] -> [0, 0, 2, 2, 2, 3]
1226+ fn variable_size_list_values_row_number < T : ArrowPrimitiveType > (
1227+ offsets : & [ T :: Native ] ,
1228+ ) -> PrimitiveArray < T > {
1229+ let mut rows_number = Vec :: with_capacity (
1230+ offsets[ offsets. len ( ) - 1 ] . to_usize ( ) . unwrap ( ) - offsets[ 0 ] . to_usize ( ) . unwrap ( ) ,
1231+ ) ;
1232+
1233+ for ( i, w) in offsets. windows ( 2 ) . enumerate ( ) {
1234+ let len = w[ 1 ] . as_usize ( ) - w[ 0 ] . as_usize ( ) ;
1235+ rows_number. extend ( repeat_n ( T :: Native :: usize_as ( i) , len) ) ;
1236+ }
1237+
1238+ PrimitiveArray :: new ( rows_number. into ( ) , None )
1239+ }
1240+
1241+ /// (2, 3) -> [0, 0, 1, 1, 2, 2]
1242+ fn fsl_values_row_number ( list_size : i32 , array_len : usize ) -> Result < Int32Array > {
1243+ let list_size = list_size. to_usize ( ) . ok_or_else ( || {
1244+ _exec_datafusion_err ! ( "fsl_values_index: invalid list_size {list_size}" )
1245+ } ) ?;
1246+
1247+ let mut rows_number = Vec :: with_capacity ( list_size * array_len) ;
1248+
1249+ for i in 0 ..array_len {
1250+ rows_number. extend ( repeat_n ( i as i32 , list_size) ) ;
1251+ }
1252+
1253+ Ok ( PrimitiveArray :: new ( rows_number. into ( ) , None ) )
1254+ }
1255+
11841256#[ cfg( test) ]
11851257mod tests {
11861258 use std:: sync:: Arc ;
@@ -1617,4 +1689,85 @@ mod tests {
16171689 assert_eq ! ( res. values( ) , expected. values( ) ) ;
16181690 assert_eq ! ( res. offsets( ) , expected. offsets( ) ) ;
16191691 }
1692+
1693+ #[ test]
1694+ fn test_list_array_values_row_number ( ) {
1695+ assert_eq ! (
1696+ variable_size_list_values_row_number:: <Int32Type >(
1697+ & OffsetBuffer :: from_lengths( [ 1 , 3 , 0 , 2 , ] )
1698+ ) ,
1699+ Int32Array :: from( vec![ 0 , 1 , 1 , 1 , 3 , 3 ] )
1700+ ) ;
1701+
1702+ assert_eq ! (
1703+ variable_size_list_values_row_number:: <Int32Type >(
1704+ & OffsetBuffer :: from_lengths( [ ] )
1705+ ) ,
1706+ Int32Array :: new_null( 0 )
1707+ ) ;
1708+
1709+ assert_eq ! (
1710+ variable_size_list_values_row_number:: <Int32Type >(
1711+ & OffsetBuffer :: from_lengths( [ 0 ] )
1712+ ) ,
1713+ Int32Array :: new_null( 0 )
1714+ ) ;
1715+
1716+ assert_eq ! (
1717+ variable_size_list_values_row_number:: <Int32Type >(
1718+ & OffsetBuffer :: from_lengths( [ 0 , 0 ] )
1719+ ) ,
1720+ Int32Array :: new_null( 0 )
1721+ ) ;
1722+
1723+ assert_eq ! (
1724+ variable_size_list_values_row_number:: <Int32Type >(
1725+ & OffsetBuffer :: from_lengths( [ 1 ] )
1726+ ) ,
1727+ Int32Array :: from( vec![ 0 ] )
1728+ ) ;
1729+
1730+ assert_eq ! (
1731+ variable_size_list_values_row_number:: <Int32Type >(
1732+ & OffsetBuffer :: from_lengths( [ 2 ] )
1733+ ) ,
1734+ Int32Array :: from( vec![ 0 , 0 ] )
1735+ ) ;
1736+ }
1737+
1738+ #[ test]
1739+ fn test_fsl_values_row_number ( ) {
1740+ assert_eq ! (
1741+ fsl_values_row_number( 2 , 3 ) . unwrap( ) ,
1742+ Int32Array :: from( vec![ 0 , 0 , 1 , 1 , 2 , 2 ] )
1743+ ) ;
1744+
1745+ assert_eq ! (
1746+ fsl_values_row_number( 1 , 3 ) . unwrap( ) ,
1747+ Int32Array :: from( vec![ 0 , 1 , 2 ] )
1748+ ) ;
1749+
1750+ assert_eq ! (
1751+ fsl_values_row_number( 2 , 1 ) . unwrap( ) ,
1752+ Int32Array :: from( vec![ 0 , 0 ] )
1753+ ) ;
1754+
1755+ assert_eq ! (
1756+ fsl_values_row_number( 2 , 0 ) . unwrap( ) ,
1757+ Int32Array :: new_null( 0 ) ,
1758+ ) ;
1759+
1760+ assert_eq ! (
1761+ fsl_values_row_number( 0 , 2 ) . unwrap( ) ,
1762+ Int32Array :: new_null( 0 ) ,
1763+ ) ;
1764+
1765+ assert_eq ! (
1766+ fsl_values_row_number( 0 , 0 ) . unwrap( ) ,
1767+ Int32Array :: new_null( 0 ) ,
1768+ ) ;
1769+
1770+ fsl_values_row_number ( -1 , 2 ) . unwrap_err ( ) ;
1771+ fsl_values_row_number ( -1 , 0 ) . unwrap_err ( ) ;
1772+ }
16201773}
0 commit comments