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_sql_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_sql_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_sql_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_sql_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_sql_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(&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(&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(&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_sql_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 mz_expr::REPEAT_ROW_NAME => Table {
4737 params!(Int64) => Operation::unary(move |ecx, n| {
4738 ecx.require_feature_flag(&vars::ENABLE_REPEAT_ROW)?;
4739 Ok(TableFuncPlan {
4740 imp: TableFuncImpl::CallTable {
4741 func: TableFunc::RepeatRow,
4742 exprs: vec![n],
4743 },
4744 column_names: vec![]
4745 })
4746 }) => ReturnType::none(true), oid::FUNC_REPEAT_ROW_OID;
4747 },
4748 "repeat_row_non_negative" => Table {
4749 params!(Int64) => Operation::unary(move |ecx, n| {
4750 ecx.require_feature_flag(&vars::ENABLE_REPEAT_ROW_NON_NEGATIVE)?;
4751 Ok(TableFuncPlan {
4752 imp: TableFuncImpl::CallTable {
4753 func: TableFunc::RepeatRowNonNegative,
4754 exprs: vec![n],
4755 },
4756 column_names: vec![]
4757 })
4758 }) => ReturnType::none(true), oid::FUNC_REPEAT_ROW_NON_NEGATIVE_OID;
4759 },
4760 "seahash" => Scalar {
4761 params!(String) => UnaryFunc::SeahashString(func::SeahashString)
4762 => UInt32, oid::FUNC_SEAHASH_STRING_OID;
4763 params!(Bytes) => UnaryFunc::SeahashBytes(func::SeahashBytes)
4764 => UInt32, oid::FUNC_SEAHASH_BYTES_OID;
4765 },
4766 "starts_with" => Scalar {
4767 params!(String, String) => BinaryFunc::from(func::StartsWith) => Bool, 3696;
4768 },
4769 "timezone_offset" => Scalar {
4770 params!(String, TimestampTz) => BinaryFunc::from(func::TimezoneOffset)
4771 => RecordAny, oid::FUNC_TIMEZONE_OFFSET;
4772 },
4773 "try_parse_monotonic_iso8601_timestamp" => Scalar {
4774 params!(String) => Operation::unary(move |_ecx, e| {
4775 Ok(e.call_unary(UnaryFunc::TryParseMonotonicIso8601Timestamp(
4776 func::TryParseMonotonicIso8601Timestamp,
4777 )))
4778 }) => Timestamp, oid::FUNC_TRY_PARSE_MONOTONIC_ISO8601_TIMESTAMP;
4779 },
4780 "unnest" => Table {
4781 vec![ArrayAny] => Operation::unary(move |ecx, e| {
4782 let el_typ = ecx.scalar_type(&e).unwrap_array_element_type().clone();
4783 Ok(TableFuncPlan {
4784 imp: TableFuncImpl::CallTable {
4785 func: TableFunc::UnnestArray { el_typ },
4786 exprs: vec![e],
4787 },
4788 column_names: vec!["unnest".into()],
4789 })
4790 }) =>
4791 ReturnType::set_of(AnyElement), 2331;
4794 vec![ListAny] => Operation::unary(move |ecx, e| {
4795 let el_typ = ecx.scalar_type(&e).unwrap_list_element_type().clone();
4796 Ok(TableFuncPlan {
4797 imp: TableFuncImpl::CallTable {
4798 func: TableFunc::UnnestList { el_typ },
4799 exprs: vec![e],
4800 },
4801 column_names: vec!["unnest".into()],
4802 })
4803 }) =>
4804 ReturnType::set_of(Any), oid::FUNC_UNNEST_LIST_OID;
4807 vec![MapAny] => Operation::unary(move |ecx, e| {
4808 let value_type = ecx.scalar_type(&e).unwrap_map_value_type().clone();
4809 Ok(TableFuncPlan {
4810 imp: TableFuncImpl::CallTable {
4811 func: TableFunc::UnnestMap { value_type },
4812 exprs: vec![e],
4813 },
4814 column_names: vec!["key".into(), "value".into()],
4815 })
4816 }) =>
4817 ReturnType::set_of(Any), oid::FUNC_UNNEST_MAP_OID;
4820 }
4821 }
4822});
4823
4824pub static MZ_INTERNAL_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
4825 use ParamType::*;
4826 use SqlScalarBaseType::*;
4827 builtins! {
4828 "aclitem_grantor" => Scalar {
4829 params!(AclItem) => UnaryFunc::AclItemGrantor(func::AclItemGrantor)
4830 => Oid, oid::FUNC_ACL_ITEM_GRANTOR_OID;
4831 },
4832 "aclitem_grantee" => Scalar {
4833 params!(AclItem) => UnaryFunc::AclItemGrantee(func::AclItemGrantee)
4834 => Oid, oid::FUNC_ACL_ITEM_GRANTEE_OID;
4835 },
4836 "aclitem_privileges" => Scalar {
4837 params!(AclItem) => UnaryFunc::AclItemPrivileges(func::AclItemPrivileges)
4838 => String, oid::FUNC_ACL_ITEM_PRIVILEGES_OID;
4839 },
4840 "is_rbac_enabled" => Scalar {
4841 params!() => UnmaterializableFunc::IsRbacEnabled => Bool, oid::FUNC_IS_RBAC_ENABLED_OID;
4842 },
4843 "make_mz_aclitem" => Scalar {
4844 params!(String, String, String) => VariadicFunc::from(variadic::MakeMzAclItem)
4845 => MzAclItem, oid::FUNC_MAKE_MZ_ACL_ITEM_OID;
4846 },
4847 "mz_acl_item_contains_privilege" => Scalar {
4848 params!(MzAclItem, String)
4849 => BinaryFunc::from(func::MzAclItemContainsPrivilege)
4850 => Bool, oid::FUNC_MZ_ACL_ITEM_CONTAINS_PRIVILEGE_OID;
4851 },
4852 "mz_aclexplode" => Table {
4853 params!(SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)))
4854 => Operation::unary(move |_ecx, mz_aclitems| {
4855 Ok(TableFuncPlan {
4856 imp: TableFuncImpl::CallTable {
4857 func: TableFunc::MzAclExplode,
4858 exprs: vec![mz_aclitems],
4859 },
4860 column_names: vec![
4861 "grantor".into(), "grantee".into(),
4862 "privilege_type".into(), "is_grantable".into(),
4863 ],
4864 })
4865 }) => ReturnType::set_of(RecordAny), oid::FUNC_MZ_ACL_ITEM_EXPLODE_OID;
4866 },
4867 "mz_aclitem_grantor" => Scalar {
4868 params!(MzAclItem) => UnaryFunc::MzAclItemGrantor(func::MzAclItemGrantor)
4869 => String, oid::FUNC_MZ_ACL_ITEM_GRANTOR_OID;
4870 },
4871 "mz_aclitem_grantee" => Scalar {
4872 params!(MzAclItem) => UnaryFunc::MzAclItemGrantee(func::MzAclItemGrantee)
4873 => String, oid::FUNC_MZ_ACL_ITEM_GRANTEE_OID;
4874 },
4875 "mz_aclitem_privileges" => Scalar {
4876 params!(MzAclItem) => UnaryFunc::MzAclItemPrivileges(
4877 func::MzAclItemPrivileges,
4878 ) => String, oid::FUNC_MZ_ACL_ITEM_PRIVILEGES_OID;
4879 },
4880 "mz_connection_oid" => Scalar {
4885 params!(String) => sql_impl_func("
4886 CASE
4887 WHEN $1 IS NULL THEN NULL
4888 ELSE (
4889 mz_unsafe.mz_error_if_null(
4890 (SELECT oid FROM mz_catalog.mz_objects
4891 WHERE name = $1 AND type = 'connection'),
4892 'connection \"' || $1 || '\" does not exist'
4893 )
4894 )
4895 END
4896 ") => Oid, oid::FUNC_CONNECTION_OID_OID;
4897 },
4898 "mz_format_privileges" => Scalar {
4899 params!(String) => UnaryFunc::MzFormatPrivileges(func::MzFormatPrivileges)
4900 => SqlScalarType::Array(Box::new(SqlScalarType::String)),
4901 oid::FUNC_MZ_FORMAT_PRIVILEGES_OID;
4902 },
4903 "mz_name_rank" => Table {
4904 params!(
4907 String,
4909 ParamType::Plain(SqlScalarType::Array(Box::new(SqlScalarType::String))),
4911 String,
4913 String
4915 ) =>
4916 sql_impl_table_func("
4918 -- The best ranked name is the one that belongs to the schema correlated with the lowest
4919 -- index in the search path
4920 SELECT id, name, count, min(schema_pref) OVER () = schema_pref AS best_ranked FROM (
4921 SELECT DISTINCT
4922 o.id,
4923 ARRAY[CASE WHEN s.database_id IS NULL THEN NULL ELSE d.name END, s.name, o.name]
4924 AS name,
4925 o.count,
4926 pg_catalog.array_position($2, s.name) AS schema_pref
4927 FROM
4928 (
4929 SELECT
4930 o.id,
4931 o.schema_id,
4932 o.name,
4933 count(*)
4934 FROM mz_catalog.mz_objects AS o
4935 JOIN mz_internal.mz_object_oid_alias AS a
4936 ON o.type = a.object_type
4937 WHERE o.name = CAST($3 AS pg_catalog.text) AND a.oid_alias = $4
4938 GROUP BY 1, 2, 3
4939 )
4940 AS o
4941 JOIN mz_catalog.mz_schemas AS s ON o.schema_id = s.id
4942 JOIN
4943 unnest($2) AS search_schema (name)
4944 ON search_schema.name = s.name
4945 JOIN
4946 (
4947 SELECT id, name FROM mz_catalog.mz_databases
4948 -- If the provided database does not exist, add a row for it so that it
4949 -- can still join against ambient schemas.
4950 UNION ALL
4951 SELECT '', $1 WHERE $1 NOT IN (SELECT name FROM mz_catalog.mz_databases)
4952 ) AS d
4953 ON d.id = COALESCE(s.database_id, d.id)
4954 WHERE d.name = CAST($1 AS pg_catalog.text)
4955 );
4956 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_NAME_RANK;
4957 },
4958 "mz_resolve_object_name" => Table {
4959 params!(String, String) =>
4960 sql_impl_table_func("
4963 SELECT
4964 o.id, o.oid, o.schema_id, o.name, o.type, o.owner_id, o.privileges
4965 FROM
4966 (SELECT mz_internal.mz_normalize_object_name($2))
4967 AS normalized (n),
4968 mz_internal.mz_name_rank(
4969 COALESCE(n[1], pg_catalog.current_database()),
4970 CASE
4971 WHEN n[2] IS NULL
4972 THEN pg_catalog.current_schemas(true)
4973 ELSE
4974 ARRAY[n[2]]
4975 END,
4976 n[3],
4977 $1
4978 ) AS r,
4979 mz_catalog.mz_objects AS o
4980 WHERE r.id = o.id AND r.best_ranked;
4981 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_RESOLVE_OBJECT_NAME;
4982 },
4983 "mz_minimal_name_qualification" => Scalar {
4995 params!(SqlScalarType::Array(Box::new(SqlScalarType::String)), String) => {
4996 sql_impl_func("(
4997 SELECT
4998 CASE
4999 WHEN $1::pg_catalog.text[] IS NULL
5000 THEN NULL
5001 -- If DB doesn't match, requires full qual
5002 WHEN $1[1] != pg_catalog.current_database()
5003 THEN $1
5004 -- If not in currently searchable schema, must be schema qualified
5005 WHEN NOT $1[2] = ANY(pg_catalog.current_schemas(true))
5006 THEN ARRAY[$1[2], $1[3]]
5007 ELSE
5008 minimal_name
5009 END
5010 FROM (
5011 -- Subquery so we return one null row in the cases where
5012 -- there are no matches.
5013 SELECT (
5014 SELECT DISTINCT
5015 CASE
5016 -- If there is only one item with this name and it's rank 1,
5017 -- it is uniquely nameable with just the final element
5018 WHEN best_ranked AND count = 1
5019 THEN ARRAY[r.name[3]]
5020 -- Otherwise, it is findable in the search path, so does not
5021 -- need database qualification
5022 ELSE
5023 ARRAY[r.name[2], r.name[3]]
5024 END AS minimal_name
5025 FROM mz_catalog.mz_objects AS o
5026 JOIN mz_internal.mz_object_oid_alias AS a
5027 ON o.type = a.object_type,
5028 -- implied lateral to put the OID alias into scope
5029 mz_internal.mz_name_rank(
5030 pg_catalog.current_database(),
5031 pg_catalog.current_schemas(true),
5032 $1[3],
5033 a.oid_alias
5034 ) AS r
5035 WHERE o.id = $2 AND r.id = $2
5036 )
5037 )
5038 )")
5039 } => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5040 oid::FUNC_MZ_MINIMINAL_NAME_QUALIFICATION;
5041 },
5042 "mz_global_id_to_name" => Scalar {
5043 params!(String) => sql_impl_func("
5044 CASE
5045 WHEN $1 IS NULL THEN NULL
5046 ELSE (
5047 SELECT array_to_string(minimal_name, '.')
5048 FROM (
5049 SELECT mz_unsafe.mz_error_if_null(
5050 (
5051 -- Return the fully-qualified name
5052 SELECT DISTINCT ARRAY[qual.d, qual.s, item.name]
5053 FROM
5054 mz_catalog.mz_objects AS item
5055 JOIN
5056 (
5057 SELECT
5058 d.name AS d,
5059 s.name AS s,
5060 s.id AS schema_id
5061 FROM
5062 mz_catalog.mz_schemas AS s
5063 LEFT JOIN
5064 (SELECT id, name FROM mz_catalog.mz_databases)
5065 AS d
5066 ON s.database_id = d.id
5067 ) AS qual
5068 ON qual.schema_id = item.schema_id
5069 WHERE item.id = CAST($1 AS text)
5070 ),
5071 'global ID ' || $1 || ' does not exist'
5072 )
5073 ) AS n (fqn),
5074 LATERAL (
5075 -- Get the minimal qualification of the fully qualified name
5076 SELECT mz_internal.mz_minimal_name_qualification(fqn, $1)
5077 ) AS m (minimal_name)
5078 )
5079 END
5080 ") => String, oid::FUNC_MZ_GLOBAL_ID_TO_NAME;
5081 },
5082 "mz_normalize_object_name" => Scalar {
5083 params!(String) => sql_impl_func("
5084 (
5085 SELECT
5086 CASE
5087 WHEN $1 IS NULL OR ident IS NULL THEN NULL
5088 WHEN pg_catalog.array_length(ident, 1) > 3
5089 THEN mz_unsafe.mz_error_if_null(
5090 NULL::pg_catalog.text[],
5091 'improper relation name (too many dotted names): ' || $1
5092 )
5093 ELSE pg_catalog.array_cat(
5094 pg_catalog.array_fill(
5095 CAST(NULL AS pg_catalog.text),
5096 ARRAY[3 - pg_catalog.array_length(ident, 1)]
5097 ),
5098 ident
5099 )
5100 END
5101 FROM (
5102 SELECT pg_catalog.parse_ident($1) AS ident
5103 ) AS i
5104 )") => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5105 oid::FUNC_MZ_NORMALIZE_OBJECT_NAME;
5106 },
5107 "mz_normalize_schema_name" => Scalar {
5108 params!(String) => sql_impl_func("
5109 (
5110 SELECT
5111 CASE
5112 WHEN $1 IS NULL OR ident IS NULL THEN NULL
5113 WHEN pg_catalog.array_length(ident, 1) > 2
5114 THEN mz_unsafe.mz_error_if_null(
5115 NULL::pg_catalog.text[],
5116 'improper schema name (too many dotted names): ' || $1
5117 )
5118 ELSE pg_catalog.array_cat(
5119 pg_catalog.array_fill(
5120 CAST(NULL AS pg_catalog.text),
5121 ARRAY[2 - pg_catalog.array_length(ident, 1)]
5122 ),
5123 ident
5124 )
5125 END
5126 FROM (
5127 SELECT pg_catalog.parse_ident($1) AS ident
5128 ) AS i
5129 )") => SqlScalarType::Array(Box::new(SqlScalarType::String)),
5130 oid::FUNC_MZ_NORMALIZE_SCHEMA_NAME;
5131 },
5132 "mz_render_typmod" => Scalar {
5133 params!(Oid, Int32) => BinaryFunc::from(func::MzRenderTypmod)
5134 => String, oid::FUNC_MZ_RENDER_TYPMOD_OID;
5135 },
5136 "mz_role_oid_memberships" => Scalar {
5137 params!() => UnmaterializableFunc::MzRoleOidMemberships
5138 => SqlScalarType::Map {
5139 value_type: Box::new(SqlScalarType::Array(
5140 Box::new(SqlScalarType::String),
5141 )),
5142 custom_id: None,
5143 }, oid::FUNC_MZ_ROLE_OID_MEMBERSHIPS;
5144 },
5145 "mz_database_oid" => Scalar {
5148 params!(String) => sql_impl_func("
5149 CASE
5150 WHEN $1 IS NULL THEN NULL
5151 ELSE (
5152 mz_unsafe.mz_error_if_null(
5153 (SELECT oid FROM mz_databases WHERE name = $1),
5154 'database \"' || $1 || '\" does not exist'
5155 )
5156 )
5157 END
5158 ") => Oid, oid::FUNC_DATABASE_OID_OID;
5159 },
5160 "mz_schema_oid" => Scalar {
5163 params!(String) => sql_impl_func("
5164 CASE
5165 WHEN $1 IS NULL THEN NULL
5166 ELSE
5167 mz_unsafe.mz_error_if_null(
5168 (
5169 SELECT
5170 (
5171 SELECT s.oid
5172 FROM mz_catalog.mz_schemas AS s
5173 LEFT JOIN mz_databases AS d ON s.database_id = d.id
5174 WHERE
5175 (
5176 -- Filter to only schemas in the named database or the
5177 -- current database if no database was specified.
5178 d.name = COALESCE(n[1], pg_catalog.current_database())
5179 -- Always include all ambient schemas.
5180 OR s.database_id IS NULL
5181 )
5182 AND s.name = n[2]
5183 )
5184 FROM mz_internal.mz_normalize_schema_name($1) AS n
5185 ),
5186 'schema \"' || $1 || '\" does not exist'
5187 )
5188 END
5189 ") => Oid, oid::FUNC_SCHEMA_OID_OID;
5190 },
5191 "mz_role_oid" => Scalar {
5194 params!(String) => sql_impl_func("
5195 CASE
5196 WHEN $1 IS NULL THEN NULL
5197 ELSE (
5198 mz_unsafe.mz_error_if_null(
5199 (SELECT oid FROM mz_catalog.mz_roles WHERE name = $1),
5200 'role \"' || $1 || '\" does not exist'
5201 )
5202 )
5203 END
5204 ") => Oid, oid::FUNC_ROLE_OID_OID;
5205 },
5206 "mz_secret_oid" => Scalar {
5211 params!(String) => sql_impl_func("
5212 CASE
5213 WHEN $1 IS NULL THEN NULL
5214 ELSE (
5215 mz_unsafe.mz_error_if_null(
5216 (SELECT oid FROM mz_catalog.mz_objects WHERE name = $1 AND type = 'secret'),
5217 'secret \"' || $1 || '\" does not exist'
5218 )
5219 )
5220 END
5221 ") => Oid, oid::FUNC_SECRET_OID_OID;
5222 },
5223 "mz_session_id" => Scalar {
5227 params!() => UnmaterializableFunc::MzSessionId => Uuid, oid::FUNC_MZ_SESSION_ID_OID;
5228 },
5229 "mz_type_name" => Scalar {
5230 params!(Oid) => UnaryFunc::MzTypeName(func::MzTypeName)
5231 => String, oid::FUNC_MZ_TYPE_NAME;
5232 },
5233 "mz_validate_privileges" => Scalar {
5234 params!(String) => UnaryFunc::MzValidatePrivileges(func::MzValidatePrivileges)
5235 => Bool, oid::FUNC_MZ_VALIDATE_PRIVILEGES_OID;
5236 },
5237 "mz_validate_role_privilege" => Scalar {
5238 params!(String) => UnaryFunc::MzValidateRolePrivilege(
5239 func::MzValidateRolePrivilege,
5240 ) => Bool, oid::FUNC_MZ_VALIDATE_ROLE_PRIVILEGE_OID;
5241 },
5242 "parse_catalog_create_sql" => Scalar {
5243 params!(String) => UnaryFunc::ParseCatalogCreateSql(func::ParseCatalogCreateSql)
5244 => Jsonb, oid::FUNC_PARSE_CATALOG_CREATE_SQL_OID;
5245 },
5246 "parse_catalog_id" => Scalar {
5247 params!(Jsonb) => UnaryFunc::ParseCatalogId(func::ParseCatalogId)
5248 => String, oid::FUNC_PARSE_CATALOG_ID_OID;
5249 },
5250 "parse_catalog_privileges" => Scalar {
5251 params!(Jsonb) => UnaryFunc::ParseCatalogPrivileges(func::ParseCatalogPrivileges)
5252 => SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)),
5253 oid::FUNC_PARSE_CATALOG_PRIVILEGES_OID;
5254 },
5255 "redact_sql" => Scalar {
5256 params!(String) => UnaryFunc::RedactSql(func::RedactSql)
5257 => String, oid::FUNC_REDACT_SQL_OID;
5258 }
5259 }
5260});
5261
5262pub static MZ_UNSAFE_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
5263 use ParamType::*;
5264 use SqlScalarBaseType::*;
5265 builtins! {
5266 "mz_all" => Aggregate {
5267 params!(Any) => AggregateFunc::All => Bool, oid::FUNC_MZ_ALL_OID;
5268 },
5269 "mz_any" => Aggregate {
5270 params!(Any) => AggregateFunc::Any => Bool, oid::FUNC_MZ_ANY_OID;
5271 },
5272 "mz_avg_promotion_internal_v1" => Scalar {
5273 params!(Float32) => Operation::identity()
5279 => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID_INTERNAL_V1;
5280 params!(Float64) => Operation::identity()
5281 => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID_INTERNAL_V1;
5282 params!(Int16) => Operation::unary(|ecx, e| {
5283 typeconv::plan_cast(
5284 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5285 )
5286 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID_INTERNAL_V1;
5287 params!(Int32) => Operation::unary(|ecx, e| {
5288 typeconv::plan_cast(
5289 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5290 )
5291 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID_INTERNAL_V1;
5292 params!(UInt16) => Operation::unary(|ecx, e| {
5293 typeconv::plan_cast(
5294 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5295 )
5296 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID_INTERNAL_V1;
5297 params!(UInt32) => Operation::unary(|ecx, e| {
5298 typeconv::plan_cast(
5299 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5300 )
5301 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID_INTERNAL_V1;
5302 },
5303 "mz_avg_promotion" => Scalar {
5304 params!(Float32) => Operation::identity()
5310 => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID;
5311 params!(Float64) => Operation::identity()
5312 => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID;
5313 params!(Int16) => Operation::unary(|ecx, e| {
5314 typeconv::plan_cast(
5315 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5316 )
5317 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID;
5318 params!(Int32) => Operation::unary(|ecx, e| {
5319 typeconv::plan_cast(
5320 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5321 )
5322 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID;
5323 params!(Int64) => Operation::unary(|ecx, e| {
5324 typeconv::plan_cast(
5325 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5326 )
5327 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I64_OID;
5328 params!(UInt16) => Operation::unary(|ecx, e| {
5329 typeconv::plan_cast(
5330 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5331 )
5332 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID;
5333 params!(UInt32) => Operation::unary(|ecx, e| {
5334 typeconv::plan_cast(
5335 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5336 )
5337 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID;
5338 params!(UInt64) => Operation::unary(|ecx, e| {
5339 typeconv::plan_cast(
5340 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5341 )
5342 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U64_OID;
5343 params!(Numeric) => Operation::unary(|ecx, e| {
5344 typeconv::plan_cast(
5345 ecx, CastContext::Explicit, e, &SqlScalarType::Numeric {max_scale: None},
5346 )
5347 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_NUMERIC_OID;
5348 },
5349 "mz_error_if_null" => Scalar {
5350 params!(Any, String) => VariadicFunc::from(variadic::ErrorIfNull)
5353 => Any, oid::FUNC_MZ_ERROR_IF_NULL_OID;
5354 },
5355 "mz_sleep" => Scalar {
5356 params!(Float64) => UnaryFunc::Sleep(func::Sleep)
5357 => TimestampTz, oid::FUNC_MZ_SLEEP_OID;
5358 },
5359 "mz_panic" => Scalar {
5360 params!(String) => UnaryFunc::Panic(func::Panic) => String, oid::FUNC_MZ_PANIC_OID;
5361 }
5362 }
5363});
5364
5365fn digest(algorithm: &'static str) -> Operation<HirScalarExpr> {
5366 Operation::unary(move |_ecx, input| {
5367 let algorithm = HirScalarExpr::literal(Datum::String(algorithm), SqlScalarType::String);
5368 Ok(input.call_binary(algorithm, BinaryFunc::from(func::DigestBytes)))
5369 })
5370}
5371
5372fn array_to_string(
5373 ecx: &ExprContext,
5374 exprs: Vec<HirScalarExpr>,
5375) -> Result<HirScalarExpr, PlanError> {
5376 let elem_type = match ecx.scalar_type(&exprs[0]) {
5377 SqlScalarType::Array(elem_type) => *elem_type,
5378 _ => unreachable!("array_to_string is guaranteed to receive array as first argument"),
5379 };
5380 Ok(HirScalarExpr::call_variadic(
5381 variadic::ArrayToString { elem_type },
5382 exprs,
5383 ))
5384}
5385
5386pub static OP_IMPLS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
5388 use BinaryFunc as BF;
5389 use ParamType::*;
5390 use SqlScalarBaseType::*;
5391 builtins! {
5392 "+" => Scalar {
5415 params!(Any) => Operation::new(|ecx, exprs, _params, _order_by| {
5416 typeconv::plan_coerce(ecx, exprs.into_element(), &SqlScalarType::Float64)
5429 }) => Any, oid::OP_UNARY_PLUS_OID;
5430 params!(Int16, Int16) => BF::from(func::AddInt16) => Int16, 550;
5431 params!(Int32, Int32) => BF::from(func::AddInt32) => Int32, 551;
5432 params!(Int64, Int64) => BF::from(func::AddInt64) => Int64, 684;
5433 params!(UInt16, UInt16) => BF::from(func::AddUint16) => UInt16, oid::FUNC_ADD_UINT16;
5434 params!(UInt32, UInt32) => BF::from(func::AddUint32) => UInt32, oid::FUNC_ADD_UINT32;
5435 params!(UInt64, UInt64) => BF::from(func::AddUint64) => UInt64, oid::FUNC_ADD_UINT64;
5436 params!(Float32, Float32) => BF::from(func::AddFloat32) => Float32, 586;
5437 params!(Float64, Float64) => BF::from(func::AddFloat64) => Float64, 591;
5438 params!(Interval, Interval) => BF::from(func::AddInterval) => Interval, 1337;
5439 params!(Timestamp, Interval) => BF::from(func::AddTimestampInterval) => Timestamp, 2066;
5440 params!(Interval, Timestamp) => {
5441 Operation::binary(|_ecx, lhs, rhs| {
5442 Ok(rhs.call_binary(lhs, func::AddTimestampInterval))
5443 })
5444 } => Timestamp, 2553;
5445 params!(TimestampTz, Interval)
5446 => BF::from(func::AddTimestampTzInterval) => TimestampTz, 1327;
5447 params!(Interval, TimestampTz) => {
5448 Operation::binary(|_ecx, lhs, rhs| {
5449 Ok(rhs.call_binary(lhs, func::AddTimestampTzInterval))
5450 })
5451 } => TimestampTz, 2554;
5452 params!(Date, Interval) => BF::from(func::AddDateInterval) => Timestamp, 1076;
5453 params!(Interval, Date) => {
5454 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddDateInterval)))
5455 } => Timestamp, 2551;
5456 params!(Date, Time) => BF::from(func::AddDateTime) => Timestamp, 1360;
5457 params!(Time, Date) => {
5458 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddDateTime)))
5459 } => Timestamp, 1363;
5460 params!(Time, Interval) => BF::from(func::AddTimeInterval) => Time, 1800;
5461 params!(Interval, Time) => {
5462 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::AddTimeInterval)))
5463 } => Time, 1849;
5464 params!(Numeric, Numeric) => BF::from(func::AddNumeric) => Numeric, 1758;
5465 params!(RangeAny, RangeAny) => BF::from(func::RangeUnion) => RangeAny, 3898;
5466 },
5467 "-" => Scalar {
5468 params!(Int16) => UnaryFunc::NegInt16(func::NegInt16) => Int16, 559;
5469 params!(Int32) => UnaryFunc::NegInt32(func::NegInt32) => Int32, 558;
5470 params!(Int64) => UnaryFunc::NegInt64(func::NegInt64) => Int64, 484;
5471 params!(Float32) => UnaryFunc::NegFloat32(func::NegFloat32) => Float32, 584;
5472 params!(Float64) => UnaryFunc::NegFloat64(func::NegFloat64) => Float64, 585;
5473 params!(Numeric) => UnaryFunc::NegNumeric(func::NegNumeric) => Numeric, 17510;
5474 params!(Interval) => UnaryFunc::NegInterval(func::NegInterval) => Interval, 1336;
5475 params!(Int32, Int32) => BF::from(func::SubInt32) => Int32, 555;
5476 params!(Int64, Int64) => BF::from(func::SubInt64) => Int64, 685;
5477 params!(UInt16, UInt16) => BF::from(func::SubUint16) => UInt16, oid::FUNC_SUB_UINT16;
5478 params!(UInt32, UInt32) => BF::from(func::SubUint32) => UInt32, oid::FUNC_SUB_UINT32;
5479 params!(UInt64, UInt64) => BF::from(func::SubUint64) => UInt64, oid::FUNC_SUB_UINT64;
5480 params!(Float32, Float32) => BF::from(func::SubFloat32) => Float32, 587;
5481 params!(Float64, Float64) => BF::from(func::SubFloat64) => Float64, 592;
5482 params!(Numeric, Numeric) => BF::from(func::SubNumeric) => Numeric, 17590;
5483 params!(Interval, Interval) => BF::from(func::SubInterval) => Interval, 1338;
5484 params!(Timestamp, Timestamp) => BF::from(func::SubTimestamp) => Interval, 2067;
5485 params!(TimestampTz, TimestampTz) => BF::from(func::SubTimestampTz) => Interval, 1328;
5486 params!(Timestamp, Interval) => BF::from(func::SubTimestampInterval) => Timestamp, 2068;
5487 params!(TimestampTz, Interval)
5488 => BF::from(func::SubTimestampTzInterval) => TimestampTz, 1329;
5489 params!(Date, Date) => BF::from(func::SubDate) => Int32, 1099;
5490 params!(Date, Interval) => BF::from(func::SubDateInterval) => Timestamp, 1077;
5491 params!(Time, Time) => BF::from(func::SubTime) => Interval, 1399;
5492 params!(Time, Interval) => BF::from(func::SubTimeInterval) => Time, 1801;
5493 params!(Jsonb, Int64) => BF::from(func::JsonbDeleteInt64) => Jsonb, 3286;
5494 params!(Jsonb, String) => BF::from(func::JsonbDeleteString) => Jsonb, 3285;
5495 params!(RangeAny, RangeAny) => BF::from(func::RangeDifference) => RangeAny, 3899;
5496 },
5499 "*" => Scalar {
5500 params!(Int16, Int16) => BF::from(func::MulInt16) => Int16, 526;
5501 params!(Int32, Int32) => BF::from(func::MulInt32) => Int32, 514;
5502 params!(Int64, Int64) => BF::from(func::MulInt64) => Int64, 686;
5503 params!(UInt16, UInt16) => BF::from(func::MulUint16) => UInt16, oid::FUNC_MUL_UINT16;
5504 params!(UInt32, UInt32) => BF::from(func::MulUint32) => UInt32, oid::FUNC_MUL_UINT32;
5505 params!(UInt64, UInt64) => BF::from(func::MulUint64) => UInt64, oid::FUNC_MUL_UINT64;
5506 params!(Float32, Float32) => BF::from(func::MulFloat32) => Float32, 589;
5507 params!(Float64, Float64) => BF::from(func::MulFloat64) => Float64, 594;
5508 params!(Interval, Float64) => BF::from(func::MulInterval) => Interval, 1583;
5509 params!(Float64, Interval) => {
5510 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, func::MulInterval)))
5511 } => Interval, 1584;
5512 params!(Numeric, Numeric) => BF::from(func::MulNumeric) => Numeric, 1760;
5513 params!(RangeAny, RangeAny) => BF::from(func::RangeIntersection) => RangeAny, 3900;
5514 },
5515 "/" => Scalar {
5516 params!(Int16, Int16) => BF::from(func::DivInt16) => Int16, 527;
5517 params!(Int32, Int32) => BF::from(func::DivInt32) => Int32, 528;
5518 params!(Int64, Int64) => BF::from(func::DivInt64) => Int64, 687;
5519 params!(UInt16, UInt16) => BF::from(func::DivUint16) => UInt16, oid::FUNC_DIV_UINT16;
5520 params!(UInt32, UInt32) => BF::from(func::DivUint32) => UInt32, oid::FUNC_DIV_UINT32;
5521 params!(UInt64, UInt64) => BF::from(func::DivUint64) => UInt64, oid::FUNC_DIV_UINT64;
5522 params!(Float32, Float32) => BF::from(func::DivFloat32) => Float32, 588;
5523 params!(Float64, Float64) => BF::from(func::DivFloat64) => Float64, 593;
5524 params!(Interval, Float64) => BF::from(func::DivInterval) => Interval, 1585;
5525 params!(Numeric, Numeric) => BF::from(func::DivNumeric) => Numeric, 1761;
5526 },
5527 "%" => Scalar {
5528 params!(Int16, Int16) => BF::from(func::ModInt16) => Int16, 529;
5529 params!(Int32, Int32) => BF::from(func::ModInt32) => Int32, 530;
5530 params!(Int64, Int64) => BF::from(func::ModInt64) => Int64, 439;
5531 params!(UInt16, UInt16) => BF::from(func::ModUint16) => UInt16, oid::FUNC_MOD_UINT16;
5532 params!(UInt32, UInt32) => BF::from(func::ModUint32) => UInt32, oid::FUNC_MOD_UINT32;
5533 params!(UInt64, UInt64) => BF::from(func::ModUint64) => UInt64, oid::FUNC_MOD_UINT64;
5534 params!(Float32, Float32) => BF::from(func::ModFloat32) => Float32, oid::OP_MOD_F32_OID;
5535 params!(Float64, Float64) => BF::from(func::ModFloat64) => Float64, oid::OP_MOD_F64_OID;
5536 params!(Numeric, Numeric) => BF::from(func::ModNumeric) => Numeric, 1762;
5537 },
5538 "&" => Scalar {
5539 params!(Int16, Int16) => BF::from(func::BitAndInt16) => Int16, 1874;
5540 params!(Int32, Int32) => BF::from(func::BitAndInt32) => Int32, 1880;
5541 params!(Int64, Int64) => BF::from(func::BitAndInt64) => Int64, 1886;
5542 params!(UInt16, UInt16) => BF::from(func::BitAndUint16) => UInt16, oid::FUNC_AND_UINT16;
5543 params!(UInt32, UInt32) => BF::from(func::BitAndUint32) => UInt32, oid::FUNC_AND_UINT32;
5544 params!(UInt64, UInt64) => BF::from(func::BitAndUint64) => UInt64, oid::FUNC_AND_UINT64;
5545 },
5546 "|" => Scalar {
5547 params!(Int16, Int16) => BF::from(func::BitOrInt16) => Int16, 1875;
5548 params!(Int32, Int32) => BF::from(func::BitOrInt32) => Int32, 1881;
5549 params!(Int64, Int64) => BF::from(func::BitOrInt64) => Int64, 1887;
5550 params!(UInt16, UInt16) => BF::from(func::BitOrUint16) => UInt16, oid::FUNC_OR_UINT16;
5551 params!(UInt32, UInt32) => BF::from(func::BitOrUint32) => UInt32, oid::FUNC_OR_UINT32;
5552 params!(UInt64, UInt64) => BF::from(func::BitOrUint64) => UInt64, oid::FUNC_OR_UINT64;
5553 },
5554 "#" => Scalar {
5555 params!(Int16, Int16) => BF::from(func::BitXorInt16) => Int16, 1876;
5556 params!(Int32, Int32) => BF::from(func::BitXorInt32) => Int32, 1882;
5557 params!(Int64, Int64) => BF::from(func::BitXorInt64) => Int64, 1888;
5558 params!(UInt16, UInt16) => BF::from(func::BitXorUint16) => UInt16, oid::FUNC_XOR_UINT16;
5559 params!(UInt32, UInt32) => BF::from(func::BitXorUint32) => UInt32, oid::FUNC_XOR_UINT32;
5560 params!(UInt64, UInt64) => BF::from(func::BitXorUint64) => UInt64, oid::FUNC_XOR_UINT64;
5561 },
5562 "<<" => Scalar {
5563 params!(Int16, Int32) => BF::from(func::BitShiftLeftInt16) => Int16, 1878;
5564 params!(Int32, Int32) => BF::from(func::BitShiftLeftInt32) => Int32, 1884;
5565 params!(Int64, Int32) => BF::from(func::BitShiftLeftInt64) => Int64, 1890;
5566 params!(UInt16, UInt32) => BF::from(func::BitShiftLeftUint16)
5567 => UInt16, oid::FUNC_SHIFT_LEFT_UINT16;
5568 params!(UInt32, UInt32) => BF::from(func::BitShiftLeftUint32)
5569 => UInt32, oid::FUNC_SHIFT_LEFT_UINT32;
5570 params!(UInt64, UInt32) => BF::from(func::BitShiftLeftUint64)
5571 => UInt64, oid::FUNC_SHIFT_LEFT_UINT64;
5572 params!(RangeAny, RangeAny) => BF::from(func::RangeBefore) => Bool, 3893;
5573 },
5574 ">>" => Scalar {
5575 params!(Int16, Int32) => BF::from(func::BitShiftRightInt16) => Int16, 1879;
5576 params!(Int32, Int32) => BF::from(func::BitShiftRightInt32) => Int32, 1885;
5577 params!(Int64, Int32) => BF::from(func::BitShiftRightInt64) => Int64, 1891;
5578 params!(UInt16, UInt32) => BF::from(func::BitShiftRightUint16)
5579 => UInt16, oid::FUNC_SHIFT_RIGHT_UINT16;
5580 params!(UInt32, UInt32) => BF::from(func::BitShiftRightUint32)
5581 => UInt32, oid::FUNC_SHIFT_RIGHT_UINT32;
5582 params!(UInt64, UInt32) => BF::from(func::BitShiftRightUint64)
5583 => UInt64, oid::FUNC_SHIFT_RIGHT_UINT64;
5584 params!(RangeAny, RangeAny) => BF::from(func::RangeAfter) => Bool, 3894;
5585 },
5586
5587 "~~*" => Scalar {
5589 params!(String, String) => BF::from(func::IsLikeMatchCaseInsensitive) => Bool, 1627;
5590 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5591 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5592 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5593 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5594 )
5595 }) => Bool, 1629;
5596 },
5597 "!~~*" => Scalar {
5598 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5599 Ok(lhs
5600 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5601 .call_unary(UnaryFunc::Not(func::Not)))
5602 }) => Bool, 1628;
5603 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5604 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5605 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5606 .call_binary(rhs, BF::from(func::IsLikeMatchCaseInsensitive))
5607 .call_unary(UnaryFunc::Not(func::Not))
5608 )
5609 }) => Bool, 1630;
5610 },
5611
5612
5613 "~~" => Scalar {
5615 params!(String, String) => BF::from(func::IsLikeMatchCaseSensitive) => Bool, 1209;
5616 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5617 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5618 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5619 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5620 )
5621 }) => Bool, 1211;
5622 },
5623 "!~~" => Scalar {
5624 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5625 Ok(lhs
5626 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5627 .call_unary(UnaryFunc::Not(func::Not)))
5628 }) => Bool, 1210;
5629 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5630 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5631 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5632 .call_binary(rhs, BF::from(func::IsLikeMatchCaseSensitive))
5633 .call_unary(UnaryFunc::Not(func::Not))
5634 )
5635 }) => Bool, 1212;
5636 },
5637
5638 "~" => Scalar {
5640 params!(Int16) => UnaryFunc::BitNotInt16(func::BitNotInt16) => Int16, 1877;
5641 params!(Int32) => UnaryFunc::BitNotInt32(func::BitNotInt32) => Int32, 1883;
5642 params!(Int64) => UnaryFunc::BitNotInt64(func::BitNotInt64) => Int64, 1889;
5643 params!(UInt16) => UnaryFunc::BitNotUint16(func::BitNotUint16)
5644 => UInt16, oid::FUNC_BIT_NOT_UINT16_OID;
5645 params!(UInt32) => UnaryFunc::BitNotUint32(func::BitNotUint32)
5646 => UInt32, oid::FUNC_BIT_NOT_UINT32_OID;
5647 params!(UInt64) => UnaryFunc::BitNotUint64(func::BitNotUint64)
5648 => UInt64, oid::FUNC_BIT_NOT_UINT64_OID;
5649 params!(String, String)
5650 => BinaryFunc::IsRegexpMatchCaseSensitive(
5651 func::IsRegexpMatchCaseSensitive,
5652 ) => Bool, 641;
5653 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5654 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5655 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5656 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5657 func::IsRegexpMatchCaseSensitive,
5658 )))
5659 }) => Bool, 1055;
5660 },
5661 "~*" => Scalar {
5662 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5663 Ok(lhs.call_binary(
5664 rhs,
5665 BinaryFunc::IsRegexpMatchCaseInsensitive(
5666 func::IsRegexpMatchCaseInsensitive,
5667 ),
5668 ))
5669 }) => Bool, 1228;
5670 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5671 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5672 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5673 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5674 func::IsRegexpMatchCaseInsensitive,
5675 )))
5676 }) => Bool, 1234;
5677 },
5678 "!~" => Scalar {
5679 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5680 Ok(lhs
5681 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5682 func::IsRegexpMatchCaseSensitive,
5683 ))
5684 .call_unary(UnaryFunc::Not(func::Not)))
5685 }) => Bool, 642;
5686 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5687 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5688 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5689 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseSensitive(
5690 func::IsRegexpMatchCaseSensitive,
5691 ))
5692 .call_unary(UnaryFunc::Not(func::Not)))
5693 }) => Bool, 1056;
5694 },
5695 "!~*" => Scalar {
5696 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
5697 Ok(lhs
5698 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5699 func::IsRegexpMatchCaseInsensitive,
5700 ))
5701 .call_unary(UnaryFunc::Not(func::Not)))
5702 }) => Bool, 1229;
5703 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
5704 let length = ecx.scalar_type(&lhs).unwrap_char_length();
5705 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
5706 .call_binary(rhs, BinaryFunc::IsRegexpMatchCaseInsensitive(
5707 func::IsRegexpMatchCaseInsensitive,
5708 ))
5709 .call_unary(UnaryFunc::Not(func::Not)))
5710 }) => Bool, 1235;
5711 },
5712
5713 "||" => Scalar {
5715 params!(String, NonVecAny) => Operation::binary(|ecx, lhs, rhs| {
5716 let rhs = typeconv::plan_cast(
5717 ecx,
5718 CastContext::Explicit,
5719 rhs,
5720 &SqlScalarType::String,
5721 )?;
5722 Ok(lhs.call_binary(rhs, func::TextConcatBinary))
5723 }) => String, 2779;
5724 params!(NonVecAny, String) => Operation::binary(|ecx, lhs, rhs| {
5725 let lhs = typeconv::plan_cast(
5726 ecx,
5727 CastContext::Explicit,
5728 lhs,
5729 &SqlScalarType::String,
5730 )?;
5731 Ok(lhs.call_binary(rhs, func::TextConcatBinary))
5732 }) => String, 2780;
5733 params!(String, String) => BF::from(func::TextConcatBinary) => String, 654;
5734 params!(Jsonb, Jsonb) => BF::from(func::JsonbConcat) => Jsonb, 3284;
5735 params!(ArrayAnyCompatible, ArrayAnyCompatible)
5736 => BF::from(func::ArrayArrayConcat) => ArrayAnyCompatible, 375;
5737 params!(ListAnyCompatible, ListAnyCompatible)
5738 => BF::from(func::ListListConcat)
5739 => ListAnyCompatible, oid::OP_CONCAT_LIST_LIST_OID;
5740 params!(ListAnyCompatible, ListElementAnyCompatible)
5741 => BF::from(func::ListElementConcat)
5742 => ListAnyCompatible, oid::OP_CONCAT_LIST_ELEMENT_OID;
5743 params!(ListElementAnyCompatible, ListAnyCompatible)
5744 => BF::from(func::ElementListConcat)
5745 => ListAnyCompatible, oid::OP_CONCAT_ELEMENY_LIST_OID;
5746 },
5747
5748 "->" => Scalar {
5750 params!(Jsonb, Int64) => BF::from(func::JsonbGetInt64) => Jsonb, 3212;
5751 params!(Jsonb, String) => BF::from(func::JsonbGetString) => Jsonb, 3211;
5752 params!(MapAny, String) => BF::from(func::MapGetValue)
5753 => Any, oid::OP_GET_VALUE_MAP_OID;
5754 },
5755 "->>" => Scalar {
5756 params!(Jsonb, Int64) => BF::from(func::JsonbGetInt64Stringify) => String, 3481;
5757 params!(Jsonb, String) => BF::from(func::JsonbGetStringStringify) => String, 3477;
5758 },
5759 "#>" => Scalar {
5760 params!(Jsonb, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5761 => BF::from(func::JsonbGetPath) => Jsonb, 3213;
5762 },
5763 "#>>" => Scalar {
5764 params!(Jsonb, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5765 => BF::from(func::JsonbGetPathStringify) => String, 3206;
5766 },
5767 "@>" => Scalar {
5768 params!(Jsonb, Jsonb) => BF::from(func::JsonbContainsJsonb) => Bool, 3246;
5769 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
5770 Ok(lhs.call_binary(
5771 rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
5772 BinaryFunc::from(func::JsonbContainsJsonb),
5773 ))
5774 }) => Bool, oid::OP_CONTAINS_JSONB_STRING_OID;
5775 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5776 Ok(lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
5777 .call_binary(rhs, func::JsonbContainsJsonb))
5778 }) => Bool, oid::OP_CONTAINS_STRING_JSONB_OID;
5779 params!(MapAnyCompatible, MapAnyCompatible)
5780 => BF::from(func::MapContainsMap)
5781 => Bool, oid::OP_CONTAINS_MAP_MAP_OID;
5782 params!(RangeAny, AnyElement) => Operation::binary(|ecx, lhs, rhs| {
5783 let elem_type = ecx.scalar_type(&lhs).unwrap_range_element_type().clone();
5784 let f = match elem_type {
5785 SqlScalarType::Int32 => BF::from(func::RangeContainsI32),
5786 SqlScalarType::Int64 => BF::from(func::RangeContainsI64),
5787 SqlScalarType::Date => BF::from(func::RangeContainsDate),
5788 SqlScalarType::Numeric { .. } => BF::from(func::RangeContainsNumeric),
5789 SqlScalarType::Timestamp { .. } => BF::from(func::RangeContainsTimestamp),
5790 SqlScalarType::TimestampTz { .. } => BF::from(func::RangeContainsTimestampTz),
5791 _ => bail_unsupported!(format!("range element type: {elem_type:?}")),
5792 };
5793 Ok(lhs.call_binary(rhs, f))
5794 }) => Bool, 3889;
5795 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
5796 Ok(lhs.call_binary(rhs, BF::from(func::RangeContainsRange)))
5797 }) => Bool, 3890;
5798 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
5799 Ok(lhs.call_binary(rhs, BF::from(func::ArrayContainsArray)))
5800 }) => Bool, 2751;
5801 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
5802 Ok(lhs.call_binary(rhs, BF::from(func::ListContainsList)))
5803 }) => Bool, oid::OP_CONTAINS_LIST_LIST_OID;
5804 },
5805 "<@" => Scalar {
5806 params!(Jsonb, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5807 Ok(rhs.call_binary(
5808 lhs,
5809 func::JsonbContainsJsonb
5810 ))
5811 }) => Bool, 3250;
5812 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
5813 Ok(rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
5814 .call_binary(lhs, func::JsonbContainsJsonb))
5815 }) => Bool, oid::OP_CONTAINED_JSONB_STRING_OID;
5816 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
5817 Ok(rhs.call_binary(
5818 lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
5819 func::JsonbContainsJsonb,
5820 ))
5821 }) => Bool, oid::OP_CONTAINED_STRING_JSONB_OID;
5822 params!(MapAnyCompatible, MapAnyCompatible) => Operation::binary(|_ecx, lhs, rhs| {
5823 Ok(rhs.call_binary(lhs, func::MapContainsMap))
5824 }) => Bool, oid::OP_CONTAINED_MAP_MAP_OID;
5825 params!(AnyElement, RangeAny) => Operation::binary(|ecx, lhs, rhs| {
5826 let elem_type = ecx.scalar_type(&rhs).unwrap_range_element_type().clone();
5827 let f = match elem_type {
5828 SqlScalarType::Int32 => BF::from(func::RangeContainsI32Rev),
5829 SqlScalarType::Int64 => BF::from(func::RangeContainsI64Rev),
5830 SqlScalarType::Date => BF::from(func::RangeContainsDateRev),
5831 SqlScalarType::Numeric { .. } => BF::from(func::RangeContainsNumericRev),
5832 SqlScalarType::Timestamp { .. } => BF::from(func::RangeContainsTimestampRev),
5833 SqlScalarType::TimestampTz { .. } => {
5834 BF::from(func::RangeContainsTimestampTzRev)
5835 }
5836 _ => bail_unsupported!(format!("range element type: {elem_type:?}")),
5837 };
5838 Ok(rhs.call_binary(lhs, f))
5839 }) => Bool, 3891;
5840 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
5841 Ok(rhs.call_binary(lhs, BF::from(func::RangeContainsRangeRev)))
5842 }) => Bool, 3892;
5843 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
5844 Ok(lhs.call_binary(rhs, BF::from(func::ArrayContainsArrayRev)))
5845 }) => Bool, 2752;
5846 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
5847 Ok(lhs.call_binary(rhs, BF::from(func::ListContainsListRev)))
5848 }) => Bool, oid::OP_IS_CONTAINED_LIST_LIST_OID;
5849 },
5850 "?" => Scalar {
5851 params!(Jsonb, String) => BF::from(func::JsonbContainsString) => Bool, 3247;
5852 params!(MapAny, String) => BF::from(func::MapContainsKey)
5853 => Bool, oid::OP_CONTAINS_KEY_MAP_OID;
5854 },
5855 "?&" => Scalar {
5856 params!(MapAny, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5857 => BF::from(func::MapContainsAllKeys)
5858 => Bool, oid::OP_CONTAINS_ALL_KEYS_MAP_OID;
5859 },
5860 "?|" => Scalar {
5861 params!(MapAny, SqlScalarType::Array(Box::new(SqlScalarType::String)))
5862 => BF::from(func::MapContainsAnyKeys)
5863 => Bool, oid::OP_CONTAINS_ANY_KEYS_MAP_OID;
5864 },
5865 "&&" => Scalar {
5866 params!(RangeAny, RangeAny) => BF::from(func::RangeOverlaps) => Bool, 3888;
5867 },
5868 "&<" => Scalar {
5869 params!(RangeAny, RangeAny) => BF::from(func::RangeOverleft) => Bool, 3895;
5870 },
5871 "&>" => Scalar {
5872 params!(RangeAny, RangeAny) => BF::from(func::RangeOverright) => Bool, 3896;
5873 },
5874 "-|-" => Scalar {
5875 params!(RangeAny, RangeAny) => BF::from(func::RangeAdjacent) => Bool, 3897;
5876 },
5877
5878 "<" => Scalar {
5880 params!(Numeric, Numeric) => BF::from(func::Lt) => Bool, 1754;
5881 params!(Bool, Bool) => BF::from(func::Lt) => Bool, 58;
5882 params!(Int16, Int16) => BF::from(func::Lt) => Bool, 95;
5883 params!(Int32, Int32) => BF::from(func::Lt) => Bool, 97;
5884 params!(Int64, Int64) => BF::from(func::Lt) => Bool, 412;
5885 params!(UInt16, UInt16) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT16_OID;
5886 params!(UInt32, UInt32) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT32_OID;
5887 params!(UInt64, UInt64) => BF::from(func::Lt) => Bool, oid::FUNC_LT_UINT64_OID;
5888 params!(Float32, Float32) => BF::from(func::Lt) => Bool, 622;
5889 params!(Float64, Float64) => BF::from(func::Lt) => Bool, 672;
5890 params!(Oid, Oid) => BF::from(func::Lt) => Bool, 609;
5891 params!(Date, Date) => BF::from(func::Lt) => Bool, 1095;
5892 params!(Time, Time) => BF::from(func::Lt) => Bool, 1110;
5893 params!(Timestamp, Timestamp) => BF::from(func::Lt) => Bool, 2062;
5894 params!(TimestampTz, TimestampTz) => BF::from(func::Lt) => Bool, 1322;
5895 params!(Uuid, Uuid) => BF::from(func::Lt) => Bool, 2974;
5896 params!(Interval, Interval) => BF::from(func::Lt) => Bool, 1332;
5897 params!(Bytes, Bytes) => BF::from(func::Lt) => Bool, 1957;
5898 params!(String, String) => BF::from(func::Lt) => Bool, 664;
5899 params!(Char, Char) => BF::from(func::Lt) => Bool, 1058;
5900 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Lt) => Bool, 631;
5901 params!(PgLegacyName, PgLegacyName) => BF::from(func::Lt) => Bool, 660;
5902 params!(Jsonb, Jsonb) => BF::from(func::Lt) => Bool, 3242;
5903 params!(ArrayAny, ArrayAny) => BF::from(func::Lt) => Bool, 1072;
5904 params!(RecordAny, RecordAny) => BF::from(func::Lt) => Bool, 2990;
5905 params!(MzTimestamp, MzTimestamp) => BF::from(func::Lt)
5906 => Bool, oid::FUNC_MZ_TIMESTAMP_LT_MZ_TIMESTAMP_OID;
5907 params!(RangeAny, RangeAny) => BF::from(func::Lt) => Bool, 3884;
5908 },
5909 "<=" => Scalar {
5910 params!(Numeric, Numeric) => BF::from(func::Lte) => Bool, 1755;
5911 params!(Bool, Bool) => BF::from(func::Lte) => Bool, 1694;
5912 params!(Int16, Int16) => BF::from(func::Lte) => Bool, 522;
5913 params!(Int32, Int32) => BF::from(func::Lte) => Bool, 523;
5914 params!(Int64, Int64) => BF::from(func::Lte) => Bool, 414;
5915 params!(UInt16, UInt16) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT16_OID;
5916 params!(UInt32, UInt32) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT32_OID;
5917 params!(UInt64, UInt64) => BF::from(func::Lte) => Bool, oid::FUNC_LTE_UINT64_OID;
5918 params!(Float32, Float32) => BF::from(func::Lte) => Bool, 624;
5919 params!(Float64, Float64) => BF::from(func::Lte) => Bool, 673;
5920 params!(Oid, Oid) => BF::from(func::Lte) => Bool, 611;
5921 params!(Date, Date) => BF::from(func::Lte) => Bool, 1096;
5922 params!(Time, Time) => BF::from(func::Lte) => Bool, 1111;
5923 params!(Timestamp, Timestamp) => BF::from(func::Lte) => Bool, 2063;
5924 params!(TimestampTz, TimestampTz) => BF::from(func::Lte) => Bool, 1323;
5925 params!(Uuid, Uuid) => BF::from(func::Lte) => Bool, 2976;
5926 params!(Interval, Interval) => BF::from(func::Lte) => Bool, 1333;
5927 params!(Bytes, Bytes) => BF::from(func::Lte) => Bool, 1958;
5928 params!(String, String) => BF::from(func::Lte) => Bool, 665;
5929 params!(Char, Char) => BF::from(func::Lte) => Bool, 1059;
5930 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Lte) => Bool, 632;
5931 params!(PgLegacyName, PgLegacyName) => BF::from(func::Lte) => Bool, 661;
5932 params!(Jsonb, Jsonb) => BF::from(func::Lte) => Bool, 3244;
5933 params!(ArrayAny, ArrayAny) => BF::from(func::Lte) => Bool, 1074;
5934 params!(RecordAny, RecordAny) => BF::from(func::Lte) => Bool, 2992;
5935 params!(MzTimestamp, MzTimestamp) => BF::from(func::Lte)
5936 => Bool, oid::FUNC_MZ_TIMESTAMP_LTE_MZ_TIMESTAMP_OID;
5937 params!(RangeAny, RangeAny) => BF::from(func::Lte) => Bool, 3885;
5938 },
5939 ">" => Scalar {
5940 params!(Numeric, Numeric) => BF::from(func::Gt) => Bool, 1756;
5941 params!(Bool, Bool) => BF::from(func::Gt) => Bool, 59;
5942 params!(Int16, Int16) => BF::from(func::Gt) => Bool, 520;
5943 params!(Int32, Int32) => BF::from(func::Gt) => Bool, 521;
5944 params!(Int64, Int64) => BF::from(func::Gt) => Bool, 413;
5945 params!(UInt16, UInt16) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT16_OID;
5946 params!(UInt32, UInt32) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT32_OID;
5947 params!(UInt64, UInt64) => BF::from(func::Gt) => Bool, oid::FUNC_GT_UINT64_OID;
5948 params!(Float32, Float32) => BF::from(func::Gt) => Bool, 623;
5949 params!(Float64, Float64) => BF::from(func::Gt) => Bool, 674;
5950 params!(Oid, Oid) => BF::from(func::Gt) => Bool, 610;
5951 params!(Date, Date) => BF::from(func::Gt) => Bool, 1097;
5952 params!(Time, Time) => BF::from(func::Gt) => Bool, 1112;
5953 params!(Timestamp, Timestamp) => BF::from(func::Gt) => Bool, 2064;
5954 params!(TimestampTz, TimestampTz) => BF::from(func::Gt) => Bool, 1324;
5955 params!(Uuid, Uuid) => BF::from(func::Gt) => Bool, 2975;
5956 params!(Interval, Interval) => BF::from(func::Gt) => Bool, 1334;
5957 params!(Bytes, Bytes) => BF::from(func::Gt) => Bool, 1959;
5958 params!(String, String) => BF::from(func::Gt) => Bool, 666;
5959 params!(Char, Char) => BF::from(func::Gt) => Bool, 1060;
5960 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Gt) => Bool, 633;
5961 params!(PgLegacyName, PgLegacyName) => BF::from(func::Gt) => Bool, 662;
5962 params!(Jsonb, Jsonb) => BF::from(func::Gt) => Bool, 3243;
5963 params!(ArrayAny, ArrayAny) => BF::from(func::Gt) => Bool, 1073;
5964 params!(RecordAny, RecordAny) => BF::from(func::Gt) => Bool, 2991;
5965 params!(MzTimestamp, MzTimestamp) => BF::from(func::Gt)
5966 => Bool, oid::FUNC_MZ_TIMESTAMP_GT_MZ_TIMESTAMP_OID;
5967 params!(RangeAny, RangeAny) => BF::from(func::Gt) => Bool, 3887;
5968 },
5969 ">=" => Scalar {
5970 params!(Numeric, Numeric) => BF::from(func::Gte) => Bool, 1757;
5971 params!(Bool, Bool) => BF::from(func::Gte) => Bool, 1695;
5972 params!(Int16, Int16) => BF::from(func::Gte) => Bool, 524;
5973 params!(Int32, Int32) => BF::from(func::Gte) => Bool, 525;
5974 params!(Int64, Int64) => BF::from(func::Gte) => Bool, 415;
5975 params!(UInt16, UInt16) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT16_OID;
5976 params!(UInt32, UInt32) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT32_OID;
5977 params!(UInt64, UInt64) => BF::from(func::Gte) => Bool, oid::FUNC_GTE_UINT64_OID;
5978 params!(Float32, Float32) => BF::from(func::Gte) => Bool, 625;
5979 params!(Float64, Float64) => BF::from(func::Gte) => Bool, 675;
5980 params!(Oid, Oid) => BF::from(func::Gte) => Bool, 612;
5981 params!(Date, Date) => BF::from(func::Gte) => Bool, 1098;
5982 params!(Time, Time) => BF::from(func::Gte) => Bool, 1113;
5983 params!(Timestamp, Timestamp) => BF::from(func::Gte) => Bool, 2065;
5984 params!(TimestampTz, TimestampTz) => BF::from(func::Gte) => Bool, 1325;
5985 params!(Uuid, Uuid) => BF::from(func::Gte) => Bool, 2977;
5986 params!(Interval, Interval) => BF::from(func::Gte) => Bool, 1335;
5987 params!(Bytes, Bytes) => BF::from(func::Gte) => Bool, 1960;
5988 params!(String, String) => BF::from(func::Gte) => Bool, 667;
5989 params!(Char, Char) => BF::from(func::Gte) => Bool, 1061;
5990 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Gte) => Bool, 634;
5991 params!(PgLegacyName, PgLegacyName) => BF::from(func::Gte) => Bool, 663;
5992 params!(Jsonb, Jsonb) => BF::from(func::Gte) => Bool, 3245;
5993 params!(ArrayAny, ArrayAny) => BF::from(func::Gte) => Bool, 1075;
5994 params!(RecordAny, RecordAny) => BF::from(func::Gte) => Bool, 2993;
5995 params!(MzTimestamp, MzTimestamp) => BF::from(func::Gte)
5996 => Bool, oid::FUNC_MZ_TIMESTAMP_GTE_MZ_TIMESTAMP_OID;
5997 params!(RangeAny, RangeAny) => BF::from(func::Gte) => Bool, 3886;
5998 },
5999 "=" => Scalar {
6010 params!(Numeric, Numeric) => BF::from(func::Eq) => Bool, 1752;
6011 params!(Bool, Bool) => BF::from(func::Eq) => Bool, 91;
6012 params!(Int16, Int16) => BF::from(func::Eq) => Bool, 94;
6013 params!(Int32, Int32) => BF::from(func::Eq) => Bool, 96;
6014 params!(Int64, Int64) => BF::from(func::Eq) => Bool, 410;
6015 params!(UInt16, UInt16) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT16_OID;
6016 params!(UInt32, UInt32) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT32_OID;
6017 params!(UInt64, UInt64) => BF::from(func::Eq) => Bool, oid::FUNC_EQ_UINT64_OID;
6018 params!(Float32, Float32) => BF::from(func::Eq) => Bool, 620;
6019 params!(Float64, Float64) => BF::from(func::Eq) => Bool, 670;
6020 params!(Oid, Oid) => BF::from(func::Eq) => Bool, 607;
6021 params!(Date, Date) => BF::from(func::Eq) => Bool, 1093;
6022 params!(Time, Time) => BF::from(func::Eq) => Bool, 1108;
6023 params!(Timestamp, Timestamp) => BF::from(func::Eq) => Bool, 2060;
6024 params!(TimestampTz, TimestampTz) => BF::from(func::Eq) => Bool, 1320;
6025 params!(Uuid, Uuid) => BF::from(func::Eq) => Bool, 2972;
6026 params!(Interval, Interval) => BF::from(func::Eq) => Bool, 1330;
6027 params!(Bytes, Bytes) => BF::from(func::Eq) => Bool, 1955;
6028 params!(String, String) => BF::from(func::Eq) => Bool, 98;
6029 params!(Char, Char) => BF::from(func::Eq) => Bool, 1054;
6030 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::Eq) => Bool, 92;
6031 params!(PgLegacyName, PgLegacyName) => BF::from(func::Eq) => Bool, 93;
6032 params!(Jsonb, Jsonb) => BF::from(func::Eq) => Bool, 3240;
6033 params!(ListAny, ListAny) => BF::from(func::Eq) => Bool, oid::FUNC_LIST_EQ_OID;
6034 params!(ArrayAny, ArrayAny) => BF::from(func::Eq) => Bool, 1070;
6035 params!(RecordAny, RecordAny) => BF::from(func::Eq) => Bool, 2988;
6036 params!(MzTimestamp, MzTimestamp) => BF::from(func::Eq)
6037 => Bool, oid::FUNC_MZ_TIMESTAMP_EQ_MZ_TIMESTAMP_OID;
6038 params!(RangeAny, RangeAny) => BF::from(func::Eq) => Bool, 3882;
6039 params!(MzAclItem, MzAclItem) => BF::from(func::Eq)
6040 => Bool, oid::FUNC_MZ_ACL_ITEM_EQ_MZ_ACL_ITEM_OID;
6041 params!(AclItem, AclItem) => BF::from(func::Eq) => Bool, 974;
6042 },
6043 "<>" => Scalar {
6044 params!(Numeric, Numeric) => BF::from(func::NotEq) => Bool, 1753;
6045 params!(Bool, Bool) => BF::from(func::NotEq) => Bool, 85;
6046 params!(Int16, Int16) => BF::from(func::NotEq) => Bool, 519;
6047 params!(Int32, Int32) => BF::from(func::NotEq) => Bool, 518;
6048 params!(Int64, Int64) => BF::from(func::NotEq) => Bool, 411;
6049 params!(UInt16, UInt16) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT16_OID;
6050 params!(UInt32, UInt32) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT32_OID;
6051 params!(UInt64, UInt64) => BF::from(func::NotEq) => Bool, oid::FUNC_NOT_EQ_UINT64_OID;
6052 params!(Float32, Float32) => BF::from(func::NotEq) => Bool, 621;
6053 params!(Float64, Float64) => BF::from(func::NotEq) => Bool, 671;
6054 params!(Oid, Oid) => BF::from(func::NotEq) => Bool, 608;
6055 params!(Date, Date) => BF::from(func::NotEq) => Bool, 1094;
6056 params!(Time, Time) => BF::from(func::NotEq) => Bool, 1109;
6057 params!(Timestamp, Timestamp) => BF::from(func::NotEq) => Bool, 2061;
6058 params!(TimestampTz, TimestampTz) => BF::from(func::NotEq) => Bool, 1321;
6059 params!(Uuid, Uuid) => BF::from(func::NotEq) => Bool, 2973;
6060 params!(Interval, Interval) => BF::from(func::NotEq) => Bool, 1331;
6061 params!(Bytes, Bytes) => BF::from(func::NotEq) => Bool, 1956;
6062 params!(String, String) => BF::from(func::NotEq) => Bool, 531;
6063 params!(Char, Char) => BF::from(func::NotEq) => Bool, 1057;
6064 params!(PgLegacyChar, PgLegacyChar) => BF::from(func::NotEq) => Bool, 630;
6065 params!(PgLegacyName, PgLegacyName) => BF::from(func::NotEq) => Bool, 643;
6066 params!(Jsonb, Jsonb) => BF::from(func::NotEq) => Bool, 3241;
6067 params!(ArrayAny, ArrayAny) => BF::from(func::NotEq) => Bool, 1071;
6068 params!(RecordAny, RecordAny) => BF::from(func::NotEq) => Bool, 2989;
6069 params!(MzTimestamp, MzTimestamp) => BF::from(func::NotEq)
6070 => Bool, oid::FUNC_MZ_TIMESTAMP_NOT_EQ_MZ_TIMESTAMP_OID;
6071 params!(RangeAny, RangeAny) => BF::from(func::NotEq) => Bool, 3883;
6072 params!(MzAclItem, MzAclItem) => BF::from(func::NotEq)
6073 => Bool, oid::FUNC_MZ_ACL_ITEM_NOT_EQ_MZ_ACL_ITEM_OID;
6074 }
6075 }
6076});
6077
6078pub fn resolve_op(op: &str) -> Result<&'static [FuncImpl<HirScalarExpr>], PlanError> {
6080 match OP_IMPLS.get(op) {
6081 Some(Func::Scalar(impls)) => Ok(impls),
6082 Some(_) => unreachable!("all operators must be scalar functions"),
6083 None => bail_unsupported!(format!("[{}]", op)),
6093 }
6094}
6095
6096fn current_settings(
6099 name: HirScalarExpr,
6100 missing_ok: HirScalarExpr,
6101) -> Result<HirScalarExpr, PlanError> {
6102 let expr = HirScalarExpr::call_binary(
6104 HirScalarExpr::call_unmaterializable(UnmaterializableFunc::ViewableVariables),
6105 HirScalarExpr::call_unary(name, UnaryFunc::Lower(func::Lower)),
6106 func::MapGetValue,
6107 );
6108 let expr = HirScalarExpr::if_then_else(
6109 missing_ok,
6110 expr.clone(),
6111 HirScalarExpr::call_variadic(
6112 variadic::ErrorIfNull,
6113 vec![
6114 expr,
6115 HirScalarExpr::literal(
6116 Datum::String("unrecognized configuration parameter"),
6117 SqlScalarType::String,
6118 ),
6119 ],
6120 ),
6121 );
6122 Ok(expr)
6123}