@@ -102,6 +102,8 @@ pub fn register(registry: &mut FunctionRegistry) {
102102 } ) ;
103103 }
104104
105+ register_bucket ( registry) ;
106+
105107 // Could be used in exchange
106108 registry
107109 . scalar_builder ( "siphash64" )
@@ -222,6 +224,99 @@ pub fn register(registry: &mut FunctionRegistry) {
222224 ) ;
223225}
224226
227+ fn register_bucket ( registry : & mut FunctionRegistry ) {
228+ registry
229+ . register_passthrough_nullable_2_arg :: < NumberType < u64 > , StringType , NumberType < i32 > , _ , _ > (
230+ "bucket" ,
231+ |_, _, _| FunctionDomain :: MayThrow ,
232+ vectorize_with_builder_2_arg :: < NumberType < u64 > , StringType , NumberType < i32 > > (
233+ |buckets, value, output, ctx| {
234+ output. push ( bucket ( buckets, value. as_bytes ( ) , output. len ( ) , ctx) ) ;
235+ } ,
236+ ) ,
237+ ) ;
238+ registry
239+ . register_passthrough_nullable_2_arg :: < NumberType < u64 > , DateType , NumberType < i32 > , _ , _ > (
240+ "bucket" ,
241+ |_, _, _| FunctionDomain :: MayThrow ,
242+ vectorize_with_builder_2_arg :: < NumberType < u64 > , DateType , NumberType < i32 > > (
243+ |buckets, value, output, ctx| {
244+ output. push ( bucket ( buckets, & value. to_le_bytes ( ) , output. len ( ) , ctx) ) ;
245+ } ,
246+ ) ,
247+ ) ;
248+ registry. register_passthrough_nullable_2_arg :: <
249+ NumberType < u64 > ,
250+ TimestampType ,
251+ NumberType < i32 > ,
252+ _ ,
253+ _ ,
254+ > (
255+ "bucket" ,
256+ |_, _, _| FunctionDomain :: MayThrow ,
257+ vectorize_with_builder_2_arg :: < NumberType < u64 > , TimestampType , NumberType < i32 > > (
258+ |buckets, value, output, ctx| {
259+ output. push ( bucket (
260+ buckets,
261+ & value. to_le_bytes ( ) ,
262+ output. len ( ) ,
263+ ctx,
264+ ) ) ;
265+ } ,
266+ ) ,
267+ ) ;
268+ for num_type in ALL_INTEGER_TYPES {
269+ with_integer_mapped_type ! ( |NUM_TYPE | match num_type {
270+ NumberDataType :: NUM_TYPE => {
271+ registry. register_passthrough_nullable_2_arg:: <
272+ NumberType <u64 >,
273+ NumberType <NUM_TYPE >,
274+ NumberType <i32 >,
275+ _,
276+ _,
277+ >(
278+ "bucket" ,
279+ |_, _, _| FunctionDomain :: MayThrow ,
280+ vectorize_with_builder_2_arg:: <
281+ NumberType <u64 >,
282+ NumberType <NUM_TYPE >,
283+ NumberType <i32 >,
284+ >( |buckets, value, output, ctx| {
285+ let value: i64 = value. as_( ) ;
286+ output. push( bucket(
287+ buckets,
288+ & value. to_le_bytes( ) ,
289+ output. len( ) ,
290+ ctx,
291+ ) ) ;
292+ } ) ,
293+ ) ;
294+ }
295+ _ => unreachable!( ) ,
296+ } ) ;
297+ }
298+ }
299+
300+ fn bucket (
301+ buckets : u64 ,
302+ bytes : & [ u8 ] ,
303+ row : usize ,
304+ ctx : & mut databend_common_expression:: EvalContext ,
305+ ) -> i32 {
306+ let Ok ( buckets) = i32:: try_from ( buckets) else {
307+ ctx. set_error ( row, "bucket count must be between 1 and 2147483647" ) ;
308+ return 0 ;
309+ } ;
310+ if buckets == 0 {
311+ ctx. set_error ( row, "bucket count must be greater than zero" ) ;
312+ return 0 ;
313+ }
314+
315+ let mut bytes = bytes;
316+ let hash = murmur3:: murmur3_32 ( & mut bytes, 0 ) . unwrap ( ) as i32 ;
317+ ( hash & i32:: MAX ) % buckets
318+ }
319+
225320fn register_simple_domain_type_hash < T : ArgType > ( registry : & mut FunctionRegistry )
226321where for < ' a > T :: ScalarRef < ' a > : DFHash {
227322 registry
0 commit comments