1use mz_repr::{ColumnType, Datum, DatumType, RowArena};
13
14use crate::{EvalError, MirScalarExpr};
15
16#[allow(unused)]
19pub(crate) trait LazyBinaryFunc {
20 fn eval<'a>(
21 &'a self,
22 datums: &[Datum<'a>],
23 temp_storage: &'a RowArena,
24 a: &'a MirScalarExpr,
25 b: &'a MirScalarExpr,
26 ) -> Result<Datum<'a>, EvalError>;
27
28 fn output_type(&self, input_type_a: ColumnType, input_type_b: ColumnType) -> ColumnType;
30
31 fn propagates_nulls(&self) -> bool;
33
34 fn introduces_nulls(&self) -> bool;
36
37 fn could_error(&self) -> bool {
39 true
41 }
42
43 fn negate(&self) -> Option<crate::BinaryFunc>;
45
46 fn is_monotone(&self) -> (bool, bool);
59
60 fn is_infix_op(&self) -> bool;
62}
63
64#[allow(unused)]
65pub(crate) trait EagerBinaryFunc<'a> {
66 type Input1: DatumType<'a, EvalError>;
67 type Input2: DatumType<'a, EvalError>;
68 type Output: DatumType<'a, EvalError>;
69
70 fn call(&self, a: Self::Input1, b: Self::Input2, temp_storage: &'a RowArena) -> Self::Output;
71
72 fn output_type(&self, input_type_a: ColumnType, input_type_b: ColumnType) -> ColumnType;
74
75 fn propagates_nulls(&self) -> bool {
77 !Self::Input1::nullable() && !Self::Input2::nullable()
79 }
80
81 fn introduces_nulls(&self) -> bool {
83 Self::Output::nullable()
85 }
86
87 fn could_error(&self) -> bool {
89 Self::Output::fallible()
90 }
91
92 fn negate(&self) -> Option<crate::BinaryFunc> {
94 None
95 }
96
97 fn is_monotone(&self) -> (bool, bool) {
98 (false, false)
99 }
100
101 fn is_infix_op(&self) -> bool {
102 false
103 }
104}
105
106impl<T: for<'a> EagerBinaryFunc<'a>> LazyBinaryFunc for T {
107 fn eval<'a>(
108 &'a self,
109 datums: &[Datum<'a>],
110 temp_storage: &'a RowArena,
111 a: &'a MirScalarExpr,
112 b: &'a MirScalarExpr,
113 ) -> Result<Datum<'a>, EvalError> {
114 let a = match T::Input1::try_from_result(a.eval(datums, temp_storage)) {
115 Ok(input) => input,
117 Err(Ok(datum)) if !datum.is_null() => {
119 return Err(EvalError::Internal("invalid input type".into()));
120 }
121 Err(res) => return res,
123 };
124 let b = match T::Input2::try_from_result(b.eval(datums, temp_storage)) {
125 Ok(input) => input,
127 Err(Ok(datum)) if !datum.is_null() => {
129 return Err(EvalError::Internal("invalid input type".into()));
130 }
131 Err(res) => return res,
133 };
134 self.call(a, b, temp_storage).into_result(temp_storage)
135 }
136
137 fn output_type(&self, input_type_a: ColumnType, input_type_b: ColumnType) -> ColumnType {
138 self.output_type(input_type_a, input_type_b)
139 }
140
141 fn propagates_nulls(&self) -> bool {
142 self.propagates_nulls()
143 }
144
145 fn introduces_nulls(&self) -> bool {
146 self.introduces_nulls()
147 }
148
149 fn could_error(&self) -> bool {
150 self.could_error()
151 }
152
153 fn negate(&self) -> Option<crate::BinaryFunc> {
154 self.negate()
155 }
156
157 fn is_monotone(&self) -> (bool, bool) {
158 self.is_monotone()
159 }
160
161 fn is_infix_op(&self) -> bool {
162 self.is_infix_op()
163 }
164}
165
166#[cfg(test)]
167mod test {
168 use mz_expr_derive::sqlfunc;
169 use mz_repr::ColumnType;
170 use mz_repr::ScalarType;
171
172 use crate::scalar::func::binary::LazyBinaryFunc;
173 use crate::{BinaryFunc, EvalError, func};
174
175 #[sqlfunc(sqlname = "INFALLIBLE", is_infix_op = true)]
176 #[allow(dead_code)]
177 fn infallible1(a: f32, b: f32) -> f32 {
178 a + b
179 }
180
181 #[sqlfunc]
182 #[allow(dead_code)]
183 fn infallible2(a: Option<f32>, b: Option<f32>) -> f32 {
184 a.unwrap_or_default() + b.unwrap_or_default()
185 }
186
187 #[sqlfunc]
188 #[allow(dead_code)]
189 fn infallible3(a: f32, b: f32) -> Option<f32> {
190 Some(a + b)
191 }
192
193 #[mz_ore::test]
194 fn elision_rules_infallible() {
195 assert_eq!(format!("{}", Infallible1), "INFALLIBLE");
196 assert!(Infallible1.propagates_nulls());
197 assert!(!Infallible1.introduces_nulls());
198
199 assert!(!Infallible2.propagates_nulls());
200 assert!(!Infallible2.introduces_nulls());
201
202 assert!(Infallible3.propagates_nulls());
203 assert!(Infallible3.introduces_nulls());
204 }
205
206 #[mz_ore::test]
207 fn output_types_infallible() {
208 assert_eq!(
209 Infallible1.output_type(
210 ScalarType::Float32.nullable(true),
211 ScalarType::Float32.nullable(true)
212 ),
213 ScalarType::Float32.nullable(true)
214 );
215 assert_eq!(
216 Infallible1.output_type(
217 ScalarType::Float32.nullable(true),
218 ScalarType::Float32.nullable(false)
219 ),
220 ScalarType::Float32.nullable(true)
221 );
222 assert_eq!(
223 Infallible1.output_type(
224 ScalarType::Float32.nullable(false),
225 ScalarType::Float32.nullable(true)
226 ),
227 ScalarType::Float32.nullable(true)
228 );
229 assert_eq!(
230 Infallible1.output_type(
231 ScalarType::Float32.nullable(false),
232 ScalarType::Float32.nullable(false)
233 ),
234 ScalarType::Float32.nullable(false)
235 );
236
237 assert_eq!(
238 Infallible2.output_type(
239 ScalarType::Float32.nullable(true),
240 ScalarType::Float32.nullable(true)
241 ),
242 ScalarType::Float32.nullable(false)
243 );
244 assert_eq!(
245 Infallible2.output_type(
246 ScalarType::Float32.nullable(true),
247 ScalarType::Float32.nullable(false)
248 ),
249 ScalarType::Float32.nullable(false)
250 );
251 assert_eq!(
252 Infallible2.output_type(
253 ScalarType::Float32.nullable(false),
254 ScalarType::Float32.nullable(true)
255 ),
256 ScalarType::Float32.nullable(false)
257 );
258 assert_eq!(
259 Infallible2.output_type(
260 ScalarType::Float32.nullable(false),
261 ScalarType::Float32.nullable(false)
262 ),
263 ScalarType::Float32.nullable(false)
264 );
265
266 assert_eq!(
267 Infallible3.output_type(
268 ScalarType::Float32.nullable(true),
269 ScalarType::Float32.nullable(true)
270 ),
271 ScalarType::Float32.nullable(true)
272 );
273 assert_eq!(
274 Infallible3.output_type(
275 ScalarType::Float32.nullable(true),
276 ScalarType::Float32.nullable(false)
277 ),
278 ScalarType::Float32.nullable(true)
279 );
280 assert_eq!(
281 Infallible3.output_type(
282 ScalarType::Float32.nullable(false),
283 ScalarType::Float32.nullable(true)
284 ),
285 ScalarType::Float32.nullable(true)
286 );
287 assert_eq!(
288 Infallible3.output_type(
289 ScalarType::Float32.nullable(false),
290 ScalarType::Float32.nullable(false)
291 ),
292 ScalarType::Float32.nullable(true)
293 );
294 }
295
296 #[sqlfunc]
297 #[allow(dead_code)]
298 fn fallible1(a: f32, b: f32) -> Result<f32, EvalError> {
299 Ok(a + b)
300 }
301
302 #[sqlfunc]
303 #[allow(dead_code)]
304 fn fallible2(a: Option<f32>, b: Option<f32>) -> Result<f32, EvalError> {
305 Ok(a.unwrap_or_default() + b.unwrap_or_default())
306 }
307
308 #[sqlfunc]
309 #[allow(dead_code)]
310 fn fallible3(a: f32, b: f32) -> Result<Option<f32>, EvalError> {
311 Ok(Some(a + b))
312 }
313
314 #[mz_ore::test]
315 fn elision_rules_fallible() {
316 assert!(Fallible1.propagates_nulls());
317 assert!(!Fallible1.introduces_nulls());
318
319 assert!(!Fallible2.propagates_nulls());
320 assert!(!Fallible2.introduces_nulls());
321
322 assert!(Fallible3.propagates_nulls());
323 assert!(Fallible3.introduces_nulls());
324 }
325
326 #[mz_ore::test]
327 fn output_types_fallible() {
328 assert_eq!(
329 Fallible1.output_type(
330 ScalarType::Float32.nullable(true),
331 ScalarType::Float32.nullable(true)
332 ),
333 ScalarType::Float32.nullable(true)
334 );
335 assert_eq!(
336 Fallible1.output_type(
337 ScalarType::Float32.nullable(true),
338 ScalarType::Float32.nullable(false)
339 ),
340 ScalarType::Float32.nullable(true)
341 );
342 assert_eq!(
343 Fallible1.output_type(
344 ScalarType::Float32.nullable(false),
345 ScalarType::Float32.nullable(true)
346 ),
347 ScalarType::Float32.nullable(true)
348 );
349 assert_eq!(
350 Fallible1.output_type(
351 ScalarType::Float32.nullable(false),
352 ScalarType::Float32.nullable(false)
353 ),
354 ScalarType::Float32.nullable(false)
355 );
356
357 assert_eq!(
358 Fallible2.output_type(
359 ScalarType::Float32.nullable(true),
360 ScalarType::Float32.nullable(true)
361 ),
362 ScalarType::Float32.nullable(false)
363 );
364 assert_eq!(
365 Fallible2.output_type(
366 ScalarType::Float32.nullable(true),
367 ScalarType::Float32.nullable(false)
368 ),
369 ScalarType::Float32.nullable(false)
370 );
371 assert_eq!(
372 Fallible2.output_type(
373 ScalarType::Float32.nullable(false),
374 ScalarType::Float32.nullable(true)
375 ),
376 ScalarType::Float32.nullable(false)
377 );
378 assert_eq!(
379 Fallible2.output_type(
380 ScalarType::Float32.nullable(false),
381 ScalarType::Float32.nullable(false)
382 ),
383 ScalarType::Float32.nullable(false)
384 );
385
386 assert_eq!(
387 Fallible3.output_type(
388 ScalarType::Float32.nullable(true),
389 ScalarType::Float32.nullable(true)
390 ),
391 ScalarType::Float32.nullable(true)
392 );
393 assert_eq!(
394 Fallible3.output_type(
395 ScalarType::Float32.nullable(true),
396 ScalarType::Float32.nullable(false)
397 ),
398 ScalarType::Float32.nullable(true)
399 );
400 assert_eq!(
401 Fallible3.output_type(
402 ScalarType::Float32.nullable(false),
403 ScalarType::Float32.nullable(true)
404 ),
405 ScalarType::Float32.nullable(true)
406 );
407 assert_eq!(
408 Fallible3.output_type(
409 ScalarType::Float32.nullable(false),
410 ScalarType::Float32.nullable(false)
411 ),
412 ScalarType::Float32.nullable(true)
413 );
414 }
415
416 #[mz_ore::test]
417 fn test_equivalence_nullable() {
418 test_equivalence_inner(true);
419 }
420
421 #[mz_ore::test]
422 fn test_equivalence_non_nullable() {
423 test_equivalence_inner(false);
424 }
425
426 fn test_equivalence_inner(input_nullable: bool) {
430 #[track_caller]
431 fn check<T: LazyBinaryFunc + std::fmt::Display + std::fmt::Debug>(
432 new: T,
433 old: BinaryFunc,
434 column_a_ty: &ColumnType,
435 column_b_ty: &ColumnType,
436 ) {
437 assert_eq!(
438 new.propagates_nulls(),
439 old.propagates_nulls(),
440 "{new:?} propagates_nulls mismatch"
441 );
442 assert_eq!(
443 new.introduces_nulls(),
444 old.introduces_nulls(),
445 "{new:?} introduces_nulls mismatch"
446 );
447 assert_eq!(
448 new.could_error(),
449 old.could_error(),
450 "{new:?} could_error mismatch"
451 );
452 assert_eq!(
453 new.is_monotone(),
454 old.is_monotone(),
455 "{new:?} is_monotone mismatch"
456 );
457 assert_eq!(
458 new.is_infix_op(),
459 old.is_infix_op(),
460 "{new:?} is_infix_op mismatch"
461 );
462 assert_eq!(
463 new.output_type(column_a_ty.clone(), column_b_ty.clone()),
464 old.output_type(column_a_ty.clone(), column_b_ty.clone()),
465 "{new:?} output_type mismatch"
466 );
467 assert_eq!(
468 format!("{}", new),
469 format!("{}", old),
470 "{new:?} format mismatch"
471 );
472 }
473
474 let i32_ty = ColumnType {
475 nullable: input_nullable,
476 scalar_type: ScalarType::Int32,
477 };
478 let ts_tz_ty = ColumnType {
479 nullable: input_nullable,
480 scalar_type: ScalarType::TimestampTz { precision: None },
481 };
482 let time_ty = ColumnType {
483 nullable: input_nullable,
484 scalar_type: ScalarType::Time,
485 };
486 let interval_ty = ColumnType {
487 nullable: input_nullable,
488 scalar_type: ScalarType::Interval,
489 };
490 let i32_map_ty = ColumnType {
491 nullable: input_nullable,
492 scalar_type: ScalarType::Map {
493 value_type: Box::new(ScalarType::Int32),
494 custom_id: None,
495 },
496 };
497
498 use BinaryFunc as BF;
499
500 check(func::AddInt16, BF::AddInt16, &i32_ty, &i32_ty);
505 check(func::AddInt32, BF::AddInt32, &i32_ty, &i32_ty);
506 check(func::AddInt64, BF::AddInt64, &i32_ty, &i32_ty);
507 check(func::AddUint16, BF::AddUInt16, &i32_ty, &i32_ty);
508 check(func::AddUint32, BF::AddUInt32, &i32_ty, &i32_ty);
509 check(func::AddUint64, BF::AddUInt64, &i32_ty, &i32_ty);
510 check(func::AddFloat32, BF::AddFloat32, &i32_ty, &i32_ty);
511 check(func::AddFloat64, BF::AddFloat64, &i32_ty, &i32_ty);
512 check(func::AddDateTime, BF::AddDateTime, &i32_ty, &i32_ty);
513 check(func::AddDateInterval, BF::AddDateInterval, &i32_ty, &i32_ty);
514 check(
515 func::AddTimeInterval,
516 BF::AddTimeInterval,
517 &ts_tz_ty,
518 &i32_ty,
519 );
520 check(func::RoundNumericBinary, BF::RoundNumeric, &i32_ty, &i32_ty);
521 check(func::ConvertFrom, BF::ConvertFrom, &i32_ty, &i32_ty);
522 check(func::Left, BF::Left, &i32_ty, &i32_ty);
523 check(func::Right, BF::Right, &i32_ty, &i32_ty);
524 check(func::Trim, BF::Trim, &i32_ty, &i32_ty);
525 check(func::TrimLeading, BF::TrimLeading, &i32_ty, &i32_ty);
526 check(func::TrimTrailing, BF::TrimTrailing, &i32_ty, &i32_ty);
527 check(func::Encode, BF::Encode, &i32_ty, &i32_ty);
528 check(func::Decode, BF::Decode, &i32_ty, &i32_ty);
529 check(
530 func::EncodedBytesCharLength,
531 BF::EncodedBytesCharLength,
532 &i32_ty,
533 &i32_ty,
534 );
535 check(func::AddNumeric, BF::AddNumeric, &i32_ty, &i32_ty);
536 check(func::AddInterval, BF::AddInterval, &i32_ty, &i32_ty);
537 check(func::BitAndInt16, BF::BitAndInt16, &i32_ty, &i32_ty);
538 check(func::BitAndInt32, BF::BitAndInt32, &i32_ty, &i32_ty);
539 check(func::BitAndInt64, BF::BitAndInt64, &i32_ty, &i32_ty);
540 check(func::BitAndUint16, BF::BitAndUInt16, &i32_ty, &i32_ty);
541 check(func::BitAndUint32, BF::BitAndUInt32, &i32_ty, &i32_ty);
542 check(func::BitAndUint64, BF::BitAndUInt64, &i32_ty, &i32_ty);
543 check(func::BitOrInt16, BF::BitOrInt16, &i32_ty, &i32_ty);
544 check(func::BitOrInt32, BF::BitOrInt32, &i32_ty, &i32_ty);
545 check(func::BitOrInt64, BF::BitOrInt64, &i32_ty, &i32_ty);
546 check(func::BitOrUint16, BF::BitOrUInt16, &i32_ty, &i32_ty);
547 check(func::BitOrUint32, BF::BitOrUInt32, &i32_ty, &i32_ty);
548 check(func::BitOrUint64, BF::BitOrUInt64, &i32_ty, &i32_ty);
549 check(func::BitXorInt16, BF::BitXorInt16, &i32_ty, &i32_ty);
550 check(func::BitXorInt32, BF::BitXorInt32, &i32_ty, &i32_ty);
551 check(func::BitXorInt64, BF::BitXorInt64, &i32_ty, &i32_ty);
552 check(func::BitXorUint16, BF::BitXorUInt16, &i32_ty, &i32_ty);
553 check(func::BitXorUint32, BF::BitXorUInt32, &i32_ty, &i32_ty);
554 check(func::BitXorUint64, BF::BitXorUInt64, &i32_ty, &i32_ty);
555
556 check(
557 func::BitShiftLeftInt16,
558 BF::BitShiftLeftInt16,
559 &i32_ty,
560 &i32_ty,
561 );
562 check(
563 func::BitShiftLeftInt32,
564 BF::BitShiftLeftInt32,
565 &i32_ty,
566 &i32_ty,
567 );
568 check(
569 func::BitShiftLeftInt64,
570 BF::BitShiftLeftInt64,
571 &i32_ty,
572 &i32_ty,
573 );
574 check(
575 func::BitShiftLeftUint16,
576 BF::BitShiftLeftUInt16,
577 &i32_ty,
578 &i32_ty,
579 );
580 check(
581 func::BitShiftLeftUint32,
582 BF::BitShiftLeftUInt32,
583 &i32_ty,
584 &i32_ty,
585 );
586 check(
587 func::BitShiftLeftUint64,
588 BF::BitShiftLeftUInt64,
589 &i32_ty,
590 &i32_ty,
591 );
592
593 check(
594 func::BitShiftRightInt16,
595 BF::BitShiftRightInt16,
596 &i32_ty,
597 &i32_ty,
598 );
599 check(
600 func::BitShiftRightInt32,
601 BF::BitShiftRightInt32,
602 &i32_ty,
603 &i32_ty,
604 );
605 check(
606 func::BitShiftRightInt64,
607 BF::BitShiftRightInt64,
608 &i32_ty,
609 &i32_ty,
610 );
611 check(
612 func::BitShiftRightUint16,
613 BF::BitShiftRightUInt16,
614 &i32_ty,
615 &i32_ty,
616 );
617 check(
618 func::BitShiftRightUint32,
619 BF::BitShiftRightUInt32,
620 &i32_ty,
621 &i32_ty,
622 );
623 check(
624 func::BitShiftRightUint64,
625 BF::BitShiftRightUInt64,
626 &i32_ty,
627 &i32_ty,
628 );
629
630 check(func::SubInt16, BF::SubInt16, &i32_ty, &i32_ty);
631 check(func::SubInt32, BF::SubInt32, &i32_ty, &i32_ty);
632 check(func::SubInt64, BF::SubInt64, &i32_ty, &i32_ty);
633 check(func::SubUint16, BF::SubUInt16, &i32_ty, &i32_ty);
634 check(func::SubUint32, BF::SubUInt32, &i32_ty, &i32_ty);
635 check(func::SubUint64, BF::SubUInt64, &i32_ty, &i32_ty);
636 check(func::SubFloat32, BF::SubFloat32, &i32_ty, &i32_ty);
637 check(func::SubFloat64, BF::SubFloat64, &i32_ty, &i32_ty);
638 check(func::SubNumeric, BF::SubNumeric, &i32_ty, &i32_ty);
639
640 check(func::AgeTimestamp, BF::AgeTimestamp, &i32_ty, &i32_ty);
641 check(func::AgeTimestamptz, BF::AgeTimestampTz, &i32_ty, &i32_ty);
642
643 check(func::SubTimestamp, BF::SubTimestamp, &ts_tz_ty, &i32_ty);
644 check(func::SubTimestamptz, BF::SubTimestampTz, &ts_tz_ty, &i32_ty);
645 check(func::SubDate, BF::SubDate, &i32_ty, &i32_ty);
646 check(func::SubTime, BF::SubTime, &i32_ty, &i32_ty);
647 check(func::SubInterval, BF::SubInterval, &i32_ty, &i32_ty);
648 check(func::SubDateInterval, BF::SubDateInterval, &i32_ty, &i32_ty);
649 check(
650 func::SubTimeInterval,
651 BF::SubTimeInterval,
652 &time_ty,
653 &interval_ty,
654 );
655
656 check(func::MulInt16, BF::MulInt16, &i32_ty, &i32_ty);
657 check(func::MulInt32, BF::MulInt32, &i32_ty, &i32_ty);
658 check(func::MulInt64, BF::MulInt64, &i32_ty, &i32_ty);
659 check(func::MulUint16, BF::MulUInt16, &i32_ty, &i32_ty);
660 check(func::MulUint32, BF::MulUInt32, &i32_ty, &i32_ty);
661 check(func::MulUint64, BF::MulUInt64, &i32_ty, &i32_ty);
662 check(func::MulFloat32, BF::MulFloat32, &i32_ty, &i32_ty);
663 check(func::MulFloat64, BF::MulFloat64, &i32_ty, &i32_ty);
664 check(func::MulNumeric, BF::MulNumeric, &i32_ty, &i32_ty);
665 check(func::MulInterval, BF::MulInterval, &i32_ty, &i32_ty);
666
667 check(func::DivInt16, BF::DivInt16, &i32_ty, &i32_ty);
668 check(func::DivInt32, BF::DivInt32, &i32_ty, &i32_ty);
669 check(func::DivInt64, BF::DivInt64, &i32_ty, &i32_ty);
670 check(func::DivUint16, BF::DivUInt16, &i32_ty, &i32_ty);
671 check(func::DivUint32, BF::DivUInt32, &i32_ty, &i32_ty);
672 check(func::DivUint64, BF::DivUInt64, &i32_ty, &i32_ty);
673 check(func::DivFloat32, BF::DivFloat32, &i32_ty, &i32_ty);
674 check(func::DivFloat64, BF::DivFloat64, &i32_ty, &i32_ty);
675 check(func::DivNumeric, BF::DivNumeric, &i32_ty, &i32_ty);
676 check(func::DivInterval, BF::DivInterval, &i32_ty, &i32_ty);
677
678 check(func::ModInt16, BF::ModInt16, &i32_ty, &i32_ty);
679 check(func::ModInt32, BF::ModInt32, &i32_ty, &i32_ty);
680 check(func::ModInt64, BF::ModInt64, &i32_ty, &i32_ty);
681 check(func::ModUint16, BF::ModUInt16, &i32_ty, &i32_ty);
682 check(func::ModUint32, BF::ModUInt32, &i32_ty, &i32_ty);
683 check(func::ModUint64, BF::ModUInt64, &i32_ty, &i32_ty);
684 check(func::ModFloat32, BF::ModFloat32, &i32_ty, &i32_ty);
685 check(func::ModFloat64, BF::ModFloat64, &i32_ty, &i32_ty);
686 check(func::ModNumeric, BF::ModNumeric, &i32_ty, &i32_ty);
687
688 check(func::LogBaseNumeric, BF::LogNumeric, &i32_ty, &i32_ty);
689 check(func::Power, BF::Power, &i32_ty, &i32_ty);
690 check(func::PowerNumeric, BF::PowerNumeric, &i32_ty, &i32_ty);
691
692 check(func::UuidGenerateV5, BF::UuidGenerateV5, &i32_ty, &i32_ty);
693
694 check(func::GetBit, BF::GetBit, &i32_ty, &i32_ty);
695 check(func::GetByte, BF::GetByte, &i32_ty, &i32_ty);
696
697 check(
698 func::ConstantTimeEqBytes,
699 BF::ConstantTimeEqBytes,
700 &i32_ty,
701 &i32_ty,
702 );
703 check(
704 func::ConstantTimeEqString,
705 BF::ConstantTimeEqString,
706 &i32_ty,
707 &i32_ty,
708 );
709
710 check(
711 func::RangeContainsI32,
712 BF::RangeContainsElem {
713 elem_type: ScalarType::Int32,
714 rev: false,
715 },
716 &i32_ty,
717 &i32_ty,
718 );
719 check(
720 func::RangeContainsI64,
721 BF::RangeContainsElem {
722 elem_type: ScalarType::Int64,
723 rev: false,
724 },
725 &i32_ty,
726 &i32_ty,
727 );
728 check(
729 func::RangeContainsDate,
730 BF::RangeContainsElem {
731 elem_type: ScalarType::Date,
732 rev: false,
733 },
734 &i32_ty,
735 &i32_ty,
736 );
737 check(
738 func::RangeContainsNumeric,
739 BF::RangeContainsElem {
740 elem_type: ScalarType::Numeric { max_scale: None },
741 rev: false,
742 },
743 &i32_ty,
744 &i32_ty,
745 );
746 check(
747 func::RangeContainsTimestamp,
748 BF::RangeContainsElem {
749 elem_type: ScalarType::Timestamp { precision: None },
750 rev: false,
751 },
752 &i32_ty,
753 &i32_ty,
754 );
755 check(
756 func::RangeContainsTimestampTz,
757 BF::RangeContainsElem {
758 elem_type: ScalarType::TimestampTz { precision: None },
759 rev: false,
760 },
761 &i32_ty,
762 &i32_ty,
763 );
764 check(
765 func::RangeContainsI32Rev,
766 BF::RangeContainsElem {
767 elem_type: ScalarType::Int32,
768 rev: true,
769 },
770 &i32_ty,
771 &i32_ty,
772 );
773 check(
774 func::RangeContainsI64Rev,
775 BF::RangeContainsElem {
776 elem_type: ScalarType::Int64,
777 rev: true,
778 },
779 &i32_ty,
780 &i32_ty,
781 );
782 check(
783 func::RangeContainsDateRev,
784 BF::RangeContainsElem {
785 elem_type: ScalarType::Date,
786 rev: true,
787 },
788 &i32_ty,
789 &i32_ty,
790 );
791 check(
792 func::RangeContainsNumericRev,
793 BF::RangeContainsElem {
794 elem_type: ScalarType::Numeric { max_scale: None },
795 rev: true,
796 },
797 &i32_ty,
798 &i32_ty,
799 );
800 check(
801 func::RangeContainsTimestampRev,
802 BF::RangeContainsElem {
803 elem_type: ScalarType::Timestamp { precision: None },
804 rev: true,
805 },
806 &i32_ty,
807 &i32_ty,
808 );
809 check(
810 func::RangeContainsTimestampTzRev,
811 BF::RangeContainsElem {
812 elem_type: ScalarType::TimestampTz { precision: None },
813 rev: true,
814 },
815 &i32_ty,
816 &i32_ty,
817 );
818
819 check(
820 func::RangeContainsRange,
821 BF::RangeContainsRange { rev: false },
822 &i32_ty,
823 &i32_ty,
824 );
825 check(
826 func::RangeContainsRangeRev,
827 BF::RangeContainsRange { rev: true },
828 &i32_ty,
829 &i32_ty,
830 );
831 check(func::RangeOverlaps, BF::RangeOverlaps, &i32_ty, &i32_ty);
832 check(func::RangeAfter, BF::RangeAfter, &i32_ty, &i32_ty);
833 check(func::RangeBefore, BF::RangeBefore, &i32_ty, &i32_ty);
834 check(func::RangeOverleft, BF::RangeOverleft, &i32_ty, &i32_ty);
835 check(func::RangeOverright, BF::RangeOverright, &i32_ty, &i32_ty);
836 check(func::RangeAdjacent, BF::RangeAdjacent, &i32_ty, &i32_ty);
837
838 check(func::RangeUnion, BF::RangeUnion, &i32_ty, &i32_ty);
839 check(
840 func::RangeIntersection,
841 BF::RangeIntersection,
842 &i32_ty,
843 &i32_ty,
844 );
845 check(func::RangeDifference, BF::RangeDifference, &i32_ty, &i32_ty);
846
847 check(func::Eq, BF::Eq, &i32_ty, &i32_ty);
848 check(func::NotEq, BF::NotEq, &i32_ty, &i32_ty);
849 check(func::Lt, BF::Lt, &i32_ty, &i32_ty);
850 check(func::Lte, BF::Lte, &i32_ty, &i32_ty);
851 check(func::Gt, BF::Gt, &i32_ty, &i32_ty);
852 check(func::Gte, BF::Gte, &i32_ty, &i32_ty);
853
854 check(func::LikeEscape, BF::LikeEscape, &i32_ty, &i32_ty);
855 check(func::TimezoneOffset, BF::TimezoneOffset, &i32_ty, &i32_ty);
856 check(func::TextConcatBinary, BF::TextConcat, &i32_ty, &i32_ty);
857
858 check(
859 func::ToCharTimestampFormat,
860 BF::ToCharTimestamp,
861 &i32_ty,
862 &i32_ty,
863 );
864 check(
865 func::ToCharTimestampTzFormat,
866 BF::ToCharTimestampTz,
867 &i32_ty,
868 &i32_ty,
869 );
870
871 check(
876 func::JsonbContainsString,
877 BF::JsonbContainsString,
878 &i32_ty,
879 &i32_ty,
880 );
881 check(func::MapContainsKey, BF::MapContainsKey, &i32_ty, &i32_ty);
882 check(
883 func::MapContainsAllKeys,
884 BF::MapContainsAllKeys,
885 &i32_ty,
886 &i32_ty,
887 );
888 check(
889 func::MapContainsAnyKeys,
890 BF::MapContainsAnyKeys,
891 &i32_ty,
892 &i32_ty,
893 );
894 check(func::MapContainsMap, BF::MapContainsMap, &i32_ty, &i32_ty);
895 check(func::MapGetValue, BF::MapGetValue, &i32_map_ty, &i32_ty);
896 check(
897 func::ListContainsList,
898 BF::ListContainsList { rev: false },
899 &i32_ty,
900 &i32_ty,
901 );
902 check(
903 func::ListContainsListRev,
904 BF::ListContainsList { rev: true },
905 &i32_ty,
906 &i32_ty,
907 );
908
909 check(
910 func::JsonbContainsJsonb,
911 BF::JsonbContainsJsonb,
912 &i32_ty,
913 &i32_ty,
914 );
915 check(func::JsonbConcat, BF::JsonbConcat, &i32_ty, &i32_ty);
916 check(
917 func::JsonbDeleteInt64,
918 BF::JsonbDeleteInt64,
919 &i32_ty,
920 &i32_ty,
921 );
922 check(
923 func::JsonbDeleteString,
924 BF::JsonbDeleteString,
925 &i32_ty,
926 &i32_ty,
927 );
928
929 check(
930 func::DateBinTimestamp,
931 BF::DateBinTimestamp,
932 &i32_ty,
933 &i32_ty,
934 );
935 check(
936 func::DateBinTimestampTz,
937 BF::DateBinTimestampTz,
938 &i32_ty,
939 &i32_ty,
940 );
941 check(
942 func::DatePartIntervalNumeric,
943 BF::ExtractInterval,
944 &i32_ty,
945 &i32_ty,
946 );
947 check(func::DatePartTimeNumeric, BF::ExtractTime, &i32_ty, &i32_ty);
948 check(
949 func::DatePartTimestampTimestampNumeric,
950 BF::ExtractTimestamp,
951 &i32_ty,
952 &i32_ty,
953 );
954 check(
955 func::DatePartTimestampTimestampTzNumeric,
956 BF::ExtractTimestampTz,
957 &i32_ty,
958 &i32_ty,
959 );
960 check(
961 func::DatePartIntervalF64,
962 BF::DatePartInterval,
963 &i32_ty,
964 &i32_ty,
965 );
966 check(func::DatePartTimeF64, BF::DatePartTime, &i32_ty, &i32_ty);
967 check(
968 func::DatePartTimestampTimestampF64,
969 BF::DatePartTimestamp,
970 &i32_ty,
971 &i32_ty,
972 );
973 check(
974 func::DatePartTimestampTimestampTzF64,
975 BF::DatePartTimestampTz,
976 &i32_ty,
977 &i32_ty,
978 );
979
980 check(func::ExtractDateUnits, BF::ExtractDate, &i32_ty, &i32_ty);
981 check(
982 func::DateTruncUnitsTimestamp,
983 BF::DateTruncTimestamp,
984 &i32_ty,
985 &i32_ty,
986 );
987 check(
988 func::DateTruncUnitsTimestampTz,
989 BF::DateTruncTimestampTz,
990 &i32_ty,
991 &i32_ty,
992 );
993 check(
994 func::DateTruncInterval,
995 BF::DateTruncInterval,
996 &i32_ty,
997 &i32_ty,
998 );
999
1000 check(func::ArrayLength, BF::ArrayLength, &i32_ty, &i32_ty);
1001 check(func::ArrayLower, BF::ArrayLower, &i32_ty, &i32_ty);
1002 check(func::ArrayRemove, BF::ArrayRemove, &i32_ty, &i32_ty);
1003 check(func::ArrayUpper, BF::ArrayUpper, &i32_ty, &i32_ty);
1004 check(func::ArrayContains, BF::ArrayContains, &i32_ty, &i32_ty);
1006 check(
1007 func::ArrayContainsArray,
1008 BF::ArrayContainsArray { rev: false },
1009 &i32_ty,
1010 &i32_ty,
1011 );
1012 check(
1013 func::ArrayContainsArrayRev,
1014 BF::ArrayContainsArray { rev: true },
1015 &i32_ty,
1016 &i32_ty,
1017 );
1018 check(
1019 func::ArrayArrayConcat,
1020 BF::ArrayArrayConcat,
1021 &i32_ty,
1022 &i32_ty,
1023 );
1024 check(func::ListListConcat, BF::ListListConcat, &i32_ty, &i32_ty);
1025 check(
1026 func::ListElementConcat,
1027 BF::ListElementConcat,
1028 &i32_ty,
1029 &i32_ty,
1030 );
1031 check(
1032 func::ElementListConcat,
1033 BF::ElementListConcat,
1034 &i32_ty,
1035 &i32_ty,
1036 );
1037 check(func::ListRemove, BF::ListRemove, &i32_ty, &i32_ty);
1038 check(func::DigestString, BF::DigestString, &i32_ty, &i32_ty);
1039 check(func::DigestBytes, BF::DigestBytes, &i32_ty, &i32_ty);
1040 check(func::MzRenderTypmod, BF::MzRenderTypmod, &i32_ty, &i32_ty);
1041 check(
1042 func::MzAclItemContainsPrivilege,
1043 BF::MzAclItemContainsPrivilege,
1044 &i32_ty,
1045 &i32_ty,
1046 );
1047 check(func::ParseIdent, BF::ParseIdent, &i32_ty, &i32_ty);
1048 check(func::StartsWith, BF::StartsWith, &i32_ty, &i32_ty);
1049 check(func::PrettySql, BF::PrettySql, &i32_ty, &i32_ty);
1050 }
1051}