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