1use std::cell::RefCell;
14use std::collections::BTreeMap;
15use std::fmt;
16use std::sync::LazyLock;
17
18use itertools::Itertools;
19use mz_expr::func;
20use mz_ore::collections::CollectionExt;
21use mz_ore::str::StrExt;
22use mz_pgrepr::oid;
23use mz_repr::role_id::RoleId;
24use mz_repr::{ColumnName, Datum, SqlRelationType, SqlScalarBaseType, SqlScalarType};
25
26use crate::ast::{SelectStatement, Statement};
27use crate::catalog::{CatalogType, TypeCategory, TypeReference};
28use crate::names::{self, ResolvedItemName};
29use crate::plan::error::PlanError;
30use crate::plan::hir::{
31 AggregateFunc, BinaryFunc, CoercibleScalarExpr, CoercibleScalarType, ColumnOrder,
32 HirRelationExpr, HirScalarExpr, ScalarWindowFunc, TableFunc, UnaryFunc, UnmaterializableFunc,
33 ValueWindowFunc, VariadicFunc,
34};
35use crate::plan::query::{self, ExprContext, QueryContext};
36use crate::plan::scope::Scope;
37use crate::plan::side_effecting_func::PG_CATALOG_SEF_BUILTINS;
38use crate::plan::transform_ast;
39use crate::plan::typeconv::{self, CastContext};
40use crate::session::vars::{self, ENABLE_TIME_AT_TIME_ZONE};
41
42#[derive(Clone, Copy, Debug)]
44pub enum FuncSpec<'a> {
45 Func(&'a ResolvedItemName),
47 Op(&'a str),
49}
50
51impl<'a> fmt::Display for FuncSpec<'a> {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 match self {
54 FuncSpec::Func(n) => n.fmt(f),
55 FuncSpec::Op(o) => o.fmt(f),
56 }
57 }
58}
59
60impl TypeCategory {
61 pub fn from_type(typ: &SqlScalarType) -> Self {
73 match typ {
75 SqlScalarType::Array(..) | SqlScalarType::Int2Vector => Self::Array,
76 SqlScalarType::Bool => Self::Boolean,
77 SqlScalarType::AclItem
78 | SqlScalarType::Bytes
79 | SqlScalarType::Jsonb
80 | SqlScalarType::Uuid
81 | SqlScalarType::MzAclItem => Self::UserDefined,
82 SqlScalarType::Date
83 | SqlScalarType::Time
84 | SqlScalarType::Timestamp { .. }
85 | SqlScalarType::TimestampTz { .. } => Self::DateTime,
86 SqlScalarType::Float32
87 | SqlScalarType::Float64
88 | SqlScalarType::Int16
89 | SqlScalarType::Int32
90 | SqlScalarType::Int64
91 | SqlScalarType::UInt16
92 | SqlScalarType::UInt32
93 | SqlScalarType::UInt64
94 | SqlScalarType::Oid
95 | SqlScalarType::RegClass
96 | SqlScalarType::RegProc
97 | SqlScalarType::RegType
98 | SqlScalarType::Numeric { .. } => Self::Numeric,
99 SqlScalarType::Interval => Self::Timespan,
100 SqlScalarType::List { .. } => Self::List,
101 SqlScalarType::PgLegacyChar
102 | SqlScalarType::PgLegacyName
103 | SqlScalarType::String
104 | SqlScalarType::Char { .. }
105 | SqlScalarType::VarChar { .. } => Self::String,
106 SqlScalarType::Record { custom_id, .. } => {
107 if custom_id.is_some() {
108 Self::Composite
109 } else {
110 Self::Pseudo
111 }
112 }
113 SqlScalarType::Map { .. } => Self::Pseudo,
114 SqlScalarType::MzTimestamp => Self::Numeric,
115 SqlScalarType::Range { .. } => Self::Range,
116 }
117 }
118
119 pub fn from_param(param: &ParamType) -> Self {
120 match param {
121 ParamType::Any
122 | ParamType::AnyElement
123 | ParamType::ArrayAny
124 | ParamType::ArrayAnyCompatible
125 | ParamType::AnyCompatible
126 | ParamType::ListAny
127 | ParamType::ListAnyCompatible
128 | ParamType::ListElementAnyCompatible
129 | ParamType::Internal
130 | ParamType::NonVecAny
131 | ParamType::NonVecAnyCompatible
132 | ParamType::MapAny
133 | ParamType::MapAnyCompatible
134 | ParamType::RecordAny => Self::Pseudo,
135 ParamType::RangeAnyCompatible | ParamType::RangeAny => Self::Range,
136 ParamType::Plain(t) => Self::from_type(t),
137 }
138 }
139
140 pub fn from_catalog_type<T>(catalog_type: &CatalogType<T>) -> Self
144 where
145 T: TypeReference,
146 {
147 match catalog_type {
149 CatalogType::Array { .. } | CatalogType::Int2Vector => Self::Array,
150 CatalogType::Bool => Self::Boolean,
151 CatalogType::AclItem
152 | CatalogType::Bytes
153 | CatalogType::Jsonb
154 | CatalogType::Uuid
155 | CatalogType::MzAclItem => Self::UserDefined,
156 CatalogType::Date
157 | CatalogType::Time
158 | CatalogType::Timestamp
159 | CatalogType::TimestampTz => Self::DateTime,
160 CatalogType::Float32
161 | CatalogType::Float64
162 | CatalogType::Int16
163 | CatalogType::Int32
164 | CatalogType::Int64
165 | CatalogType::UInt16
166 | CatalogType::UInt32
167 | CatalogType::UInt64
168 | CatalogType::Oid
169 | CatalogType::RegClass
170 | CatalogType::RegProc
171 | CatalogType::RegType
172 | CatalogType::Numeric { .. } => Self::Numeric,
173 CatalogType::Interval => Self::Timespan,
174 CatalogType::List { .. } => Self::List,
175 CatalogType::PgLegacyChar
176 | CatalogType::PgLegacyName
177 | CatalogType::String
178 | CatalogType::Char { .. }
179 | CatalogType::VarChar { .. } => Self::String,
180 CatalogType::Record { .. } => TypeCategory::Composite,
181 CatalogType::Map { .. } | CatalogType::Pseudo => Self::Pseudo,
182 CatalogType::MzTimestamp => Self::String,
183 CatalogType::Range { .. } => Self::Range,
184 }
185 }
186
187 pub fn preferred_type(&self) -> Option<SqlScalarType> {
195 match self {
196 Self::Array
197 | Self::BitString
198 | Self::Composite
199 | Self::Enum
200 | Self::Geometric
201 | Self::List
202 | Self::NetworkAddress
203 | Self::Pseudo
204 | Self::Range
205 | Self::Unknown
206 | Self::UserDefined => None,
207 Self::Boolean => Some(SqlScalarType::Bool),
208 Self::DateTime => Some(SqlScalarType::TimestampTz { precision: None }),
209 Self::Numeric => Some(SqlScalarType::Float64),
210 Self::String => Some(SqlScalarType::String),
211 Self::Timespan => Some(SqlScalarType::Interval),
212 }
213 }
214}
215
216pub struct Operation<R>(
219 pub Box<
220 dyn Fn(
221 &ExprContext,
222 Vec<CoercibleScalarExpr>,
223 &ParamList,
224 Vec<ColumnOrder>,
225 ) -> Result<R, PlanError>
226 + Send
227 + Sync,
228 >,
229);
230
231impl<R> fmt::Debug for Operation<R> {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 f.debug_struct("Operation").finish()
234 }
235}
236
237impl Operation<HirScalarExpr> {
238 fn identity() -> Operation<HirScalarExpr> {
240 Operation::unary(|_ecx, e| Ok(e))
241 }
242}
243
244impl<R> Operation<R> {
245 fn new<F>(f: F) -> Operation<R>
246 where
247 F: Fn(
248 &ExprContext,
249 Vec<CoercibleScalarExpr>,
250 &ParamList,
251 Vec<ColumnOrder>,
252 ) -> Result<R, PlanError>
253 + Send
254 + Sync
255 + 'static,
256 {
257 Operation(Box::new(f))
258 }
259
260 fn nullary<F>(f: F) -> Operation<R>
262 where
263 F: Fn(&ExprContext) -> Result<R, PlanError> + Send + Sync + 'static,
264 {
265 Self::variadic(move |ecx, exprs| {
266 assert!(exprs.is_empty());
267 f(ecx)
268 })
269 }
270
271 fn unary<F>(f: F) -> Operation<R>
273 where
274 F: Fn(&ExprContext, HirScalarExpr) -> Result<R, PlanError> + Send + Sync + 'static,
275 {
276 Self::variadic(move |ecx, exprs| f(ecx, exprs.into_element()))
277 }
278
279 fn unary_ordered<F>(f: F) -> Operation<R>
281 where
282 F: Fn(&ExprContext, HirScalarExpr, Vec<ColumnOrder>) -> Result<R, PlanError>
283 + Send
284 + Sync
285 + 'static,
286 {
287 Self::new(move |ecx, cexprs, params, order_by| {
288 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
289 f(ecx, exprs.into_element(), order_by)
290 })
291 }
292
293 fn binary<F>(f: F) -> Operation<R>
295 where
296 F: Fn(&ExprContext, HirScalarExpr, HirScalarExpr) -> Result<R, PlanError>
297 + Send
298 + Sync
299 + 'static,
300 {
301 Self::variadic(move |ecx, exprs| {
302 assert_eq!(exprs.len(), 2);
303 let mut exprs = exprs.into_iter();
304 let left = exprs.next().unwrap();
305 let right = exprs.next().unwrap();
306 f(ecx, left, right)
307 })
308 }
309
310 fn binary_ordered<F>(f: F) -> Operation<R>
315 where
316 F: Fn(&ExprContext, HirScalarExpr, HirScalarExpr, Vec<ColumnOrder>) -> Result<R, PlanError>
317 + Send
318 + Sync
319 + 'static,
320 {
321 Self::new(move |ecx, cexprs, params, order_by| {
322 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
323 assert_eq!(exprs.len(), 2);
324 let mut exprs = exprs.into_iter();
325 let left = exprs.next().unwrap();
326 let right = exprs.next().unwrap();
327 f(ecx, left, right, order_by)
328 })
329 }
330
331 fn variadic<F>(f: F) -> Operation<R>
333 where
334 F: Fn(&ExprContext, Vec<HirScalarExpr>) -> Result<R, PlanError> + Send + Sync + 'static,
335 {
336 Self::new(move |ecx, cexprs, params, _order_by| {
337 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
338 f(ecx, exprs)
339 })
340 }
341}
342
343pub fn sql_impl(
346 expr: &str,
347) -> impl Fn(&QueryContext, Vec<SqlScalarType>) -> Result<HirScalarExpr, PlanError> + use<> {
348 let expr = mz_sql_parser::parser::parse_expr(expr).unwrap_or_else(|e| {
349 panic!(
350 "static function definition failed to parse {}: {}",
351 expr.quoted(),
352 e,
353 )
354 });
355 move |qcx, types| {
356 let mut scx = qcx.scx.clone();
359 scx.param_types = RefCell::new(
360 types
361 .into_iter()
362 .enumerate()
363 .map(|(i, ty)| (i + 1, ty))
364 .collect(),
365 );
366 let qcx = QueryContext::root(&scx, qcx.lifetime);
367
368 let (mut expr, _) = names::resolve(qcx.scx.catalog, expr.clone())?;
369 transform_ast::transform(&scx, &mut expr)?;
371
372 let ecx = ExprContext {
373 qcx: &qcx,
374 name: "static function definition",
375 scope: &Scope::empty(),
376 relation_type: &SqlRelationType::empty(),
377 allow_aggregates: false,
378 allow_subqueries: true,
379 allow_parameters: true,
380 allow_windows: false,
381 };
382
383 query::plan_expr(&ecx, &expr)?.type_as_any(&ecx)
385 }
386}
387
388fn sql_impl_func(expr: &str) -> Operation<HirScalarExpr> {
402 let invoke = sql_impl(expr);
403 Operation::variadic(move |ecx, args| {
404 let types = args.iter().map(|arg| ecx.scalar_type(arg)).collect();
405 let mut out = invoke(ecx.qcx, types)?;
406 out.splice_parameters(&args, 0);
407 Ok(out)
408 })
409}
410
411fn sql_impl_table_func_inner(
424 sql: &'static str,
425 feature_flag: Option<&'static vars::FeatureFlag>,
426) -> Operation<TableFuncPlan> {
427 let query = match mz_sql_parser::parser::parse_statements(sql)
428 .expect("static function definition failed to parse")
429 .expect_element(|| "static function definition must have exactly one statement")
430 .ast
431 {
432 Statement::Select(SelectStatement { query, as_of: None }) => query,
433 _ => panic!("static function definition expected SELECT statement"),
434 };
435 let invoke = move |qcx: &QueryContext, types: Vec<SqlScalarType>| {
436 let mut scx = qcx.scx.clone();
439 scx.param_types = RefCell::new(
440 types
441 .into_iter()
442 .enumerate()
443 .map(|(i, ty)| (i + 1, ty))
444 .collect(),
445 );
446 let mut qcx = QueryContext::root(&scx, qcx.lifetime);
447
448 let query = query.clone();
449 let (mut query, _) = names::resolve(qcx.scx.catalog, query)?;
450 transform_ast::transform(&scx, &mut query)?;
451
452 query::plan_nested_query(&mut qcx, &query)
453 };
454
455 Operation::variadic(move |ecx, args| {
456 if let Some(feature_flag) = feature_flag {
457 ecx.require_feature_flag(feature_flag)?;
458 }
459 let types = args.iter().map(|arg| ecx.scalar_type(arg)).collect();
460 let (mut expr, scope) = invoke(ecx.qcx, types)?;
461 expr.splice_parameters(&args, 0);
462 Ok(TableFuncPlan {
463 imp: TableFuncImpl::Expr(expr),
464 column_names: scope.column_names().cloned().collect(),
465 })
466 })
467}
468
469fn sql_impl_table_func(sql: &'static str) -> Operation<TableFuncPlan> {
474 sql_impl_table_func_inner(sql, None)
475}
476
477fn experimental_sql_impl_table_func(
478 feature: &'static vars::FeatureFlag,
479 sql: &'static str,
480) -> Operation<TableFuncPlan> {
481 sql_impl_table_func_inner(sql, Some(feature))
482}
483
484pub struct FuncImpl<R> {
486 pub oid: u32,
487 pub params: ParamList,
488 pub return_type: ReturnType,
489 pub op: Operation<R>,
490}
491
492#[derive(Debug)]
494pub struct FuncImplCatalogDetails {
495 pub oid: u32,
496 pub arg_typs: Vec<&'static str>,
497 pub variadic_typ: Option<&'static str>,
498 pub return_typ: Option<&'static str>,
499 pub return_is_set: bool,
500}
501
502impl<R> FuncImpl<R> {
503 pub fn details(&self) -> FuncImplCatalogDetails {
504 FuncImplCatalogDetails {
505 oid: self.oid,
506 arg_typs: self.params.arg_names(),
507 variadic_typ: self.params.variadic_name(),
508 return_typ: self.return_type.typ.as_ref().map(|t| t.name()),
509 return_is_set: self.return_type.is_set_of,
510 }
511 }
512}
513
514impl<R> fmt::Debug for FuncImpl<R> {
515 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
516 f.debug_struct("FuncImpl")
517 .field("oid", &self.oid)
518 .field("params", &self.params)
519 .field("ret", &self.return_type)
520 .field("op", &"<omitted>")
521 .finish()
522 }
523}
524
525impl From<UnmaterializableFunc> for Operation<HirScalarExpr> {
526 fn from(n: UnmaterializableFunc) -> Operation<HirScalarExpr> {
527 Operation::nullary(move |_ecx| Ok(HirScalarExpr::call_unmaterializable(n.clone())))
528 }
529}
530
531impl From<UnaryFunc> for Operation<HirScalarExpr> {
532 fn from(u: UnaryFunc) -> Operation<HirScalarExpr> {
533 Operation::unary(move |_ecx, e| Ok(e.call_unary(u.clone())))
534 }
535}
536
537impl From<BinaryFunc> for Operation<HirScalarExpr> {
538 fn from(b: BinaryFunc) -> Operation<HirScalarExpr> {
539 Operation::binary(move |_ecx, left, right| Ok(left.call_binary(right, b.clone())))
540 }
541}
542
543impl From<VariadicFunc> for Operation<HirScalarExpr> {
544 fn from(v: VariadicFunc) -> Operation<HirScalarExpr> {
545 Operation::variadic(move |_ecx, exprs| Ok(HirScalarExpr::call_variadic(v.clone(), exprs)))
546 }
547}
548
549impl From<AggregateFunc> for Operation<(HirScalarExpr, AggregateFunc)> {
550 fn from(a: AggregateFunc) -> Operation<(HirScalarExpr, AggregateFunc)> {
551 Operation::unary(move |_ecx, e| Ok((e, a.clone())))
552 }
553}
554
555impl From<ScalarWindowFunc> for Operation<ScalarWindowFunc> {
556 fn from(a: ScalarWindowFunc) -> Operation<ScalarWindowFunc> {
557 Operation::nullary(move |_ecx| Ok(a.clone()))
558 }
559}
560
561impl From<ValueWindowFunc> for Operation<(HirScalarExpr, ValueWindowFunc)> {
562 fn from(a: ValueWindowFunc) -> Operation<(HirScalarExpr, ValueWindowFunc)> {
563 Operation::unary(move |_ecx, e| Ok((e, a.clone())))
564 }
565}
566
567#[derive(Debug, Clone, Eq, PartialEq, Hash)]
568pub enum ParamList {
572 Exact(Vec<ParamType>),
573 Variadic {
574 leading: Vec<ParamType>,
575 trailing: ParamType,
576 },
577}
578
579impl ParamList {
580 fn matches_argtypes(&self, ecx: &ExprContext, typs: &[CoercibleScalarType]) -> bool {
582 if !self.validate_arg_len(typs.len()) {
583 return false;
584 }
585
586 for (i, typ) in typs.iter().enumerate() {
587 let param = &self[i];
588 if let CoercibleScalarType::Coerced(typ) = typ {
589 if !param.accepts_type(ecx, typ) {
596 return false;
597 }
598 }
599 }
600
601 PolymorphicSolution::new(ecx, typs, self).is_some()
604 }
605
606 fn validate_arg_len(&self, input_len: usize) -> bool {
608 match self {
609 Self::Exact(p) => p.len() == input_len,
610 Self::Variadic { leading, .. } => input_len > leading.len(),
611 }
612 }
613
614 fn exact_match(&self, types: &[&SqlScalarType]) -> bool {
617 types.iter().enumerate().all(|(i, t)| self[i] == **t)
618 }
619
620 fn arg_names(&self) -> Vec<&'static str> {
622 match self {
623 ParamList::Exact(p) => p.iter().map(|p| p.name()).collect::<Vec<_>>(),
624 ParamList::Variadic { leading, trailing } => leading
625 .iter()
626 .chain([trailing])
627 .map(|p| p.name())
628 .collect::<Vec<_>>(),
629 }
630 }
631
632 fn variadic_name(&self) -> Option<&'static str> {
634 match self {
635 ParamList::Exact(_) => None,
636 ParamList::Variadic { trailing, .. } => Some(trailing.name()),
637 }
638 }
639}
640
641impl std::ops::Index<usize> for ParamList {
642 type Output = ParamType;
643
644 fn index(&self, i: usize) -> &Self::Output {
645 match self {
646 Self::Exact(p) => &p[i],
647 Self::Variadic { leading, trailing } => leading.get(i).unwrap_or(trailing),
648 }
649 }
650}
651
652impl From<Vec<ParamType>> for ParamList {
654 fn from(p: Vec<ParamType>) -> ParamList {
655 ParamList::Exact(p)
656 }
657}
658
659#[derive(Debug, Clone, Eq, PartialEq, Hash)]
660pub enum ParamType {
673 Any,
676 AnyCompatible,
679 AnyElement,
682 ArrayAny,
685 ArrayAnyCompatible,
688 ListAny,
691 ListAnyCompatible,
694 ListElementAnyCompatible,
699 MapAny,
702 MapAnyCompatible,
705 NonVecAny,
709 NonVecAnyCompatible,
713 Plain(SqlScalarType),
716 RecordAny,
719 RangeAny,
722 RangeAnyCompatible,
729 Internal,
732}
733
734impl ParamType {
735 fn accepts_type(&self, ecx: &ExprContext, t: &SqlScalarType) -> bool {
737 use ParamType::*;
738 use SqlScalarType::*;
739
740 match self {
741 Any | AnyElement | AnyCompatible | ListElementAnyCompatible => true,
742 ArrayAny | ArrayAnyCompatible => matches!(t, Array(..) | Int2Vector),
743 ListAny | ListAnyCompatible => matches!(t, List { .. }),
744 MapAny | MapAnyCompatible => matches!(t, Map { .. }),
745 RangeAny | RangeAnyCompatible => matches!(t, Range { .. }),
746 NonVecAny | NonVecAnyCompatible => !t.is_vec(),
747 Internal => false,
748 Plain(to) => typeconv::can_cast(ecx, CastContext::Implicit, t, to),
749 RecordAny => matches!(t, Record { .. }),
750 }
751 }
752
753 fn is_preferred_by(&self, t: &SqlScalarType) -> bool {
756 if let Some(pt) = TypeCategory::from_type(t).preferred_type() {
757 *self == pt
758 } else {
759 false
760 }
761 }
762
763 fn is_near_match(&self, t: &SqlScalarType) -> bool {
767 match (self, t.near_match()) {
768 (ParamType::Plain(t), Some(near_match)) => t.structural_eq(near_match),
769 _ => false,
770 }
771 }
772
773 fn prefers_self(&self) -> bool {
775 if let Some(pt) = TypeCategory::from_param(self).preferred_type() {
776 *self == pt
777 } else {
778 false
779 }
780 }
781
782 fn is_polymorphic(&self) -> bool {
783 use ParamType::*;
784 match self {
785 AnyElement
786 | ArrayAny
787 | ArrayAnyCompatible
788 | AnyCompatible
789 | ListAny
790 | ListAnyCompatible
791 | ListElementAnyCompatible
792 | MapAny
793 | MapAnyCompatible
794 | NonVecAny
795 | NonVecAnyCompatible
796 | RecordAny
800 | RangeAny
801 | RangeAnyCompatible => true,
802 Any | Internal | Plain(_) => false,
803 }
804 }
805
806 fn name(&self) -> &'static str {
807 match self {
808 ParamType::Plain(t) => {
809 assert!(
810 !t.is_custom_type(),
811 "custom types cannot currently be used as \
812 parameters; use a polymorphic parameter that \
813 accepts the custom type instead"
814 );
815 let t: mz_pgrepr::Type = t.into();
816 t.catalog_name()
817 }
818 ParamType::Any => "any",
819 ParamType::AnyCompatible => "anycompatible",
820 ParamType::AnyElement => "anyelement",
821 ParamType::ArrayAny => "anyarray",
822 ParamType::ArrayAnyCompatible => "anycompatiblearray",
823 ParamType::Internal => "internal",
824 ParamType::ListAny => "list",
825 ParamType::ListAnyCompatible => "anycompatiblelist",
826 ParamType::ListElementAnyCompatible => "anycompatible",
829 ParamType::MapAny => "map",
830 ParamType::MapAnyCompatible => "anycompatiblemap",
831 ParamType::NonVecAny => "anynonarray",
832 ParamType::NonVecAnyCompatible => "anycompatiblenonarray",
833 ParamType::RecordAny => "record",
834 ParamType::RangeAny => "anyrange",
835 ParamType::RangeAnyCompatible => "anycompatiblerange",
836 }
837 }
838}
839
840impl PartialEq<SqlScalarType> for ParamType {
841 fn eq(&self, other: &SqlScalarType) -> bool {
842 match self {
843 ParamType::Plain(s) => s.base_eq(other),
844 _ => false,
846 }
847 }
848}
849
850impl PartialEq<ParamType> for SqlScalarType {
851 fn eq(&self, other: &ParamType) -> bool {
852 other == self
853 }
854}
855
856impl From<SqlScalarType> for ParamType {
857 fn from(s: SqlScalarType) -> ParamType {
858 ParamType::Plain(s)
859 }
860}
861
862impl From<SqlScalarBaseType> for ParamType {
863 fn from(s: SqlScalarBaseType) -> ParamType {
864 use SqlScalarBaseType::*;
865 let s = match s {
866 Array | List | Map | Record | Range => {
867 panic!("use polymorphic parameters rather than {:?}", s);
868 }
869 AclItem => SqlScalarType::AclItem,
870 Bool => SqlScalarType::Bool,
871 Int16 => SqlScalarType::Int16,
872 Int32 => SqlScalarType::Int32,
873 Int64 => SqlScalarType::Int64,
874 UInt16 => SqlScalarType::UInt16,
875 UInt32 => SqlScalarType::UInt32,
876 UInt64 => SqlScalarType::UInt64,
877 Float32 => SqlScalarType::Float32,
878 Float64 => SqlScalarType::Float64,
879 Numeric => SqlScalarType::Numeric { max_scale: None },
880 Date => SqlScalarType::Date,
881 Time => SqlScalarType::Time,
882 Timestamp => SqlScalarType::Timestamp { precision: None },
883 TimestampTz => SqlScalarType::TimestampTz { precision: None },
884 Interval => SqlScalarType::Interval,
885 Bytes => SqlScalarType::Bytes,
886 String => SqlScalarType::String,
887 Char => SqlScalarType::Char { length: None },
888 VarChar => SqlScalarType::VarChar { max_length: None },
889 PgLegacyChar => SqlScalarType::PgLegacyChar,
890 PgLegacyName => SqlScalarType::PgLegacyName,
891 Jsonb => SqlScalarType::Jsonb,
892 Uuid => SqlScalarType::Uuid,
893 Oid => SqlScalarType::Oid,
894 RegClass => SqlScalarType::RegClass,
895 RegProc => SqlScalarType::RegProc,
896 RegType => SqlScalarType::RegType,
897 Int2Vector => SqlScalarType::Int2Vector,
898 MzTimestamp => SqlScalarType::MzTimestamp,
899 MzAclItem => SqlScalarType::MzAclItem,
900 };
901 ParamType::Plain(s)
902 }
903}
904
905#[derive(Debug, Clone, Eq, PartialEq, Hash)]
906pub struct ReturnType {
907 pub typ: Option<ParamType>,
908 pub is_set_of: bool,
909}
910
911impl ReturnType {
912 fn scalar(typ: ParamType) -> ReturnType {
914 ReturnType {
915 typ: Some(typ),
916 is_set_of: false,
917 }
918 }
919
920 fn set_of(typ: ParamType) -> ReturnType {
923 ReturnType {
924 typ: Some(typ),
925 is_set_of: true,
926 }
927 }
928
929 fn none(is_set_of: bool) -> ReturnType {
931 ReturnType {
932 typ: None,
933 is_set_of,
934 }
935 }
936}
937
938impl From<ParamType> for ReturnType {
939 fn from(typ: ParamType) -> ReturnType {
940 ReturnType::scalar(typ)
941 }
942}
943
944impl From<SqlScalarBaseType> for ReturnType {
945 fn from(s: SqlScalarBaseType) -> ReturnType {
946 ParamType::from(s).into()
947 }
948}
949
950impl From<SqlScalarType> for ReturnType {
951 fn from(s: SqlScalarType) -> ReturnType {
952 ParamType::Plain(s).into()
953 }
954}
955
956#[derive(Clone, Debug)]
957pub struct Candidate<'a, R> {
959 fimpl: &'a FuncImpl<R>,
961 exact_matches: usize,
962 preferred_types: usize,
963 near_matches: usize,
964}
965
966pub fn select_impl<R>(
980 ecx: &ExprContext,
981 spec: FuncSpec,
982 impls: &[FuncImpl<R>],
983 args: Vec<CoercibleScalarExpr>,
984 order_by: Vec<ColumnOrder>,
985) -> Result<R, PlanError>
986where
987 R: fmt::Debug,
988{
989 let name = spec.to_string();
990 let ecx = &ecx.with_name(&name);
991 let mut types: Vec<_> = args.iter().map(|e| ecx.scalar_type(e)).collect();
992
993 for ty in &mut types {
999 ty.force_coerced_if_record();
1000 }
1001
1002 let impls: Vec<_> = impls
1007 .iter()
1008 .filter(|i| i.params.matches_argtypes(ecx, &types))
1009 .collect();
1010
1011 let f = find_match(ecx, &types, impls).map_err(|candidates| {
1012 let arg_types: Vec<_> = types
1013 .into_iter()
1014 .map(|ty| match ty {
1015 CoercibleScalarType::Coerced(ty) => ecx.humanize_scalar_type(&ty, false),
1017 CoercibleScalarType::Record(_) => "record".to_string(),
1018 CoercibleScalarType::Uncoerced => "unknown".to_string(),
1019 })
1020 .collect();
1021
1022 if candidates == 0 {
1023 match spec {
1024 FuncSpec::Func(name) => PlanError::UnknownFunction {
1025 name: ecx
1026 .qcx
1027 .scx
1028 .humanize_resolved_name(name)
1029 .expect("resolved to object")
1030 .to_string(),
1031 arg_types,
1032 },
1033 FuncSpec::Op(name) => PlanError::UnknownOperator {
1034 name: name.to_string(),
1035 arg_types,
1036 },
1037 }
1038 } else {
1039 match spec {
1040 FuncSpec::Func(name) => PlanError::IndistinctFunction {
1041 name: ecx
1042 .qcx
1043 .scx
1044 .humanize_resolved_name(name)
1045 .expect("resolved to object")
1046 .to_string(),
1047 arg_types,
1048 },
1049 FuncSpec::Op(name) => PlanError::IndistinctOperator {
1050 name: name.to_string(),
1051 arg_types,
1052 },
1053 }
1054 }
1055 })?;
1056
1057 (f.op.0)(ecx, args, &f.params, order_by)
1058}
1059
1060fn find_match<'a, R: std::fmt::Debug>(
1066 ecx: &ExprContext,
1067 types: &[CoercibleScalarType],
1068 impls: Vec<&'a FuncImpl<R>>,
1069) -> Result<&'a FuncImpl<R>, usize> {
1070 let all_types_known = types.iter().all(|t| t.is_coerced());
1071
1072 if all_types_known {
1074 let known_types: Vec<_> = types.iter().filter_map(|t| t.as_coerced()).collect();
1075 let matching_impls: Vec<&FuncImpl<_>> = impls
1076 .iter()
1077 .filter(|i| i.params.exact_match(&known_types))
1078 .cloned()
1079 .collect();
1080
1081 if matching_impls.len() == 1 {
1082 return Ok(matching_impls[0]);
1083 }
1084 }
1085
1086 let mut candidates: Vec<Candidate<_>> = Vec::new();
1090 macro_rules! maybe_get_last_candidate {
1091 () => {
1092 if candidates.len() == 1 {
1093 return Ok(&candidates[0].fimpl);
1094 }
1095 };
1096 }
1097 let mut max_exact_matches = 0;
1098
1099 for fimpl in impls {
1100 let mut exact_matches = 0;
1101 let mut preferred_types = 0;
1102 let mut near_matches = 0;
1103
1104 for (i, arg_type) in types.iter().enumerate() {
1105 let param_type = &fimpl.params[i];
1106
1107 match arg_type {
1108 CoercibleScalarType::Coerced(arg_type) => {
1109 if param_type == arg_type {
1110 exact_matches += 1;
1111 }
1112 if param_type.is_preferred_by(arg_type) {
1113 preferred_types += 1;
1114 }
1115 if param_type.is_near_match(arg_type) {
1116 near_matches += 1;
1117 }
1118 }
1119 CoercibleScalarType::Record(_) | CoercibleScalarType::Uncoerced => {
1120 if param_type.prefers_self() {
1121 preferred_types += 1;
1122 }
1123 }
1124 }
1125 }
1126
1127 max_exact_matches = std::cmp::max(max_exact_matches, exact_matches);
1132 candidates.push(Candidate {
1133 fimpl,
1134 exact_matches,
1135 preferred_types,
1136 near_matches,
1137 });
1138 }
1139
1140 if candidates.is_empty() {
1141 return Err(0);
1142 }
1143
1144 maybe_get_last_candidate!();
1145
1146 candidates.retain(|c| c.exact_matches >= max_exact_matches);
1149
1150 maybe_get_last_candidate!();
1151
1152 let mut max_near_matches = 0;
1157 for c in &candidates {
1158 max_near_matches = std::cmp::max(max_near_matches, c.near_matches);
1159 }
1160 candidates.retain(|c| c.near_matches >= max_near_matches);
1161
1162 let mut max_preferred_types = 0;
1166 for c in &candidates {
1167 max_preferred_types = std::cmp::max(max_preferred_types, c.preferred_types);
1168 }
1169 candidates.retain(|c| c.preferred_types >= max_preferred_types);
1170
1171 maybe_get_last_candidate!();
1172
1173 if all_types_known {
1174 return Err(candidates.len());
1175 }
1176
1177 let mut found_known = false;
1178 let mut types_match = true;
1179 let mut common_type: Option<SqlScalarType> = None;
1180
1181 for (i, arg_type) in types.iter().enumerate() {
1182 let mut selected_category: Option<TypeCategory> = None;
1183 let mut categories_match = true;
1184
1185 match arg_type {
1186 CoercibleScalarType::Uncoerced | CoercibleScalarType::Record(_) => {
1190 for c in candidates.iter() {
1191 let this_category = TypeCategory::from_param(&c.fimpl.params[i]);
1192 if this_category == TypeCategory::String {
1197 selected_category = Some(TypeCategory::String);
1198 break;
1199 }
1200 match selected_category {
1201 Some(ref mut selected_category) => {
1202 categories_match =
1205 selected_category == &this_category && categories_match;
1206 }
1207 None => selected_category = Some(this_category.clone()),
1208 }
1209 }
1210
1211 if selected_category != Some(TypeCategory::String) && !categories_match {
1215 break;
1216 }
1217
1218 let selected_category = selected_category.unwrap();
1223
1224 let preferred_type = selected_category.preferred_type();
1225 let mut found_preferred_type_candidate = false;
1226 candidates.retain(|c| {
1227 if let Some(typ) = &preferred_type {
1228 found_preferred_type_candidate = c.fimpl.params[i].accepts_type(ecx, typ)
1229 || found_preferred_type_candidate;
1230 }
1231 selected_category == TypeCategory::from_param(&c.fimpl.params[i])
1232 });
1233
1234 if found_preferred_type_candidate {
1235 let preferred_type = preferred_type.unwrap();
1236 candidates.retain(|c| c.fimpl.params[i].accepts_type(ecx, &preferred_type));
1237 }
1238 }
1239 CoercibleScalarType::Coerced(typ) => {
1240 found_known = true;
1241 match common_type {
1244 Some(ref common_type) => types_match = common_type == typ && types_match,
1245 None => common_type = Some(typ.clone()),
1246 }
1247 }
1248 }
1249 }
1250
1251 maybe_get_last_candidate!();
1252
1253 if found_known && types_match {
1259 let common_type = common_type.unwrap();
1260 let common_typed: Vec<_> = types
1261 .iter()
1262 .map(|t| match t {
1263 CoercibleScalarType::Coerced(t) => CoercibleScalarType::Coerced(t.clone()),
1264 CoercibleScalarType::Uncoerced | CoercibleScalarType::Record(_) => {
1265 CoercibleScalarType::Coerced(common_type.clone())
1266 }
1267 })
1268 .collect();
1269
1270 candidates.retain(|c| c.fimpl.params.matches_argtypes(ecx, &common_typed));
1271
1272 maybe_get_last_candidate!();
1273 }
1274
1275 Err(candidates.len())
1276}
1277
1278#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1279enum PolymorphicCompatClass {
1280 Any,
1284 BestCommonAny,
1300 BestCommonList,
1309 BestCommonMap,
1314 StructuralEq,
1324}
1325
1326impl TryFrom<&ParamType> for PolymorphicCompatClass {
1327 type Error = ();
1328 fn try_from(param: &ParamType) -> Result<PolymorphicCompatClass, Self::Error> {
1329 use ParamType::*;
1330
1331 Ok(match param {
1332 AnyElement | ArrayAny | ListAny | MapAny | NonVecAny | RangeAny => {
1333 PolymorphicCompatClass::Any
1334 }
1335 ArrayAnyCompatible | AnyCompatible | RangeAnyCompatible | NonVecAnyCompatible => {
1336 PolymorphicCompatClass::BestCommonAny
1337 }
1338 ListAnyCompatible | ListElementAnyCompatible => PolymorphicCompatClass::BestCommonList,
1339 MapAnyCompatible => PolymorphicCompatClass::BestCommonMap,
1340 RecordAny => PolymorphicCompatClass::StructuralEq,
1341 _ => return Err(()),
1342 })
1343 }
1344}
1345
1346impl PolymorphicCompatClass {
1347 fn compatible(&self, ecx: &ExprContext, from: &SqlScalarType, to: &SqlScalarType) -> bool {
1348 use PolymorphicCompatClass::*;
1349 match self {
1350 StructuralEq => from.structural_eq(to),
1351 Any => from.base_eq(to),
1352 _ => typeconv::can_cast(ecx, CastContext::Implicit, from, to),
1353 }
1354 }
1355}
1356
1357#[derive(Debug)]
1360pub(crate) struct PolymorphicSolution {
1361 compat: Option<PolymorphicCompatClass>,
1364 seen: Vec<CoercibleScalarType>,
1365 key: Option<SqlScalarType>,
1367}
1368
1369impl PolymorphicSolution {
1370 fn new(
1377 ecx: &ExprContext,
1378 args: &[CoercibleScalarType],
1379 params: &ParamList,
1380 ) -> Option<PolymorphicSolution> {
1381 let mut r = PolymorphicSolution {
1382 compat: None,
1383 seen: vec![],
1384 key: None,
1385 };
1386
1387 for (i, scalar_type) in args.iter().cloned().enumerate() {
1388 r.track_seen(¶ms[i], scalar_type);
1389 }
1390
1391 if !r.determine_key(ecx) { None } else { Some(r) }
1392 }
1393
1394 fn track_seen(&mut self, param: &ParamType, seen: CoercibleScalarType) {
1397 use ParamType::*;
1398
1399 self.seen.push(match param {
1400 AnyElement | AnyCompatible | ListAnyCompatible | MapAnyCompatible | NonVecAny
1402 | RecordAny => seen,
1403 MapAny => seen.map_coerced(|array| array.unwrap_map_value_type().clone()),
1404 ListAny => seen.map_coerced(|array| array.unwrap_list_element_type().clone()),
1405 ArrayAny | ArrayAnyCompatible => {
1406 seen.map_coerced(|array| array.unwrap_array_element_type().clone())
1407 }
1408 RangeAny | RangeAnyCompatible => {
1409 seen.map_coerced(|range| range.unwrap_range_element_type().clone())
1410 }
1411 ListElementAnyCompatible => seen.map_coerced(|el| SqlScalarType::List {
1412 custom_id: None,
1413 element_type: Box::new(el),
1414 }),
1415 o => {
1416 assert!(
1417 !o.is_polymorphic(),
1418 "polymorphic parameters must track types they \
1419 encounter to determine polymorphic solution"
1420 );
1421 return;
1422 }
1423 });
1424
1425 let compat_class = param
1426 .try_into()
1427 .expect("already returned for non-polymorphic params");
1428
1429 match &self.compat {
1430 None => self.compat = Some(compat_class),
1431 Some(c) => {
1432 assert_eq!(
1433 c, &compat_class,
1434 "do not know how to correlate polymorphic classes {:?} and {:?}",
1435 c, &compat_class,
1436 )
1437 }
1438 };
1439 }
1440
1441 fn determine_key(&mut self, ecx: &ExprContext) -> bool {
1445 self.key = if !self.seen.iter().any(|v| v.is_coerced()) {
1446 match &self.compat {
1447 None => None,
1449 Some(t) => match t {
1454 PolymorphicCompatClass::BestCommonAny => Some(SqlScalarType::String),
1455 PolymorphicCompatClass::BestCommonList => Some(SqlScalarType::List {
1456 custom_id: None,
1457 element_type: Box::new(SqlScalarType::String),
1458 }),
1459 PolymorphicCompatClass::BestCommonMap => Some(SqlScalarType::Map {
1460 value_type: Box::new(SqlScalarType::String),
1461 custom_id: None,
1462 }),
1463 PolymorphicCompatClass::StructuralEq | PolymorphicCompatClass::Any => None,
1465 },
1466 }
1467 } else {
1468 let compat = self.compat.as_ref().unwrap();
1471
1472 let r = match compat {
1473 PolymorphicCompatClass::Any => {
1474 let mut s = self
1475 .seen
1476 .iter()
1477 .filter_map(|f| f.as_coerced().cloned())
1478 .collect::<Vec<_>>();
1479 let (candiate, remaining) =
1480 s.split_first().expect("have at least one non-None element");
1481 if remaining.iter().all(|r| r.base_eq(candiate)) {
1482 s.remove(0)
1483 } else {
1484 return false;
1485 }
1486 }
1487 _ => match typeconv::guess_best_common_type(ecx, &self.seen) {
1488 Ok(r) => r,
1489 Err(_) => return false,
1490 },
1491 };
1492
1493 for t in self.seen.iter() {
1495 if let CoercibleScalarType::Coerced(t) = t {
1496 if !compat.compatible(ecx, t, &r) {
1497 return false;
1498 }
1499 }
1500 }
1501 Some(r)
1502 };
1503
1504 true
1505 }
1506
1507 fn target_for_param_type(&self, param: &ParamType) -> Option<SqlScalarType> {
1510 use ParamType::*;
1511 assert_eq!(
1512 self.compat,
1513 Some(
1514 param
1515 .try_into()
1516 .expect("target_for_param_type only supports polymorphic parameters")
1517 ),
1518 "cannot use polymorphic solution for different compatibility classes"
1519 );
1520
1521 assert!(
1522 !matches!(param, RecordAny),
1523 "RecordAny should not be cast to a target type"
1524 );
1525
1526 match param {
1527 AnyElement | AnyCompatible | ListAnyCompatible | MapAnyCompatible | NonVecAny => {
1528 self.key.clone()
1529 }
1530 ArrayAny | ArrayAnyCompatible => self
1531 .key
1532 .as_ref()
1533 .map(|key| SqlScalarType::Array(Box::new(key.clone()))),
1534 ListAny => self.key.as_ref().map(|key| SqlScalarType::List {
1535 element_type: Box::new(key.clone()),
1536 custom_id: None,
1537 }),
1538 MapAny => self.key.as_ref().map(|key| SqlScalarType::Map {
1539 value_type: Box::new(key.clone()),
1540 custom_id: None,
1541 }),
1542 RangeAny | RangeAnyCompatible => self.key.as_ref().map(|key| SqlScalarType::Range {
1543 element_type: Box::new(key.clone()),
1544 }),
1545 ListElementAnyCompatible => self
1546 .key
1547 .as_ref()
1548 .map(|key| key.unwrap_list_element_type().clone()),
1549 _ => unreachable!(
1550 "cannot use polymorphic solution to resolve target type for param {:?}",
1551 param,
1552 ),
1553 }
1554 }
1555}
1556
1557fn coerce_args_to_types(
1558 ecx: &ExprContext,
1559 args: Vec<CoercibleScalarExpr>,
1560 params: &ParamList,
1561) -> Result<Vec<HirScalarExpr>, PlanError> {
1562 use ParamType::*;
1563
1564 let mut scalar_types: Vec<_> = args.iter().map(|e| ecx.scalar_type(e)).collect();
1565
1566 for ty in &mut scalar_types {
1568 ty.force_coerced_if_record();
1569 }
1570
1571 let polymorphic_solution = PolymorphicSolution::new(ecx, &scalar_types, params)
1572 .expect("polymorphic solution previously determined to be valid");
1573
1574 let do_convert =
1575 |arg: CoercibleScalarExpr, ty: &SqlScalarType| arg.cast_to(ecx, CastContext::Implicit, ty);
1576
1577 let mut res_exprs = Vec::with_capacity(args.len());
1578 for (i, cexpr) in args.into_iter().enumerate() {
1579 let expr = match ¶ms[i] {
1580 Any => match cexpr {
1581 CoercibleScalarExpr::Parameter(n) => {
1582 sql_bail!("could not determine data type of parameter ${}", n)
1583 }
1584 _ => cexpr.type_as_any(ecx)?,
1585 },
1586 RecordAny => match cexpr {
1587 CoercibleScalarExpr::LiteralString(_) => {
1588 sql_bail!("input of anonymous composite types is not implemented");
1589 }
1590 _ => cexpr.type_as_any(ecx)?,
1594 },
1595 Plain(ty) => do_convert(cexpr, ty)?,
1596 Internal => return Err(PlanError::InternalFunctionCall),
1597 p => {
1598 let target = polymorphic_solution
1599 .target_for_param_type(p)
1600 .ok_or_else(|| {
1601 PlanError::UnsolvablePolymorphicFunctionInput
1610 })?;
1611 do_convert(cexpr, &target)?
1612 }
1613 };
1614 res_exprs.push(expr);
1615 }
1616
1617 Ok(res_exprs)
1618}
1619
1620macro_rules! params {
1622 ([$($p:expr),*], $v:ident...) => {
1623 ParamList::Variadic {
1624 leading: vec![$($p.into(),)*],
1625 trailing: $v.into(),
1626 }
1627 };
1628 ($v:ident...) => { ParamList::Variadic { leading: vec![], trailing: $v.into() } };
1629 ($($p:expr),*) => { ParamList::Exact(vec![$($p.into(),)*]) };
1630}
1631
1632macro_rules! impl_def {
1633 ($params:expr, $op:expr, $return_type:expr, $oid:expr) => {{
1643 FuncImpl {
1644 oid: $oid,
1645 params: $params.into(),
1646 op: $op.into(),
1647 return_type: $return_type.into(),
1648 }
1649 }};
1650}
1651
1652macro_rules! builtins {
1654 {
1655 $(
1656 $name:expr => $ty:ident {
1657 $($params:expr => $op:expr => $return_type:expr, $oid:expr;)+
1658 }
1659 ),+
1660 } => {{
1661
1662 let mut builtins = BTreeMap::new();
1663 $(
1664 let impls = vec![$(impl_def!($params, $op, $return_type, $oid)),+];
1665 let func = Func::$ty(impls);
1666 let expect_set_return = matches!(&func, Func::Table(_));
1667 for imp in func.func_impls() {
1668 assert_eq!(
1669 imp.return_is_set, expect_set_return,
1670 "wrong set return value for func with oid {}",
1671 imp.oid
1672 );
1673 }
1674 let old = builtins.insert($name, func);
1675 mz_ore::assert_none!(old, "duplicate entry in builtins list");
1676 )+
1677 builtins
1678 }};
1679}
1680
1681#[derive(Debug)]
1682pub struct TableFuncPlan {
1683 pub imp: TableFuncImpl,
1684 pub column_names: Vec<ColumnName>,
1685}
1686
1687#[derive(Debug)]
1720pub enum TableFuncImpl {
1721 CallTable {
1722 func: TableFunc,
1723 exprs: Vec<HirScalarExpr>,
1724 },
1725 Expr(HirRelationExpr),
1726}
1727
1728#[derive(Debug)]
1729pub enum Func {
1730 Scalar(Vec<FuncImpl<HirScalarExpr>>),
1731 Aggregate(Vec<FuncImpl<(HirScalarExpr, AggregateFunc)>>),
1732 Table(Vec<FuncImpl<TableFuncPlan>>),
1733 ScalarWindow(Vec<FuncImpl<ScalarWindowFunc>>),
1734 ValueWindow(Vec<FuncImpl<(HirScalarExpr, ValueWindowFunc)>>),
1735}
1736
1737impl Func {
1738 pub fn func_impls(&self) -> Vec<FuncImplCatalogDetails> {
1739 match self {
1740 Func::Scalar(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1741 Func::Aggregate(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1742 Func::Table(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1743 Func::ScalarWindow(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1744 Func::ValueWindow(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1745 }
1746 }
1747
1748 pub fn class(&self) -> &str {
1749 match self {
1750 Func::Scalar(..) => "scalar",
1751 Func::Aggregate(..) => "aggregate",
1752 Func::Table(..) => "table",
1753 Func::ScalarWindow(..) => "window",
1754 Func::ValueWindow(..) => "window",
1755 }
1756 }
1757}
1758
1759macro_rules! catalog_name_only {
1763 ($name:expr) => {
1764 panic!(
1765 "{} should be planned away before reaching function selection",
1766 $name
1767 )
1768 };
1769}
1770
1771macro_rules! privilege_fn {
1773 ( $fn_name:expr, $catalog_tbl:expr ) => {{
1774 let fn_name = $fn_name;
1775 let catalog_tbl = $catalog_tbl;
1776 let public_role = RoleId::Public;
1777 format!(
1778 "
1779 CASE
1780 -- We need to validate the privileges to return a proper error before anything
1781 -- else.
1782 WHEN NOT mz_internal.mz_validate_privileges($3)
1783 OR $1 IS NULL
1784 OR $2 IS NULL
1785 OR $3 IS NULL
1786 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
1787 OR $2 NOT IN (SELECT oid FROM {catalog_tbl})
1788 THEN NULL
1789 ELSE COALESCE(
1790 (
1791 SELECT
1792 bool_or(
1793 mz_internal.mz_acl_item_contains_privilege(privilege, $3)
1794 )
1795 AS {fn_name}
1796 FROM
1797 (
1798 SELECT
1799 unnest(privileges)
1800 FROM
1801 {catalog_tbl}
1802 WHERE
1803 {catalog_tbl}.oid = $2
1804 )
1805 AS user_privs (privilege)
1806 LEFT JOIN mz_catalog.mz_roles ON
1807 mz_internal.mz_aclitem_grantee(privilege) = mz_roles.id
1808 WHERE
1809 mz_internal.mz_aclitem_grantee(privilege) = '{public_role}'
1810 OR pg_has_role($1, mz_roles.oid, 'USAGE')
1811 ),
1812 false
1813 )
1814 END
1815 ",
1816 )
1817 }};
1818}
1819
1820pub static PG_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
1822 use ParamType::*;
1823 use SqlScalarBaseType::*;
1824 let mut builtins = builtins! {
1825 "abs" => Scalar {
1838 params!(Int16) => UnaryFunc::AbsInt16(func::AbsInt16) => Int16, 1398;
1839 params!(Int32) => UnaryFunc::AbsInt32(func::AbsInt32) => Int32, 1397;
1840 params!(Int64) => UnaryFunc::AbsInt64(func::AbsInt64) => Int64, 1396;
1841 params!(Numeric) => UnaryFunc::AbsNumeric(func::AbsNumeric) => Numeric, 1705;
1842 params!(Float32) => UnaryFunc::AbsFloat32(func::AbsFloat32) => Float32, 1394;
1843 params!(Float64) => UnaryFunc::AbsFloat64(func::AbsFloat64) => Float64, 1395;
1844 },
1845 "aclexplode" => Table {
1846 params!(SqlScalarType::Array(Box::new(
1847 SqlScalarType::AclItem,
1848 ))) => Operation::unary(move |_ecx, aclitems| {
1849 Ok(TableFuncPlan {
1850 imp: TableFuncImpl::CallTable {
1851 func: TableFunc::AclExplode,
1852 exprs: vec![aclitems],
1853 },
1854 column_names: vec![
1855 "grantor".into(), "grantee".into(),
1856 "privilege_type".into(), "is_grantable".into(),
1857 ],
1858 })
1859 }) => ReturnType::set_of(RecordAny), 1689;
1860 },
1861 "array_cat" => Scalar {
1862 params!(ArrayAnyCompatible, ArrayAnyCompatible) => Operation::binary(|_ecx, lhs, rhs| {
1863 Ok(lhs.call_binary(rhs, func::ArrayArrayConcat))
1864 }) => ArrayAnyCompatible, 383;
1865 },
1866 "array_fill" => Scalar {
1867 params!(AnyElement, SqlScalarType::Array(Box::new(SqlScalarType::Int32)))
1868 => Operation::binary(|ecx, elem, dims| {
1869 let elem_type = ecx.scalar_type(&elem);
1870
1871 let elem_type = match elem_type.array_of_self_elem_type() {
1872 Ok(elem_type) => elem_type,
1873 Err(elem_type) => bail_unsupported!(
1874 format!("array_fill on {}", ecx.humanize_scalar_type(&elem_type, false))
1877 ),
1878 };
1879
1880 Ok(HirScalarExpr::call_variadic(
1881 VariadicFunc::ArrayFill { elem_type },
1882 vec![elem, dims],
1883 ))
1884 }) => ArrayAny, 1193;
1885 params!(
1886 AnyElement,
1887 SqlScalarType::Array(Box::new(SqlScalarType::Int32)),
1888 SqlScalarType::Array(Box::new(SqlScalarType::Int32))
1889 ) => Operation::variadic(|ecx, exprs| {
1890 let elem_type = ecx.scalar_type(&exprs[0]);
1891
1892 let elem_type = match elem_type.array_of_self_elem_type() {
1893 Ok(elem_type) => elem_type,
1894 Err(elem_type) => bail_unsupported!(
1895 format!("array_fill on {}", ecx.humanize_scalar_type(&elem_type, false))
1896 ),
1897 };
1898
1899 Ok(HirScalarExpr::call_variadic(VariadicFunc::ArrayFill { elem_type }, exprs))
1900 }) => ArrayAny, 1286;
1901 },
1902 "array_length" => Scalar {
1903 params![ArrayAny, Int64] => BinaryFunc::from(func::ArrayLength) => Int32, 2176;
1904 },
1905 "array_lower" => Scalar {
1906 params!(ArrayAny, Int64) => BinaryFunc::from(func::ArrayLower) => Int32, 2091;
1907 },
1908 "array_position" => Scalar {
1909 params!(ArrayAnyCompatible, AnyCompatible)
1910 => VariadicFunc::ArrayPosition => Int32, 3277;
1911 params!(ArrayAnyCompatible, AnyCompatible, Int32)
1912 => VariadicFunc::ArrayPosition => Int32, 3278;
1913 },
1914 "array_remove" => Scalar {
1915 params!(ArrayAnyCompatible, AnyCompatible)
1916 => BinaryFunc::from(func::ArrayRemove)
1917 => ArrayAnyCompatible, 3167;
1918 },
1919 "array_to_string" => Scalar {
1920 params!(ArrayAny, String) => Operation::variadic(array_to_string) => String, 395;
1921 params!(ArrayAny, String, String)
1922 => Operation::variadic(array_to_string) => String, 384;
1923 },
1924 "array_upper" => Scalar {
1925 params!(ArrayAny, Int64) => BinaryFunc::from(func::ArrayUpper) => Int32, 2092;
1926 },
1927 "ascii" => Scalar {
1928 params!(String) => UnaryFunc::Ascii(func::Ascii) => Int32, 1620;
1929 },
1930 "avg" => Scalar {
1931 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2100;
1932 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2101;
1933 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2102;
1934 params!(UInt64) =>
1935 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1936 => Numeric, oid::FUNC_AVG_UINT64_OID;
1937 params!(UInt32) =>
1938 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1939 => Numeric, oid::FUNC_AVG_UINT32_OID;
1940 params!(UInt16) =>
1941 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1942 => Numeric, oid::FUNC_AVG_UINT16_OID;
1943 params!(Float32) =>
1944 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1945 => Float64, 2104;
1946 params!(Float64) =>
1947 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1948 => Float64, 2105;
1949 params!(Interval) =>
1950 Operation::nullary(|_ecx| catalog_name_only!("avg"))
1951 => Interval, 2106;
1952 },
1953 "bit_count" => Scalar {
1954 params!(Bytes) => UnaryFunc::BitCountBytes(func::BitCountBytes) => Int64, 6163;
1955 },
1956 "bit_length" => Scalar {
1957 params!(Bytes) => UnaryFunc::BitLengthBytes(func::BitLengthBytes) => Int32, 1810;
1958 params!(String) => UnaryFunc::BitLengthString(func::BitLengthString) => Int32, 1811;
1959 },
1960 "btrim" => Scalar {
1961 params!(String) => UnaryFunc::TrimWhitespace(func::TrimWhitespace) => String, 885;
1962 params!(String, String) => BinaryFunc::from(func::Trim) => String, 884;
1963 },
1964 "cbrt" => Scalar {
1965 params!(Float64) => UnaryFunc::CbrtFloat64(func::CbrtFloat64) => Float64, 1345;
1966 },
1967 "ceil" => Scalar {
1968 params!(Float32) => UnaryFunc::CeilFloat32(func::CeilFloat32)
1969 => Float32, oid::FUNC_CEIL_F32_OID;
1970 params!(Float64) => UnaryFunc::CeilFloat64(func::CeilFloat64) => Float64, 2308;
1971 params!(Numeric) => UnaryFunc::CeilNumeric(func::CeilNumeric) => Numeric, 1711;
1972 },
1973 "ceiling" => Scalar {
1974 params!(Float32) => UnaryFunc::CeilFloat32(func::CeilFloat32)
1975 => Float32, oid::FUNC_CEILING_F32_OID;
1976 params!(Float64) => UnaryFunc::CeilFloat64(func::CeilFloat64) => Float64, 2320;
1977 params!(Numeric) => UnaryFunc::CeilNumeric(func::CeilNumeric) => Numeric, 2167;
1978 },
1979 "char_length" => Scalar {
1980 params!(String) => UnaryFunc::CharLength(func::CharLength) => Int32, 1381;
1981 },
1982 "col_description" => Scalar {
1984 params!(Oid, Int32) => sql_impl_func(
1985 "(SELECT description
1986 FROM pg_description
1987 WHERE objoid = $1 AND classoid = 'pg_class'::regclass AND objsubid = $2)"
1988 ) => String, 1216;
1989 },
1990 "concat" => Scalar {
1991 params!(Any...) => Operation::variadic(|ecx, cexprs| {
1992 if cexprs.is_empty() {
1993 sql_bail!("No function matches the given name and argument types. \
1994 You might need to add explicit type casts.")
1995 }
1996 let mut exprs = vec![];
1997 for expr in cexprs {
1998 exprs.push(match ecx.scalar_type(&expr) {
1999 SqlScalarType::Bool => expr.call_unary(
2002 UnaryFunc::CastBoolToStringNonstandard(
2003 func::CastBoolToStringNonstandard,
2004 ),
2005 ),
2006 SqlScalarType::Char { length } => {
2008 expr.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
2009 }
2010 _ => typeconv::to_string(ecx, expr)
2011 });
2012 }
2013 Ok(HirScalarExpr::call_variadic(VariadicFunc::Concat, exprs))
2014 }) => String, 3058;
2015 },
2016 "concat_ws" => Scalar {
2017 params!([String], Any...) => Operation::variadic(|ecx, cexprs| {
2018 if cexprs.len() < 2 {
2019 sql_bail!("No function matches the given name and argument types. \
2020 You might need to add explicit type casts.")
2021 }
2022 let mut exprs = vec![];
2023 for expr in cexprs {
2024 exprs.push(match ecx.scalar_type(&expr) {
2025 SqlScalarType::Bool => expr.call_unary(
2028 UnaryFunc::CastBoolToStringNonstandard(
2029 func::CastBoolToStringNonstandard,
2030 ),
2031 ),
2032 SqlScalarType::Char { length } => {
2034 expr.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
2035 }
2036 _ => typeconv::to_string(ecx, expr)
2037 });
2038 }
2039 Ok(HirScalarExpr::call_variadic(VariadicFunc::ConcatWs, exprs))
2040 }) => String, 3059;
2041 },
2042 "convert_from" => Scalar {
2043 params!(Bytes, String) => BinaryFunc::from(func::ConvertFrom) => String, 1714;
2044 },
2045 "cos" => Scalar {
2046 params!(Float64) => UnaryFunc::Cos(func::Cos) => Float64, 1605;
2047 },
2048 "acos" => Scalar {
2049 params!(Float64) => UnaryFunc::Acos(func::Acos) => Float64, 1601;
2050 },
2051 "cosh" => Scalar {
2052 params!(Float64) => UnaryFunc::Cosh(func::Cosh) => Float64, 2463;
2053 },
2054 "acosh" => Scalar {
2055 params!(Float64) => UnaryFunc::Acosh(func::Acosh) => Float64, 2466;
2056 },
2057 "cot" => Scalar {
2058 params!(Float64) => UnaryFunc::Cot(func::Cot) => Float64, 1607;
2059 },
2060 "current_schema" => Scalar {
2061 params!() => UnmaterializableFunc::CurrentSchema => String, 1402;
2065 },
2066 "current_schemas" => Scalar {
2067 params!(Bool) => Operation::unary(|_ecx, e| {
2068 Ok(HirScalarExpr::if_then_else(
2069 e,
2070 HirScalarExpr::call_unmaterializable(
2071 UnmaterializableFunc::CurrentSchemasWithSystem,
2072 ),
2073 HirScalarExpr::call_unmaterializable(
2074 UnmaterializableFunc::CurrentSchemasWithoutSystem,
2075 ),
2076 ))
2077 }) => SqlScalarType::Array(Box::new(SqlScalarType::String)), 1403;
2081 },
2082 "current_database" => Scalar {
2083 params!() => UnmaterializableFunc::CurrentDatabase => String, 861;
2084 },
2085 "current_catalog" => Scalar {
2086 params!() => UnmaterializableFunc::CurrentDatabase => String, oid::FUNC_CURRENT_CATALOG;
2087 },
2088 "current_setting" => Scalar {
2089 params!(String) => Operation::unary(|_ecx, name| {
2090 current_settings(name, HirScalarExpr::literal_false())
2091 }) => SqlScalarType::String, 2077;
2092 params!(String, Bool) => Operation::binary(|_ecx, name, missing_ok| {
2093 current_settings(name, missing_ok)
2094 }) => SqlScalarType::String, 3294;
2095 },
2096 "current_timestamp" => Scalar {
2097 params!() => UnmaterializableFunc::CurrentTimestamp
2098 => TimestampTz, oid::FUNC_CURRENT_TIMESTAMP_OID;
2099 },
2100 "current_user" => Scalar {
2101 params!() => UnmaterializableFunc::CurrentUser => String, 745;
2102 },
2103 "current_role" => Scalar {
2104 params!() => UnmaterializableFunc::CurrentUser => String, oid::FUNC_CURRENT_ROLE;
2105 },
2106 "user" => Scalar {
2107 params!() => UnmaterializableFunc::CurrentUser => String, oid::FUNC_USER;
2108 },
2109 "session_user" => Scalar {
2110 params!() => UnmaterializableFunc::SessionUser => String, 746;
2111 },
2112 "chr" => Scalar {
2113 params!(Int32) => UnaryFunc::Chr(func::Chr) => String, 1621;
2114 },
2115 "date" => Scalar {
2116 params!(String) => UnaryFunc::CastStringToDate(func::CastStringToDate)
2117 => Date, oid::FUNC_DATE_FROM_TEXT;
2118 params!(Timestamp) => UnaryFunc::CastTimestampToDate(func::CastTimestampToDate)
2119 => Date, 2029;
2120 params!(TimestampTz) => UnaryFunc::CastTimestampTzToDate(func::CastTimestampTzToDate)
2121 => Date, 1178;
2122 },
2123 "date_bin" => Scalar {
2124 params!(Interval, Timestamp) => Operation::binary(|ecx, stride, source| {
2125 ecx.require_feature_flag(&vars::ENABLE_BINARY_DATE_BIN)?;
2126 Ok(stride.call_binary(source, func::DateBinTimestamp))
2127 }) => Timestamp, oid::FUNC_MZ_DATE_BIN_UNIX_EPOCH_TS_OID;
2128 params!(Interval, TimestampTz) => Operation::binary(|ecx, stride, source| {
2129 ecx.require_feature_flag(&vars::ENABLE_BINARY_DATE_BIN)?;
2130 Ok(stride.call_binary(source, func::DateBinTimestampTz))
2131 }) => TimestampTz, oid::FUNC_MZ_DATE_BIN_UNIX_EPOCH_TSTZ_OID;
2132 params!(Interval, Timestamp, Timestamp)
2133 => VariadicFunc::DateBinTimestamp => Timestamp, 6177;
2134 params!(Interval, TimestampTz, TimestampTz)
2135 => VariadicFunc::DateBinTimestampTz => TimestampTz, 6178;
2136 },
2137 "extract" => Scalar {
2138 params!(String, Interval)
2139 => BinaryFunc::from(func::DatePartIntervalNumeric) => Numeric, 6204;
2140 params!(String, Time)
2141 => BinaryFunc::from(func::DatePartTimeNumeric) => Numeric, 6200;
2142 params!(String, Timestamp)
2143 => BinaryFunc::from(func::DatePartTimestampTimestampNumeric)
2144 => Numeric, 6202;
2145 params!(String, TimestampTz)
2146 => BinaryFunc::from(func::DatePartTimestampTimestampTzNumeric)
2147 => Numeric, 6203;
2148 params!(String, Date) => BinaryFunc::from(func::ExtractDateUnits) => Numeric, 6199;
2149 },
2150 "date_part" => Scalar {
2151 params!(String, Interval)
2152 => BinaryFunc::from(func::DatePartIntervalF64) => Float64, 1172;
2153 params!(String, Time)
2154 => BinaryFunc::from(func::DatePartTimeF64) => Float64, 1385;
2155 params!(String, Timestamp)
2156 => BinaryFunc::from(func::DatePartTimestampTimestampF64)
2157 => Float64, 2021;
2158 params!(String, TimestampTz)
2159 => BinaryFunc::from(func::DatePartTimestampTimestampTzF64)
2160 => Float64, 1171;
2161 },
2162 "date_trunc" => Scalar {
2163 params!(String, Timestamp)
2164 => BinaryFunc::from(func::DateTruncUnitsTimestamp) => Timestamp, 2020;
2165 params!(String, TimestampTz)
2166 => BinaryFunc::from(func::DateTruncUnitsTimestampTz)
2167 => TimestampTz, 1217;
2168 params!(String, Interval)
2169 => BinaryFunc::from(func::DateTruncInterval) => Interval, 1218;
2170 },
2171 "daterange" => Scalar {
2172 params!(Date, Date) => Operation::variadic(|_ecx, mut exprs| {
2173 exprs.push(HirScalarExpr::literal(
2174 Datum::String("[)"), SqlScalarType::String,
2175 ));
2176 Ok(HirScalarExpr::call_variadic(
2177 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Date },
2178 exprs,
2179 ))
2180 }) => SqlScalarType::Range {
2181 element_type: Box::new(SqlScalarType::Date),
2182 }, 3941;
2183 params!(Date, Date, String) => Operation::variadic(|_ecx, exprs| {
2184 Ok(HirScalarExpr::call_variadic(
2185 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Date },
2186 exprs,
2187 ))
2188 }) => SqlScalarType::Range {
2189 element_type: Box::new(SqlScalarType::Date),
2190 }, 3942;
2191 },
2192 "degrees" => Scalar {
2193 params!(Float64) => UnaryFunc::Degrees(func::Degrees) => Float64, 1608;
2194 },
2195 "digest" => Scalar {
2196 params!(String, String) => BinaryFunc::from(func::DigestString)
2197 => Bytes, oid::FUNC_PG_DIGEST_STRING;
2198 params!(Bytes, String) => BinaryFunc::from(func::DigestBytes)
2199 => Bytes, oid::FUNC_PG_DIGEST_BYTES;
2200 },
2201 "exp" => Scalar {
2202 params!(Float64) => UnaryFunc::Exp(func::Exp) => Float64, 1347;
2203 params!(Numeric) => UnaryFunc::ExpNumeric(func::ExpNumeric) => Numeric, 1732;
2204 },
2205 "floor" => Scalar {
2206 params!(Float32) => UnaryFunc::FloorFloat32(func::FloorFloat32)
2207 => Float32, oid::FUNC_FLOOR_F32_OID;
2208 params!(Float64) => UnaryFunc::FloorFloat64(func::FloorFloat64) => Float64, 2309;
2209 params!(Numeric) => UnaryFunc::FloorNumeric(func::FloorNumeric) => Numeric, 1712;
2210 },
2211 "format_type" => Scalar {
2212 params!(Oid, Int32) => sql_impl_func(
2213 "CASE
2214 WHEN $1 IS NULL THEN NULL
2215 -- timestamp and timestamptz have the typmod in
2216 -- a nonstandard location that requires special
2217 -- handling.
2218 WHEN $1 = 1114 AND $2 >= 0 THEN 'timestamp(' || $2 || ') without time zone'
2219 WHEN $1 = 1184 AND $2 >= 0 THEN 'timestamp(' || $2 || ') with time zone'
2220 ELSE coalesce(
2221 (SELECT pg_catalog.concat(
2222 coalesce(mz_internal.mz_type_name($1), name),
2223 mz_internal.mz_render_typmod($1, $2))
2224 FROM mz_catalog.mz_types WHERE oid = $1),
2225 '???')
2226 END"
2227 ) => String, 1081;
2228 },
2229 "get_bit" => Scalar {
2230 params!(Bytes, Int32) => BinaryFunc::from(func::GetBit) => Int32, 723;
2231 },
2232 "get_byte" => Scalar {
2233 params!(Bytes, Int32) => BinaryFunc::from(func::GetByte) => Int32, 721;
2234 },
2235 "pg_get_ruledef" => Scalar {
2236 params!(Oid) => sql_impl_func("NULL::pg_catalog.text") => String, 1573;
2237 params!(Oid, Bool) => sql_impl_func("NULL::pg_catalog.text") => String, 2504;
2238 },
2239 "has_schema_privilege" => Scalar {
2240 params!(String, String, String) => sql_impl_func(
2241 "has_schema_privilege(\
2242 mz_internal.mz_role_oid($1), \
2243 mz_internal.mz_schema_oid($2), $3)",
2244 ) => Bool, 2268;
2245 params!(String, Oid, String) => sql_impl_func(
2246 "has_schema_privilege(\
2247 mz_internal.mz_role_oid($1), $2, $3)",
2248 ) => Bool, 2269;
2249 params!(Oid, String, String) => sql_impl_func(
2250 "has_schema_privilege(\
2251 $1, mz_internal.mz_schema_oid($2), $3)",
2252 ) => Bool, 2270;
2253 params!(Oid, Oid, String) => sql_impl_func(
2254 &privilege_fn!(
2255 "has_schema_privilege", "mz_schemas"
2256 ),
2257 ) => Bool, 2271;
2258 params!(String, String) => sql_impl_func(
2259 "has_schema_privilege(current_user, $1, $2)",
2260 ) => Bool, 2272;
2261 params!(Oid, String) => sql_impl_func(
2262 "has_schema_privilege(current_user, $1, $2)",
2263 ) => Bool, 2273;
2264 },
2265 "has_database_privilege" => Scalar {
2266 params!(String, String, String) => sql_impl_func(
2267 "has_database_privilege(\
2268 mz_internal.mz_role_oid($1), \
2269 mz_internal.mz_database_oid($2), $3)",
2270 ) => Bool, 2250;
2271 params!(String, Oid, String) => sql_impl_func(
2272 "has_database_privilege(\
2273 mz_internal.mz_role_oid($1), $2, $3)",
2274 ) => Bool, 2251;
2275 params!(Oid, String, String) => sql_impl_func(
2276 "has_database_privilege(\
2277 $1, mz_internal.mz_database_oid($2), $3)",
2278 ) => Bool, 2252;
2279 params!(Oid, Oid, String) => sql_impl_func(
2280 &privilege_fn!(
2281 "has_database_privilege", "mz_databases"
2282 ),
2283 ) => Bool, 2253;
2284 params!(String, String) => sql_impl_func(
2285 "has_database_privilege(current_user, $1, $2)",
2286 ) => Bool, 2254;
2287 params!(Oid, String) => sql_impl_func(
2288 "has_database_privilege(current_user, $1, $2)",
2289 ) => Bool, 2255;
2290 },
2291 "has_table_privilege" => Scalar {
2292 params!(String, String, String) => sql_impl_func(
2293 "has_table_privilege(\
2294 mz_internal.mz_role_oid($1), \
2295 $2::regclass::oid, $3)",
2296 ) => Bool, 1922;
2297 params!(String, Oid, String) => sql_impl_func(
2298 "has_table_privilege(\
2299 mz_internal.mz_role_oid($1), $2, $3)",
2300 ) => Bool, 1923;
2301 params!(Oid, String, String) => sql_impl_func(
2302 "has_table_privilege(\
2303 $1, $2::regclass::oid, $3)",
2304 ) => Bool, 1924;
2305 params!(Oid, Oid, String) => sql_impl_func(
2306 &privilege_fn!(
2307 "has_table_privilege", "mz_relations"
2308 ),
2309 ) => Bool, 1925;
2310 params!(String, String) => sql_impl_func(
2311 "has_table_privilege(current_user, $1, $2)",
2312 ) => Bool, 1926;
2313 params!(Oid, String) => sql_impl_func(
2314 "has_table_privilege(current_user, $1, $2)",
2315 ) => Bool, 1927;
2316 },
2317 "hmac" => Scalar {
2318 params!(String, String, String) => VariadicFunc::HmacString
2319 => Bytes, oid::FUNC_PG_HMAC_STRING;
2320 params!(Bytes, Bytes, String) => VariadicFunc::HmacBytes
2321 => Bytes, oid::FUNC_PG_HMAC_BYTES;
2322 },
2323 "initcap" => Scalar {
2324 params!(String) => UnaryFunc::Initcap(func::Initcap) => String, 872;
2325 },
2326 "int4range" => Scalar {
2327 params!(Int32, Int32) => Operation::variadic(|_ecx, mut exprs| {
2328 exprs.push(HirScalarExpr::literal(
2329 Datum::String("[)"), SqlScalarType::String,
2330 ));
2331 Ok(HirScalarExpr::call_variadic(
2332 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Int32 },
2333 exprs,
2334 ))
2335 }) => SqlScalarType::Range {
2336 element_type: Box::new(SqlScalarType::Int32),
2337 }, 3840;
2338 params!(Int32, Int32, String) => Operation::variadic(|_ecx, exprs| {
2339 Ok(HirScalarExpr::call_variadic(
2340 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Int32 },
2341 exprs,
2342 ))
2343 }) => SqlScalarType::Range {
2344 element_type: Box::new(SqlScalarType::Int32),
2345 }, 3841;
2346 },
2347 "int8range" => Scalar {
2348 params!(Int64, Int64) => Operation::variadic(|_ecx, mut exprs| {
2349 exprs.push(HirScalarExpr::literal(
2350 Datum::String("[)"), SqlScalarType::String,
2351 ));
2352 Ok(HirScalarExpr::call_variadic(
2353 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Int64 },
2354 exprs,
2355 ))
2356 }) => SqlScalarType::Range {
2357 element_type: Box::new(SqlScalarType::Int64),
2358 }, 3945;
2359 params!(Int64, Int64, String) => Operation::variadic(|_ecx, exprs| {
2360 Ok(HirScalarExpr::call_variadic(
2361 VariadicFunc::RangeCreate { elem_type: SqlScalarType::Int64 },
2362 exprs,
2363 ))
2364 }) => SqlScalarType::Range {
2365 element_type: Box::new(SqlScalarType::Int64),
2366 }, 3946;
2367 },
2368 "isempty" => Scalar {
2369 params!(RangeAny) => UnaryFunc::RangeEmpty(func::RangeEmpty) => Bool, 3850;
2370 },
2371 "jsonb_array_length" => Scalar {
2372 params!(Jsonb) => UnaryFunc::JsonbArrayLength(func::JsonbArrayLength) => Int32, 3207;
2373 },
2374 "jsonb_build_array" => Scalar {
2375 params!() => VariadicFunc::JsonbBuildArray => Jsonb, 3272;
2376 params!(Any...) => Operation::variadic(|ecx, exprs| {
2377 Ok(HirScalarExpr::call_variadic(
2378 VariadicFunc::JsonbBuildArray,
2379 exprs.into_iter().map(|e| typeconv::to_jsonb(ecx, e)).collect(),
2380 ))
2381 }) => Jsonb, 3271;
2382 },
2383 "jsonb_build_object" => Scalar {
2384 params!() => VariadicFunc::JsonbBuildObject => Jsonb, 3274;
2385 params!(Any...) => Operation::variadic(|ecx, exprs| {
2386 if exprs.len() % 2 != 0 {
2387 sql_bail!("argument list must have even number of elements")
2388 }
2389 Ok(HirScalarExpr::call_variadic(
2390 VariadicFunc::JsonbBuildObject,
2391 exprs.into_iter().tuples().map(|(key, val)| {
2392 let key = typeconv::to_string(ecx, key);
2393 let val = typeconv::to_jsonb(ecx, val);
2394 vec![key, val]
2395 }).flatten().collect()))
2396 }) => Jsonb, 3273;
2397 },
2398 "jsonb_pretty" => Scalar {
2399 params!(Jsonb) => UnaryFunc::JsonbPretty(func::JsonbPretty) => String, 3306;
2400 },
2401 "jsonb_strip_nulls" => Scalar {
2402 params!(Jsonb) => UnaryFunc::JsonbStripNulls(func::JsonbStripNulls) => Jsonb, 3262;
2403 },
2404 "jsonb_typeof" => Scalar {
2405 params!(Jsonb) => UnaryFunc::JsonbTypeof(func::JsonbTypeof) => String, 3210;
2406 },
2407 "justify_days" => Scalar {
2408 params!(Interval) => UnaryFunc::JustifyDays(func::JustifyDays) => Interval, 1295;
2409 },
2410 "justify_hours" => Scalar {
2411 params!(Interval) => UnaryFunc::JustifyHours(func::JustifyHours) => Interval, 1175;
2412 },
2413 "justify_interval" => Scalar {
2414 params!(Interval) => UnaryFunc::JustifyInterval(func::JustifyInterval)
2415 => Interval, 2711;
2416 },
2417 "left" => Scalar {
2418 params!(String, Int32) => BinaryFunc::from(func::Left) => String, 3060;
2419 },
2420 "length" => Scalar {
2421 params!(Bytes) => UnaryFunc::ByteLengthBytes(func::ByteLengthBytes) => Int32, 2010;
2422 params!(String) => UnaryFunc::CharLength(func::CharLength) => Int32, 1317;
2424 params!(Bytes, String) => BinaryFunc::from(func::EncodedBytesCharLength) => Int32, 1713;
2425 },
2426 "like_escape" => Scalar {
2427 params!(String, String) => BinaryFunc::from(func::LikeEscape) => String, 1637;
2428 },
2429 "ln" => Scalar {
2430 params!(Float64) => UnaryFunc::Ln(func::Ln) => Float64, 1341;
2431 params!(Numeric) => UnaryFunc::LnNumeric(func::LnNumeric) => Numeric, 1734;
2432 },
2433 "log10" => Scalar {
2434 params!(Float64) => UnaryFunc::Log10(func::Log10) => Float64, 1194;
2435 params!(Numeric) => UnaryFunc::Log10Numeric(func::Log10Numeric) => Numeric, 1481;
2436 },
2437 "log" => Scalar {
2438 params!(Float64) => UnaryFunc::Log10(func::Log10) => Float64, 1340;
2439 params!(Numeric) => UnaryFunc::Log10Numeric(func::Log10Numeric) => Numeric, 1741;
2440 params!(Numeric, Numeric) => BinaryFunc::from(func::LogBaseNumeric) => Numeric, 1736;
2441 },
2442 "lower" => Scalar {
2443 params!(String) => UnaryFunc::Lower(func::Lower) => String, 870;
2444 params!(RangeAny) => UnaryFunc::RangeLower(func::RangeLower) => AnyElement, 3848;
2445 },
2446 "lower_inc" => Scalar {
2447 params!(RangeAny) => UnaryFunc::RangeLowerInc(func::RangeLowerInc) => Bool, 3851;
2448 },
2449 "lower_inf" => Scalar {
2450 params!(RangeAny) => UnaryFunc::RangeLowerInf(func::RangeLowerInf) => Bool, 3853;
2451 },
2452 "lpad" => Scalar {
2453 params!(String, Int32) => VariadicFunc::PadLeading => String, 879;
2454 params!(String, Int32, String) => VariadicFunc::PadLeading => String, 873;
2455 },
2456 "ltrim" => Scalar {
2457 params!(String) => UnaryFunc::TrimLeadingWhitespace(
2458 func::TrimLeadingWhitespace,
2459 ) => String, 881;
2460 params!(String, String) => BinaryFunc::from(func::TrimLeading) => String, 875;
2461 },
2462 "makeaclitem" => Scalar {
2463 params!(Oid, Oid, String, Bool) => VariadicFunc::MakeAclItem => AclItem, 1365;
2464 },
2465 "make_timestamp" => Scalar {
2466 params!(Int64, Int64, Int64, Int64, Int64, Float64)
2467 => VariadicFunc::MakeTimestamp => Timestamp, 3461;
2468 },
2469 "md5" => Scalar {
2470 params!(String) => Operation::unary(move |_ecx, input| {
2471 let algorithm = HirScalarExpr::literal(Datum::String("md5"), SqlScalarType::String);
2472 let encoding = HirScalarExpr::literal(Datum::String("hex"), SqlScalarType::String);
2473 Ok(input
2474 .call_binary(algorithm, func::DigestString)
2475 .call_binary(encoding, func::Encode))
2476 }) => String, 2311;
2477 params!(Bytes) => Operation::unary(move |_ecx, input| {
2478 let algorithm = HirScalarExpr::literal(
2479 Datum::String("md5"), SqlScalarType::String,
2480 );
2481 let encoding = HirScalarExpr::literal(
2482 Datum::String("hex"), SqlScalarType::String,
2483 );
2484 Ok(input
2485 .call_binary(algorithm, func::DigestBytes)
2486 .call_binary(encoding, func::Encode))
2487 }) => String, 2321;
2488 },
2489 "mod" => Scalar {
2490 params!(Numeric, Numeric) =>
2491 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2492 => Numeric, 1728;
2493 params!(Int16, Int16) =>
2494 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2495 => Int16, 940;
2496 params!(Int32, Int32) =>
2497 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2498 => Int32, 941;
2499 params!(Int64, Int64) =>
2500 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2501 => Int64, 947;
2502 params!(UInt16, UInt16) =>
2503 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2504 => UInt16, oid::FUNC_MOD_UINT16_OID;
2505 params!(UInt32, UInt32) =>
2506 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2507 => UInt32, oid::FUNC_MOD_UINT32_OID;
2508 params!(UInt64, UInt64) =>
2509 Operation::nullary(|_ecx| catalog_name_only!("mod"))
2510 => UInt64, oid::FUNC_MOD_UINT64_OID;
2511 },
2512 "normalize" => Scalar {
2513 params!(String, String) => BinaryFunc::Normalize(func::Normalize)
2515 => String, oid::FUNC_NORMALIZE_OID;
2516 },
2517 "now" => Scalar {
2518 params!() => UnmaterializableFunc::CurrentTimestamp => TimestampTz, 1299;
2519 },
2520 "numrange" => Scalar {
2521 params!(Numeric, Numeric) => Operation::variadic(|_ecx, mut exprs| {
2522 exprs.push(HirScalarExpr::literal(
2523 Datum::String("[)"), SqlScalarType::String,
2524 ));
2525 Ok(HirScalarExpr::call_variadic(
2526 VariadicFunc::RangeCreate {
2527 elem_type: SqlScalarType::Numeric { max_scale: None },
2528 },
2529 exprs,
2530 ))
2531 }) => SqlScalarType::Range {
2532 element_type: Box::new(SqlScalarType::Numeric { max_scale: None }),
2533 }, 3844;
2534 params!(Numeric, Numeric, String) => Operation::variadic(|_ecx, exprs| {
2535 Ok(HirScalarExpr::call_variadic(
2536 VariadicFunc::RangeCreate {
2537 elem_type: SqlScalarType::Numeric { max_scale: None },
2538 },
2539 exprs,
2540 ))
2541 }) => SqlScalarType::Range {
2542 element_type: Box::new(SqlScalarType::Numeric { max_scale: None }),
2543 }, 3845;
2544 },
2545 "octet_length" => Scalar {
2546 params!(Bytes) => UnaryFunc::ByteLengthBytes(func::ByteLengthBytes) => Int32, 720;
2547 params!(String) => UnaryFunc::ByteLengthString(func::ByteLengthString) => Int32, 1374;
2548 params!(Char) => Operation::unary(|ecx, e| {
2549 let length = ecx.scalar_type(&e).unwrap_char_length();
2550 Ok(e.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
2551 .call_unary(UnaryFunc::ByteLengthString(func::ByteLengthString))
2552 )
2553 }) => Int32, 1375;
2554 },
2555 "obj_description" => Scalar {
2559 params!(Oid, String) => sql_impl_func(&format!(
2560 "(SELECT description FROM pg_description
2561 WHERE objoid = $1
2562 AND classoid = (
2563 SELECT oid FROM pg_class WHERE relname = $2 AND relnamespace = {})
2564 AND objsubid = 0)",
2565 oid::SCHEMA_PG_CATALOG_OID
2566 )) => String, 1215;
2567 },
2568 "pg_column_size" => Scalar {
2569 params!(Any) => UnaryFunc::PgColumnSize(func::PgColumnSize) => Int32, 1269;
2570 },
2571 "pg_size_pretty" => Scalar {
2572 params!(Numeric) => UnaryFunc::PgSizePretty(func::PgSizePretty) => String, 3166;
2573 },
2574 "mz_row_size" => Scalar {
2575 params!(Any) => Operation::unary(|ecx, e| {
2576 let s = ecx.scalar_type(&e);
2577 if !matches!(s, SqlScalarType::Record{..}) {
2578 sql_bail!("mz_row_size requires a record type");
2579 }
2580 Ok(e.call_unary(UnaryFunc::MzRowSize(func::MzRowSize)))
2581 }) => Int32, oid::FUNC_MZ_ROW_SIZE;
2582 },
2583 "parse_ident" => Scalar {
2584 params!(String) => Operation::unary(|_ecx, ident| {
2585 Ok(ident.call_binary(HirScalarExpr::literal_true(), func::ParseIdent))
2586 }) => SqlScalarType::Array(Box::new(SqlScalarType::String)),
2587 oid::FUNC_PARSE_IDENT_DEFAULT_STRICT;
2588 params!(String, Bool) => BinaryFunc::from(func::ParseIdent)
2589 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 1268;
2590 },
2591 "pg_encoding_to_char" => Scalar {
2592 params!(Int64) => sql_impl_func(
2595 "CASE WHEN $1 = 6 THEN 'UTF8' ELSE NULL END",
2596 ) => String, 1597;
2597 },
2598 "pg_backend_pid" => Scalar {
2599 params!() => UnmaterializableFunc::PgBackendPid => Int32, 2026;
2600 },
2601 "pg_get_constraintdef" => Scalar {
2607 params!(Oid) => Operation::unary(|_ecx, _oid|
2608 Ok(HirScalarExpr::literal_null(SqlScalarType::String))) => String, 1387;
2609 params!(Oid, Bool) => Operation::binary(|_ecx, _oid, _pretty|
2610 Ok(HirScalarExpr::literal_null(SqlScalarType::String))) => String, 2508;
2611 },
2612 "pg_get_indexdef" => Scalar {
2617 params!(Oid) => sql_impl_func(
2618 "(SELECT 'CREATE INDEX ' || i.name
2619 || ' ON ' || r.name
2620 || ' USING arrangement (' || (
2621 SELECT pg_catalog.string_agg(
2622 cols.col_exp, ',' ORDER BY cols.index_position)
2623 FROM (
2624 SELECT c.name AS col_exp, ic.index_position
2625 FROM mz_catalog.mz_index_columns AS ic
2626 JOIN mz_catalog.mz_indexes AS i2
2627 ON ic.index_id = i2.id
2628 JOIN mz_catalog.mz_columns AS c
2629 ON i2.on_id = c.id
2630 AND ic.on_position = c.position
2631 WHERE ic.index_id = i.id
2632 AND ic.on_expression IS NULL
2633 UNION
2634 SELECT ic.on_expression AS col_exp,
2635 ic.index_position
2636 FROM mz_catalog.mz_index_columns AS ic
2637 WHERE ic.index_id = i.id
2638 AND ic.on_expression IS NOT NULL
2639 ) AS cols
2640 ) || ')'
2641 FROM mz_catalog.mz_indexes AS i
2642 JOIN mz_catalog.mz_relations AS r
2643 ON i.on_id = r.id
2644 WHERE i.oid = $1)"
2645 ) => String, 1643;
2646 params!(Oid, Int32, Bool) => sql_impl_func(
2649 "(SELECT CASE
2650 WHEN $2 = 0
2651 THEN pg_catalog.pg_get_indexdef($1)
2652 ELSE (
2653 SELECT c.name
2654 FROM mz_catalog.mz_indexes AS i
2655 JOIN mz_catalog.mz_index_columns AS ic
2656 ON i.id = ic.index_id
2657 JOIN mz_catalog.mz_columns AS c
2658 ON i.on_id = c.id
2659 AND ic.on_position = c.position
2660 WHERE i.oid = $1
2661 AND ic.on_expression IS NULL
2662 AND ic.index_position = $2
2663 UNION
2664 SELECT ic.on_expression
2665 FROM mz_catalog.mz_indexes AS i
2666 JOIN mz_catalog.mz_index_columns AS ic
2667 ON i.id = ic.index_id
2668 WHERE i.oid = $1
2669 AND ic.on_expression IS NOT NULL
2670 AND ic.index_position = $2)
2671 END)"
2672 ) => String, 2507;
2673 },
2674 "pg_get_viewdef" => Scalar {
2677 params!(String) => sql_impl_func(
2678 "(SELECT definition FROM mz_catalog.mz_views WHERE name = $1)"
2679 ) => String, 1640;
2680 params!(Oid) => sql_impl_func(
2681 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2682 ) => String, 1641;
2683 params!(String, Bool) => sql_impl_func(
2684 "(SELECT definition FROM mz_catalog.mz_views WHERE name = $1)"
2685 ) => String, 2505;
2686 params!(Oid, Bool) => sql_impl_func(
2687 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2688 ) => String, 2506;
2689 params!(Oid, Int32) => sql_impl_func(
2690 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2691 ) => String, 3159;
2692 },
2693 "pg_get_expr" => Scalar {
2701 params!(String, Oid) => Operation::binary(|_ecx, l, _r| Ok(l)) => String, 1716;
2702 params!(String, Oid, Bool) => Operation::variadic(
2703 move |_ecx, mut args| Ok(args.remove(0)),
2704 ) => String, 2509;
2705 },
2706 "pg_get_userbyid" => Scalar {
2707 params!(Oid) => sql_impl_func(
2708 "CASE \
2709 WHEN $1 IS NULL THEN NULL \
2710 ELSE COALESCE(\
2711 (SELECT name FROM mz_catalog.mz_roles WHERE oid = $1),\
2712 'unknown (OID=' || $1 || ')'\
2713 ) \
2714 END"
2715 ) => String, 1642;
2716 },
2717 "pg_has_role" => Scalar {
2724 params!(String, String, String) => sql_impl_func(
2725 "pg_has_role(\
2726 mz_internal.mz_role_oid($1), \
2727 mz_internal.mz_role_oid($2), $3)",
2728 ) => Bool, 2705;
2729 params!(String, Oid, String) => sql_impl_func(
2730 "pg_has_role(\
2731 mz_internal.mz_role_oid($1), $2, $3)",
2732 ) => Bool, 2706;
2733 params!(Oid, String, String) => sql_impl_func(
2734 "pg_has_role(\
2735 $1, mz_internal.mz_role_oid($2), $3)",
2736 ) => Bool, 2707;
2737 params!(Oid, Oid, String) => sql_impl_func(
2738 "CASE
2739 -- We need to validate the privilege to return a proper error before anything
2740 -- else.
2741 WHEN NOT mz_internal.mz_validate_role_privilege($3)
2742 OR $1 IS NULL
2743 OR $2 IS NULL
2744 OR $3 IS NULL
2745 THEN NULL
2746 WHEN $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
2747 OR $2 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
2748 THEN false
2749 ELSE $2::text IN (SELECT UNNEST(mz_internal.mz_role_oid_memberships() -> $1::text))
2750 END",
2751 ) => Bool, 2708;
2752 params!(String, String) => sql_impl_func(
2753 "pg_has_role(current_user, $1, $2)",
2754 ) => Bool, 2709;
2755 params!(Oid, String) => sql_impl_func(
2756 "pg_has_role(current_user, $1, $2)",
2757 ) => Bool, 2710;
2758 },
2759 "pg_is_in_recovery" => Scalar {
2762 params!() => Operation::nullary(|_ecx| {
2763 Ok(HirScalarExpr::literal_false())
2764 }) => Bool, 3810;
2765 },
2766 "pg_postmaster_start_time" => Scalar {
2767 params!() => UnmaterializableFunc::PgPostmasterStartTime => TimestampTz, 2560;
2768 },
2769 "pg_relation_size" => Scalar {
2770 params!(RegClass, String) => sql_impl_func(
2771 "CASE WHEN $1 IS NULL OR $2 IS NULL \
2772 THEN NULL ELSE -1::pg_catalog.int8 END",
2773 ) => Int64, 2332;
2774 params!(RegClass) => sql_impl_func(
2775 "CASE WHEN $1 IS NULL \
2776 THEN NULL ELSE -1::pg_catalog.int8 END",
2777 ) => Int64, 2325;
2778 },
2779 "pg_stat_get_numscans" => Scalar {
2780 params!(Oid) => sql_impl_func(
2781 "CASE WHEN $1 IS NULL \
2782 THEN NULL ELSE -1::pg_catalog.int8 END",
2783 ) => Int64, 1928;
2784 },
2785 "pg_table_is_visible" => Scalar {
2786 params!(Oid) => sql_impl_func(
2787 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2788 FROM mz_catalog.mz_objects o JOIN mz_catalog.mz_schemas s ON o.schema_id = s.id
2789 WHERE o.oid = $1)"
2790 ) => Bool, 2079;
2791 },
2792 "pg_type_is_visible" => Scalar {
2793 params!(Oid) => sql_impl_func(
2794 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2795 FROM mz_catalog.mz_types t JOIN mz_catalog.mz_schemas s ON t.schema_id = s.id
2796 WHERE t.oid = $1)"
2797 ) => Bool, 2080;
2798 },
2799 "pg_function_is_visible" => Scalar {
2800 params!(Oid) => sql_impl_func(
2801 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2802 FROM mz_catalog.mz_functions f
2803 JOIN mz_catalog.mz_schemas s
2804 ON f.schema_id = s.id
2805 WHERE f.oid = $1)"
2806 ) => Bool, 2081;
2807 },
2808 "pg_tablespace_location" => Scalar {
2812 params!(Oid) => Operation::unary(|_ecx, _e| {
2813 Ok(HirScalarExpr::literal_null(SqlScalarType::String))
2814 }) => String, 3778;
2815 },
2816 "pg_typeof" => Scalar {
2817 params!(Any) => Operation::new(|ecx, exprs, params, _order_by| {
2818 let name = match ecx.scalar_type(&exprs[0]) {
2820 CoercibleScalarType::Uncoerced => "unknown".to_string(),
2821 CoercibleScalarType::Record(_) => "record".to_string(),
2822 CoercibleScalarType::Coerced(ty) => ecx.humanize_scalar_type(&ty, true),
2823 };
2824
2825 coerce_args_to_types(ecx, exprs, params)?;
2829
2830 Ok(HirScalarExpr::literal(Datum::String(&name), SqlScalarType::String))
2835 }) => String, 1619;
2836 },
2837 "position" => Scalar {
2838 params!(String, String) => BinaryFunc::from(func::Position) => Int32, 849;
2839 },
2840 "pow" => Scalar {
2841 params!(Float64, Float64) =>
2842 Operation::nullary(|_ecx| catalog_name_only!("pow"))
2843 => Float64, 1346;
2844 },
2845 "power" => Scalar {
2846 params!(Float64, Float64) => BinaryFunc::from(func::Power) => Float64, 1368;
2847 params!(Numeric, Numeric) => BinaryFunc::from(func::PowerNumeric) => Numeric, 2169;
2848 },
2849 "quote_ident" => Scalar {
2850 params!(String) => UnaryFunc::QuoteIdent(func::QuoteIdent) => String, 1282;
2851 },
2852 "radians" => Scalar {
2853 params!(Float64) => UnaryFunc::Radians(func::Radians) => Float64, 1609;
2854 },
2855 "repeat" => Scalar {
2856 params!(String, Int32) => BinaryFunc::RepeatString(func::RepeatString) => String, 1622;
2857 },
2858 "regexp_match" => Scalar {
2859 params!(String, String) => VariadicFunc::RegexpMatch
2860 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 3396;
2861 params!(String, String, String) => VariadicFunc::RegexpMatch
2862 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 3397;
2863 },
2864 "replace" => Scalar {
2865 params!(String, String, String) => VariadicFunc::Replace => String, 2087;
2866 },
2867 "right" => Scalar {
2868 params!(String, Int32) => BinaryFunc::from(func::Right) => String, 3061;
2869 },
2870 "round" => Scalar {
2871 params!(Float32) => UnaryFunc::RoundFloat32(func::RoundFloat32)
2872 => Float32, oid::FUNC_ROUND_F32_OID;
2873 params!(Float64) => UnaryFunc::RoundFloat64(func::RoundFloat64) => Float64, 1342;
2874 params!(Numeric) => UnaryFunc::RoundNumeric(func::RoundNumeric) => Numeric, 1708;
2875 params!(Numeric, Int32) => BinaryFunc::from(func::RoundNumericBinary) => Numeric, 1707;
2876 },
2877 "rtrim" => Scalar {
2878 params!(String) => UnaryFunc::TrimTrailingWhitespace(
2879 func::TrimTrailingWhitespace,
2880 ) => String, 882;
2881 params!(String, String) => BinaryFunc::from(func::TrimTrailing) => String, 876;
2882 },
2883 "sha224" => Scalar {
2884 params!(Bytes) => digest("sha224") => Bytes, 3419;
2885 },
2886 "sha256" => Scalar {
2887 params!(Bytes) => digest("sha256") => Bytes, 3420;
2888 },
2889 "sha384" => Scalar {
2890 params!(Bytes) => digest("sha384") => Bytes, 3421;
2891 },
2892 "sha512" => Scalar {
2893 params!(Bytes) => digest("sha512") => Bytes, 3422;
2894 },
2895 "sin" => Scalar {
2896 params!(Float64) => UnaryFunc::Sin(func::Sin) => Float64, 1604;
2897 },
2898 "asin" => Scalar {
2899 params!(Float64) => UnaryFunc::Asin(func::Asin) => Float64, 1600;
2900 },
2901 "sinh" => Scalar {
2902 params!(Float64) => UnaryFunc::Sinh(func::Sinh) => Float64, 2462;
2903 },
2904 "asinh" => Scalar {
2905 params!(Float64) => UnaryFunc::Asinh(func::Asinh) => Float64, 2465;
2906 },
2907 "strpos" => Scalar {
2908 params!(String, String) => BinaryFunc::from(func::Strpos) => Int32, 868;
2909 },
2910 "split_part" => Scalar {
2911 params!(String, String, Int32) => VariadicFunc::SplitPart => String, 2088;
2912 },
2913 "stddev" => Scalar {
2914 params!(Float32) =>
2915 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2916 => Float64, 2157;
2917 params!(Float64) =>
2918 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2919 => Float64, 2158;
2920 params!(Int16) =>
2921 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2922 => Numeric, 2156;
2923 params!(Int32) =>
2924 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2925 => Numeric, 2155;
2926 params!(Int64) =>
2927 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2928 => Numeric, 2154;
2929 params!(UInt16) =>
2930 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2931 => Numeric, oid::FUNC_STDDEV_UINT16_OID;
2932 params!(UInt32) =>
2933 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2934 => Numeric, oid::FUNC_STDDEV_UINT32_OID;
2935 params!(UInt64) =>
2936 Operation::nullary(|_ecx| catalog_name_only!("stddev"))
2937 => Numeric, oid::FUNC_STDDEV_UINT64_OID;
2938 },
2939 "stddev_pop" => Scalar {
2940 params!(Float32) =>
2941 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2942 => Float64, 2727;
2943 params!(Float64) =>
2944 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2945 => Float64, 2728;
2946 params!(Int16) =>
2947 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2948 => Numeric, 2726;
2949 params!(Int32) =>
2950 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2951 => Numeric, 2725;
2952 params!(Int64) =>
2953 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2954 => Numeric, 2724;
2955 params!(UInt16) =>
2956 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2957 => Numeric, oid::FUNC_STDDEV_POP_UINT16_OID;
2958 params!(UInt32) =>
2959 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2960 => Numeric, oid::FUNC_STDDEV_POP_UINT32_OID;
2961 params!(UInt64) =>
2962 Operation::nullary(|_ecx| catalog_name_only!("stddev_pop"))
2963 => Numeric, oid::FUNC_STDDEV_POP_UINT64_OID;
2964 },
2965 "stddev_samp" => Scalar {
2966 params!(Float32) =>
2967 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2968 => Float64, 2715;
2969 params!(Float64) =>
2970 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2971 => Float64, 2716;
2972 params!(Int16) =>
2973 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2974 => Numeric, 2714;
2975 params!(Int32) =>
2976 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2977 => Numeric, 2713;
2978 params!(Int64) =>
2979 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2980 => Numeric, 2712;
2981 params!(UInt16) =>
2982 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2983 => Numeric, oid::FUNC_STDDEV_SAMP_UINT16_OID;
2984 params!(UInt32) =>
2985 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2986 => Numeric, oid::FUNC_STDDEV_SAMP_UINT32_OID;
2987 params!(UInt64) =>
2988 Operation::nullary(|_ecx| catalog_name_only!("stddev_samp"))
2989 => Numeric, oid::FUNC_STDDEV_SAMP_UINT64_OID;
2990 },
2991 "substr" => Scalar {
2992 params!(String, Int32) => VariadicFunc::Substr => String, 883;
2993 params!(String, Int32, Int32) => VariadicFunc::Substr => String, 877;
2994 },
2995 "substring" => Scalar {
2996 params!(String, Int32) => VariadicFunc::Substr => String, 937;
2997 params!(String, Int32, Int32) => VariadicFunc::Substr => String, 936;
2998 },
2999 "sqrt" => Scalar {
3000 params!(Float64) => UnaryFunc::SqrtFloat64(func::SqrtFloat64) => Float64, 1344;
3001 params!(Numeric) => UnaryFunc::SqrtNumeric(func::SqrtNumeric) => Numeric, 1730;
3002 },
3003 "tan" => Scalar {
3004 params!(Float64) => UnaryFunc::Tan(func::Tan) => Float64, 1606;
3005 },
3006 "atan" => Scalar {
3007 params!(Float64) => UnaryFunc::Atan(func::Atan) => Float64, 1602;
3008 },
3009 "tanh" => Scalar {
3010 params!(Float64) => UnaryFunc::Tanh(func::Tanh) => Float64, 2464;
3011 },
3012 "atanh" => Scalar {
3013 params!(Float64) => UnaryFunc::Atanh(func::Atanh) => Float64, 2467;
3014 },
3015 "age" => Scalar {
3016 params!(Timestamp, Timestamp) => BinaryFunc::from(func::AgeTimestamp) => Interval, 2058;
3017 params!(TimestampTz, TimestampTz)
3018 => BinaryFunc::from(func::AgeTimestampTz) => Interval, 1199;
3019 },
3020 "timezone" => Scalar {
3021 params!(String, Timestamp)
3022 => BinaryFunc::TimezoneTimestampBinary(
3023 func::TimezoneTimestampBinary,
3024 ) => TimestampTz, 2069;
3025 params!(String, TimestampTz)
3026 => BinaryFunc::TimezoneTimestampTzBinary(
3027 func::TimezoneTimestampTzBinary,
3028 ) => Timestamp, 1159;
3029 params!(String, Time) => Operation::binary(|ecx, lhs, rhs| {
3031 ecx.require_feature_flag(&ENABLE_TIME_AT_TIME_ZONE)?;
3045 Ok(HirScalarExpr::call_variadic(
3046 VariadicFunc::TimezoneTime,
3047 vec![
3048 lhs,
3049 rhs,
3050 HirScalarExpr::call_unmaterializable(
3051 UnmaterializableFunc::CurrentTimestamp,
3052 ),
3053 ],
3054 ))
3055 }) => Time, 2037;
3056 params!(Interval, Timestamp)
3057 => BinaryFunc::from(func::TimezoneIntervalTimestampBinary)
3058 => TimestampTz, 2070;
3059 params!(Interval, TimestampTz)
3060 => BinaryFunc::from(func::TimezoneIntervalTimestampTzBinary)
3061 => Timestamp, 1026;
3062 params!(Interval, Time)
3064 => BinaryFunc::from(func::TimezoneIntervalTimeBinary) => Time, 2038;
3065 },
3066 "to_char" => Scalar {
3067 params!(Timestamp, String)
3068 => BinaryFunc::from(func::ToCharTimestampFormat) => String, 2049;
3069 params!(TimestampTz, String)
3070 => BinaryFunc::from(func::ToCharTimestampTzFormat) => String, 1770;
3071 },
3072 "to_jsonb" => Scalar {
3083 params!(Any) => Operation::unary(|ecx, e| {
3084 let e = match ecx.scalar_type(&e) {
3086 SqlScalarType::Char { length } => {
3087 e.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
3088 }
3089 _ => e,
3090 };
3091 Ok(typeconv::to_jsonb(ecx, e))
3092 }) => Jsonb, 3787;
3093 },
3094 "to_timestamp" => Scalar {
3095 params!(Float64) => UnaryFunc::ToTimestamp(func::ToTimestamp) => TimestampTz, 1158;
3096 },
3097 "translate" => Scalar {
3098 params!(String, String, String) => VariadicFunc::Translate => String, 878;
3099 },
3100 "trunc" => Scalar {
3101 params!(Float32) => UnaryFunc::TruncFloat32(func::TruncFloat32)
3102 => Float32, oid::FUNC_TRUNC_F32_OID;
3103 params!(Float64) => UnaryFunc::TruncFloat64(func::TruncFloat64) => Float64, 1343;
3104 params!(Numeric) => UnaryFunc::TruncNumeric(func::TruncNumeric) => Numeric, 1710;
3105 },
3106 "tsrange" => Scalar {
3107 params!(Timestamp, Timestamp) => Operation::variadic(|_ecx, mut exprs| {
3108 exprs.push(HirScalarExpr::literal(
3109 Datum::String("[)"), SqlScalarType::String,
3110 ));
3111 Ok(HirScalarExpr::call_variadic(
3112 VariadicFunc::RangeCreate {
3113 elem_type: SqlScalarType::Timestamp { precision: None },
3114 },
3115 exprs,
3116 ))
3117 }) => SqlScalarType::Range {
3118 element_type: Box::new(SqlScalarType::Timestamp { precision: None }),
3119 }, 3933;
3120 params!(Timestamp, Timestamp, String) => Operation::variadic(|_ecx, exprs| {
3121 Ok(HirScalarExpr::call_variadic(
3122 VariadicFunc::RangeCreate {
3123 elem_type: SqlScalarType::Timestamp { precision: None },
3124 },
3125 exprs,
3126 ))
3127 }) => SqlScalarType::Range {
3128 element_type: Box::new(SqlScalarType::Timestamp { precision: None }),
3129 }, 3934;
3130 },
3131 "tstzrange" => Scalar {
3132 params!(TimestampTz, TimestampTz) => Operation::variadic(|_ecx, mut exprs| {
3133 exprs.push(HirScalarExpr::literal(
3134 Datum::String("[)"), SqlScalarType::String,
3135 ));
3136 Ok(HirScalarExpr::call_variadic(
3137 VariadicFunc::RangeCreate {
3138 elem_type: SqlScalarType::TimestampTz { precision: None },
3139 },
3140 exprs,
3141 ))
3142 }) => SqlScalarType::Range {
3143 element_type: Box::new(SqlScalarType::TimestampTz { precision: None }),
3144 }, 3937;
3145 params!(TimestampTz, TimestampTz, String) => Operation::variadic(|_ecx, exprs| {
3146 Ok(HirScalarExpr::call_variadic(
3147 VariadicFunc::RangeCreate {
3148 elem_type: SqlScalarType::TimestampTz { precision: None },
3149 },
3150 exprs,
3151 ))
3152 }) => SqlScalarType::Range {
3153 element_type: Box::new(SqlScalarType::TimestampTz { precision: None }),
3154 }, 3938;
3155 },
3156 "upper" => Scalar {
3157 params!(String) => UnaryFunc::Upper(func::Upper) => String, 871;
3158 params!(RangeAny) => UnaryFunc::RangeUpper(func::RangeUpper) => AnyElement, 3849;
3159 },
3160 "upper_inc" => Scalar {
3161 params!(RangeAny) => UnaryFunc::RangeUpperInc(func::RangeUpperInc) => Bool, 3852;
3162 },
3163 "upper_inf" => Scalar {
3164 params!(RangeAny) => UnaryFunc::RangeUpperInf(func::RangeUpperInf) => Bool, 3854;
3165 },
3166 "uuid_generate_v5" => Scalar {
3167 params!(Uuid, String) => BinaryFunc::from(func::UuidGenerateV5)
3168 => Uuid, oid::FUNC_PG_UUID_GENERATE_V5;
3169 },
3170 "variance" => Scalar {
3171 params!(Float32) =>
3172 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3173 => Float64, 2151;
3174 params!(Float64) =>
3175 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3176 => Float64, 2152;
3177 params!(Int16) =>
3178 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3179 => Numeric, 2150;
3180 params!(Int32) =>
3181 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3182 => Numeric, 2149;
3183 params!(Int64) =>
3184 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3185 => Numeric, 2148;
3186 params!(UInt16) =>
3187 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3188 => Numeric, oid::FUNC_VARIANCE_UINT16_OID;
3189 params!(UInt32) =>
3190 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3191 => Numeric, oid::FUNC_VARIANCE_UINT32_OID;
3192 params!(UInt64) =>
3193 Operation::nullary(|_ecx| catalog_name_only!("variance"))
3194 => Numeric, oid::FUNC_VARIANCE_UINT64_OID;
3195 },
3196 "var_pop" => Scalar {
3197 params!(Float32) =>
3198 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3199 => Float64, 2721;
3200 params!(Float64) =>
3201 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3202 => Float64, 2722;
3203 params!(Int16) =>
3204 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3205 => Numeric, 2720;
3206 params!(Int32) =>
3207 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3208 => Numeric, 2719;
3209 params!(Int64) =>
3210 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3211 => Numeric, 2718;
3212 params!(UInt16) =>
3213 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3214 => Numeric, oid::FUNC_VAR_POP_UINT16_OID;
3215 params!(UInt32) =>
3216 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3217 => Numeric, oid::FUNC_VAR_POP_UINT32_OID;
3218 params!(UInt64) =>
3219 Operation::nullary(|_ecx| catalog_name_only!("var_pop"))
3220 => Numeric, oid::FUNC_VAR_POP_UINT64_OID;
3221 },
3222 "var_samp" => Scalar {
3223 params!(Float32) =>
3224 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3225 => Float64, 2644;
3226 params!(Float64) =>
3227 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3228 => Float64, 2645;
3229 params!(Int16) =>
3230 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3231 => Numeric, 2643;
3232 params!(Int32) =>
3233 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3234 => Numeric, 2642;
3235 params!(Int64) =>
3236 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3237 => Numeric, 2641;
3238 params!(UInt16) =>
3239 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3240 => Numeric, oid::FUNC_VAR_SAMP_UINT16_OID;
3241 params!(UInt32) =>
3242 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3243 => Numeric, oid::FUNC_VAR_SAMP_UINT32_OID;
3244 params!(UInt64) =>
3245 Operation::nullary(|_ecx| catalog_name_only!("var_samp"))
3246 => Numeric, oid::FUNC_VAR_SAMP_UINT64_OID;
3247 },
3248 "version" => Scalar {
3249 params!() => UnmaterializableFunc::Version => String, 89;
3250 },
3251
3252 "aclitemin" => Scalar {
3254 params!(String) => Operation::variadic(|_ecx, _exprs| {
3255 bail_unsupported!("aclitemin")
3256 }) => AclItem, 1031;
3257 },
3258 "any_in" => Scalar {
3259 params!(String) => Operation::variadic(|_ecx, _exprs| {
3260 bail_unsupported!("any_in")
3261 }) => Any, 2294;
3262 },
3263 "anyarray_in" => Scalar {
3264 params!(String) => Operation::variadic(|_ecx, _exprs| {
3265 bail_unsupported!("anyarray_in")
3266 }) => ArrayAny, 2296;
3267 },
3268 "anycompatible_in" => Scalar {
3269 params!(String) => Operation::variadic(|_ecx, _exprs| {
3270 bail_unsupported!("anycompatible_in")
3271 }) => AnyCompatible, 5086;
3272 },
3273 "anycompatiblearray_in" => Scalar {
3274 params!(String) => Operation::variadic(|_ecx, _exprs| {
3275 bail_unsupported!("anycompatiblearray_in")
3276 }) => ArrayAnyCompatible, 5088;
3277 },
3278 "anycompatiblenonarray_in" => Scalar {
3279 params!(String) => Operation::variadic(|_ecx, _exprs| {
3280 bail_unsupported!("anycompatiblenonarray_in")
3281 }) => NonVecAnyCompatible, 5092;
3282 },
3283 "anycompatiblerange_in" => Scalar {
3284 params!(String, Oid, Int32) =>
3285 Operation::variadic(|_ecx, _exprs| {
3286 bail_unsupported!("anycompatiblerange_in")
3287 }) => RangeAnyCompatible, 5094;
3288 },
3289 "anyelement_in" => Scalar {
3290 params!(String) => Operation::variadic(|_ecx, _exprs| {
3291 bail_unsupported!("anyelement_in")
3292 }) => AnyElement, 2312;
3293 },
3294 "anynonarray_in" => Scalar {
3295 params!(String) => Operation::variadic(|_ecx, _exprs| {
3296 bail_unsupported!("anynonarray_in")
3297 }) => NonVecAny, 2777;
3298 },
3299 "anyrange_in" => Scalar {
3300 params!(String, Oid, Int32) =>
3301 Operation::variadic(|_ecx, _exprs| {
3302 bail_unsupported!("anyrange_in")
3303 }) => RangeAny, 3832;
3304 },
3305 "array_in" => Scalar {
3306 params!(String, Oid, Int32) =>
3307 Operation::variadic(|_ecx, _exprs| {
3308 bail_unsupported!("array_in")
3309 }) => ArrayAny, 750;
3310 },
3311 "boolin" => Scalar {
3312 params!(String) => Operation::variadic(|_ecx, _exprs| {
3313 bail_unsupported!("boolin")
3314 }) => Bool, 1242;
3315 },
3316 "bpcharin" => Scalar {
3317 params!(String, Oid, Int32) =>
3318 Operation::variadic(|_ecx, _exprs| {
3319 bail_unsupported!("bpcharin")
3320 }) => Char, 1044;
3321 },
3322 "byteain" => Scalar {
3323 params!(String) => Operation::variadic(|_ecx, _exprs| {
3324 bail_unsupported!("byteain")
3325 }) => Bytes, 1244;
3326 },
3327 "charin" => Scalar {
3328 params!(String) => Operation::variadic(|_ecx, _exprs| {
3329 bail_unsupported!("charin")
3330 }) => PgLegacyChar, 1245;
3331 },
3332 "date_in" => Scalar {
3333 params!(String) => Operation::variadic(|_ecx, _exprs| {
3334 bail_unsupported!("date_in")
3335 }) => Date, 1084;
3336 },
3337 "float4in" => Scalar {
3338 params!(String) => Operation::variadic(|_ecx, _exprs| {
3339 bail_unsupported!("float4in")
3340 }) => Float32, 200;
3341 },
3342 "float8in" => Scalar {
3343 params!(String) => Operation::variadic(|_ecx, _exprs| {
3344 bail_unsupported!("float8in")
3345 }) => Float64, 214;
3346 },
3347 "int2in" => Scalar {
3348 params!(String) => Operation::variadic(|_ecx, _exprs| {
3349 bail_unsupported!("int2in")
3350 }) => Int16, 38;
3351 },
3352 "int2vectorin" => Scalar {
3353 params!(String) => Operation::variadic(|_ecx, _exprs| {
3354 bail_unsupported!("int2vectorin")
3355 }) => Int2Vector, 40;
3356 },
3357 "int4in" => Scalar {
3358 params!(String) => Operation::variadic(|_ecx, _exprs| {
3359 bail_unsupported!("int4in")
3360 }) => Int32, 42;
3361 },
3362 "int8in" => Scalar {
3363 params!(String) => Operation::variadic(|_ecx, _exprs| {
3364 bail_unsupported!("int8in")
3365 }) => Int64, 460;
3366 },
3367 "internal_in" => Scalar {
3368 params!(String) => Operation::variadic(|_ecx, _exprs| {
3369 bail_unsupported!("internal_in")
3370 }) => Internal, 2304;
3371 },
3372 "interval_in" => Scalar {
3373 params!(String, Oid, Int32) =>
3374 Operation::variadic(|_ecx, _exprs| {
3375 bail_unsupported!("interval_in")
3376 }) => Interval, 1160;
3377 },
3378 "jsonb_in" => Scalar {
3379 params!(String) => Operation::variadic(|_ecx, _exprs| {
3380 bail_unsupported!("jsonb_in")
3381 }) => Jsonb, 3806;
3382 },
3383 "namein" => Scalar {
3384 params!(String) => Operation::variadic(|_ecx, _exprs| {
3385 bail_unsupported!("namein")
3386 }) => PgLegacyName, 34;
3387 },
3388 "numeric_in" => Scalar {
3389 params!(String, Oid, Int32) =>
3390 Operation::variadic(|_ecx, _exprs| {
3391 bail_unsupported!("numeric_in")
3392 }) => Numeric, 1701;
3393 },
3394 "oidin" => Scalar {
3395 params!(String) => Operation::variadic(|_ecx, _exprs| {
3396 bail_unsupported!("oidin")
3397 }) => Oid, 1798;
3398 },
3399 "range_in" => Scalar {
3400 params!(String, Oid, Int32) =>
3401 Operation::variadic(|_ecx, _exprs| {
3402 bail_unsupported!("range_in")
3403 }) => RangeAny, 3834;
3404 },
3405 "record_in" => Scalar {
3406 params!(String, Oid, Int32) =>
3407 Operation::variadic(|_ecx, _exprs| {
3408 bail_unsupported!("record_in")
3409 }) => RecordAny, 2290;
3410 },
3411 "regclassin" => Scalar {
3412 params!(String) => Operation::variadic(|_ecx, _exprs| {
3413 bail_unsupported!("regclassin")
3414 }) => RegClass, 2218;
3415 },
3416 "regprocin" => Scalar {
3417 params!(String) => Operation::variadic(|_ecx, _exprs| {
3418 bail_unsupported!("regprocin")
3419 }) => RegProc, 44;
3420 },
3421 "regtypein" => Scalar {
3422 params!(String) => Operation::variadic(|_ecx, _exprs| {
3423 bail_unsupported!("regtypein")
3424 }) => RegType, 2220;
3425 },
3426 "textin" => Scalar {
3427 params!(String) => Operation::variadic(|_ecx, _exprs| {
3428 bail_unsupported!("textin")
3429 }) => String, 46;
3430 },
3431 "time_in" => Scalar {
3432 params!(String, Oid, Int32) =>
3433 Operation::variadic(|_ecx, _exprs| {
3434 bail_unsupported!("time_in")
3435 }) => Time, 1143;
3436 },
3437 "timestamp_in" => Scalar {
3438 params!(String, Oid, Int32) =>
3439 Operation::variadic(|_ecx, _exprs| {
3440 bail_unsupported!("timestamp_in")
3441 }) => Timestamp, 1312;
3442 },
3443 "timestamptz_in" => Scalar {
3444 params!(String, Oid, Int32) =>
3445 Operation::variadic(|_ecx, _exprs| {
3446 bail_unsupported!("timestamptz_in")
3447 }) => TimestampTz, 1150;
3448 },
3449 "varcharin" => Scalar {
3450 params!(String, Oid, Int32) =>
3451 Operation::variadic(|_ecx, _exprs| {
3452 bail_unsupported!("varcharin")
3453 }) => VarChar, 1046;
3454 },
3455 "uuid_in" => Scalar {
3456 params!(String) => Operation::variadic(|_ecx, _exprs| {
3457 bail_unsupported!("uuid_in")
3458 }) => Uuid, 2952;
3459 },
3460 "boolrecv" => Scalar {
3461 params!(Internal) =>
3462 Operation::nullary(|_ecx| catalog_name_only!("boolrecv"))
3463 => Bool, 2436;
3464 },
3465 "textrecv" => Scalar {
3466 params!(Internal) =>
3467 Operation::nullary(|_ecx| catalog_name_only!("textrecv"))
3468 => String, 2414;
3469 },
3470 "anyarray_recv" => Scalar {
3471 params!(Internal) =>
3472 Operation::nullary(|_ecx| {
3473 catalog_name_only!("anyarray_recv")
3474 }) => ArrayAny, 2502;
3475 },
3476 "bytearecv" => Scalar {
3477 params!(Internal) =>
3478 Operation::nullary(|_ecx| catalog_name_only!("bytearecv"))
3479 => Bytes, 2412;
3480 },
3481 "bpcharrecv" => Scalar {
3482 params!(Internal) =>
3483 Operation::nullary(|_ecx| {
3484 catalog_name_only!("bpcharrecv")
3485 }) => Char, 2430;
3486 },
3487 "charrecv" => Scalar {
3488 params!(Internal) =>
3489 Operation::nullary(|_ecx| catalog_name_only!("charrecv"))
3490 => PgLegacyChar, 2434;
3491 },
3492 "date_recv" => Scalar {
3493 params!(Internal) =>
3494 Operation::nullary(|_ecx| catalog_name_only!("date_recv"))
3495 => Date, 2468;
3496 },
3497 "float4recv" => Scalar {
3498 params!(Internal) =>
3499 Operation::nullary(|_ecx| {
3500 catalog_name_only!("float4recv")
3501 }) => Float32, 2424;
3502 },
3503 "float8recv" => Scalar {
3504 params!(Internal) =>
3505 Operation::nullary(|_ecx| {
3506 catalog_name_only!("float8recv")
3507 }) => Float64, 2426;
3508 },
3509 "int4recv" => Scalar {
3510 params!(Internal) =>
3511 Operation::nullary(|_ecx| catalog_name_only!("int4recv"))
3512 => Int32, 2406;
3513 },
3514 "int8recv" => Scalar {
3515 params!(Internal) =>
3516 Operation::nullary(|_ecx| catalog_name_only!("int8recv"))
3517 => Int64, 2408;
3518 },
3519 "interval_recv" => Scalar {
3520 params!(Internal) =>
3521 Operation::nullary(|_ecx| {
3522 catalog_name_only!("interval_recv")
3523 }) => Interval, 2478;
3524 },
3525 "jsonb_recv" => Scalar {
3526 params!(Internal) =>
3527 Operation::nullary(|_ecx| {
3528 catalog_name_only!("jsonb_recv")
3529 }) => Jsonb, 3805;
3530 },
3531 "namerecv" => Scalar {
3532 params!(Internal) =>
3533 Operation::nullary(|_ecx| catalog_name_only!("namerecv"))
3534 => PgLegacyName, 2422;
3535 },
3536 "numeric_recv" => Scalar {
3537 params!(Internal) =>
3538 Operation::nullary(|_ecx| {
3539 catalog_name_only!("numeric_recv")
3540 }) => Numeric, 2460;
3541 },
3542 "oidrecv" => Scalar {
3543 params!(Internal) =>
3544 Operation::nullary(|_ecx| catalog_name_only!("oidrecv"))
3545 => Oid, 2418;
3546 },
3547 "record_recv" => Scalar {
3548 params!(Internal) =>
3549 Operation::nullary(|_ecx| {
3550 catalog_name_only!("recordrerecord_recvcv")
3551 }) => RecordAny, 2402;
3552 },
3553 "regclassrecv" => Scalar {
3554 params!(Internal) =>
3555 Operation::nullary(|_ecx| {
3556 catalog_name_only!("regclassrecv")
3557 }) => RegClass, 2452;
3558 },
3559 "regprocrecv" => Scalar {
3560 params!(Internal) =>
3561 Operation::nullary(|_ecx| {
3562 catalog_name_only!("regprocrecv")
3563 }) => RegProc, 2444;
3564 },
3565 "regtyperecv" => Scalar {
3566 params!(Internal) =>
3567 Operation::nullary(|_ecx| {
3568 catalog_name_only!("regtyperecv")
3569 }) => RegType, 2454;
3570 },
3571 "int2recv" => Scalar {
3572 params!(Internal) =>
3573 Operation::nullary(|_ecx| catalog_name_only!("int2recv"))
3574 => Int16, 2404;
3575 },
3576 "time_recv" => Scalar {
3577 params!(Internal) =>
3578 Operation::nullary(|_ecx| catalog_name_only!("time_recv"))
3579 => Time, 2470;
3580 },
3581 "timestamp_recv" => Scalar {
3582 params!(Internal) =>
3583 Operation::nullary(|_ecx| {
3584 catalog_name_only!("timestamp_recv")
3585 }) => Timestamp, 2474;
3586 },
3587 "timestamptz_recv" => Scalar {
3588 params!(Internal) =>
3589 Operation::nullary(|_ecx| {
3590 catalog_name_only!("timestamptz_recv")
3591 }) => TimestampTz, 2476;
3592 },
3593 "uuid_recv" => Scalar {
3594 params!(Internal) =>
3595 Operation::nullary(|_ecx| catalog_name_only!("uuid_recv"))
3596 => Uuid, 2961;
3597 },
3598 "varcharrecv" => Scalar {
3599 params!(Internal) =>
3600 Operation::nullary(|_ecx| {
3601 catalog_name_only!("varcharrecv")
3602 }) => VarChar, 2432;
3603 },
3604 "int2vectorrecv" => Scalar {
3605 params!(Internal) =>
3606 Operation::nullary(|_ecx| {
3607 catalog_name_only!("int2vectorrecv")
3608 }) => Int2Vector, 2410;
3609 },
3610 "anycompatiblearray_recv" => Scalar {
3611 params!(Internal) =>
3612 Operation::nullary(|_ecx| {
3613 catalog_name_only!("anycompatiblearray_recv")
3614 }) => ArrayAnyCompatible, 5090;
3615 },
3616 "array_recv" => Scalar {
3617 params!(Internal) =>
3618 Operation::nullary(|_ecx| {
3619 catalog_name_only!("array_recv")
3620 }) => ArrayAny, 2400;
3621 },
3622 "range_recv" => Scalar {
3623 params!(Internal) =>
3624 Operation::nullary(|_ecx| {
3625 catalog_name_only!("range_recv")
3626 }) => RangeAny, 3836;
3627 },
3628
3629
3630 "array_agg" => Aggregate {
3632 params!(NonVecAny) => Operation::unary_ordered(|ecx, e, order_by| {
3633 let elem_type = ecx.scalar_type(&e);
3634
3635 let elem_type = match elem_type.array_of_self_elem_type() {
3636 Ok(elem_type) => elem_type,
3637 Err(elem_type) => bail_unsupported!(
3638 format!("array_agg on {}", ecx.humanize_scalar_type(&elem_type, false))
3639 ),
3640 };
3641
3642 let e_arr = HirScalarExpr::call_variadic(
3645 VariadicFunc::ArrayCreate { elem_type },
3646 vec![e],
3647 );
3648 Ok((e_arr, AggregateFunc::ArrayConcat { order_by }))
3649 }) => ArrayAny, 2335;
3650 params!(ArrayAny) => Operation::unary(|_ecx, _e| {
3651 bail_unsupported!("array_agg on arrays")
3652 }) => ArrayAny, 4053;
3653 },
3654 "bool_and" => Aggregate {
3655 params!(Bool) =>
3656 Operation::nullary(|_ecx| catalog_name_only!("bool_and"))
3657 => Bool, 2517;
3658 },
3659 "bool_or" => Aggregate {
3660 params!(Bool) => Operation::nullary(|_ecx| catalog_name_only!("bool_or")) => Bool, 2518;
3661 },
3662 "count" => Aggregate {
3663 params!() => Operation::nullary(|_ecx| {
3664 Ok((HirScalarExpr::literal_true(), AggregateFunc::Count))
3668 }) => Int64, 2803;
3669 params!(Any) => AggregateFunc::Count => Int64, 2147;
3670 },
3671 "max" => Aggregate {
3672 params!(Bool) => AggregateFunc::MaxBool => Bool, oid::FUNC_MAX_BOOL_OID;
3673 params!(Int16) => AggregateFunc::MaxInt16 => Int16, 2117;
3674 params!(Int32) => AggregateFunc::MaxInt32 => Int32, 2116;
3675 params!(Int64) => AggregateFunc::MaxInt64 => Int64, 2115;
3676 params!(UInt16) => AggregateFunc::MaxUInt16 => UInt16, oid::FUNC_MAX_UINT16_OID;
3677 params!(UInt32) => AggregateFunc::MaxUInt32 => UInt32, oid::FUNC_MAX_UINT32_OID;
3678 params!(UInt64) => AggregateFunc::MaxUInt64 => UInt64, oid::FUNC_MAX_UINT64_OID;
3679 params!(MzTimestamp) => AggregateFunc::MaxMzTimestamp
3680 => MzTimestamp, oid::FUNC_MAX_MZ_TIMESTAMP_OID;
3681 params!(Float32) => AggregateFunc::MaxFloat32 => Float32, 2119;
3682 params!(Float64) => AggregateFunc::MaxFloat64 => Float64, 2120;
3683 params!(String) => AggregateFunc::MaxString => String, 2129;
3684 params!(Char) => AggregateFunc::MaxString => Char, 2244;
3686 params!(Date) => AggregateFunc::MaxDate => Date, 2122;
3687 params!(Timestamp) => AggregateFunc::MaxTimestamp => Timestamp, 2126;
3688 params!(TimestampTz) => AggregateFunc::MaxTimestampTz => TimestampTz, 2127;
3689 params!(Numeric) => AggregateFunc::MaxNumeric => Numeric, oid::FUNC_MAX_NUMERIC_OID;
3690 params!(Interval) => AggregateFunc::MaxInterval => Interval, 2128;
3691 params!(Time) => AggregateFunc::MaxTime => Time, 2123;
3692 },
3693 "min" => Aggregate {
3694 params!(Bool) => AggregateFunc::MinBool => Bool, oid::FUNC_MIN_BOOL_OID;
3695 params!(Int16) => AggregateFunc::MinInt16 => Int16, 2133;
3696 params!(Int32) => AggregateFunc::MinInt32 => Int32, 2132;
3697 params!(Int64) => AggregateFunc::MinInt64 => Int64, 2131;
3698 params!(UInt16) => AggregateFunc::MinUInt16 => UInt16, oid::FUNC_MIN_UINT16_OID;
3699 params!(UInt32) => AggregateFunc::MinUInt32 => UInt32, oid::FUNC_MIN_UINT32_OID;
3700 params!(UInt64) => AggregateFunc::MinUInt64 => UInt64, oid::FUNC_MIN_UINT64_OID;
3701 params!(MzTimestamp) => AggregateFunc::MinMzTimestamp
3702 => MzTimestamp, oid::FUNC_MIN_MZ_TIMESTAMP_OID;
3703 params!(Float32) => AggregateFunc::MinFloat32 => Float32, 2135;
3704 params!(Float64) => AggregateFunc::MinFloat64 => Float64, 2136;
3705 params!(String) => AggregateFunc::MinString => String, 2145;
3706 params!(Char) => AggregateFunc::MinString => Char, 2245;
3708 params!(Date) => AggregateFunc::MinDate => Date, 2138;
3709 params!(Timestamp) => AggregateFunc::MinTimestamp => Timestamp, 2142;
3710 params!(TimestampTz) => AggregateFunc::MinTimestampTz => TimestampTz, 2143;
3711 params!(Numeric) => AggregateFunc::MinNumeric => Numeric, oid::FUNC_MIN_NUMERIC_OID;
3712 params!(Interval) => AggregateFunc::MinInterval => Interval, 2144;
3713 params!(Time) => AggregateFunc::MinTime => Time, 2139;
3714 },
3715 "jsonb_agg" => Aggregate {
3716 params!(Any) => Operation::unary_ordered(|ecx, e, order_by| {
3717 let e = match ecx.scalar_type(&e) {
3719 SqlScalarType::Char { length } => {
3720 e.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
3721 }
3722 _ => e,
3723 };
3724 let json_null = HirScalarExpr::literal(Datum::JsonNull, SqlScalarType::Jsonb);
3730 let e = HirScalarExpr::call_variadic(
3731 VariadicFunc::Coalesce,
3732 vec![typeconv::to_jsonb(ecx, e), json_null],
3733 );
3734 Ok((e, AggregateFunc::JsonbAgg { order_by }))
3735 }) => Jsonb, 3267;
3736 },
3737 "jsonb_object_agg" => Aggregate {
3738 params!(Any, Any) => Operation::binary_ordered(|ecx, key, val, order_by| {
3739 let key = match ecx.scalar_type(&key) {
3741 SqlScalarType::Char { length } => {
3742 key.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
3743 }
3744 _ => key,
3745 };
3746 let val = match ecx.scalar_type(&val) {
3747 SqlScalarType::Char { length } => {
3748 val.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
3749 }
3750 _ => val,
3751 };
3752
3753 let json_null = HirScalarExpr::literal(Datum::JsonNull, SqlScalarType::Jsonb);
3754 let key = typeconv::to_string(ecx, key);
3755 let val = HirScalarExpr::call_variadic(
3762 VariadicFunc::Coalesce,
3763 vec![typeconv::to_jsonb(ecx, val), json_null],
3764 );
3765 let e = HirScalarExpr::call_variadic(
3766 VariadicFunc::RecordCreate {
3767 field_names: vec![ColumnName::from("key"), ColumnName::from("val")],
3768 },
3769 vec![key, val],
3770 );
3771 Ok((e, AggregateFunc::JsonbObjectAgg { order_by }))
3772 }) => Jsonb, 3270;
3773 },
3774 "string_agg" => Aggregate {
3775 params!(String, String) => Operation::binary_ordered(|_ecx, value, sep, order_by| {
3776 let e = HirScalarExpr::call_variadic(
3777 VariadicFunc::RecordCreate {
3778 field_names: vec![ColumnName::from("value"), ColumnName::from("sep")],
3779 },
3780 vec![value, sep],
3781 );
3782 Ok((e, AggregateFunc::StringAgg { order_by }))
3783 }) => String, 3538;
3784 params!(Bytes, Bytes) =>
3785 Operation::binary(|_ecx, _l, _r| {
3786 bail_unsupported!("string_agg on BYTEA")
3787 }) => Bytes, 3545;
3788 },
3789 "string_to_array" => Scalar {
3790 params!(String, String) => VariadicFunc::StringToArray
3791 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 376;
3792 params!(String, String, String) => VariadicFunc::StringToArray
3793 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 394;
3794 },
3795 "sum" => Aggregate {
3796 params!(Int16) => AggregateFunc::SumInt16 => Int64, 2109;
3797 params!(Int32) => AggregateFunc::SumInt32 => Int64, 2108;
3798 params!(Int64) => AggregateFunc::SumInt64 => Numeric, 2107;
3799 params!(UInt16) => AggregateFunc::SumUInt16 => UInt64, oid::FUNC_SUM_UINT16_OID;
3800 params!(UInt32) => AggregateFunc::SumUInt32 => UInt64, oid::FUNC_SUM_UINT32_OID;
3801 params!(UInt64) => AggregateFunc::SumUInt64 => Numeric, oid::FUNC_SUM_UINT64_OID;
3802 params!(Float32) => AggregateFunc::SumFloat32 => Float32, 2110;
3803 params!(Float64) => AggregateFunc::SumFloat64 => Float64, 2111;
3804 params!(Numeric) => AggregateFunc::SumNumeric => Numeric, 2114;
3805 params!(Interval) => Operation::unary(|_ecx, _e| {
3806 bail_unsupported!("sum(interval)");
3811 }) => Interval, 2113;
3812 },
3813
3814 "row_number" => ScalarWindow {
3816 params!() => ScalarWindowFunc::RowNumber => Int64, 3100;
3817 },
3818 "rank" => ScalarWindow {
3819 params!() => ScalarWindowFunc::Rank => Int64, 3101;
3820 },
3821 "dense_rank" => ScalarWindow {
3822 params!() => ScalarWindowFunc::DenseRank => Int64, 3102;
3823 },
3824 "lag" => ValueWindow {
3825 params!(AnyElement) => Operation::unary(|ecx, e| {
3827 let typ = ecx.scalar_type(&e);
3828 let e = HirScalarExpr::call_variadic(
3829 VariadicFunc::RecordCreate {
3830 field_names: vec![
3831 ColumnName::from("expr"),
3832 ColumnName::from("offset"),
3833 ColumnName::from("default"),
3834 ],
3835 },
3836 vec![
3837 e,
3838 HirScalarExpr::literal(Datum::Int32(1), SqlScalarType::Int32),
3839 HirScalarExpr::literal_null(typ),
3840 ],
3841 );
3842 Ok((e, ValueWindowFunc::Lag))
3843 }) => AnyElement, 3106;
3844 params!(AnyElement, Int32) => Operation::binary(|ecx, e, offset| {
3845 let typ = ecx.scalar_type(&e);
3846 let e = HirScalarExpr::call_variadic(
3847 VariadicFunc::RecordCreate {
3848 field_names: vec![
3849 ColumnName::from("expr"),
3850 ColumnName::from("offset"),
3851 ColumnName::from("default"),
3852 ],
3853 },
3854 vec![e, offset, HirScalarExpr::literal_null(typ)],
3855 );
3856 Ok((e, ValueWindowFunc::Lag))
3857 }) => AnyElement, 3107;
3858 params!(AnyCompatible, Int32, AnyCompatible) => Operation::variadic(|_ecx, exprs| {
3859 let e = HirScalarExpr::call_variadic(
3860 VariadicFunc::RecordCreate {
3861 field_names: vec![
3862 ColumnName::from("expr"),
3863 ColumnName::from("offset"),
3864 ColumnName::from("default"),
3865 ],
3866 },
3867 exprs,
3868 );
3869 Ok((e, ValueWindowFunc::Lag))
3870 }) => AnyCompatible, 3108;
3871 },
3872 "lead" => ValueWindow {
3873 params!(AnyElement) => Operation::unary(|ecx, e| {
3875 let typ = ecx.scalar_type(&e);
3876 let e = HirScalarExpr::call_variadic(
3877 VariadicFunc::RecordCreate {
3878 field_names: vec![
3879 ColumnName::from("expr"),
3880 ColumnName::from("offset"),
3881 ColumnName::from("default"),
3882 ],
3883 },
3884 vec![
3885 e,
3886 HirScalarExpr::literal(Datum::Int32(1), SqlScalarType::Int32),
3887 HirScalarExpr::literal_null(typ),
3888 ],
3889 );
3890 Ok((e, ValueWindowFunc::Lead))
3891 }) => AnyElement, 3109;
3892 params!(AnyElement, Int32) => Operation::binary(|ecx, e, offset| {
3893 let typ = ecx.scalar_type(&e);
3894 let e = HirScalarExpr::call_variadic(
3895 VariadicFunc::RecordCreate {
3896 field_names: vec![
3897 ColumnName::from("expr"),
3898 ColumnName::from("offset"),
3899 ColumnName::from("default"),
3900 ],
3901 },
3902 vec![e, offset, HirScalarExpr::literal_null(typ)],
3903 );
3904 Ok((e, ValueWindowFunc::Lead))
3905 }) => AnyElement, 3110;
3906 params!(AnyCompatible, Int32, AnyCompatible) => Operation::variadic(|_ecx, exprs| {
3907 let e = HirScalarExpr::call_variadic(
3908 VariadicFunc::RecordCreate {
3909 field_names: vec![
3910 ColumnName::from("expr"),
3911 ColumnName::from("offset"),
3912 ColumnName::from("default"),
3913 ],
3914 },
3915 exprs,
3916 );
3917 Ok((e, ValueWindowFunc::Lead))
3918 }) => AnyCompatible, 3111;
3919 },
3920 "first_value" => ValueWindow {
3921 params!(AnyElement) => ValueWindowFunc::FirstValue => AnyElement, 3112;
3922 },
3923 "last_value" => ValueWindow {
3924 params!(AnyElement) => ValueWindowFunc::LastValue => AnyElement, 3113;
3925 },
3926
3927 "generate_series" => Table {
3929 params!(Int32, Int32, Int32) => Operation::variadic(move |_ecx, exprs| {
3930 Ok(TableFuncPlan {
3931 imp: TableFuncImpl::CallTable {
3932 func: TableFunc::GenerateSeriesInt32,
3933 exprs,
3934 },
3935 column_names: vec!["generate_series".into()],
3936 })
3937 }) => ReturnType::set_of(Int32.into()), 1066;
3938 params!(Int32, Int32) => Operation::binary(move |_ecx, start, stop| {
3939 Ok(TableFuncPlan {
3940 imp: TableFuncImpl::CallTable {
3941 func: TableFunc::GenerateSeriesInt32,
3942 exprs: vec![
3943 start, stop,
3944 HirScalarExpr::literal(Datum::Int32(1), SqlScalarType::Int32),
3945 ],
3946 },
3947 column_names: vec!["generate_series".into()],
3948 })
3949 }) => ReturnType::set_of(Int32.into()), 1067;
3950 params!(Int64, Int64, Int64) => Operation::variadic(move |_ecx, exprs| {
3951 Ok(TableFuncPlan {
3952 imp: TableFuncImpl::CallTable {
3953 func: TableFunc::GenerateSeriesInt64,
3954 exprs,
3955 },
3956 column_names: vec!["generate_series".into()],
3957 })
3958 }) => ReturnType::set_of(Int64.into()), 1068;
3959 params!(Int64, Int64) => Operation::binary(move |_ecx, start, stop| {
3960 Ok(TableFuncPlan {
3961 imp: TableFuncImpl::CallTable {
3962 func: TableFunc::GenerateSeriesInt64,
3963 exprs: vec![
3964 start, stop,
3965 HirScalarExpr::literal(Datum::Int64(1), SqlScalarType::Int64),
3966 ],
3967 },
3968 column_names: vec!["generate_series".into()],
3969 })
3970 }) => ReturnType::set_of(Int64.into()), 1069;
3971 params!(Timestamp, Timestamp, Interval) => Operation::variadic(move |_ecx, exprs| {
3972 Ok(TableFuncPlan {
3973 imp: TableFuncImpl::CallTable {
3974 func: TableFunc::GenerateSeriesTimestamp,
3975 exprs,
3976 },
3977 column_names: vec!["generate_series".into()],
3978 })
3979 }) => ReturnType::set_of(Timestamp.into()), 938;
3980 params!(TimestampTz, TimestampTz, Interval) => Operation::variadic(move |_ecx, exprs| {
3981 Ok(TableFuncPlan {
3982 imp: TableFuncImpl::CallTable {
3983 func: TableFunc::GenerateSeriesTimestampTz,
3984 exprs,
3985 },
3986 column_names: vec!["generate_series".into()],
3987 })
3988 }) => ReturnType::set_of(TimestampTz.into()), 939;
3989 },
3990
3991 "generate_subscripts" => Table {
3992 params!(ArrayAny, Int32) => Operation::variadic(move |_ecx, exprs| {
3993 Ok(TableFuncPlan {
3994 imp: TableFuncImpl::CallTable {
3995 func: TableFunc::GenerateSubscriptsArray,
3996 exprs,
3997 },
3998 column_names: vec!["generate_subscripts".into()],
3999 })
4000 }) => ReturnType::set_of(Int32.into()), 1192;
4001 },
4002
4003 "jsonb_array_elements" => Table {
4004 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
4005 Ok(TableFuncPlan {
4006 imp: TableFuncImpl::CallTable {
4007 func: TableFunc::JsonbArrayElements,
4008 exprs: vec![jsonb],
4009 },
4010 column_names: vec!["value".into()],
4011 })
4012 }) => ReturnType::set_of(Jsonb.into()), 3219;
4013 },
4014 "jsonb_array_elements_text" => Table {
4015 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
4016 Ok(TableFuncPlan {
4017 imp: TableFuncImpl::CallTable {
4018 func: TableFunc::JsonbArrayElementsStringify,
4019 exprs: vec![jsonb],
4020 },
4021 column_names: vec!["value".into()],
4022 })
4023 }) => ReturnType::set_of(String.into()), 3465;
4024 },
4025 "jsonb_each" => Table {
4026 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
4027 Ok(TableFuncPlan {
4028 imp: TableFuncImpl::CallTable {
4029 func: TableFunc::JsonbEach,
4030 exprs: vec![jsonb],
4031 },
4032 column_names: vec!["key".into(), "value".into()],
4033 })
4034 }) => ReturnType::set_of(RecordAny), 3208;
4035 },
4036 "jsonb_each_text" => Table {
4037 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
4038 Ok(TableFuncPlan {
4039 imp: TableFuncImpl::CallTable {
4040 func: TableFunc::JsonbEachStringify,
4041 exprs: vec![jsonb],
4042 },
4043 column_names: vec!["key".into(), "value".into()],
4044 })
4045 }) => ReturnType::set_of(RecordAny), 3932;
4046 },
4047 "jsonb_object_keys" => Table {
4048 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
4049 Ok(TableFuncPlan {
4050 imp: TableFuncImpl::CallTable {
4051 func: TableFunc::JsonbObjectKeys,
4052 exprs: vec![jsonb],
4053 },
4054 column_names: vec!["jsonb_object_keys".into()],
4055 })
4056 }) => ReturnType::set_of(String.into()), 3931;
4057 },
4058 "date_bin_hopping" => Table {
4062 params!(Interval, Interval, Timestamp)
4064 => experimental_sql_impl_table_func(
4065 &vars::ENABLE_DATE_BIN_HOPPING, "
4066 SELECT *
4067 FROM pg_catalog.generate_series(
4068 pg_catalog.date_bin($1, $3 + $1, '1970-01-01') - $2, $3, $1
4069 ) AS dbh(date_bin_hopping)
4070 ") => ReturnType::set_of(Timestamp.into()),
4071 oid::FUNC_MZ_DATE_BIN_HOPPING_UNIX_EPOCH_TS_OID;
4072 params!(Interval, Interval, TimestampTz)
4074 => experimental_sql_impl_table_func(
4075 &vars::ENABLE_DATE_BIN_HOPPING, "
4076 SELECT *
4077 FROM pg_catalog.generate_series(
4078 pg_catalog.date_bin($1, $3 + $1, '1970-01-01') - $2, $3, $1
4079 ) AS dbh(date_bin_hopping)
4080 ") => ReturnType::set_of(TimestampTz.into()),
4081 oid::FUNC_MZ_DATE_BIN_HOPPING_UNIX_EPOCH_TSTZ_OID;
4082 params!(Interval, Interval, Timestamp, Timestamp)
4084 => experimental_sql_impl_table_func(
4085 &vars::ENABLE_DATE_BIN_HOPPING, "
4086 SELECT *
4087 FROM pg_catalog.generate_series(
4088 pg_catalog.date_bin($1, $3 + $1, $4) - $2, $3, $1
4089 ) AS dbh(date_bin_hopping)
4090 ") => ReturnType::set_of(Timestamp.into()),
4091 oid::FUNC_MZ_DATE_BIN_HOPPING_TS_OID;
4092 params!(Interval, Interval, TimestampTz, TimestampTz)
4094 => experimental_sql_impl_table_func(
4095 &vars::ENABLE_DATE_BIN_HOPPING, "
4096 SELECT *
4097 FROM pg_catalog.generate_series(
4098 pg_catalog.date_bin($1, $3 + $1, $4) - $2, $3, $1
4099 ) AS dbh(date_bin_hopping)
4100 ") => ReturnType::set_of(TimestampTz.into()),
4101 oid::FUNC_MZ_DATE_BIN_HOPPING_TSTZ_OID;
4102 },
4103 "encode" => Scalar {
4104 params!(Bytes, String) => BinaryFunc::from(func::Encode) => String, 1946;
4105 },
4106 "decode" => Scalar {
4107 params!(String, String) => BinaryFunc::from(func::Decode) => Bytes, 1947;
4108 },
4109 "regexp_split_to_array" => Scalar {
4110 params!(String, String) => VariadicFunc::RegexpSplitToArray
4111 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 2767;
4112 params!(String, String, String) => VariadicFunc::RegexpSplitToArray
4113 => SqlScalarType::Array(Box::new(SqlScalarType::String)), 2768;
4114 },
4115 "regexp_split_to_table" => Table {
4116 params!(String, String) => sql_impl_table_func("
4117 SELECT unnest(regexp_split_to_array($1, $2))
4118 ") => ReturnType::set_of(String.into()), 2765;
4119 params!(String, String, String) => sql_impl_table_func("
4120 SELECT unnest(regexp_split_to_array($1, $2, $3))
4121 ") => ReturnType::set_of(String.into()), 2766;
4122 },
4123 "regexp_replace" => Scalar {
4124 params!(String, String, String) => VariadicFunc::RegexpReplace => String, 2284;
4125 params!(String, String, String, String) => VariadicFunc::RegexpReplace => String, 2285;
4126 },
4130 "regexp_matches" => Table {
4131 params!(String, String) => Operation::variadic(move |_ecx, exprs| {
4132 let column_names = vec!["regexp_matches".into()];
4133 Ok(TableFuncPlan {
4134 imp: TableFuncImpl::CallTable {
4135 func: TableFunc::RegexpMatches,
4136 exprs: vec![exprs[0].clone(), exprs[1].clone()],
4137 },
4138 column_names,
4139 })
4140 }) => ReturnType::set_of(
4141 SqlScalarType::Array(Box::new(SqlScalarType::String)).into(),
4142 ), 2763;
4143 params!(String, String, String) => Operation::variadic(move |_ecx, exprs| {
4144 let column_names = vec!["regexp_matches".into()];
4145 Ok(TableFuncPlan {
4146 imp: TableFuncImpl::CallTable {
4147 func: TableFunc::RegexpMatches,
4148 exprs: vec![exprs[0].clone(), exprs[1].clone(), exprs[2].clone()],
4149 },
4150 column_names,
4151 })
4152 }) => ReturnType::set_of(
4153 SqlScalarType::Array(Box::new(SqlScalarType::String)).into(),
4154 ), 2764;
4155 },
4156 "reverse" => Scalar {
4157 params!(String) => UnaryFunc::Reverse(func::Reverse) => String, 3062;
4158 }
4159 };
4160
4161 for sef_builtin in PG_CATALOG_SEF_BUILTINS.values() {
4165 builtins.insert(
4166 sef_builtin.name,
4167 Func::Scalar(vec![FuncImpl {
4168 oid: sef_builtin.oid,
4169 params: ParamList::Exact(
4170 sef_builtin
4171 .param_types
4172 .iter()
4173 .map(|t| ParamType::from(t.clone()))
4174 .collect(),
4175 ),
4176 return_type: ReturnType::scalar(ParamType::from(
4177 sef_builtin.return_type.scalar_type.clone(),
4178 )),
4179 op: Operation::variadic(|_ecx, _e| {
4180 bail_unsupported!(format!("{} in this position", sef_builtin.name))
4181 }),
4182 }]),
4183 );
4184 }
4185
4186 builtins
4187});
4188
4189pub static INFORMATION_SCHEMA_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> =
4190 LazyLock::new(|| {
4191 use ParamType::*;
4192 builtins! {
4193 "_pg_expandarray" => Table {
4194 params!(ArrayAny) => sql_impl_table_func("
4198 SELECT
4199 $1[s] AS x,
4200 s - pg_catalog.array_lower($1, 1) + 1 AS n
4201 FROM pg_catalog.generate_series(
4202 pg_catalog.array_lower($1, 1),
4203 pg_catalog.array_upper($1, 1),
4204 1) as g(s)
4205 ") => ReturnType::set_of(RecordAny), oid::FUNC_PG_EXPAND_ARRAY;
4206 }
4207 }
4208 });
4209
4210pub static MZ_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
4211 use ParamType::*;
4212 use SqlScalarBaseType::*;
4213 builtins! {
4214 "constant_time_eq" => Scalar {
4215 params!(Bytes, Bytes) => BinaryFunc::from(func::ConstantTimeEqBytes)
4216 => Bool, oid::FUNC_CONSTANT_TIME_EQ_BYTES_OID;
4217 params!(String, String) => BinaryFunc::from(func::ConstantTimeEqString)
4218 => Bool, oid::FUNC_CONSTANT_TIME_EQ_STRING_OID;
4219 },
4220 "avg_internal_v1" => Scalar {
4228 params!(Int64) =>
4229 Operation::nullary(|_ecx| {
4230 catalog_name_only!("avg_internal_v1")
4231 }) => Numeric,
4232 oid::FUNC_AVG_INTERNAL_V1_INT64_OID;
4233 params!(Int32) =>
4234 Operation::nullary(|_ecx| {
4235 catalog_name_only!("avg_internal_v1")
4236 }) => Numeric,
4237 oid::FUNC_AVG_INTERNAL_V1_INT32_OID;
4238 params!(Int16) =>
4239 Operation::nullary(|_ecx| {
4240 catalog_name_only!("avg_internal_v1")
4241 }) => Numeric,
4242 oid::FUNC_AVG_INTERNAL_V1_INT16_OID;
4243 params!(UInt64) =>
4244 Operation::nullary(|_ecx| {
4245 catalog_name_only!("avg_internal_v1")
4246 }) => Numeric,
4247 oid::FUNC_AVG_INTERNAL_V1_UINT64_OID;
4248 params!(UInt32) =>
4249 Operation::nullary(|_ecx| {
4250 catalog_name_only!("avg_internal_v1")
4251 }) => Numeric,
4252 oid::FUNC_AVG_INTERNAL_V1_UINT32_OID;
4253 params!(UInt16) =>
4254 Operation::nullary(|_ecx| {
4255 catalog_name_only!("avg_internal_v1")
4256 }) => Numeric,
4257 oid::FUNC_AVG_INTERNAL_V1_UINT16_OID;
4258 params!(Float32) =>
4259 Operation::nullary(|_ecx| {
4260 catalog_name_only!("avg_internal_v1")
4261 }) => Float64,
4262 oid::FUNC_AVG_INTERNAL_V1_FLOAT32_OID;
4263 params!(Float64) =>
4264 Operation::nullary(|_ecx| {
4265 catalog_name_only!("avg_internal_v1")
4266 }) => Float64,
4267 oid::FUNC_AVG_INTERNAL_V1_FLOAT64_OID;
4268 params!(Interval) =>
4269 Operation::nullary(|_ecx| {
4270 catalog_name_only!("avg_internal_v1")
4271 }) => Interval,
4272 oid::FUNC_AVG_INTERNAL_V1_INTERVAL_OID;
4273 },
4274 "csv_extract" => Table {
4275 params!(Int64, String) => Operation::binary(move |_ecx, ncols, input| {
4276 const MAX_EXTRACT_COLUMNS: i64 = 8192;
4277 const TOO_MANY_EXTRACT_COLUMNS: i64 = MAX_EXTRACT_COLUMNS + 1;
4278
4279 let ncols = match ncols.into_literal_int64() {
4280 None | Some(i64::MIN..=0) => {
4281 sql_bail!(
4282 "csv_extract number of columns \
4283 must be a positive integer literal"
4284 );
4285 },
4286 Some(ncols @ 1..=MAX_EXTRACT_COLUMNS) => ncols,
4287 Some(ncols @ TOO_MANY_EXTRACT_COLUMNS..) => {
4288 return Err(PlanError::TooManyColumns {
4289 max_num_columns: usize::try_from(MAX_EXTRACT_COLUMNS)
4290 .unwrap_or(usize::MAX),
4291 req_num_columns: usize::try_from(ncols)
4292 .unwrap_or(usize::MAX),
4293 });
4294 },
4295 };
4296 let ncols = usize::try_from(ncols).expect("known to be greater than zero");
4297
4298 let column_names = (1..=ncols).map(|i| format!("column{}", i).into()).collect();
4299 Ok(TableFuncPlan {
4300 imp: TableFuncImpl::CallTable {
4301 func: TableFunc::CsvExtract(ncols),
4302 exprs: vec![input],
4303 },
4304 column_names,
4305 })
4306 }) => ReturnType::set_of(RecordAny), oid::FUNC_CSV_EXTRACT_OID;
4307 },
4308 "concat_agg" => Aggregate {
4309 params!(Any) => Operation::unary(|_ecx, _e| {
4310 bail_unsupported!("concat_agg")
4311 }) => String, oid::FUNC_CONCAT_AGG_OID;
4312 },
4313 "crc32" => Scalar {
4314 params!(String) => UnaryFunc::Crc32String(func::Crc32String)
4315 => UInt32, oid::FUNC_CRC32_STRING_OID;
4316 params!(Bytes) => UnaryFunc::Crc32Bytes(func::Crc32Bytes)
4317 => UInt32, oid::FUNC_CRC32_BYTES_OID;
4318 },
4319 "datediff" => Scalar {
4320 params!(String, Timestamp, Timestamp)
4321 => VariadicFunc::DateDiffTimestamp
4322 => Int64, oid::FUNC_DATEDIFF_TIMESTAMP;
4323 params!(String, TimestampTz, TimestampTz)
4324 => VariadicFunc::DateDiffTimestampTz
4325 => Int64, oid::FUNC_DATEDIFF_TIMESTAMPTZ;
4326 params!(String, Date, Date) => VariadicFunc::DateDiffDate
4327 => Int64, oid::FUNC_DATEDIFF_DATE;
4328 params!(String, Time, Time) => VariadicFunc::DateDiffTime
4329 => Int64, oid::FUNC_DATEDIFF_TIME;
4330 },
4331 "has_cluster_privilege" => Scalar {
4334 params!(String, String, String) => sql_impl_func(
4335 "has_cluster_privilege(mz_internal.mz_role_oid($1), $2, $3)",
4336 ) => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_TEXT_TEXT_TEXT_OID;
4337 params!(Oid, String, String) => sql_impl_func(&format!("
4338 CASE
4339 -- We must first check $2 to avoid a potentially
4340 -- null error message (an error itself).
4341 WHEN $2 IS NULL
4342 THEN NULL
4343 -- Validate the cluster name to return a proper error.
4344 WHEN NOT EXISTS (
4345 SELECT name FROM mz_clusters WHERE name = $2)
4346 THEN mz_unsafe.mz_error_if_null(
4347 NULL::boolean,
4348 'error cluster \"' || $2 || '\" does not exist')
4349 -- Validate the privileges and other arguments.
4350 WHEN NOT mz_internal.mz_validate_privileges($3)
4351 OR $1 IS NULL
4352 OR $3 IS NULL
4353 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
4354 THEN NULL
4355 ELSE COALESCE(
4356 (
4357 SELECT
4358 bool_or(
4359 mz_internal.mz_acl_item_contains_privilege(privilege, $3)
4360 )
4361 AS has_cluster_privilege
4362 FROM
4363 (
4364 SELECT
4365 unnest(privileges)
4366 FROM
4367 mz_clusters
4368 WHERE
4369 mz_clusters.name = $2
4370 )
4371 AS user_privs (privilege)
4372 LEFT JOIN mz_catalog.mz_roles ON
4373 mz_internal.mz_aclitem_grantee(privilege) = mz_roles.id
4374 WHERE
4375 mz_internal.mz_aclitem_grantee(privilege) = '{}'
4376 OR pg_has_role($1, mz_roles.oid, 'USAGE')
4377 ),
4378 false
4379 )
4380 END
4381 ", RoleId::Public))
4382 => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_OID_TEXT_TEXT_OID;
4383 params!(String, String) => sql_impl_func(
4384 "has_cluster_privilege(current_user, $1, $2)",
4385 ) => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_TEXT_TEXT_OID;
4386 },
4387 "has_connection_privilege" => Scalar {
4388 params!(String, String, String) => sql_impl_func(
4389 "has_connection_privilege(\
4390 mz_internal.mz_role_oid($1), \
4391 mz_internal.mz_connection_oid($2), $3)",
4392 ) => Bool,
4393 oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_TEXT_TEXT_OID;
4394 params!(String, Oid, String) => sql_impl_func(
4395 "has_connection_privilege(mz_internal.mz_role_oid($1), $2, $3)",
4396 ) => Bool,
4397 oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_OID_TEXT_OID;
4398 params!(Oid, String, String) => sql_impl_func(
4399 "has_connection_privilege($1, mz_internal.mz_connection_oid($2), $3)",
4400 ) => Bool,
4401 oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_TEXT_TEXT_OID;
4402 params!(Oid, Oid, String) => sql_impl_func(
4403 &privilege_fn!("has_connection_privilege", "mz_connections"),
4404 ) => Bool,
4405 oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_OID_TEXT_OID;
4406 params!(String, String) => sql_impl_func(
4407 "has_connection_privilege(current_user, $1, $2)",
4408 ) => Bool,
4409 oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_TEXT_OID;
4410 params!(Oid, String) => sql_impl_func(
4411 "has_connection_privilege(current_user, $1, $2)",
4412 ) => Bool,
4413 oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_TEXT_OID;
4414 },
4415 "has_role" => Scalar {
4416 params!(String, String, String)
4417 => sql_impl_func("pg_has_role($1, $2, $3)")
4418 => Bool, oid::FUNC_HAS_ROLE_TEXT_TEXT_TEXT_OID;
4419 params!(String, Oid, String)
4420 => sql_impl_func("pg_has_role($1, $2, $3)")
4421 => Bool, oid::FUNC_HAS_ROLE_TEXT_OID_TEXT_OID;
4422 params!(Oid, String, String)
4423 => sql_impl_func("pg_has_role($1, $2, $3)")
4424 => Bool, oid::FUNC_HAS_ROLE_OID_TEXT_TEXT_OID;
4425 params!(Oid, Oid, String)
4426 => sql_impl_func("pg_has_role($1, $2, $3)")
4427 => Bool, oid::FUNC_HAS_ROLE_OID_OID_TEXT_OID;
4428 params!(String, String)
4429 => sql_impl_func("pg_has_role($1, $2)")
4430 => Bool, oid::FUNC_HAS_ROLE_TEXT_TEXT_OID;
4431 params!(Oid, String)
4432 => sql_impl_func("pg_has_role($1, $2)")
4433 => Bool, oid::FUNC_HAS_ROLE_OID_TEXT_OID;
4434 },
4435 "has_secret_privilege" => Scalar {
4436 params!(String, String, String) => sql_impl_func(
4437 "has_secret_privilege(\
4438 mz_internal.mz_role_oid($1), \
4439 mz_internal.mz_secret_oid($2), $3)",
4440 ) => Bool,
4441 oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_TEXT_TEXT_OID;
4442 params!(String, Oid, String) => sql_impl_func(
4443 "has_secret_privilege(mz_internal.mz_role_oid($1), $2, $3)",
4444 ) => Bool,
4445 oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_OID_TEXT_OID;
4446 params!(Oid, String, String) => sql_impl_func(
4447 "has_secret_privilege($1, mz_internal.mz_secret_oid($2), $3)",
4448 ) => Bool,
4449 oid::FUNC_HAS_SECRET_PRIVILEGE_OID_TEXT_TEXT_OID;
4450 params!(Oid, Oid, String) => sql_impl_func(
4451 &privilege_fn!("has_secret_privilege", "mz_secrets"),
4452 ) => Bool,
4453 oid::FUNC_HAS_SECRET_PRIVILEGE_OID_OID_TEXT_OID;
4454 params!(String, String) => sql_impl_func(
4455 "has_secret_privilege(current_user, $1, $2)",
4456 ) => Bool,
4457 oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_TEXT_OID;
4458 params!(Oid, String) => sql_impl_func(
4459 "has_secret_privilege(current_user, $1, $2)",
4460 ) => Bool,
4461 oid::FUNC_HAS_SECRET_PRIVILEGE_OID_TEXT_OID;
4462 },
4463 "has_system_privilege" => Scalar {
4464 params!(String, String) => sql_impl_func(
4465 "has_system_privilege(mz_internal.mz_role_oid($1), $2)",
4466 ) => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_TEXT_TEXT_OID;
4467 params!(Oid, String) => sql_impl_func(&format!("
4468 CASE
4469 -- We need to validate the privileges to return a proper error before
4470 -- anything else.
4471 WHEN NOT mz_internal.mz_validate_privileges($2)
4472 OR $1 IS NULL
4473 OR $2 IS NULL
4474 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
4475 THEN NULL
4476 ELSE COALESCE(
4477 (
4478 SELECT
4479 bool_or(
4480 mz_internal.mz_acl_item_contains_privilege(privileges, $2)
4481 )
4482 AS has_system_privilege
4483 FROM mz_catalog.mz_system_privileges
4484 LEFT JOIN mz_catalog.mz_roles ON
4485 mz_internal.mz_aclitem_grantee(privileges) = mz_roles.id
4486 WHERE
4487 mz_internal.mz_aclitem_grantee(privileges) = '{}'
4488 OR pg_has_role($1, mz_roles.oid, 'USAGE')
4489 ),
4490 false
4491 )
4492 END
4493 ", RoleId::Public))
4494 => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_OID_TEXT_OID;
4495 params!(String) => sql_impl_func(
4496 "has_system_privilege(current_user, $1)",
4497 ) => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_TEXT_OID;
4498 },
4499 "has_type_privilege" => Scalar {
4500 params!(String, String, String) => sql_impl_func(
4501 "has_type_privilege(mz_internal.mz_role_oid($1), $2::regtype::oid, $3)",
4502 ) => Bool, 3138;
4503 params!(String, Oid, String) => sql_impl_func(
4504 "has_type_privilege(mz_internal.mz_role_oid($1), $2, $3)",
4505 ) => Bool, 3139;
4506 params!(Oid, String, String) => sql_impl_func(
4507 "has_type_privilege($1, $2::regtype::oid, $3)",
4508 ) => Bool, 3140;
4509 params!(Oid, Oid, String) => sql_impl_func(
4510 &privilege_fn!("has_type_privilege", "mz_types"),
4511 ) => Bool, 3141;
4512 params!(String, String) => sql_impl_func(
4513 "has_type_privilege(current_user, $1, $2)",
4514 ) => Bool, 3142;
4515 params!(Oid, String) => sql_impl_func(
4516 "has_type_privilege(current_user, $1, $2)",
4517 ) => Bool, 3143;
4518 },
4519 "kafka_murmur2" => Scalar {
4520 params!(String) => UnaryFunc::KafkaMurmur2String(func::KafkaMurmur2String)
4521 => Int32, oid::FUNC_KAFKA_MURMUR2_STRING_OID;
4522 params!(Bytes) => UnaryFunc::KafkaMurmur2Bytes(func::KafkaMurmur2Bytes)
4523 => Int32, oid::FUNC_KAFKA_MURMUR2_BYTES_OID;
4524 },
4525 "list_agg" => Aggregate {
4526 params!(Any) => Operation::unary_ordered(|ecx, e, order_by| {
4527 if let SqlScalarType::Char {.. } = ecx.scalar_type(&e) {
4528 bail_unsupported!("list_agg on char");
4529 };
4530 let e_arr = HirScalarExpr::call_variadic(
4533 VariadicFunc::ListCreate { elem_type: ecx.scalar_type(&e) },
4534 vec![e],
4535 );
4536 Ok((e_arr, AggregateFunc::ListConcat { order_by }))
4537 }) => ListAnyCompatible, oid::FUNC_LIST_AGG_OID;
4538 },
4539 "list_append" => Scalar {
4540 vec![ListAnyCompatible, ListElementAnyCompatible]
4541 => BinaryFunc::from(func::ListElementConcat)
4542 => ListAnyCompatible, oid::FUNC_LIST_APPEND_OID;
4543 },
4544 "list_cat" => Scalar {
4545 vec![ListAnyCompatible, ListAnyCompatible]
4546 => BinaryFunc::from(func::ListListConcat)
4547 => ListAnyCompatible, oid::FUNC_LIST_CAT_OID;
4548 },
4549 "list_n_layers" => Scalar {
4550 vec![ListAny] => Operation::unary(|ecx, e| {
4551 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_N_LAYERS)?;
4552 let d = ecx.scalar_type(&e).unwrap_list_n_layers();
4553 match i32::try_from(d) {
4554 Ok(d) => Ok(HirScalarExpr::literal(Datum::Int32(d), SqlScalarType::Int32)),
4555 Err(_) => sql_bail!("list has more than {} layers", i32::MAX),
4556 }
4557
4558 }) => Int32, oid::FUNC_LIST_N_LAYERS_OID;
4559 },
4560 "list_length" => Scalar {
4561 vec![ListAny] => UnaryFunc::ListLength(func::ListLength)
4562 => Int32, oid::FUNC_LIST_LENGTH_OID;
4563 },
4564 "list_length_max" => Scalar {
4565 vec![ListAny, Plain(SqlScalarType::Int64)] => Operation::binary(|ecx, lhs, rhs| {
4566 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_LENGTH_MAX)?;
4567 let max_layer = ecx.scalar_type(&lhs).unwrap_list_n_layers();
4568 Ok(lhs.call_binary(rhs, BinaryFunc::from(func::ListLengthMax { max_layer })))
4569 }) => Int32, oid::FUNC_LIST_LENGTH_MAX_OID;
4570 },
4571 "list_prepend" => Scalar {
4572 vec![ListElementAnyCompatible, ListAnyCompatible]
4573 => BinaryFunc::from(func::ElementListConcat)
4574 => ListAnyCompatible, oid::FUNC_LIST_PREPEND_OID;
4575 },
4576 "list_remove" => Scalar {
4577 vec![ListAnyCompatible, ListElementAnyCompatible] => Operation::binary(|ecx, lhs, rhs| {
4578 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_REMOVE)?;
4579 Ok(lhs.call_binary(rhs, func::ListRemove))
4580 }) => ListAnyCompatible, oid::FUNC_LIST_REMOVE_OID;
4581 },
4582 "map_agg" => Aggregate {
4583 params!(String, Any) => Operation::binary_ordered(|ecx, key, val, order_by| {
4584 let (value_type, val) = match ecx.scalar_type(&val) {
4585 SqlScalarType::Char { length } => (
4587 SqlScalarType::Char { length },
4588 val.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
4589 ),
4590 typ => (typ, val),
4591 };
4592
4593 let e = HirScalarExpr::call_variadic(
4594 VariadicFunc::RecordCreate {
4595 field_names: vec![ColumnName::from("key"), ColumnName::from("val")],
4596 },
4597 vec![key, val],
4598 );
4599
4600 Ok((e, AggregateFunc::MapAgg { order_by, value_type }))
4601 }) => MapAny, oid::FUNC_MAP_AGG;
4602 },
4603 "map_build" => Scalar {
4604 params!(ListAny) => Operation::unary(|ecx, expr| {
4615 let ty = ecx.scalar_type(&expr);
4616
4617 let err = || {
4620 Err(sql_err!(
4621 "function map_build({}) does not exist",
4622 ecx.humanize_scalar_type(&ty.clone(), false)
4623 ))
4624 };
4625
4626 let value_type = match &ty {
4629 SqlScalarType::List { element_type, .. } => match &**element_type {
4630 SqlScalarType::Record { fields, .. } if fields.len() == 2 => {
4631 if fields[0].1.scalar_type != SqlScalarType::String {
4632 return err();
4633 }
4634
4635 fields[1].1.scalar_type.clone()
4636 }
4637 _ => return err(),
4638 },
4639 _ => unreachable!("input guaranteed to be list"),
4640 };
4641
4642 Ok(expr.call_unary(UnaryFunc::MapBuildFromRecordList(
4643 func::MapBuildFromRecordList { value_type },
4644 )))
4645 }) => MapAny, oid::FUNC_MAP_BUILD;
4646 },
4647 "map_length" => Scalar {
4648 params![MapAny] => UnaryFunc::MapLength(func::MapLength)
4649 => Int32, oid::FUNC_MAP_LENGTH_OID;
4650 },
4651 "mz_environment_id" => Scalar {
4652 params!() => UnmaterializableFunc::MzEnvironmentId
4653 => String, oid::FUNC_MZ_ENVIRONMENT_ID_OID;
4654 },
4655 "mz_is_superuser" => Scalar {
4656 params!() => UnmaterializableFunc::MzIsSuperuser
4657 => SqlScalarType::Bool, oid::FUNC_MZ_IS_SUPERUSER;
4658 },
4659 "mz_logical_timestamp" => Scalar {
4660 params!() => Operation::nullary(|_ecx| {
4661 sql_bail!("mz_logical_timestamp() has been renamed to mz_now()")
4662 }) => MzTimestamp, oid::FUNC_MZ_LOGICAL_TIMESTAMP_OID;
4663 },
4664 "mz_now" => Scalar {
4665 params!() => UnmaterializableFunc::MzNow => MzTimestamp, oid::FUNC_MZ_NOW_OID;
4666 },
4667 "mz_uptime" => Scalar {
4668 params!() => UnmaterializableFunc::MzUptime => Interval, oid::FUNC_MZ_UPTIME_OID;
4669 },
4670 "mz_version" => Scalar {
4671 params!() => UnmaterializableFunc::MzVersion => String, oid::FUNC_MZ_VERSION_OID;
4672 },
4673 "mz_version_num" => Scalar {
4674 params!() => UnmaterializableFunc::MzVersionNum => Int32, oid::FUNC_MZ_VERSION_NUM_OID;
4675 },
4676 "pretty_sql" => Scalar {
4677 params!(String, Int32) => BinaryFunc::from(func::PrettySql)
4678 => String, oid::FUNC_PRETTY_SQL;
4679 params!(String) => Operation::unary(|_ecx, s| {
4680 let w: i32 = mz_sql_pretty::DEFAULT_WIDTH.try_into().expect("must fit");
4681 let width = HirScalarExpr::literal(Datum::Int32(w), SqlScalarType::Int32);
4682 Ok(s.call_binary(width, func::PrettySql))
4683 }) => String, oid::FUNC_PRETTY_SQL_NOWIDTH;
4684 },
4685 "regexp_extract" => Table {
4686 params!(String, String) => Operation::binary(move |_ecx, regex, haystack| {
4687 let regex = match regex.into_literal_string() {
4688 None => sql_bail!(
4689 "regexp_extract requires a string \
4690 literal as its first argument"
4691 ),
4692 Some(regex) => {
4693 let opts = mz_expr::AnalyzedRegexOpts::default();
4694 mz_expr::AnalyzedRegex::new(®ex, opts)
4695 .map_err(|e| {
4696 sql_err!("analyzing regex: {}", e)
4697 })?
4698 },
4699 };
4700 let column_names = regex
4701 .capture_groups_iter()
4702 .map(|cg| {
4703 cg.name.clone().unwrap_or_else(|| format!("column{}", cg.index)).into()
4704 })
4705 .collect::<Vec<_>>();
4706 if column_names.is_empty(){
4707 sql_bail!("regexp_extract must specify at least one capture group");
4708 }
4709 Ok(TableFuncPlan {
4710 imp: TableFuncImpl::CallTable {
4711 func: TableFunc::RegexpExtract(regex),
4712 exprs: vec![haystack],
4713 },
4714 column_names,
4715 })
4716 }) => ReturnType::set_of(RecordAny), oid::FUNC_REGEXP_EXTRACT_OID;
4717 },
4718 "repeat_row" => Table {
4719 params!(Int64) => Operation::unary(move |ecx, n| {
4720 ecx.require_feature_flag(&crate::session::vars::ENABLE_REPEAT_ROW)?;
4721 Ok(TableFuncPlan {
4722 imp: TableFuncImpl::CallTable {
4723 func: TableFunc::Repeat,
4724 exprs: vec![n],
4725 },
4726 column_names: vec![]
4727 })
4728 }) => ReturnType::none(true), oid::FUNC_REPEAT_OID;
4729 },
4730 "seahash" => Scalar {
4731 params!(String) => UnaryFunc::SeahashString(func::SeahashString)
4732 => UInt32, oid::FUNC_SEAHASH_STRING_OID;
4733 params!(Bytes) => UnaryFunc::SeahashBytes(func::SeahashBytes)
4734 => UInt32, oid::FUNC_SEAHASH_BYTES_OID;
4735 },
4736 "starts_with" => Scalar {
4737 params!(String, String) => BinaryFunc::from(func::StartsWith) => Bool, 3696;
4738 },
4739 "timezone_offset" => Scalar {
4740 params!(String, TimestampTz) => BinaryFunc::from(func::TimezoneOffset)
4741 => RecordAny, oid::FUNC_TIMEZONE_OFFSET;
4742 },
4743 "try_parse_monotonic_iso8601_timestamp" => Scalar {
4744 params!(String) => Operation::unary(move |_ecx, e| {
4745 Ok(e.call_unary(UnaryFunc::TryParseMonotonicIso8601Timestamp(
4746 func::TryParseMonotonicIso8601Timestamp,
4747 )))
4748 }) => Timestamp, oid::FUNC_TRY_PARSE_MONOTONIC_ISO8601_TIMESTAMP;
4749 },
4750 "unnest" => Table {
4751 vec![ArrayAny] => Operation::unary(move |ecx, e| {
4752 let el_typ = ecx.scalar_type(&e).unwrap_array_element_type().clone();
4753 Ok(TableFuncPlan {
4754 imp: TableFuncImpl::CallTable {
4755 func: TableFunc::UnnestArray { el_typ },
4756 exprs: vec![e],
4757 },
4758 column_names: vec!["unnest".into()],
4759 })
4760 }) =>
4761 ReturnType::set_of(AnyElement), 2331;
4764 vec![ListAny] => Operation::unary(move |ecx, e| {
4765 let el_typ = ecx.scalar_type(&e).unwrap_list_element_type().clone();
4766 Ok(TableFuncPlan {
4767 imp: TableFuncImpl::CallTable {
4768 func: TableFunc::UnnestList { el_typ },
4769 exprs: vec![e],
4770 },
4771 column_names: vec!["unnest".into()],
4772 })
4773 }) =>
4774 ReturnType::set_of(Any), oid::FUNC_UNNEST_LIST_OID;
4777 vec![MapAny] => Operation::unary(move |ecx, e| {
4778 let value_type = ecx.scalar_type(&e).unwrap_map_value_type().clone();
4779 Ok(TableFuncPlan {
4780 imp: TableFuncImpl::CallTable {
4781 func: TableFunc::UnnestMap { value_type },
4782 exprs: vec![e],
4783 },
4784 column_names: vec!["key".into(), "value".into()],
4785 })
4786 }) =>
4787 ReturnType::set_of(Any), oid::FUNC_UNNEST_MAP_OID;
4790 }
4791 }
4792});
4793
4794pub static MZ_INTERNAL_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
4795 use ParamType::*;
4796 use SqlScalarBaseType::*;
4797 builtins! {
4798 "aclitem_grantor" => Scalar {
4799 params!(AclItem) => UnaryFunc::AclItemGrantor(func::AclItemGrantor)
4800 => Oid, oid::FUNC_ACL_ITEM_GRANTOR_OID;
4801 },
4802 "aclitem_grantee" => Scalar {
4803 params!(AclItem) => UnaryFunc::AclItemGrantee(func::AclItemGrantee)
4804 => Oid, oid::FUNC_ACL_ITEM_GRANTEE_OID;
4805 },
4806 "aclitem_privileges" => Scalar {
4807 params!(AclItem) => UnaryFunc::AclItemPrivileges(func::AclItemPrivileges)
4808 => String, oid::FUNC_ACL_ITEM_PRIVILEGES_OID;
4809 },
4810 "is_rbac_enabled" => Scalar {
4811 params!() => UnmaterializableFunc::IsRbacEnabled => Bool, oid::FUNC_IS_RBAC_ENABLED_OID;
4812 },
4813 "make_mz_aclitem" => Scalar {
4814 params!(String, String, String) => VariadicFunc::MakeMzAclItem
4815 => MzAclItem, oid::FUNC_MAKE_MZ_ACL_ITEM_OID;
4816 },
4817 "mz_acl_item_contains_privilege" => Scalar {
4818 params!(MzAclItem, String)
4819 => BinaryFunc::from(func::MzAclItemContainsPrivilege)
4820 => Bool, oid::FUNC_MZ_ACL_ITEM_CONTAINS_PRIVILEGE_OID;
4821 },
4822 "mz_aclexplode" => Table {
4823 params!(SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)))
4824 => Operation::unary(move |_ecx, mz_aclitems| {
4825 Ok(TableFuncPlan {
4826 imp: TableFuncImpl::CallTable {
4827 func: TableFunc::MzAclExplode,
4828 exprs: vec![mz_aclitems],
4829 },
4830 column_names: vec![
4831 "grantor".into(), "grantee".into(),
4832 "privilege_type".into(), "is_grantable".into(),
4833 ],
4834 })
4835 }) => ReturnType::set_of(RecordAny), oid::FUNC_MZ_ACL_ITEM_EXPLODE_OID;
4836 },
4837 "mz_aclitem_grantor" => Scalar {
4838 params!(MzAclItem) => UnaryFunc::MzAclItemGrantor(func::MzAclItemGrantor)
4839 => String, oid::FUNC_MZ_ACL_ITEM_GRANTOR_OID;
4840 },
4841 "mz_aclitem_grantee" => Scalar {
4842 params!(MzAclItem) => UnaryFunc::MzAclItemGrantee(func::MzAclItemGrantee)
4843 => String, oid::FUNC_MZ_ACL_ITEM_GRANTEE_OID;
4844 },
4845 "mz_aclitem_privileges" => Scalar {
4846 params!(MzAclItem) => UnaryFunc::MzAclItemPrivileges(
4847 func::MzAclItemPrivileges,
4848 ) => String, oid::FUNC_MZ_ACL_ITEM_PRIVILEGES_OID;
4849 },
4850 "mz_connection_oid" => Scalar {
4855 params!(String) => sql_impl_func("
4856 CASE
4857 WHEN $1 IS NULL THEN NULL
4858 ELSE (
4859 mz_unsafe.mz_error_if_null(
4860 (SELECT oid FROM mz_catalog.mz_objects
4861 WHERE name = $1 AND type = 'connection'),
4862 'connection \"' || $1 || '\" does not exist'
4863 )
4864 )
4865 END
4866 ") => Oid, oid::FUNC_CONNECTION_OID_OID;
4867 },
4868 "mz_format_privileges" => Scalar {
4869 params!(String) => UnaryFunc::MzFormatPrivileges(func::MzFormatPrivileges)
4870 => SqlScalarType::Array(Box::new(SqlScalarType::String)),
4871 oid::FUNC_MZ_FORMAT_PRIVILEGES_OID;
4872 },
4873 "mz_name_rank" => Table {
4874 params!(
4877 String,
4879 ParamType::Plain(SqlScalarType::Array(Box::new(SqlScalarType::String))),
4881 String,
4883 String
4885 ) =>
4886 sql_impl_table_func("
4888 -- The best ranked name is the one that belongs to the schema correlated with the lowest
4889 -- index in the search path
4890 SELECT id, name, count, min(schema_pref) OVER () = schema_pref AS best_ranked FROM (
4891 SELECT DISTINCT
4892 o.id,
4893 ARRAY[CASE WHEN s.database_id IS NULL THEN NULL ELSE d.name END, s.name, o.name]
4894 AS name,
4895 o.count,
4896 pg_catalog.array_position($2, s.name) AS schema_pref
4897 FROM
4898 (
4899 SELECT
4900 o.id,
4901 o.schema_id,
4902 o.name,
4903 count(*)
4904 FROM mz_catalog.mz_objects AS o
4905 JOIN mz_internal.mz_object_oid_alias AS a
4906 ON o.type = a.object_type
4907 WHERE o.name = CAST($3 AS pg_catalog.text) AND a.oid_alias = $4
4908 GROUP BY 1, 2, 3
4909 )
4910 AS o
4911 JOIN mz_catalog.mz_schemas AS s ON o.schema_id = s.id
4912 JOIN
4913 unnest($2) AS search_schema (name)
4914 ON search_schema.name = s.name
4915 JOIN
4916 (
4917 SELECT id, name FROM mz_catalog.mz_databases
4918 -- If the provided database does not exist, add a row for it so that it
4919 -- can still join against ambient schemas.
4920 UNION ALL
4921 SELECT '', $1 WHERE $1 NOT IN (SELECT name FROM mz_catalog.mz_databases)
4922 ) AS d
4923 ON d.id = COALESCE(s.database_id, d.id)
4924 WHERE d.name = CAST($1 AS pg_catalog.text)
4925 );
4926 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_NAME_RANK;
4927 },
4928 "mz_resolve_object_name" => Table {
4929 params!(String, String) =>
4930 sql_impl_table_func("
4933 SELECT
4934 o.id, o.oid, o.schema_id, o.name, o.type, o.owner_id, o.privileges
4935 FROM
4936 (SELECT mz_internal.mz_normalize_object_name($2))
4937 AS normalized (n),
4938 mz_internal.mz_name_rank(
4939 COALESCE(n[1], pg_catalog.current_database()),
4940 CASE
4941 WHEN n[2] IS NULL
4942 THEN pg_catalog.current_schemas(true)
4943 ELSE
4944 ARRAY[n[2]]
4945 END,
4946 n[3],
4947 $1
4948 ) AS r,
4949 mz_catalog.mz_objects AS o
4950 WHERE r.id = o.id AND r.best_ranked;
4951 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_RESOLVE_OBJECT_NAME;
4952 },
4953 "mz_minimal_name_qualification" => Scalar {
4965 params!(SqlScalarType::Array(Box::new(SqlScalarType::String)), String) => {
4966 sql_impl_func("(
4967 SELECT
4968 CASE
4969 WHEN $1::pg_catalog.text[] IS NULL
4970 THEN NULL
4971 -- If DB doesn't match, requires full qual
4972 WHEN $1[1] != pg_catalog.current_database()
4973 THEN $1
4974 -- If not in currently searchable schema, must be schema qualified
4975 WHEN NOT $1[2] = ANY(pg_catalog.current_schemas(true))
4976 THEN ARRAY[$1[2], $1[3]]
4977 ELSE
4978 minimal_name
4979 END
4980 FROM (
4981 -- Subquery so we return one null row in the cases where
4982 -- there are no matches.
4983 SELECT (
4984 SELECT DISTINCT
4985 CASE
4986 -- If there is only one item with this name and it's rank 1,
4987 -- it is uniquely nameable with just the final element
4988 WHEN best_ranked AND count = 1
4989 THEN ARRAY[r.name[3]]
4990 -- Otherwise, it is findable in the search path, so does not
4991 -- need database qualification
4992 ELSE
4993 ARRAY[r.name[2], r.name[3]]
4994 END AS minimal_name
4995 FROM mz_catalog.mz_objects AS o
4996 JOIN mz_internal.mz_object_oid_alias AS a
4997 ON o.type = a.object_type,
4998 -- implied lateral to put the OID alias into scope
4999 mz_internal.mz_name_rank(
5000 pg_catalog.current_database(),
5001 pg_catalog.current_schemas(true),
5002 $1[3],
5003 a.oid_alias
5004 ) AS r
5005 WHERE o.id = $2 AND r.id = $2
5006 )
5007 )
5008 )")
5009 } => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5010 oid::FUNC_MZ_MINIMINAL_NAME_QUALIFICATION;
5011 },
5012 "mz_global_id_to_name" => Scalar {
5013 params!(String) => sql_impl_func("
5014 CASE
5015 WHEN $1 IS NULL THEN NULL
5016 ELSE (
5017 SELECT array_to_string(minimal_name, '.')
5018 FROM (
5019 SELECT mz_unsafe.mz_error_if_null(
5020 (
5021 -- Return the fully-qualified name
5022 SELECT DISTINCT ARRAY[qual.d, qual.s, item.name]
5023 FROM
5024 mz_catalog.mz_objects AS item
5025 JOIN
5026 (
5027 SELECT
5028 d.name AS d,
5029 s.name AS s,
5030 s.id AS schema_id
5031 FROM
5032 mz_catalog.mz_schemas AS s
5033 LEFT JOIN
5034 (SELECT id, name FROM mz_catalog.mz_databases)
5035 AS d
5036 ON s.database_id = d.id
5037 ) AS qual
5038 ON qual.schema_id = item.schema_id
5039 WHERE item.id = CAST($1 AS text)
5040 ),
5041 'global ID ' || $1 || ' does not exist'
5042 )
5043 ) AS n (fqn),
5044 LATERAL (
5045 -- Get the minimal qualification of the fully qualified name
5046 SELECT mz_internal.mz_minimal_name_qualification(fqn, $1)
5047 ) AS m (minimal_name)
5048 )
5049 END
5050 ") => String, oid::FUNC_MZ_GLOBAL_ID_TO_NAME;
5051 },
5052 "mz_normalize_object_name" => Scalar {
5053 params!(String) => sql_impl_func("
5054 (
5055 SELECT
5056 CASE
5057 WHEN $1 IS NULL THEN NULL
5058 WHEN pg_catalog.array_length(ident, 1) > 3
5059 THEN mz_unsafe.mz_error_if_null(
5060 NULL::pg_catalog.text[],
5061 'improper relation name (too many dotted names): ' || $1
5062 )
5063 ELSE pg_catalog.array_cat(
5064 pg_catalog.array_fill(
5065 CAST(NULL AS pg_catalog.text),
5066 ARRAY[3 - pg_catalog.array_length(ident, 1)]
5067 ),
5068 ident
5069 )
5070 END
5071 FROM (
5072 SELECT pg_catalog.parse_ident($1) AS ident
5073 ) AS i
5074 )") => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5075 oid::FUNC_MZ_NORMALIZE_OBJECT_NAME;
5076 },
5077 "mz_normalize_schema_name" => Scalar {
5078 params!(String) => sql_impl_func("
5079 (
5080 SELECT
5081 CASE
5082 WHEN $1 IS NULL THEN NULL
5083 WHEN pg_catalog.array_length(ident, 1) > 2
5084 THEN mz_unsafe.mz_error_if_null(
5085 NULL::pg_catalog.text[],
5086 'improper schema name (too many dotted names): ' || $1
5087 )
5088 ELSE pg_catalog.array_cat(
5089 pg_catalog.array_fill(
5090 CAST(NULL AS pg_catalog.text),
5091 ARRAY[2 - pg_catalog.array_length(ident, 1)]
5092 ),
5093 ident
5094 )
5095 END
5096 FROM (
5097 SELECT pg_catalog.parse_ident($1) AS ident
5098 ) AS i
5099 )") => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5100 oid::FUNC_MZ_NORMALIZE_SCHEMA_NAME;
5101 },
5102 "mz_render_typmod" => Scalar {
5103 params!(Oid, Int32) => BinaryFunc::from(func::MzRenderTypmod)
5104 => String, oid::FUNC_MZ_RENDER_TYPMOD_OID;
5105 },
5106 "mz_role_oid_memberships" => Scalar {
5107 params!() => UnmaterializableFunc::MzRoleOidMemberships
5108 => SqlScalarType::Map {
5109 value_type: Box::new(SqlScalarType::Array(
5110 Box::new(SqlScalarType::String),
5111 )),
5112 custom_id: None,
5113 }, oid::FUNC_MZ_ROLE_OID_MEMBERSHIPS;
5114 },
5115 "mz_database_oid" => Scalar {
5118 params!(String) => sql_impl_func("
5119 CASE
5120 WHEN $1 IS NULL THEN NULL
5121 ELSE (
5122 mz_unsafe.mz_error_if_null(
5123 (SELECT oid FROM mz_databases WHERE name = $1),
5124 'database \"' || $1 || '\" does not exist'
5125 )
5126 )
5127 END
5128 ") => Oid, oid::FUNC_DATABASE_OID_OID;
5129 },
5130 "mz_schema_oid" => Scalar {
5133 params!(String) => sql_impl_func("
5134 CASE
5135 WHEN $1 IS NULL THEN NULL
5136 ELSE
5137 mz_unsafe.mz_error_if_null(
5138 (
5139 SELECT
5140 (
5141 SELECT s.oid
5142 FROM mz_catalog.mz_schemas AS s
5143 LEFT JOIN mz_databases AS d ON s.database_id = d.id
5144 WHERE
5145 (
5146 -- Filter to only schemas in the named database or the
5147 -- current database if no database was specified.
5148 d.name = COALESCE(n[1], pg_catalog.current_database())
5149 -- Always include all ambient schemas.
5150 OR s.database_id IS NULL
5151 )
5152 AND s.name = n[2]
5153 )
5154 FROM mz_internal.mz_normalize_schema_name($1) AS n
5155 ),
5156 'schema \"' || $1 || '\" does not exist'
5157 )
5158 END
5159 ") => Oid, oid::FUNC_SCHEMA_OID_OID;
5160 },
5161 "mz_role_oid" => Scalar {
5164 params!(String) => sql_impl_func("
5165 CASE
5166 WHEN $1 IS NULL THEN NULL
5167 ELSE (
5168 mz_unsafe.mz_error_if_null(
5169 (SELECT oid FROM mz_catalog.mz_roles WHERE name = $1),
5170 'role \"' || $1 || '\" does not exist'
5171 )
5172 )
5173 END
5174 ") => Oid, oid::FUNC_ROLE_OID_OID;
5175 },
5176 "mz_secret_oid" => Scalar {
5181 params!(String) => sql_impl_func("
5182 CASE
5183 WHEN $1 IS NULL THEN NULL
5184 ELSE (
5185 mz_unsafe.mz_error_if_null(
5186 (SELECT oid FROM mz_catalog.mz_objects WHERE name = $1 AND type = 'secret'),
5187 'secret \"' || $1 || '\" does not exist'
5188 )
5189 )
5190 END
5191 ") => Oid, oid::FUNC_SECRET_OID_OID;
5192 },
5193 "mz_session_id" => Scalar {
5197 params!() => UnmaterializableFunc::MzSessionId => Uuid, oid::FUNC_MZ_SESSION_ID_OID;
5198 },
5199 "mz_type_name" => Scalar {
5200 params!(Oid) => UnaryFunc::MzTypeName(func::MzTypeName)
5201 => String, oid::FUNC_MZ_TYPE_NAME;
5202 },
5203 "mz_validate_privileges" => Scalar {
5204 params!(String) => UnaryFunc::MzValidatePrivileges(func::MzValidatePrivileges)
5205 => Bool, oid::FUNC_MZ_VALIDATE_PRIVILEGES_OID;
5206 },
5207 "mz_validate_role_privilege" => Scalar {
5208 params!(String) => UnaryFunc::MzValidateRolePrivilege(
5209 func::MzValidateRolePrivilege,
5210 ) => Bool, oid::FUNC_MZ_VALIDATE_ROLE_PRIVILEGE_OID;
5211 }
5212 }
5213});
5214
5215pub static MZ_UNSAFE_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
5216 use ParamType::*;
5217 use SqlScalarBaseType::*;
5218 builtins! {
5219 "mz_all" => Aggregate {
5220 params!(Any) => AggregateFunc::All => Bool, oid::FUNC_MZ_ALL_OID;
5221 },
5222 "mz_any" => Aggregate {
5223 params!(Any) => AggregateFunc::Any => Bool, oid::FUNC_MZ_ANY_OID;
5224 },
5225 "mz_avg_promotion_internal_v1" => Scalar {
5226 params!(Float32) => Operation::identity()
5232 => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID_INTERNAL_V1;
5233 params!(Float64) => Operation::identity()
5234 => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID_INTERNAL_V1;
5235 params!(Int16) => Operation::unary(|ecx, e| {
5236 typeconv::plan_cast(
5237 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5238 )
5239 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID_INTERNAL_V1;
5240 params!(Int32) => Operation::unary(|ecx, e| {
5241 typeconv::plan_cast(
5242 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5243 )
5244 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID_INTERNAL_V1;
5245 params!(UInt16) => Operation::unary(|ecx, e| {
5246 typeconv::plan_cast(
5247 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5248 )
5249 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID_INTERNAL_V1;
5250 params!(UInt32) => Operation::unary(|ecx, e| {
5251 typeconv::plan_cast(
5252 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5253 )
5254 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID_INTERNAL_V1;
5255 },
5256 "mz_avg_promotion" => Scalar {
5257 params!(Float32) => Operation::identity()
5263 => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID;
5264 params!(Float64) => Operation::identity()
5265 => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID;
5266 params!(Int16) => Operation::unary(|ecx, e| {
5267 typeconv::plan_cast(
5268 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5269 )
5270 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID;
5271 params!(Int32) => Operation::unary(|ecx, e| {
5272 typeconv::plan_cast(
5273 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5274 )
5275 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID;
5276 params!(Int64) => Operation::unary(|ecx, e| {
5277 typeconv::plan_cast(
5278 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5279 )
5280 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I64_OID;
5281 params!(UInt16) => Operation::unary(|ecx, e| {
5282 typeconv::plan_cast(
5283 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5284 )
5285 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID;
5286 params!(UInt32) => Operation::unary(|ecx, e| {
5287 typeconv::plan_cast(
5288 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5289 )
5290 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID;
5291 params!(UInt64) => Operation::unary(|ecx, e| {
5292 typeconv::plan_cast(
5293 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5294 )
5295 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U64_OID;
5296 params!(Numeric) => Operation::unary(|ecx, e| {
5297 typeconv::plan_cast(
5298 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5299 )
5300 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_NUMERIC_OID;
5301 },
5302 "mz_error_if_null" => Scalar {
5303 params!(Any, String) => VariadicFunc::ErrorIfNull
5306 => Any, oid::FUNC_MZ_ERROR_IF_NULL_OID;
5307 },
5308 "mz_sleep" => Scalar {
5309 params!(Float64) => UnaryFunc::Sleep(func::Sleep)
5310 => TimestampTz, oid::FUNC_MZ_SLEEP_OID;
5311 },
5312 "mz_panic" => Scalar {
5313 params!(String) => UnaryFunc::Panic(func::Panic) => String, oid::FUNC_MZ_PANIC_OID;
5314 }
5315 }
5316});
5317
5318fn digest(algorithm: &'static str) -> Operation<HirScalarExpr> {
5319 Operation::unary(move |_ecx, input| {
5320 let algorithm = HirScalarExpr::literal(Datum::String(algorithm), SqlScalarType::String);
5321 Ok(input.call_binary(algorithm, BinaryFunc::from(func::DigestBytes)))
5322 })
5323}
5324
5325fn array_to_string(
5326 ecx: &ExprContext,
5327 exprs: Vec<HirScalarExpr>,
5328) -> Result<HirScalarExpr, PlanError> {
5329 let elem_type = match ecx.scalar_type(&exprs[0]) {
5330 SqlScalarType::Array(elem_type) => *elem_type,
5331 _ => unreachable!("array_to_string is guaranteed to receive array as first argument"),
5332 };
5333 Ok(HirScalarExpr::call_variadic(
5334 VariadicFunc::ArrayToString { elem_type },
5335 exprs,
5336 ))
5337}
5338
5339pub static OP_IMPLS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
5341 use BinaryFunc as BF;
5342 use ParamType::*;
5343 use SqlScalarBaseType::*;
5344 builtins! {
5345 "+" => Scalar {
5368 params!(Any) => Operation::new(|ecx, exprs, _params, _order_by| {
5369 typeconv::plan_coerce(ecx, exprs.into_element(), &SqlScalarType::Float64)
5382 }) => Any, oid::OP_UNARY_PLUS_OID;
5383 params!(Int16, Int16) => BF::from(func::AddInt16) => Int16, 550;
5384 params!(Int32, Int32) => BF::from(func::AddInt32) => Int32, 551;
5385 params!(Int64, Int64) => BF::from(func::AddInt64) => Int64, 684;
5386 params!(UInt16, UInt16) => BF::from(func::AddUint16) => UInt16, oid::FUNC_ADD_UINT16;
5387 params!(UInt32, UInt32) => BF::from(func::AddUint32) => UInt32, oid::FUNC_ADD_UINT32;
5388 params!(UInt64, UInt64) => BF::from(func::AddUint64) => UInt64, oid::FUNC_ADD_UINT64;
5389 params!(Float32, Float32) => BF::from(func::AddFloat32) => Float32, 586;
5390 params!(Float64, Float64) => BF::from(func::AddFloat64) => Float64, 591;
5391 params!(Interval, Interval) => BF::from(func::AddInterval) => Interval, 1337;
5392 params!(Timestamp, Interval) => BF::from(func::AddTimestampInterval) => Timestamp, 2066;
5393 params!(Interval, Timestamp) => {
5394 Operation::binary(|_ecx, lhs, rhs| {
5395 Ok(rhs.call_binary(lhs, func::AddTimestampInterval))
5396 })
5397 } => Timestamp, 2553;
5398 params!(TimestampTz, Interval)
5399 => BF::from(func::AddTimestampTzInterval) => TimestampTz, 1327;
5400 params!(Interval, TimestampTz) => {
5401 Operation::binary(|_ecx, lhs, rhs| {
5402 Ok(rhs.call_binary(lhs, func::AddTimestampTzInterval))
5403 })
5404 } => TimestampTz, 2554;
5405 params!(Date, Interval) => BF::from(func::AddDateInterval) => Timestamp, 1076;
5406 params!(Interval, Date) => {
5407 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddDateInterval)))
5408 } => Timestamp, 2551;
5409 params!(Date, Time) => BF::from(func::AddDateTime) => Timestamp, 1360;
5410 params!(Time, Date) => {
5411 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddDateTime)))
5412 } => Timestamp, 1363;
5413 params!(Time, Interval) => BF::from(func::AddTimeInterval) => Time, 1800;
5414 params!(Interval, Time) => {
5415 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddTimeInterval)))
5416 } => Time, 1849;
5417 params!(Numeric, Numeric) => BF::from(func::AddNumeric) => Numeric, 1758;
5418 params!(RangeAny, RangeAny) => BF::from(func::RangeUnion) => RangeAny, 3898;
5419 },
5420 "-" => Scalar {
5421 params!(Int16) => UnaryFunc::NegInt16(func::NegInt16) => Int16, 559;
5422 params!(Int32) => UnaryFunc::NegInt32(func::NegInt32) => Int32, 558;
5423 params!(Int64) => UnaryFunc::NegInt64(func::NegInt64) => Int64, 484;
5424 params!(Float32) => UnaryFunc::NegFloat32(func::NegFloat32) => Float32, 584;
5425 params!(Float64) => UnaryFunc::NegFloat64(func::NegFloat64) => Float64, 585;
5426 params!(Numeric) => UnaryFunc::NegNumeric(func::NegNumeric) => Numeric, 17510;
5427 params!(Interval) => UnaryFunc::NegInterval(func::NegInterval) => Interval, 1336;
5428 params!(Int32, Int32) => BF::from(func::SubInt32) => Int32, 555;
5429 params!(Int64, Int64) => BF::from(func::SubInt64) => Int64, 685;
5430 params!(UInt16, UInt16) => BF::from(func::SubUint16) => UInt16, oid::FUNC_SUB_UINT16;
5431 params!(UInt32, UInt32) => BF::from(func::SubUint32) => UInt32, oid::FUNC_SUB_UINT32;
5432 params!(UInt64, UInt64) => BF::from(func::SubUint64) => UInt64, oid::FUNC_SUB_UINT64;
5433 params!(Float32, Float32) => BF::from(func::SubFloat32) => Float32, 587;
5434 params!(Float64, Float64) => BF::from(func::SubFloat64) => Float64, 592;
5435 params!(Numeric, Numeric) => BF::from(func::SubNumeric) => Numeric, 17590;
5436 params!(Interval, Interval) => BF::from(func::SubInterval) => Interval, 1338;
5437 params!(Timestamp, Timestamp) => BF::from(func::SubTimestamp) => Interval, 2067;
5438 params!(TimestampTz, TimestampTz) => BF::from(func::SubTimestampTz) => Interval, 1328;
5439 params!(Timestamp, Interval) => BF::from(func::SubTimestampInterval) => Timestamp, 2068;
5440 params!(TimestampTz, Interval)
5441 => BF::from(func::SubTimestampTzInterval) => TimestampTz, 1329;
5442 params!(Date, Date) => BF::from(func::SubDate) => Int32, 1099;
5443 params!(Date, Interval) => BF::from(func::SubDateInterval) => Timestamp, 1077;
5444 params!(Time, Time) => BF::from(func::SubTime) => Interval, 1399;
5445 params!(Time, Interval) => BF::from(func::SubTimeInterval) => Time, 1801;
5446 params!(Jsonb, Int64) => BF::from(func::JsonbDeleteInt64) => Jsonb, 3286;
5447 params!(Jsonb, String) => BF::from(func::JsonbDeleteString) => Jsonb, 3285;
5448 params!(RangeAny, RangeAny) => BF::from(func::RangeDifference) => RangeAny, 3899;
5449 },
5452 "*" => Scalar {
5453 params!(Int16, Int16) => BF::from(func::MulInt16) => Int16, 526;
5454 params!(Int32, Int32) => BF::from(func::MulInt32) => Int32, 514;
5455 params!(Int64, Int64) => BF::from(func::MulInt64) => Int64, 686;
5456 params!(UInt16, UInt16) => BF::from(func::MulUint16) => UInt16, oid::FUNC_MUL_UINT16;
5457 params!(UInt32, UInt32) => BF::from(func::MulUint32) => UInt32, oid::FUNC_MUL_UINT32;
5458 params!(UInt64, UInt64) => BF::from(func::MulUint64) => UInt64, oid::FUNC_MUL_UINT64;
5459 params!(Float32, Float32) => BF::from(func::MulFloat32) => Float32, 589;
5460 params!(Float64, Float64) => BF::from(func::MulFloat64) => Float64, 594;
5461 params!(Interval, Float64) => BF::from(func::MulInterval) => Interval, 1583;
5462 params!(Float64, Interval) => {
5463 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::MulInterval)))
5464 } => Interval, 1584;
5465 params!(Numeric, Numeric) => BF::from(func::MulNumeric) => Numeric, 1760;
5466 params!(RangeAny, RangeAny) => BF::from(func::RangeIntersection) => RangeAny, 3900;
5467 },
5468 "/" => Scalar {
5469 params!(Int16, Int16) => BF::from(func::DivInt16) => Int16, 527;
5470 params!(Int32, Int32) => BF::from(func::DivInt32) => Int32, 528;
5471 params!(Int64, Int64) => BF::from(func::DivInt64) => Int64, 687;
5472 params!(UInt16, UInt16) => BF::from(func::DivUint16) => UInt16, oid::FUNC_DIV_UINT16;
5473 params!(UInt32, UInt32) => BF::from(func::DivUint32) => UInt32, oid::FUNC_DIV_UINT32;
5474 params!(UInt64, UInt64) => BF::from(func::DivUint64) => UInt64, oid::FUNC_DIV_UINT64;
5475 params!(Float32, Float32) => BF::from(func::DivFloat32) => Float32, 588;
5476 params!(Float64, Float64) => BF::from(func::DivFloat64) => Float64, 593;
5477 params!(Interval, Float64) => BF::from(func::DivInterval) => Interval, 1585;
5478 params!(Numeric, Numeric) => BF::from(func::DivNumeric) => Numeric, 1761;
5479 },
5480 "%" => Scalar {
5481 params!(Int16, Int16) => BF::from(func::ModInt16) => Int16, 529;
5482 params!(Int32, Int32) => BF::from(func::ModInt32) => Int32, 530;
5483 params!(Int64, Int64) => BF::from(func::ModInt64) => Int64, 439;
5484 params!(UInt16, UInt16) => BF::from(func::ModUint16) => UInt16, oid::FUNC_MOD_UINT16;
5485 params!(UInt32, UInt32) => BF::from(func::ModUint32) => UInt32, oid::FUNC_MOD_UINT32;
5486 params!(UInt64, UInt64) => BF::from(func::ModUint64) => UInt64, oid::FUNC_MOD_UINT64;
5487 params!(Float32, Float32) => BF::from(func::ModFloat32) => Float32, oid::OP_MOD_F32_OID;
5488 params!(Float64, Float64) => BF::from(func::ModFloat64) => Float64, oid::OP_MOD_F64_OID;
5489 params!(Numeric, Numeric) => BF::from(func::ModNumeric) => Numeric, 1762;
5490 },
5491 "&" => Scalar {
5492 params!(Int16, Int16) => BF::from(func::BitAndInt16) => Int16, 1874;
5493 params!(Int32, Int32) => BF::from(func::BitAndInt32) => Int32, 1880;
5494 params!(Int64, Int64) => BF::from(func::BitAndInt64) => Int64, 1886;
5495 params!(UInt16, UInt16) => BF::from(func::BitAndUint16) => UInt16, oid::FUNC_AND_UINT16;
5496 params!(UInt32, UInt32) => BF::from(func::BitAndUint32) => UInt32, oid::FUNC_AND_UINT32;
5497 params!(UInt64, UInt64) => BF::from(func::BitAndUint64) => UInt64, oid::FUNC_AND_UINT64;
5498 },
5499 "|" => Scalar {
5500 params!(Int16, Int16) => BF::from(func::BitOrInt16) => Int16, 1875;
5501 params!(Int32, Int32) => BF::from(func::BitOrInt32) => Int32, 1881;
5502 params!(Int64, Int64) => BF::from(func::BitOrInt64) => Int64, 1887;
5503 params!(UInt16, UInt16) => BF::from(func::BitOrUint16) => UInt16, oid::FUNC_OR_UINT16;
5504 params!(UInt32, UInt32) => BF::from(func::BitOrUint32) => UInt32, oid::FUNC_OR_UINT32;
5505 params!(UInt64, UInt64) => BF::from(func::BitOrUint64) => UInt64, oid::FUNC_OR_UINT64;
5506 },
5507 "#" => Scalar {
5508 params!(Int16, Int16) => BF::from(func::BitXorInt16) => Int16, 1876;
5509 params!(Int32, Int32) => BF::from(func::BitXorInt32) => Int32, 1882;
5510 params!(Int64, Int64) => BF::from(func::BitXorInt64) => Int64, 1888;
5511 params!(UInt16, UInt16) => BF::from(func::BitXorUint16) => UInt16, oid::FUNC_XOR_UINT16;
5512 params!(UInt32, UInt32) => BF::from(func::BitXorUint32) => UInt32, oid::FUNC_XOR_UINT32;
5513 params!(UInt64, UInt64) => BF::from(func::BitXorUint64) => UInt64, oid::FUNC_XOR_UINT64;
5514 },
5515 "<<" => Scalar {
5516 params!(Int16, Int32) => BF::from(func::BitShiftLeftInt16) => Int16, 1878;
5517 params!(Int32, Int32) => BF::from(func::BitShiftLeftInt32) => Int32, 1884;
5518 params!(Int64, Int32) => BF::from(func::BitShiftLeftInt64) => Int64, 1890;
5519 params!(UInt16, UInt32) => BF::from(func::BitShiftLeftUint16)
5520 => UInt16, oid::FUNC_SHIFT_LEFT_UINT16;
5521 params!(UInt32, UInt32) => BF::from(func::BitShiftLeftUint32)
5522 => UInt32, oid::FUNC_SHIFT_LEFT_UINT32;
5523 params!(UInt64, UInt32) => BF::from(func::BitShiftLeftUint64)
5524 => UInt64, oid::FUNC_SHIFT_LEFT_UINT64;
5525 params!(RangeAny, RangeAny) => BF::from(func::RangeBefore) => Bool, 3893;
5526 },
5527 ">>" => Scalar {
5528 params!(Int16, Int32) => BF::from(func::BitShiftRightInt16) => Int16, 1879;
5529 params!(Int32, Int32) => BF::from(func::BitShiftRightInt32) => Int32, 1885;
5530 params!(Int64, Int32) => BF::from(func::BitShiftRightInt64) => Int64, 1891;
5531 params!(UInt16, UInt32) => BF::from(func::BitShiftRightUint16)
5532 => UInt16, oid::FUNC_SHIFT_RIGHT_UINT16;
5533 params!(UInt32, UInt32) => BF::from(func::BitShiftRightUint32)
5534 => UInt32, oid::FUNC_SHIFT_RIGHT_UINT32;
5535 params!(UInt64, UInt32) => BF::from(func::BitShiftRightUint64)
5536 => UInt64, oid::FUNC_SHIFT_RIGHT_UINT64;
5537 params!(RangeAny, RangeAny) => BF::from(func::RangeAfter) => Bool, 3894;
5538 },
5539
5540 "~~*" => Scalar {
5542 params!(String, String) => BF::from(func::IsLikeMatchCaseInsensitive) => Bool, 1627;
5543 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5544 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5545 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5546 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5547 )
5548 }) => Bool, 1629;
5549 },
5550 "!~~*" => Scalar {
5551 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5552 Ok(lhs
5553 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5554 .call_unary(UnaryFunc::Not(func::Not)))
5555 }) => Bool, 1628;
5556 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5557 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5558 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5559 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5560 .call_unary(UnaryFunc::Not(func::Not))
5561 )
5562 }) => Bool, 1630;
5563 },
5564
5565
5566 "~~" => Scalar {
5568 params!(String, String) => BF::from(func::IsLikeMatchCaseSensitive) => Bool, 1209;
5569 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5570 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5571 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5572 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5573 )
5574 }) => Bool, 1211;
5575 },
5576 "!~~" => Scalar {
5577 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5578 Ok(lhs
5579 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5580 .call_unary(UnaryFunc::Not(func::Not)))
5581 }) => Bool, 1210;
5582 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5583 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5584 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5585 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5586 .call_unary(UnaryFunc::Not(func::Not))
5587 )
5588 }) => Bool, 1212;
5589 },
5590
5591 "~" => Scalar {
5593 params!(Int16) => UnaryFunc::BitNotInt16(func::BitNotInt16) => Int16, 1877;
5594 params!(Int32) => UnaryFunc::BitNotInt32(func::BitNotInt32) => Int32, 1883;
5595 params!(Int64) => UnaryFunc::BitNotInt64(func::BitNotInt64) => Int64, 1889;
5596 params!(UInt16) => UnaryFunc::BitNotUint16(func::BitNotUint16)
5597 => UInt16, oid::FUNC_BIT_NOT_UINT16_OID;
5598 params!(UInt32) => UnaryFunc::BitNotUint32(func::BitNotUint32)
5599 => UInt32, oid::FUNC_BIT_NOT_UINT32_OID;
5600 params!(UInt64) => UnaryFunc::BitNotUint64(func::BitNotUint64)
5601 => UInt64, oid::FUNC_BIT_NOT_UINT64_OID;
5602 params!(String, String)
5603 => BinaryFunc::IsRegexpMatchCaseSensitive(
5604 func::IsRegexpMatchCaseSensitive,
5605 ) => Bool, 641;
5606 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5607 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5608 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5609 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5610 func::IsRegexpMatchCaseSensitive,
5611 )))
5612 }) => Bool, 1055;
5613 },
5614 "~*" => Scalar {
5615 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5616 Ok(lhs.call_binary(
5617 rhs,
5618 BinaryFunc::IsRegexpMatchCaseInsensitive(
5619 func::IsRegexpMatchCaseInsensitive,
5620 ),
5621 ))
5622 }) => Bool, 1228;
5623 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5624 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5625 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5626 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5627 func::IsRegexpMatchCaseInsensitive,
5628 )))
5629 }) => Bool, 1234;
5630 },
5631 "!~" => Scalar {
5632 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5633 Ok(lhs
5634 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5635 func::IsRegexpMatchCaseSensitive,
5636 ))
5637 .call_unary(UnaryFunc::Not(func::Not)))
5638 }) => Bool, 642;
5639 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5640 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5641 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5642 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5643 func::IsRegexpMatchCaseSensitive,
5644 ))
5645 .call_unary(UnaryFunc::Not(func::Not)))
5646 }) => Bool, 1056;
5647 },
5648 "!~*" => Scalar {
5649 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5650 Ok(lhs
5651 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5652 func::IsRegexpMatchCaseInsensitive,
5653 ))
5654 .call_unary(UnaryFunc::Not(func::Not)))
5655 }) => Bool, 1229;
5656 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5657 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5658 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5659 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5660 func::IsRegexpMatchCaseInsensitive,
5661 ))
5662 .call_unary(UnaryFunc::Not(func::Not)))
5663 }) => Bool, 1235;
5664 },
5665
5666 "||" => Scalar {
5668 params!(String, NonVecAny) => Operation::binary(|ecx, lhs, rhs| {
5669 let rhs = typeconv::plan_cast(
5670 ecx,
5671 CastContext::Explicit,
5672 rhs,
5673 &SqlScalarType::String,
5674 )?;
5675 Ok(lhs.call_binary(rhs, func::TextConcatBinary))
5676 }) => String, 2779;
5677 params!(NonVecAny, String) => Operation::binary(|ecx, lhs, rhs| {
5678 let lhs = typeconv::plan_cast(
5679 ecx,
5680 CastContext::Explicit,
5681 lhs,
5682 &SqlScalarType::String,
5683 )?;
5684 Ok(lhs.call_binary(rhs, func::TextConcatBinary))
5685 }) => String, 2780;
5686 params!(String, String) => BF::from(func::TextConcatBinary) => String, 654;
5687 params!(Jsonb, Jsonb) => BF::from(func::JsonbConcat) => Jsonb, 3284;
5688 params!(ArrayAnyCompatible, ArrayAnyCompatible)
5689 => BF::from(func::ArrayArrayConcat) => ArrayAnyCompatible, 375;
5690 params!(ListAnyCompatible, ListAnyCompatible)
5691 => BF::from(func::ListListConcat)
5692 => ListAnyCompatible, oid::OP_CONCAT_LIST_LIST_OID;
5693 params!(ListAnyCompatible, ListElementAnyCompatible)
5694 => BF::from(func::ListElementConcat)
5695 => ListAnyCompatible, oid::OP_CONCAT_LIST_ELEMENT_OID;
5696 params!(ListElementAnyCompatible, ListAnyCompatible)
5697 => BF::from(func::ElementListConcat)
5698 => ListAnyCompatible, oid::OP_CONCAT_ELEMENY_LIST_OID;
5699 },
5700
5701 "->" => Scalar {
5703 params!(Jsonb, Int64) => BF::from(func::JsonbGetInt64) => Jsonb, 3212;
5704 params!(Jsonb, String) => BF::from(func::JsonbGetString) => Jsonb, 3211;
5705 params!(MapAny, String) => BF::from(func::MapGetValue)
5706 => Any, oid::OP_GET_VALUE_MAP_OID;
5707 },
5708 "->>" => Scalar {
5709 params!(Jsonb, Int64) => BF::from(func::JsonbGetInt64Stringify) => String, 3481;
5710 params!(Jsonb, String) => BF::from(func::JsonbGetStringStringify) => String, 3477;
5711 },
5712 "#>" => Scalar {
5713 params!(Jsonb, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5714 => BF::from(func::JsonbGetPath) => Jsonb, 3213;
5715 },
5716 "#>>" => Scalar {
5717 params!(Jsonb, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5718 => BF::from(func::JsonbGetPathStringify) => String, 3206;
5719 },
5720 "@>" => Scalar {
5721 params!(Jsonb, Jsonb) => BF::from(func::JsonbContainsJsonb) => Bool, 3246;
5722 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
5723 Ok(lhs.call_binary(
5724 rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
5725 BinaryFunc::from(func::JsonbContainsJsonb),
5726 ))
5727 }) => Bool, oid::OP_CONTAINS_JSONB_STRING_OID;
5728 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5729 Ok(lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
5730 .call_binary(rhs, func::JsonbContainsJsonb))
5731 }) => Bool, oid::OP_CONTAINS_STRING_JSONB_OID;
5732 params!(MapAnyCompatible, MapAnyCompatible)
5733 => BF::from(func::MapContainsMap)
5734 => Bool, oid::OP_CONTAINS_MAP_MAP_OID;
5735 params!(RangeAny, AnyElement) => Operation::binary(|ecx, lhs, rhs| {
5736 let elem_type = ecx.scalar_type(&lhs).unwrap_range_element_type().clone();
5737 let f = match elem_type {
5738 SqlScalarType::Int32 => BF::from(func::RangeContainsI32),
5739 SqlScalarType::Int64 => BF::from(func::RangeContainsI64),
5740 SqlScalarType::Date => BF::from(func::RangeContainsDate),
5741 SqlScalarType::Numeric { .. } => BF::from(func::RangeContainsNumeric),
5742 SqlScalarType::Timestamp { .. } => BF::from(func::RangeContainsTimestamp),
5743 SqlScalarType::TimestampTz { .. } => BF::from(func::RangeContainsTimestampTz),
5744 _ => bail_unsupported!(format!("range element type: {elem_type:?}")),
5745 };
5746 Ok(lhs.call_binary(rhs, f))
5747 }) => Bool, 3889;
5748 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
5749 Ok(lhs.call_binary(rhs, BF::from(func::RangeContainsRange)))
5750 }) => Bool, 3890;
5751 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
5752 Ok(lhs.call_binary(rhs, BF::from(func::ArrayContainsArray)))
5753 }) => Bool, 2751;
5754 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
5755 Ok(lhs.call_binary(rhs, BF::from(func::ListContainsList)))
5756 }) => Bool, oid::OP_CONTAINS_LIST_LIST_OID;
5757 },
5758 "<@" => Scalar {
5759 params!(Jsonb, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5760 Ok(rhs.call_binary(
5761 lhs,
5762 func::JsonbContainsJsonb
5763 ))
5764 }) => Bool, 3250;
5765 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
5766 Ok(rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
5767 .call_binary(lhs, func::JsonbContainsJsonb))
5768 }) => Bool, oid::OP_CONTAINED_JSONB_STRING_OID;
5769 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5770 Ok(rhs.call_binary(
5771 lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
5772 func::JsonbContainsJsonb,
5773 ))
5774 }) => Bool, oid::OP_CONTAINED_STRING_JSONB_OID;
5775 params!(MapAnyCompatible, MapAnyCompatible) => Operation::binary(|_ecx, lhs, rhs| {
5776 Ok(rhs.call_binary(lhs, func::MapContainsMap))
5777 }) => Bool, oid::OP_CONTAINED_MAP_MAP_OID;
5778 params!(AnyElement, RangeAny) => Operation::binary(|ecx, lhs, rhs| {
5779 let elem_type = ecx.scalar_type(&rhs).unwrap_range_element_type().clone();
5780 let f = match elem_type {
5781 SqlScalarType::Int32 => BF::from(func::RangeContainsI32Rev),
5782 SqlScalarType::Int64 => BF::from(func::RangeContainsI64Rev),
5783 SqlScalarType::Date => BF::from(func::RangeContainsDateRev),
5784 SqlScalarType::Numeric { .. } => BF::from(func::RangeContainsNumericRev),
5785 SqlScalarType::Timestamp { .. } => BF::from(func::RangeContainsTimestampRev),
5786 SqlScalarType::TimestampTz { .. } => {
5787 BF::from(func::RangeContainsTimestampTzRev)
5788 }
5789 _ => bail_unsupported!(format!("range element type: {elem_type:?}")),
5790 };
5791 Ok(rhs.call_binary(lhs, f))
5792 }) => Bool, 3891;
5793 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
5794 Ok(rhs.call_binary(lhs, BF::from(func::RangeContainsRangeRev)))
5795 }) => Bool, 3892;
5796 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
5797 Ok(lhs.call_binary(rhs, BF::from(func::ArrayContainsArrayRev)))
5798 }) => Bool, 2752;
5799 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
5800 Ok(lhs.call_binary(rhs, BF::from(func::ListContainsListRev)))
5801 }) => Bool, oid::OP_IS_CONTAINED_LIST_LIST_OID;
5802 },
5803 "?" => Scalar {
5804 params!(Jsonb, String) => BF::from(func::JsonbContainsString) => Bool, 3247;
5805 params!(MapAny, String) => BF::from(func::MapContainsKey)
5806 => Bool, oid::OP_CONTAINS_KEY_MAP_OID;
5807 },
5808 "?&" => Scalar {
5809 params!(MapAny, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5810 => BF::from(func::MapContainsAllKeys)
5811 => Bool, oid::OP_CONTAINS_ALL_KEYS_MAP_OID;
5812 },
5813 "?|" => Scalar {
5814 params!(MapAny, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5815 => BF::from(func::MapContainsAnyKeys)
5816 => Bool, oid::OP_CONTAINS_ANY_KEYS_MAP_OID;
5817 },
5818 "&&" => Scalar {
5819 params!(RangeAny, RangeAny) => BF::from(func::RangeOverlaps) => Bool, 3888;
5820 },
5821 "&<" => Scalar {
5822 params!(RangeAny, RangeAny) => BF::from(func::RangeOverleft) => Bool, 3895;
5823 },
5824 "&>" => Scalar {
5825 params!(RangeAny, RangeAny) => BF::from(func::RangeOverright) => Bool, 3896;
5826 },
5827 "-|-" => Scalar {
5828 params!(RangeAny, RangeAny) => BF::from(func::RangeAdjacent) => Bool, 3897;
5829 },
5830
5831 "<" => Scalar {
5833 params!(Numeric, Numeric) => BF::from(func::Lt) => Bool, 1754;
5834 params!(Bool, Bool) => BF::from(func::Lt) => Bool, 58;
5835 params!(Int16, Int16) => BF::from(func::Lt) => Bool, 95;
5836 params!(Int32, Int32) => BF::from(func::Lt) => Bool, 97;
5837 params!(Int64, Int64) => BF::from(func::Lt) => Bool, 412;
5838 params!(UInt16, UInt16) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT16_OID;
5839 params!(UInt32, UInt32) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT32_OID;
5840 params!(UInt64, UInt64) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT64_OID;
5841 params!(Float32, Float32) => BF::from(func::Lt) => Bool, 622;
5842 params!(Float64, Float64) => BF::from(func::Lt) => Bool, 672;
5843 params!(Oid, Oid) => BF::from(func::Lt) => Bool, 609;
5844 params!(Date, Date) => BF::from(func::Lt) => Bool, 1095;
5845 params!(Time, Time) => BF::from(func::Lt) => Bool, 1110;
5846 params!(Timestamp, Timestamp) => BF::from(func::Lt) => Bool, 2062;
5847 params!(TimestampTz, TimestampTz) => BF::from(func::Lt) => Bool, 1322;
5848 params!(Uuid, Uuid) => BF::from(func::Lt) => Bool, 2974;
5849 params!(Interval, Interval) => BF::from(func::Lt) => Bool, 1332;
5850 params!(Bytes, Bytes) => BF::from(func::Lt) => Bool, 1957;
5851 params!(String, String) => BF::from(func::Lt) => Bool, 664;
5852 params!(Char, Char) => BF::from(func::Lt) => Bool, 1058;
5853 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Lt) => Bool, 631;
5854 params!(PgLegacyName, PgLegacyName) => BF::from(func::Lt) => Bool, 660;
5855 params!(Jsonb, Jsonb) => BF::from(func::Lt) => Bool, 3242;
5856 params!(ArrayAny, ArrayAny) => BF::from(func::Lt) => Bool, 1072;
5857 params!(RecordAny, RecordAny) => BF::from(func::Lt) => Bool, 2990;
5858 params!(MzTimestamp, MzTimestamp) => BF::from(func::Lt)
5859 => Bool, oid::FUNC_MZ_TIMESTAMP_LT_MZ_TIMESTAMP_OID;
5860 params!(RangeAny, RangeAny) => BF::from(func::Lt) => Bool, 3884;
5861 },
5862 "<=" => Scalar {
5863 params!(Numeric, Numeric) => BF::from(func::Lte) => Bool, 1755;
5864 params!(Bool, Bool) => BF::from(func::Lte) => Bool, 1694;
5865 params!(Int16, Int16) => BF::from(func::Lte) => Bool, 522;
5866 params!(Int32, Int32) => BF::from(func::Lte) => Bool, 523;
5867 params!(Int64, Int64) => BF::from(func::Lte) => Bool, 414;
5868 params!(UInt16, UInt16) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT16_OID;
5869 params!(UInt32, UInt32) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT32_OID;
5870 params!(UInt64, UInt64) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT64_OID;
5871 params!(Float32, Float32) => BF::from(func::Lte) => Bool, 624;
5872 params!(Float64, Float64) => BF::from(func::Lte) => Bool, 673;
5873 params!(Oid, Oid) => BF::from(func::Lte) => Bool, 611;
5874 params!(Date, Date) => BF::from(func::Lte) => Bool, 1096;
5875 params!(Time, Time) => BF::from(func::Lte) => Bool, 1111;
5876 params!(Timestamp, Timestamp) => BF::from(func::Lte) => Bool, 2063;
5877 params!(TimestampTz, TimestampTz) => BF::from(func::Lte) => Bool, 1323;
5878 params!(Uuid, Uuid) => BF::from(func::Lte) => Bool, 2976;
5879 params!(Interval, Interval) => BF::from(func::Lte) => Bool, 1333;
5880 params!(Bytes, Bytes) => BF::from(func::Lte) => Bool, 1958;
5881 params!(String, String) => BF::from(func::Lte) => Bool, 665;
5882 params!(Char, Char) => BF::from(func::Lte) => Bool, 1059;
5883 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Lte) => Bool, 632;
5884 params!(PgLegacyName, PgLegacyName) => BF::from(func::Lte) => Bool, 661;
5885 params!(Jsonb, Jsonb) => BF::from(func::Lte) => Bool, 3244;
5886 params!(ArrayAny, ArrayAny) => BF::from(func::Lte) => Bool, 1074;
5887 params!(RecordAny, RecordAny) => BF::from(func::Lte) => Bool, 2992;
5888 params!(MzTimestamp, MzTimestamp) => BF::from(func::Lte)
5889 => Bool, oid::FUNC_MZ_TIMESTAMP_LTE_MZ_TIMESTAMP_OID;
5890 params!(RangeAny, RangeAny) => BF::from(func::Lte) => Bool, 3885;
5891 },
5892 ">" => Scalar {
5893 params!(Numeric, Numeric) => BF::from(func::Gt) => Bool, 1756;
5894 params!(Bool, Bool) => BF::from(func::Gt) => Bool, 59;
5895 params!(Int16, Int16) => BF::from(func::Gt) => Bool, 520;
5896 params!(Int32, Int32) => BF::from(func::Gt) => Bool, 521;
5897 params!(Int64, Int64) => BF::from(func::Gt) => Bool, 413;
5898 params!(UInt16, UInt16) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT16_OID;
5899 params!(UInt32, UInt32) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT32_OID;
5900 params!(UInt64, UInt64) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT64_OID;
5901 params!(Float32, Float32) => BF::from(func::Gt) => Bool, 623;
5902 params!(Float64, Float64) => BF::from(func::Gt) => Bool, 674;
5903 params!(Oid, Oid) => BF::from(func::Gt) => Bool, 610;
5904 params!(Date, Date) => BF::from(func::Gt) => Bool, 1097;
5905 params!(Time, Time) => BF::from(func::Gt) => Bool, 1112;
5906 params!(Timestamp, Timestamp) => BF::from(func::Gt) => Bool, 2064;
5907 params!(TimestampTz, TimestampTz) => BF::from(func::Gt) => Bool, 1324;
5908 params!(Uuid, Uuid) => BF::from(func::Gt) => Bool, 2975;
5909 params!(Interval, Interval) => BF::from(func::Gt) => Bool, 1334;
5910 params!(Bytes, Bytes) => BF::from(func::Gt) => Bool, 1959;
5911 params!(String, String) => BF::from(func::Gt) => Bool, 666;
5912 params!(Char, Char) => BF::from(func::Gt) => Bool, 1060;
5913 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Gt) => Bool, 633;
5914 params!(PgLegacyName, PgLegacyName) => BF::from(func::Gt) => Bool, 662;
5915 params!(Jsonb, Jsonb) => BF::from(func::Gt) => Bool, 3243;
5916 params!(ArrayAny, ArrayAny) => BF::from(func::Gt) => Bool, 1073;
5917 params!(RecordAny, RecordAny) => BF::from(func::Gt) => Bool, 2991;
5918 params!(MzTimestamp, MzTimestamp) => BF::from(func::Gt)
5919 => Bool, oid::FUNC_MZ_TIMESTAMP_GT_MZ_TIMESTAMP_OID;
5920 params!(RangeAny, RangeAny) => BF::from(func::Gt) => Bool, 3887;
5921 },
5922 ">=" => Scalar {
5923 params!(Numeric, Numeric) => BF::from(func::Gte) => Bool, 1757;
5924 params!(Bool, Bool) => BF::from(func::Gte) => Bool, 1695;
5925 params!(Int16, Int16) => BF::from(func::Gte) => Bool, 524;
5926 params!(Int32, Int32) => BF::from(func::Gte) => Bool, 525;
5927 params!(Int64, Int64) => BF::from(func::Gte) => Bool, 415;
5928 params!(UInt16, UInt16) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT16_OID;
5929 params!(UInt32, UInt32) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT32_OID;
5930 params!(UInt64, UInt64) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT64_OID;
5931 params!(Float32, Float32) => BF::from(func::Gte) => Bool, 625;
5932 params!(Float64, Float64) => BF::from(func::Gte) => Bool, 675;
5933 params!(Oid, Oid) => BF::from(func::Gte) => Bool, 612;
5934 params!(Date, Date) => BF::from(func::Gte) => Bool, 1098;
5935 params!(Time, Time) => BF::from(func::Gte) => Bool, 1113;
5936 params!(Timestamp, Timestamp) => BF::from(func::Gte) => Bool, 2065;
5937 params!(TimestampTz, TimestampTz) => BF::from(func::Gte) => Bool, 1325;
5938 params!(Uuid, Uuid) => BF::from(func::Gte) => Bool, 2977;
5939 params!(Interval, Interval) => BF::from(func::Gte) => Bool, 1335;
5940 params!(Bytes, Bytes) => BF::from(func::Gte) => Bool, 1960;
5941 params!(String, String) => BF::from(func::Gte) => Bool, 667;
5942 params!(Char, Char) => BF::from(func::Gte) => Bool, 1061;
5943 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Gte) => Bool, 634;
5944 params!(PgLegacyName, PgLegacyName) => BF::from(func::Gte) => Bool, 663;
5945 params!(Jsonb, Jsonb) => BF::from(func::Gte) => Bool, 3245;
5946 params!(ArrayAny, ArrayAny) => BF::from(func::Gte) => Bool, 1075;
5947 params!(RecordAny, RecordAny) => BF::from(func::Gte) => Bool, 2993;
5948 params!(MzTimestamp, MzTimestamp) => BF::from(func::Gte)
5949 => Bool, oid::FUNC_MZ_TIMESTAMP_GTE_MZ_TIMESTAMP_OID;
5950 params!(RangeAny, RangeAny) => BF::from(func::Gte) => Bool, 3886;
5951 },
5952 "=" => Scalar {
5963 params!(Numeric, Numeric) => BF::from(func::Eq) => Bool, 1752;
5964 params!(Bool, Bool) => BF::from(func::Eq) => Bool, 91;
5965 params!(Int16, Int16) => BF::from(func::Eq) => Bool, 94;
5966 params!(Int32, Int32) => BF::from(func::Eq) => Bool, 96;
5967 params!(Int64, Int64) => BF::from(func::Eq) => Bool, 410;
5968 params!(UInt16, UInt16) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT16_OID;
5969 params!(UInt32, UInt32) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT32_OID;
5970 params!(UInt64, UInt64) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT64_OID;
5971 params!(Float32, Float32) => BF::from(func::Eq) => Bool, 620;
5972 params!(Float64, Float64) => BF::from(func::Eq) => Bool, 670;
5973 params!(Oid, Oid) => BF::from(func::Eq) => Bool, 607;
5974 params!(Date, Date) => BF::from(func::Eq) => Bool, 1093;
5975 params!(Time, Time) => BF::from(func::Eq) => Bool, 1108;
5976 params!(Timestamp, Timestamp) => BF::from(func::Eq) => Bool, 2060;
5977 params!(TimestampTz, TimestampTz) => BF::from(func::Eq) => Bool, 1320;
5978 params!(Uuid, Uuid) => BF::from(func::Eq) => Bool, 2972;
5979 params!(Interval, Interval) => BF::from(func::Eq) => Bool, 1330;
5980 params!(Bytes, Bytes) => BF::from(func::Eq) => Bool, 1955;
5981 params!(String, String) => BF::from(func::Eq) => Bool, 98;
5982 params!(Char, Char) => BF::from(func::Eq) => Bool, 1054;
5983 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Eq) => Bool, 92;
5984 params!(PgLegacyName, PgLegacyName) => BF::from(func::Eq) => Bool, 93;
5985 params!(Jsonb, Jsonb) => BF::from(func::Eq) => Bool, 3240;
5986 params!(ListAny, ListAny) => BF::from(func::Eq) => Bool, oid::FUNC_LIST_EQ_OID;
5987 params!(ArrayAny, ArrayAny) => BF::from(func::Eq) => Bool, 1070;
5988 params!(RecordAny, RecordAny) => BF::from(func::Eq) => Bool, 2988;
5989 params!(MzTimestamp, MzTimestamp) => BF::from(func::Eq)
5990 => Bool, oid::FUNC_MZ_TIMESTAMP_EQ_MZ_TIMESTAMP_OID;
5991 params!(RangeAny, RangeAny) => BF::from(func::Eq) => Bool, 3882;
5992 params!(MzAclItem, MzAclItem) => BF::from(func::Eq)
5993 => Bool, oid::FUNC_MZ_ACL_ITEM_EQ_MZ_ACL_ITEM_OID;
5994 params!(AclItem, AclItem) => BF::from(func::Eq) => Bool, 974;
5995 },
5996 "<>" => Scalar {
5997 params!(Numeric, Numeric) => BF::from(func::NotEq) => Bool, 1753;
5998 params!(Bool, Bool) => BF::from(func::NotEq) => Bool, 85;
5999 params!(Int16, Int16) => BF::from(func::NotEq) => Bool, 519;
6000 params!(Int32, Int32) => BF::from(func::NotEq) => Bool, 518;
6001 params!(Int64, Int64) => BF::from(func::NotEq) => Bool, 411;
6002 params!(UInt16, UInt16) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT16_OID;
6003 params!(UInt32, UInt32) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT32_OID;
6004 params!(UInt64, UInt64) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT64_OID;
6005 params!(Float32, Float32) => BF::from(func::NotEq) => Bool, 621;
6006 params!(Float64, Float64) => BF::from(func::NotEq) => Bool, 671;
6007 params!(Oid, Oid) => BF::from(func::NotEq) => Bool, 608;
6008 params!(Date, Date) => BF::from(func::NotEq) => Bool, 1094;
6009 params!(Time, Time) => BF::from(func::NotEq) => Bool, 1109;
6010 params!(Timestamp, Timestamp) => BF::from(func::NotEq) => Bool, 2061;
6011 params!(TimestampTz, TimestampTz) => BF::from(func::NotEq) => Bool, 1321;
6012 params!(Uuid, Uuid) => BF::from(func::NotEq) => Bool, 2973;
6013 params!(Interval, Interval) => BF::from(func::NotEq) => Bool, 1331;
6014 params!(Bytes, Bytes) => BF::from(func::NotEq) => Bool, 1956;
6015 params!(String, String) => BF::from(func::NotEq) => Bool, 531;
6016 params!(Char, Char) => BF::from(func::NotEq) => Bool, 1057;
6017 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::NotEq) => Bool, 630;
6018 params!(PgLegacyName, PgLegacyName) => BF::from(func::NotEq) => Bool, 643;
6019 params!(Jsonb, Jsonb) => BF::from(func::NotEq) => Bool, 3241;
6020 params!(ArrayAny, ArrayAny) => BF::from(func::NotEq) => Bool, 1071;
6021 params!(RecordAny, RecordAny) => BF::from(func::NotEq) => Bool, 2989;
6022 params!(MzTimestamp, MzTimestamp) => BF::from(func::NotEq)
6023 => Bool, oid::FUNC_MZ_TIMESTAMP_NOT_EQ_MZ_TIMESTAMP_OID;
6024 params!(RangeAny, RangeAny) => BF::from(func::NotEq) => Bool, 3883;
6025 params!(MzAclItem, MzAclItem) => BF::from(func::NotEq)
6026 => Bool, oid::FUNC_MZ_ACL_ITEM_NOT_EQ_MZ_ACL_ITEM_OID;
6027 }
6028 }
6029});
6030
6031pub fn resolve_op(op: &str) -> Result<&'static [FuncImpl<HirScalarExpr>], PlanError> {
6033 match OP_IMPLS.get(op) {
6034 Some(Func::Scalar(impls)) => Ok(impls),
6035 Some(_) => unreachable!("all operators must be scalar functions"),
6036 None => bail_unsupported!(format!("[{}]", op)),
6046 }
6047}
6048
6049fn current_settings(
6052 name: HirScalarExpr,
6053 missing_ok: HirScalarExpr,
6054) -> Result<HirScalarExpr, PlanError> {
6055 let expr = HirScalarExpr::call_binary(
6057 HirScalarExpr::call_unmaterializable(UnmaterializableFunc::ViewableVariables),
6058 HirScalarExpr::call_unary(name, UnaryFunc::Lower(func::Lower)),
6059 func::MapGetValue,
6060 );
6061 let expr = HirScalarExpr::if_then_else(
6062 missing_ok,
6063 expr.clone(),
6064 HirScalarExpr::call_variadic(
6065 VariadicFunc::ErrorIfNull,
6066 vec![
6067 expr,
6068 HirScalarExpr::literal(
6069 Datum::String("unrecognized configuration parameter"),
6070 SqlScalarType::String,
6071 ),
6072 ],
6073 ),
6074 );
6075 Ok(expr)
6076}