feldera_sqllib/
lib.rs

1#![allow(non_snake_case)]
2
3#[doc(hidden)]
4pub mod aggregates;
5pub use aggregates::*;
6pub mod array;
7pub use array::*;
8#[doc(hidden)]
9pub mod binary;
10pub use binary::*;
11#[doc(hidden)]
12pub mod casts;
13pub use casts::*;
14#[doc(hidden)]
15pub mod dec;
16pub use dec::*;
17#[doc(hidden)]
18pub mod error;
19pub use error::*;
20#[doc(hidden)]
21pub mod float;
22pub use float::*;
23#[doc(hidden)]
24pub mod geopoint;
25pub use geopoint::*;
26#[doc(hidden)]
27pub mod interval;
28pub use interval::*;
29#[doc(hidden)]
30pub mod map;
31pub use map::*;
32#[doc(hidden)]
33pub mod operators;
34pub use operators::*;
35#[doc(hidden)]
36pub mod source;
37#[doc(hidden)]
38pub mod string;
39pub use string::*;
40#[doc(hidden)]
41pub mod timestamp;
42pub use timestamp::*;
43#[doc(hidden)]
44pub mod uuid;
45pub use uuid::*;
46#[doc(hidden)]
47pub mod variant;
48pub use variant::*;
49
50#[doc(hidden)]
51pub use num_traits::Float;
52pub use regex::Regex;
53#[doc(hidden)]
54pub use source::{SourcePosition, SourcePositionRange};
55
56mod string_interner;
57pub use string_interner::{build_string_interner, intern_string, unintern_string};
58
59use std::sync::LazyLock;
60
61// Re-export these types, so they can be used in UDFs without having to import the dbsp crate directly.
62// Perhaps they should be defined in sqllib in the first place?
63pub use dbsp::algebra::{F32, F64};
64use dbsp::{
65    algebra::{
66        AddByRef, HasOne, HasZero, NegByRef, OrdIndexedZSetFactories, OrdZSetFactories, Semigroup,
67        SemigroupValue, ZRingValue,
68    },
69    circuit::metrics::TOTAL_LATE_RECORDS,
70    dynamic::{DowncastTrait, DynData, Erase},
71    trace::{
72        ord::{OrdIndexedWSetBuilder, OrdWSetBuilder},
73        BatchReader, BatchReaderFactories, Builder, Cursor,
74    },
75    typed_batch::TypedBatch,
76    utils::*,
77    DBData, OrdIndexedZSet, OrdZSet, OutputHandle, SetHandle, ZSetHandle, ZWeight,
78};
79use metrics::{counter, Counter};
80use num::PrimInt;
81use num_traits::Pow;
82use std::fmt::Debug;
83use std::marker::PhantomData;
84use std::ops::{Add, Deref, Neg};
85
86/// Convert a value of a SQL data type to an integer
87/// that preserves ordering.  Used for partitioned_rolling_aggregates
88#[doc(hidden)]
89pub trait ToInteger<T>
90where
91    T: PrimInt,
92{
93    #[doc(hidden)]
94    fn to_integer(&self) -> T;
95}
96
97/// Trait that provides the inverse functionality of the ToInteger trait.
98/// Used for partitioned_rolling_aggregates
99#[doc(hidden)]
100pub trait FromInteger<T>
101where
102    T: PrimInt,
103{
104    #[doc(hidden)]
105    fn from_integer(value: &T) -> Self;
106}
107
108#[doc(hidden)]
109impl<T> ToInteger<T> for T
110where
111    T: PrimInt,
112{
113    #[doc(hidden)]
114    fn to_integer(&self) -> T {
115        *self
116    }
117}
118
119#[doc(hidden)]
120impl<T> FromInteger<T> for T
121where
122    T: PrimInt,
123{
124    #[doc(hidden)]
125    fn from_integer(value: &T) -> Self {
126        *value
127    }
128}
129
130#[doc(hidden)]
131pub type Weight = ZWeight;
132#[doc(hidden)]
133pub type WSet<D> = OrdZSet<D>;
134#[doc(hidden)]
135pub type IndexedWSet<K, D> = OrdIndexedZSet<K, D>;
136
137// Macro to create variants of a function with 1 argument
138// If there exists a function is f_(x: T) -> S, this creates a function
139// fN(x: Option<T>) -> Option<S>, defined as
140// fN(x) { let x = x?; Some(f_(x)) }.
141macro_rules! some_function1 {
142    ($func_name:ident, $arg_type:ty, $ret_type:ty) => {
143        ::paste::paste! {
144            #[doc(hidden)]
145            pub fn [<$func_name N>]( arg: Option<$arg_type> ) -> Option<$ret_type> {
146                let arg = arg?;
147                Some([<$func_name _>](arg))
148            }
149        }
150    };
151}
152
153pub(crate) use some_function1;
154
155// Macro to create variants of a function with 1 argument
156// If there exists a function is f_type(x: T) -> S, this creates a function
157// f_typeN(x: Option<T>) -> Option<S>
158// { let x = x?; Some(f_type(x)) }.
159macro_rules! some_polymorphic_function1 {
160    ($func_name:ident, $type_name: ident, $arg_type:ty, $ret_type:ty) => {
161        ::paste::paste! {
162            #[doc(hidden)]
163            pub fn [<$func_name _ $type_name N>]( arg: Option<$arg_type> ) -> Option<$ret_type> {
164                let arg = arg?;
165                Some([<$func_name _ $type_name >](arg))
166            }
167        }
168    };
169}
170
171pub(crate) use some_polymorphic_function1;
172
173// Macro to create variants of a polymorphic function with 1 argument that is
174// also polymorphic in the return type.
175// If there exists a function is f_type_result(x: T) -> S, this creates a
176// function
177// f_typeN_resultN(x: Option<T>) -> Option<S>
178// { let x = x?; Some(f_type(x)) }.
179#[allow(unused_macros)]
180macro_rules! polymorphic_return_function1 {
181    ($func_name:ident, $type_name: ident, $arg_type:ty, $ret_name: ident, $ret_type:ty) => {
182        ::paste::paste! {
183            #[doc(hidden)]
184            pub fn [<$func_name _ $type_name N _ $ret_name N>]( arg: Option<$arg_type> ) -> Option<$ret_type> {
185                let arg = arg?;
186                Some([<$func_name _ $type_name >](arg))
187            }
188        }
189    };
190}
191
192// Maybe we will need this someday
193#[allow(unused_imports)]
194pub(crate) use polymorphic_return_function1;
195
196// Macro to create variants of a function with 2 arguments
197// If there exists a function is f__(x: T, y: S) -> U, this creates
198// three functions:
199// - f_N(x: T, y: Option<S>) -> Option<U>
200// - fN_(x: Option<T>, y: S) -> Option<U>
201// - fNN(x: Option<T>, y: Option<S>) -> Option<U>
202// The resulting functions return Some only if all arguments are 'Some'.
203macro_rules! some_function2 {
204    ($func_name:ident, $arg_type0:ty, $arg_type1:ty, $ret_type:ty) => {
205        ::paste::paste! {
206            #[doc(hidden)]
207            pub fn [<$func_name NN>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
208                let arg0 = arg0?;
209                let arg1 = arg1?;
210                Some([<$func_name __>](arg0, arg1))
211            }
212
213            #[doc(hidden)]
214            pub fn [<$func_name _N>]( arg0: $arg_type0, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
215                let arg1 = arg1?;
216                Some([<$func_name __>](arg0, arg1))
217            }
218
219            #[doc(hidden)]
220            pub fn [<$func_name N_>]( arg0: Option<$arg_type0>, arg1: $arg_type1 ) -> Option<$ret_type> {
221                let arg0 = arg0?;
222                Some([<$func_name __>](arg0, arg1))
223            }
224        }
225    }
226}
227
228pub(crate) use some_function2;
229
230// Macro to create variants of a function with 2 arguments and
231// a generic trait bound
232// If there exists a function is f__<T: TraitBound>(x: X, y: S) -> U, this
233// creates three functions:
234// - f_N<T: TraitBound>(x: X, y: Option<S>) -> Option<U>
235// - fN_<T: TraitBound>(x: Option<X>, y: S) -> Option<U>
236// - fNN<T: TraitBound>(x: Option<X>, y: Option<S>) -> Option<U>
237// The resulting functions return Some only if all arguments are 'Some'.
238// The generic type may be a part of the type of both parameters, just one of
239// them or even the return type
240macro_rules! some_generic_function2 {
241    ($func_name:ident, $generic_type: ty, $arg_type0: ty, $arg_type1: ty, $bound: tt $(+ $bounds: tt)*, $ret_type: ty) => {
242        ::paste::paste! {
243            #[doc(hidden)]
244            pub fn [<$func_name NN>]<$generic_type>( arg0: Option<$arg_type0>, arg1: Option<$arg_type1> ) -> Option<$ret_type>
245            where
246                $generic_type: $bound $(+ $bounds)*,
247            {
248                let arg0 = arg0?;
249                let arg1 = arg1?;
250                Some([<$func_name __>](arg0, arg1))
251            }
252
253            #[doc(hidden)]
254            pub fn [<$func_name _N>]<$generic_type>( arg0: $arg_type0, arg1: Option<$arg_type1> ) -> Option<$ret_type>
255            where
256                $generic_type: $bound $(+ $bounds)*,
257            {
258                let arg1 = arg1?;
259                Some([<$func_name __>](arg0, arg1))
260            }
261
262            #[doc(hidden)]
263            pub fn [<$func_name N_>]<$generic_type>( arg0: Option<$arg_type0>, arg1: $arg_type1 ) -> Option<$ret_type>
264            where
265                $generic_type: $bound $(+ $bounds)*,
266            {
267                let arg0 = arg0?;
268                Some([<$func_name __>](arg0, arg1))
269            }
270        }
271    };
272}
273
274pub(crate) use some_generic_function2;
275
276// Macro to create variants of a polymorphic function with 2 arguments
277// that is also polymorphic in the return type
278// If there exists a function is f_type1_type2_result(x: T, y: S) -> U, this
279// creates three functions:
280// - f_type1_type2N_resultN(x: T, y: Option<S>) -> Option<U>
281// - f_type1N_type2_resultN(x: Option<T>, y: S) -> Option<U>
282// - f_type1N_type2N_resultN(x: Option<T>, y: Option<S>) -> Option<U>
283// The resulting functions return Some only if all arguments are 'Some'.
284macro_rules! polymorphic_return_function2 {
285    ($func_name:ident, $type_name0: ident, $arg_type0:ty, $type_name1: ident, $arg_type1:ty, $ret_name: ident, $ret_type:ty) => {
286        ::paste::paste! {
287            #[doc(hidden)]
288            pub fn [<$func_name _$type_name0 _ $type_name1 N _ $ret_name N>]( arg0: $arg_type0, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
289                let arg1 = arg1?;
290                Some([<$func_name _ $type_name0 _ $type_name1 _ $ret_name>](arg0, arg1))
291            }
292
293            #[doc(hidden)]
294            pub fn [<$func_name _ $type_name0 N _ $type_name1 _ $ret_name N>]( arg0: Option<$arg_type0>, arg1: $arg_type1 ) -> Option<$ret_type> {
295                let arg0 = arg0?;
296                Some([<$func_name _ $type_name0 _ $type_name1 _ $ret_name>](arg0, arg1))
297            }
298
299            #[doc(hidden)]
300            pub fn [<$func_name _ $type_name0 N _ $type_name1 N _ $ret_name N>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
301                let arg0 = arg0?;
302                let arg1 = arg1?;
303                Some([<$func_name _ $type_name0 _ $type_name1 _ $ret_name>](arg0, arg1))
304            }
305        }
306    }
307}
308
309pub(crate) use polymorphic_return_function2;
310
311// Macro to create variants of a polymorphic function with 2 arguments
312// If there exists a function is f_type1_type2(x: T, y: S) -> U, this
313// creates three functions:
314// - f_type1_type2N(x: T, y: Option<S>) -> Option<U>
315// - f_type1N_type2(x: Option<T>, y: S) -> Option<U>
316// - f_type1N_type2N(x: Option<T>, y: Option<S>) -> Option<U>
317// The resulting functions return Some only if all arguments are 'Some'.
318macro_rules! some_polymorphic_function2 {
319    ($func_name:ident, $type_name0: ident, $arg_type0:ty, $type_name1: ident, $arg_type1:ty, $ret_type:ty) => {
320        ::paste::paste! {
321            #[doc(hidden)]
322            pub fn [<$func_name _$type_name0 _ $type_name1 N>]( arg0: $arg_type0, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
323                let arg1 = arg1?;
324                Some([<$func_name _ $type_name0 _ $type_name1>](arg0, arg1))
325            }
326
327            #[doc(hidden)]
328            pub fn [<$func_name _ $type_name0 N _ $type_name1>]( arg0: Option<$arg_type0>, arg1: $arg_type1 ) -> Option<$ret_type> {
329                let arg0 = arg0?;
330                Some([<$func_name _ $type_name0 _ $type_name1>](arg0, arg1))
331            }
332
333            #[doc(hidden)]
334            pub fn [<$func_name _ $type_name0 N _ $type_name1 N>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1> ) -> Option<$ret_type> {
335                let arg0 = arg0?;
336                let arg1 = arg1?;
337                Some([<$func_name _ $type_name0 _ $type_name1>](arg0, arg1))
338            }
339        }
340    }
341}
342
343pub(crate) use some_polymorphic_function2;
344
345// If there exists a function is f_t1_t2_t3(x: T, y: S, z: V) -> U, this creates
346// seven functions:
347// - f_t1_t2_t3N(x: T, y: S, z: Option<V>) -> Option<U>
348// - f_t1_t2N_t2(x: T, y: Option<S>, z: V) -> Option<U>
349// - etc.
350// The resulting functions return Some only if all arguments are 'Some'.
351macro_rules! some_polymorphic_function3 {
352    ($func_name:ident,
353     $type_name0: ident, $arg_type0:ty,
354     $type_name1: ident, $arg_type1:ty,
355     $type_name2: ident, $arg_type2: ty,
356     $ret_type:ty) => {
357        ::paste::paste! {
358            #[doc(hidden)]
359            pub fn [<$func_name _ $type_name0 _ $type_name1 _ $type_name2 N>](
360                arg0: $arg_type0,
361                arg1: $arg_type1,
362                arg2: Option<$arg_type2>
363            ) -> Option<$ret_type> {
364                let arg2 = arg2?;
365                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
366            }
367
368            #[doc(hidden)]
369            pub fn [<$func_name _ $type_name0 _ $type_name1 N _ $type_name2>](
370                arg0: $arg_type0,
371                arg1: Option<$arg_type1>,
372                arg2: $arg_type2
373            ) -> Option<$ret_type> {
374                let arg1 = arg1?;
375                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
376            }
377
378            #[doc(hidden)]
379            pub fn [<$func_name _ $type_name0 _ $type_name1 N _ $type_name2 N>](
380                arg0: $arg_type0,
381                arg1: Option<$arg_type1>,
382                arg2: Option<$arg_type2>
383            ) -> Option<$ret_type> {
384                let arg1 = arg1?;
385                let arg2 = arg2?;
386                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
387            }
388
389            #[doc(hidden)]
390            pub fn [<$func_name _ $type_name0 N _ $type_name1 _ $type_name2>](
391                arg0: Option<$arg_type0>,
392                arg1: $arg_type1,
393                arg2: $arg_type2
394            ) -> Option<$ret_type> {
395                let arg0 = arg0?;
396                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
397            }
398
399            #[doc(hidden)]
400            pub fn [<$func_name _ $type_name0 N _ $type_name1 _ $type_name2 N>](
401                arg0: Option<$arg_type0>,
402                arg1: $arg_type1,
403                arg2: Option<$arg_type2>
404            ) -> Option<$ret_type> {
405                let arg0 = arg0?;
406                let arg2 = arg2?;
407                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
408            }
409
410            #[doc(hidden)]
411            pub fn [<$func_name _ $type_name0 N _ $type_name1 N _ $type_name2>](
412                arg0: Option<$arg_type0>,
413                arg1: Option<$arg_type1>,
414                arg2: $arg_type2
415            ) -> Option<$ret_type> {
416                let arg0 = arg0?;
417                let arg1 = arg1?;
418                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
419            }
420
421            #[doc(hidden)]
422            pub fn [<$func_name _ $type_name0 N _ $type_name1 N _ $type_name2 N>](
423                arg0: Option<$arg_type0>,
424                arg1: Option<$arg_type1>,
425                arg2: Option<$arg_type2>
426            ) -> Option<$ret_type> {
427                let arg0 = arg0?;
428                let arg1 = arg1?;
429                let arg2 = arg2?;
430                Some([<$func_name _ $type_name0 _ $type_name1 _ $type_name2>](arg0, arg1, arg2))
431            }
432        }
433    };
434}
435
436pub(crate) use some_polymorphic_function3;
437
438// If there exists a function is f___(x: T, y: S, z: V) -> U, this creates
439// seven functions:
440// - f__N(x: T, y: S, z: Option<V>) -> Option<U>
441// - f_N_(x: T, y: Option<S>, z: V) -> Option<U>
442// - etc.
443// The resulting functions return Some only if all arguments are 'Some'.
444macro_rules! some_function3 {
445    ($func_name:ident, $arg_type0:ty, $arg_type1:ty, $arg_type2: ty, $ret_type:ty) => {
446        ::paste::paste! {
447            #[doc(hidden)]
448            pub fn [<$func_name __N>]( arg0: $arg_type0, arg1: $arg_type1, arg2: Option<$arg_type2> ) -> Option<$ret_type> {
449                let arg2 = arg2?;
450                Some([<$func_name ___>](arg0, arg1, arg2))
451            }
452
453            #[doc(hidden)]
454            pub fn [<$func_name _N_>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: $arg_type2 ) -> Option<$ret_type> {
455                let arg1 = arg1?;
456                Some([<$func_name ___>](arg0, arg1, arg2))
457            }
458
459            #[doc(hidden)]
460            pub fn [<$func_name _NN>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: Option<$arg_type2> ) -> Option<$ret_type> {
461                let arg1 = arg1?;
462                let arg2 = arg2?;
463                Some([<$func_name ___>](arg0, arg1, arg2))
464            }
465
466            #[doc(hidden)]
467            pub fn [<$func_name N__>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: $arg_type2 ) -> Option<$ret_type> {
468                let arg0 = arg0?;
469                Some([<$func_name ___>](arg0, arg1, arg2))
470            }
471
472            #[doc(hidden)]
473            pub fn [<$func_name N_N>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: Option<$arg_type2> ) -> Option<$ret_type> {
474                let arg0 = arg0?;
475                let arg2 = arg2?;
476                Some([<$func_name ___>](arg0, arg1, arg2))
477            }
478
479            #[doc(hidden)]
480            pub fn [<$func_name NN_>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: $arg_type2 ) -> Option<$ret_type> {
481                let arg0 = arg0?;
482                let arg1 = arg1?;
483                Some([<$func_name ___>](arg0, arg1, arg2))
484            }
485
486            #[doc(hidden)]
487            pub fn [<$func_name NNN>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: Option<$arg_type2> ) -> Option<$ret_type> {
488                let arg0 = arg0?;
489                let arg1 = arg1?;
490                let arg2 = arg2?;
491                Some([<$func_name ___>](arg0, arg1, arg2))
492            }
493        }
494    }
495}
496
497pub(crate) use some_function3;
498
499// Macro to create variants of a function with 4 arguments
500// If there exists a function is f____(x: T, y: S, z: V, w: W) -> U, this
501// creates fifteen functions:
502// - f___N(x: T, y: S, z: V, w: Option<W>) -> Option<U>
503// - f__N_(x: T, y: S, z: Option<V>, w: W) -> Option<U>
504// - etc.
505// The resulting functions return Some only if all arguments are 'Some'.
506macro_rules! some_function4 {
507    ($func_name:ident, $arg_type0:ty, $arg_type1:ty, $arg_type2: ty, $arg_type3: ty, $ret_type:ty) => {
508        ::paste::paste! {
509            #[doc(hidden)]
510            pub fn [<$func_name ___N>]( arg0: $arg_type0, arg1: $arg_type1, arg2: $arg_type2, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
511                let arg3 = arg3?;
512                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
513            }
514
515            #[doc(hidden)]
516            pub fn [<$func_name __N_>]( arg0: $arg_type0, arg1: $arg_type1, arg2: Option<$arg_type2>, arg3: $arg_type3 ) -> Option<$ret_type> {
517                let arg2 = arg2?;
518                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
519            }
520
521            #[doc(hidden)]
522            pub fn [<$func_name __NN>]( arg0: $arg_type0, arg1: $arg_type1, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
523                let arg2 = arg2?;
524                let arg3 = arg3?;
525                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
526            }
527
528            #[doc(hidden)]
529            pub fn [<$func_name _N__>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: $arg_type2, arg3: $arg_type3 ) -> Option<$ret_type> {
530                let arg1 = arg1?;
531                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
532            }
533
534            #[doc(hidden)]
535            pub fn [<$func_name _N_N>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: $arg_type2, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
536                let arg1 = arg1?;
537                let arg3 = arg3?;
538                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
539            }
540
541            #[doc(hidden)]
542            pub fn [<$func_name _NN_>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: Option<$arg_type2>, arg3: $arg_type3 ) -> Option<$ret_type> {
543                let arg1 = arg1?;
544                let arg2 = arg2?;
545                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
546            }
547
548            #[doc(hidden)]
549            pub fn [<$func_name _NNN>]( arg0: $arg_type0, arg1: Option<$arg_type1>, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
550                let arg1 = arg1?;
551                let arg2 = arg2?;
552                let arg3 = arg3?;
553                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
554            }
555
556            #[doc(hidden)]
557            pub fn [<$func_name N___>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: $arg_type2, arg3: $arg_type3 ) -> Option<$ret_type> {
558                let arg0 = arg0?;
559                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
560            }
561
562            #[doc(hidden)]
563            pub fn [<$func_name N__N>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
564                let arg0 = arg0?;
565                let arg2 = arg2?;
566                let arg3 = arg3?;
567                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
568            }
569
570            #[doc(hidden)]
571            pub fn [<$func_name N_N_>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: $arg_type2, arg3: $arg_type3 ) -> Option<$ret_type> {
572                let arg0 = arg0?;
573                let arg1 = arg1?;
574                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
575            }
576
577            #[doc(hidden)]
578            pub fn [<$func_name N_NN>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
579                let arg0 = arg0?;
580                let arg1 = arg1?;
581                let arg2 = arg2?;
582                let arg3 = arg3?;
583                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
584            }
585
586            #[doc(hidden)]
587            pub fn [<$func_name NN__>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: $arg_type2, arg3: $arg_type3 ) -> Option<$ret_type> {
588                let arg0 = arg0?;
589                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
590            }
591
592            #[doc(hidden)]
593            pub fn [<$func_name NN_N>]( arg0: Option<$arg_type0>, arg1: $arg_type1, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
594                let arg0 = arg0?;
595                let arg2 = arg2?;
596                let arg3 = arg3?;
597                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
598            }
599
600            #[doc(hidden)]
601            pub fn [<$func_name NNN_>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: Option<$arg_type2>, arg3: $arg_type3 ) -> Option<$ret_type> {
602                let arg0 = arg0?;
603                let arg1 = arg1?;
604                let arg2 = arg2?;
605                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
606            }
607
608            #[doc(hidden)]
609            pub fn [<$func_name NNNN>]( arg0: Option<$arg_type0>, arg1: Option<$arg_type1>, arg2: Option<$arg_type2>, arg3: Option<$arg_type3> ) -> Option<$ret_type> {
610                let arg0 = arg0?;
611                let arg1 = arg1?;
612                let arg2 = arg2?;
613                let arg3 = arg3?;
614                Some([<$func_name ____>](arg0, arg1, arg2, arg3))
615            }
616        }
617    }
618}
619
620pub(crate) use some_function4;
621
622// Macro to create variants of a function with 2 arguments
623// optimized for the implementation of arithmetic operators.
624// Assuming there exists a function is f__(x: T, y: T) -> U, this creates
625// three functions:
626// - f_tN_t(x: T, y: Option<T>) -> Option<U>
627// - f_t_tN(x: Option<T>, y: T) -> Option<U>
628// - f_tN_tN(x: Option<T>, y: Option<T>) -> Option<U>
629// The resulting functions return Some only if all arguments are 'Some'.
630macro_rules! some_existing_operator {
631    ($func_name: ident, $short_name: ident, $arg_type: ty, $ret_type: ty) => {
632        ::paste::paste! {
633            #[inline(always)]
634            #[doc(hidden)]
635            pub fn [<$func_name _ $short_name N _ $short_name N>]( arg0: Option<$arg_type>, arg1: Option<$arg_type> ) -> Option<$ret_type> {
636                let arg0 = arg0?;
637                let arg1 = arg1?;
638                Some([<$func_name _ $short_name _ $short_name>](arg0, arg1))
639            }
640
641            #[inline(always)]
642            #[doc(hidden)]
643            pub fn [<$func_name _ $short_name _ $short_name N>]( arg0: $arg_type, arg1: Option<$arg_type> ) -> Option<$ret_type> {
644                let arg1 = arg1?;
645                Some([<$func_name _ $short_name _ $short_name>](arg0, arg1))
646            }
647
648            #[inline(always)]
649            #[doc(hidden)]
650            pub fn [<$func_name _ $short_name N _ $short_name>]( arg0: Option<$arg_type>, arg1: $arg_type ) -> Option<$ret_type> {
651                let arg0 = arg0?;
652                Some([<$func_name _ $short_name _ $short_name>](arg0, arg1))
653            }
654        }
655    }
656}
657
658pub(crate) use some_existing_operator;
659
660// Macro to create variants of a function with 2 arguments
661// optimized for the implementation of arithmetic operators.
662// Assuming there exists a function is f(x: T, y: T) -> U, this creates
663// four functions:
664// - f_t_t(x: T, y: T) -> U
665// - f_tN_t(x: T, y: Option<T>) -> Option<U>
666// - f_t_tN(x: Option<T>, y: T) -> Option<U>
667// - f_tN_tN(x: Option<T>, y: Option<T>) -> Option<U>
668// The resulting functions return Some only if all arguments are 'Some'.
669//
670// Has two variants:
671// - Takes the name of the existing function, the generated functions will have
672// this prefix
673// - Takes the name of the existing function, and the prefix for the generated
674// functions
675macro_rules! some_operator {
676    ($func_name: ident, $short_name: ident, $arg_type: ty, $ret_type: ty) => {
677        ::paste::paste! {
678            #[doc(hidden)]
679            #[inline(always)]
680            pub fn [<$func_name _ $short_name _ $short_name >]( arg0: $arg_type, arg1: $arg_type ) -> $ret_type {
681                $func_name(arg0, arg1)
682            }
683
684            some_existing_operator!($func_name, $short_name, $arg_type, $ret_type);
685        }
686    };
687
688    ($func_name: ident, $new_func_name: ident, $short_name: ident, $arg_type: ty, $ret_type: ty) => {
689        ::paste::paste! {
690            #[doc(hidden)]
691            #[inline(always)]
692            pub fn [<$new_func_name _ $short_name _ $short_name >]( arg0: $arg_type, arg1: $arg_type ) -> $ret_type {
693                $func_name(arg0, arg1)
694            }
695
696            some_existing_operator!($new_func_name, $short_name, $arg_type, $ret_type);
697        }
698    }
699}
700
701pub(crate) use some_operator;
702
703macro_rules! for_all_int_operator {
704    ($func_name: ident) => {
705        some_operator!($func_name, i8, i8, i8);
706        some_operator!($func_name, i16, i16, i16);
707        some_operator!($func_name, i32, i32, i32);
708        some_operator!($func_name, i64, i64, i64);
709        some_operator!($func_name, i128, i128, i128);
710        some_operator!($func_name, u8, u8, u8);
711        some_operator!($func_name, u16, u16, u16);
712        some_operator!($func_name, u32, u32, u32);
713        some_operator!($func_name, u64, u64, u64);
714    };
715}
716pub(crate) use for_all_int_operator;
717
718#[doc(hidden)]
719#[inline(always)]
720pub fn wrap_bool(b: Option<bool>) -> bool {
721    b.unwrap_or_default()
722}
723
724#[doc(hidden)]
725#[inline(always)]
726pub fn or_b_b<F>(left: bool, right: F) -> bool
727where
728    F: Fn() -> bool,
729{
730    left || right()
731}
732
733#[doc(hidden)]
734#[inline(always)]
735pub fn or_bN_b<F>(left: Option<bool>, right: F) -> Option<bool>
736where
737    F: Fn() -> bool,
738{
739    match left {
740        Some(l) => Some(l || right()),
741        None => match right() {
742            true => Some(true),
743            _ => None,
744        },
745    }
746}
747
748#[doc(hidden)]
749#[inline(always)]
750pub fn or_b_bN<F>(left: bool, right: F) -> Option<bool>
751where
752    F: Fn() -> Option<bool>,
753{
754    match left {
755        false => right(),
756        true => Some(true),
757    }
758}
759
760#[doc(hidden)]
761#[inline(always)]
762pub fn or_bN_bN<F>(left: Option<bool>, right: F) -> Option<bool>
763where
764    F: Fn() -> Option<bool>,
765{
766    match left {
767        None => match right() {
768            Some(true) => Some(true),
769            _ => None,
770        },
771        Some(false) => right(),
772        Some(true) => Some(true),
773    }
774}
775
776// OR and AND are special, they can't be generated by rules
777
778#[doc(hidden)]
779#[inline(always)]
780pub fn and_b_b<F>(left: bool, right: F) -> bool
781where
782    F: Fn() -> bool,
783{
784    left && right()
785}
786
787#[doc(hidden)]
788#[inline(always)]
789pub fn and_bN_b<F>(left: Option<bool>, right: F) -> Option<bool>
790where
791    F: Fn() -> bool,
792{
793    match left {
794        Some(false) => Some(false),
795        Some(true) => Some(right()),
796        None => match right() {
797            false => Some(false),
798            _ => None,
799        },
800    }
801}
802
803#[doc(hidden)]
804#[inline(always)]
805pub fn and_b_bN<F>(left: bool, right: F) -> Option<bool>
806where
807    F: Fn() -> Option<bool>,
808{
809    match left {
810        false => Some(false),
811        true => right(),
812    }
813}
814
815#[doc(hidden)]
816#[inline(always)]
817pub fn and_bN_bN<F>(left: Option<bool>, right: F) -> Option<bool>
818where
819    F: Fn() -> Option<bool>,
820{
821    match left {
822        Some(false) => Some(false),
823        Some(true) => right(),
824        None => match right() {
825            Some(false) => Some(false),
826            _ => None,
827        },
828    }
829}
830
831#[doc(hidden)]
832#[inline(always)]
833pub fn is_null<T>(value: Option<T>) -> bool {
834    value.is_none()
835}
836
837#[doc(hidden)]
838#[inline(always)]
839pub fn indicator<T, R>(value: &Option<T>) -> R
840where
841    R: HasZero + HasOne,
842{
843    match value {
844        None => R::zero(),
845        Some(_) => R::one(),
846    }
847}
848
849//////////////////////////////////////////
850
851#[doc(hidden)]
852#[inline(always)]
853pub fn abs_i8(left: i8) -> i8 {
854    left.abs()
855}
856
857#[doc(hidden)]
858#[inline(always)]
859pub fn abs_i16(left: i16) -> i16 {
860    left.abs()
861}
862
863#[doc(hidden)]
864#[inline(always)]
865pub fn abs_i32(left: i32) -> i32 {
866    left.abs()
867}
868
869#[doc(hidden)]
870#[inline(always)]
871pub fn abs_i64(left: i64) -> i64 {
872    left.abs()
873}
874
875#[doc(hidden)]
876#[inline(always)]
877pub fn abs_i128(left: i128) -> i128 {
878    left.abs()
879}
880
881#[doc(hidden)]
882#[inline(always)]
883pub fn abs_f(left: F32) -> F32 {
884    left.abs()
885}
886
887#[doc(hidden)]
888#[inline(always)]
889pub fn abs_d(left: F64) -> F64 {
890    left.abs()
891}
892
893#[doc(hidden)]
894#[inline(always)]
895pub fn abs_SqlDecimal(left: SqlDecimal) -> SqlDecimal {
896    left.abs()
897}
898
899some_polymorphic_function1!(abs, i8, i8, i8);
900some_polymorphic_function1!(abs, i16, i16, i16);
901some_polymorphic_function1!(abs, i32, i32, i32);
902some_polymorphic_function1!(abs, i64, i64, i64);
903some_polymorphic_function1!(abs, i128, i128, i128);
904some_polymorphic_function1!(abs, f, F32, F32);
905some_polymorphic_function1!(abs, d, F64, F64);
906some_polymorphic_function1!(abs, SqlDecimal, SqlDecimal, SqlDecimal);
907
908#[doc(hidden)]
909#[inline(always)]
910pub const fn is_true_b_(left: bool) -> bool {
911    left
912}
913
914#[doc(hidden)]
915#[inline(always)]
916pub const fn is_true_bN_(left: Option<bool>) -> bool {
917    matches!(left, Some(true))
918}
919
920#[doc(hidden)]
921#[inline(always)]
922pub fn is_false_b_(left: bool) -> bool {
923    !left
924}
925
926#[doc(hidden)]
927#[inline(always)]
928pub const fn is_false_bN_(left: Option<bool>) -> bool {
929    matches!(left, Some(false))
930}
931
932#[doc(hidden)]
933#[inline(always)]
934pub const fn is_not_true_b_(left: bool) -> bool {
935    !left
936}
937
938#[doc(hidden)]
939#[inline(always)]
940pub const fn is_not_true_bN_(left: Option<bool>) -> bool {
941    match left {
942        Some(true) => false,
943        Some(false) => true,
944        _ => true,
945    }
946}
947
948#[doc(hidden)]
949#[inline(always)]
950pub const fn is_not_false_b_(left: bool) -> bool {
951    left
952}
953
954#[doc(hidden)]
955#[inline(always)]
956pub const fn is_not_false_bN_(left: Option<bool>) -> bool {
957    match left {
958        Some(true) => true,
959        Some(false) => false,
960        _ => true,
961    }
962}
963
964#[doc(hidden)]
965#[inline(always)]
966pub fn is_distinct__<T>(left: T, right: T) -> bool
967where
968    T: Eq,
969{
970    left != right
971}
972
973#[doc(hidden)]
974#[inline(always)]
975pub fn is_distinct_N_N<T>(left: Option<T>, right: Option<T>) -> bool
976where
977    T: Eq,
978{
979    left != right
980}
981
982#[doc(hidden)]
983#[inline(always)]
984pub fn is_distinct__N<T>(left: T, right: Option<T>) -> bool
985where
986    T: Eq,
987{
988    match right {
989        Some(b) => left != b,
990        None => true,
991    }
992}
993
994#[doc(hidden)]
995#[inline(always)]
996pub fn is_distinct_N_<T>(left: Option<T>, right: T) -> bool
997where
998    T: Eq,
999{
1000    match left {
1001        Some(a) => a != right,
1002        None => true,
1003    }
1004}
1005
1006#[doc(hidden)]
1007pub fn weighted_push<T, W>(vec: &mut Vec<T>, value: &T, weight: W)
1008where
1009    W: ZRingValue,
1010    T: Clone,
1011{
1012    let mut w = weight;
1013    let negone = W::one().neg();
1014    while w != W::zero() {
1015        vec.push(value.clone());
1016        w = w.add_by_ref(&negone);
1017    }
1018}
1019
1020#[doc(hidden)]
1021pub fn power_i32_i32(left: i32, right: i32) -> F64 {
1022    (left as f64).pow(right).into()
1023}
1024
1025some_polymorphic_function2!(power, i32, i32, i32, i32, F64);
1026
1027////////////////////////////////////////////////
1028
1029// Functions called by 'writelog'
1030#[doc(hidden)]
1031pub fn dump<T>(prefix: SqlString, data: &T) -> T
1032where
1033    T: Debug + Clone,
1034{
1035    println!("{}: {:?}", prefix.str(), data);
1036    data.clone()
1037}
1038
1039#[doc(hidden)]
1040pub fn print(str: SqlString) {
1041    print!("{}", str.str())
1042}
1043
1044#[doc(hidden)]
1045pub fn print_opt(str: Option<SqlString>) {
1046    match str {
1047        None => print!("NULL"),
1048        Some(x) => print!("{}", x.str()),
1049    }
1050}
1051
1052#[doc(hidden)]
1053pub fn zset_map<D, T, F>(data: &WSet<D>, mapper: F) -> WSet<T>
1054where
1055    D: DBData + 'static,
1056    T: DBData + 'static,
1057    F: Fn(&D) -> T,
1058{
1059    let mut tuples = Vec::new();
1060    let mut cursor = data.cursor();
1061    while cursor.key_valid() {
1062        let item = unsafe { cursor.key().downcast::<D>() };
1063        let data = mapper(item);
1064        let weight = unsafe { *cursor.weight().downcast::<ZWeight>() };
1065        tuples.push(Tup2(Tup2(data, ()), weight));
1066        cursor.step_key();
1067    }
1068    WSet::from_tuples((), tuples)
1069}
1070
1071#[doc(hidden)]
1072pub fn late() {
1073    static TOTAL_LATE_RECORDS_COUNTER: LazyLock<Counter> =
1074        LazyLock::new(|| counter!(TOTAL_LATE_RECORDS));
1075
1076    // println!("Late record");
1077    TOTAL_LATE_RECORDS_COUNTER.increment(1);
1078}
1079
1080#[doc(hidden)]
1081pub fn zset_filter_comparator<D, T, F>(data: &WSet<D>, value: &T, comparator: F) -> WSet<D>
1082where
1083    D: DBData + 'static,
1084    T: 'static + Debug,
1085    F: Fn(&D, &T) -> bool,
1086{
1087    let factories = OrdZSetFactories::new::<D, (), ZWeight>();
1088
1089    let mut builder = OrdWSetBuilder::with_capacity(&factories, data.len());
1090
1091    let mut cursor = data.cursor();
1092    while cursor.key_valid() {
1093        let item = unsafe { cursor.key().downcast::<D>() };
1094        if comparator(item, value) {
1095            // println!("controlled_filter accepts={:?}", item);
1096            builder.push_val_diff(().erase(), cursor.weight());
1097            builder.push_key(cursor.key());
1098        } else {
1099            late();
1100        }
1101        cursor.step_key();
1102    }
1103    TypedBatch::new(builder.done())
1104}
1105
1106#[doc(hidden)]
1107pub fn indexed_zset_filter_comparator<K, D, T, F>(
1108    data: &IndexedWSet<K, D>,
1109    value: &T,
1110    comparator: F,
1111) -> IndexedWSet<K, D>
1112where
1113    K: DBData + Erase<DynData>,
1114    D: DBData + Erase<DynData>,
1115    T: 'static,
1116    F: Fn((&K, &D), &T) -> bool,
1117{
1118    let factories = OrdIndexedZSetFactories::new::<K, D, ZWeight>();
1119    let mut builder = OrdIndexedWSetBuilder::with_capacity(&factories, data.len());
1120
1121    let mut cursor = data.cursor();
1122    while cursor.key_valid() {
1123        let key = unsafe { cursor.key().downcast::<K>() }.clone();
1124        let mut any_values = false;
1125        while cursor.val_valid() {
1126            let w = *cursor.weight().deref();
1127            let item = unsafe { cursor.val().downcast::<D>() };
1128            if comparator((&key, item), value) {
1129                builder.push_val_diff(item.erase(), w.erase());
1130                any_values = true;
1131            } else {
1132                late();
1133            }
1134            cursor.step_val();
1135        }
1136        if any_values {
1137            builder.push_key(cursor.key());
1138        }
1139        cursor.step_key();
1140    }
1141    TypedBatch::new(builder.done())
1142}
1143
1144#[doc(hidden)]
1145pub fn append_to_upsert_handle<K>(data: &WSet<K>, handle: &SetHandle<K>)
1146where
1147    K: DBData,
1148{
1149    let mut cursor = data.cursor();
1150    while cursor.key_valid() {
1151        let mut w = *cursor.weight().deref();
1152        let mut insert = true;
1153        if !w.ge0() {
1154            insert = false;
1155            w = w.neg();
1156        }
1157        while !w.le0() {
1158            let key = unsafe { cursor.key().downcast::<K>() };
1159            handle.push(key.clone(), insert);
1160            w = w.add(Weight::neg(Weight::one()));
1161        }
1162        cursor.step_key();
1163    }
1164}
1165
1166#[doc(hidden)]
1167pub fn append_to_collection_handle<K>(data: &WSet<K>, handle: &ZSetHandle<K>)
1168where
1169    K: DBData,
1170{
1171    let mut cursor = data.cursor();
1172    while cursor.key_valid() {
1173        handle.push(
1174            unsafe { cursor.key().downcast::<K>() }.clone(),
1175            *cursor.weight().deref(),
1176        );
1177        cursor.step_key();
1178    }
1179}
1180
1181#[doc(hidden)]
1182pub fn read_output_handle<K>(handle: &OutputHandle<WSet<K>>) -> WSet<K>
1183where
1184    K: DBData,
1185{
1186    handle.consolidate()
1187}
1188
1189// Check that two zsets are equal.  If yes, returns true.
1190// If not, print a diff of the zsets and returns false.
1191// Assumes that the zsets are positive (all weights are positive).
1192#[doc(hidden)]
1193pub fn must_equal<K>(left: &WSet<K>, right: &WSet<K>) -> bool
1194where
1195    K: DBData + Clone,
1196{
1197    // println!("L={:?}\nR={:?}\n", left, right);
1198    let diff = left.add_by_ref(&right.neg_by_ref());
1199    if diff.is_zero() {
1200        return true;
1201    }
1202    let mut cursor = diff.cursor();
1203    while cursor.key_valid() {
1204        let weight = **cursor.weight();
1205        let key = cursor.key();
1206        if weight.le0() {
1207            println!("R: {:?}x{:?}", key, weight.neg());
1208        } else {
1209            println!("L: {:?}x{:?}", key, weight);
1210        }
1211        cursor.step_key();
1212    }
1213    false
1214}
1215
1216//////////////////////// Semigroup implementations
1217
1218#[derive(Clone)]
1219#[doc(hidden)]
1220pub struct DefaultOptSemigroup<T>(PhantomData<T>);
1221
1222#[doc(hidden)]
1223impl<T> Semigroup<Option<T>> for DefaultOptSemigroup<T>
1224where
1225    T: SemigroupValue,
1226{
1227    #[doc(hidden)]
1228    fn combine(left: &Option<T>, right: &Option<T>) -> Option<T> {
1229        match (left, right) {
1230            (None, _) => None,
1231            (_, None) => None,
1232            (Some(x), Some(y)) => Some(x.add_by_ref(y)),
1233        }
1234    }
1235}
1236
1237#[derive(Clone)]
1238#[doc(hidden)]
1239pub struct PairSemigroup<T, R, TS, RS>(PhantomData<(T, R, TS, RS)>);
1240
1241#[doc(hidden)]
1242impl<T, R, TS, RS> Semigroup<Tup2<T, R>> for PairSemigroup<T, R, TS, RS>
1243where
1244    TS: Semigroup<T>,
1245    RS: Semigroup<R>,
1246{
1247    #[doc(hidden)]
1248    fn combine(left: &Tup2<T, R>, right: &Tup2<T, R>) -> Tup2<T, R> {
1249        Tup2::new(
1250            TS::combine(&left.0, &right.0),
1251            RS::combine(&left.1, &right.1),
1252        )
1253    }
1254}
1255
1256#[derive(Clone)]
1257#[doc(hidden)]
1258pub struct TripleSemigroup<T, R, V, TS, RS, VS>(PhantomData<(T, R, V, TS, RS, VS)>);
1259
1260#[doc(hidden)]
1261impl<T, R, V, TS, RS, VS> Semigroup<Tup3<T, R, V>> for TripleSemigroup<T, R, V, TS, RS, VS>
1262where
1263    TS: Semigroup<T>,
1264    RS: Semigroup<R>,
1265    VS: Semigroup<V>,
1266{
1267    #[doc(hidden)]
1268    fn combine(left: &Tup3<T, R, V>, right: &Tup3<T, R, V>) -> Tup3<T, R, V> {
1269        Tup3::new(
1270            TS::combine(&left.0, &right.0),
1271            RS::combine(&left.1, &right.1),
1272            VS::combine(&left.2, &right.2),
1273        )
1274    }
1275}
1276
1277#[doc(hidden)]
1278#[derive(Clone)]
1279pub struct ConcatSemigroup<V>(PhantomData<V>);
1280
1281// Semigroup for the SINGLE_VALUE aggregate
1282#[derive(Clone)]
1283#[doc(hidden)]
1284pub struct SingleSemigroup<T>(PhantomData<T>);
1285
1286#[doc(hidden)]
1287impl<T> Semigroup<Tup2<bool, T>> for SingleSemigroup<Tup2<bool, T>>
1288where
1289    T: Clone,
1290{
1291    #[doc(hidden)]
1292    fn combine(left: &Tup2<bool, T>, right: &Tup2<bool, T>) -> Tup2<bool, T> {
1293        if left.0 && right.0 {
1294            panic!("More than one value in subquery");
1295        }
1296        Tup2::new(
1297            left.0 || right.0,
1298            if left.0 {
1299                left.1.clone()
1300            } else {
1301                right.1.clone()
1302            },
1303        )
1304    }
1305}