@@ -24,9 +24,11 @@ use databend_common_expression::types::ALL_NUMERICS_TYPES;
2424use databend_common_expression:: vectorize_with_builder_1_arg;
2525use databend_common_expression:: vectorize_with_builder_2_arg;
2626use databend_common_expression:: with_number_mapped_type;
27+ use databend_common_expression:: Column ;
2728use databend_common_expression:: FixedLengthEncoding ;
2829use databend_common_expression:: FunctionDomain ;
2930use databend_common_expression:: FunctionRegistry ;
31+ use databend_common_expression:: ScalarRef ;
3032
3133pub fn register ( registry : & mut FunctionRegistry ) {
3234 registry. register_passthrough_nullable_1_arg :: < StringType , BinaryType , _ , _ > (
@@ -92,22 +94,45 @@ pub fn register(registry: &mut FunctionRegistry) {
9294 // The column values are conceptually divided into multiple partitions defined by the range_bounds.
9395 // For example, given the column values (0, 1, 3, 6, 8) and a partition configuration with 3 partitions,
9496 // the range_bounds might be [1, 6]. The function would then return partition IDs as (0, 0, 1, 1, 2).
95- registry. register_passthrough_nullable_2_arg :: < GenericType < 0 > , ArrayType < GenericType < 0 > > , NumberType < u64 > , _ , _ > (
97+ registry
98+ . register_2_arg_core :: < GenericType < 0 > , ArrayType < GenericType < 0 > > , NumberType < u64 > , _ , _ > (
99+ "range_partition_id" ,
100+ |_, _, _| FunctionDomain :: Full ,
101+ vectorize_with_builder_2_arg :: <
102+ GenericType < 0 > ,
103+ ArrayType < GenericType < 0 > > ,
104+ NumberType < u64 > ,
105+ > ( |val, arr, builder, _| {
106+ let id = calc_range_partition_id ( val, arr) ;
107+ builder. push ( id) ;
108+ } ) ,
109+ ) ;
110+
111+ registry. register_2_arg_core :: < NullableType < GenericType < 0 > > , NullableType < ArrayType < GenericType < 0 > > > , NumberType < u64 > , _ , _ > (
96112 "range_partition_id" ,
97113 |_, _, _| FunctionDomain :: Full ,
98- vectorize_with_builder_2_arg :: < GenericType < 0 > , ArrayType < GenericType < 0 > > , NumberType < u64 > > ( |val, arr, builder, _| {
99- let mut low = 0 ;
100- let mut high = arr. len ( ) ;
101- while low < high {
102- let mid = low + ( ( high - low) / 2 ) ;
103- let bound = unsafe { arr. index_unchecked ( mid) } ;
104- if val > bound {
105- low = mid + 1 ;
106- } else {
107- high = mid;
108- }
109- }
110- builder. push ( low as u64 ) ;
114+ vectorize_with_builder_2_arg :: < NullableType < GenericType < 0 > > , NullableType < ArrayType < GenericType < 0 > > > , NumberType < u64 > > ( |val, arr, builder, _| {
115+ let id = match ( val, arr) {
116+ ( Some ( val) , Some ( arr) ) => calc_range_partition_id ( val, arr) ,
117+ ( None , Some ( arr) ) => arr. len ( ) as u64 + 1 ,
118+ _ => 0 ,
119+ } ;
120+ builder. push ( id) ;
111121 } ) ,
112122 ) ;
113123}
124+
125+ fn calc_range_partition_id ( val : ScalarRef , arr : Column ) -> u64 {
126+ let mut low = 0 ;
127+ let mut high = arr. len ( ) ;
128+ while low < high {
129+ let mid = low + ( ( high - low) / 2 ) ;
130+ let bound = unsafe { arr. index_unchecked ( mid) } ;
131+ if val > bound {
132+ low = mid + 1 ;
133+ } else {
134+ high = mid;
135+ }
136+ }
137+ low as u64
138+ }
0 commit comments