1use std::cell::RefCell;
14use std::collections::BTreeMap;
15use std::fmt;
16use std::sync::LazyLock;
17
18use itertools::Itertools;
19use mz_expr::func;
20use mz_ore::collections::CollectionExt;
21use mz_ore::str::StrExt;
22use mz_pgrepr::oid;
23use mz_repr::role_id::RoleId;
24use mz_repr::{ColumnName, ColumnType, Datum, RelationType, Row, ScalarBaseType, ScalarType};
25
26use crate::ast::{SelectStatement, Statement};
27use crate::catalog::{CatalogType, TypeCategory, TypeReference};
28use crate::names::{self, ResolvedItemName};
29use crate::plan::error::PlanError;
30use crate::plan::hir::{
31 AggregateFunc, BinaryFunc, CoercibleScalarExpr, CoercibleScalarType, ColumnOrder,
32 HirRelationExpr, HirScalarExpr, ScalarWindowFunc, TableFunc, UnaryFunc, UnmaterializableFunc,
33 ValueWindowFunc, VariadicFunc,
34};
35use crate::plan::query::{self, ExprContext, QueryContext};
36use crate::plan::scope::Scope;
37use crate::plan::side_effecting_func::PG_CATALOG_SEF_BUILTINS;
38use crate::plan::transform_ast;
39use crate::plan::typeconv::{self, CastContext};
40use crate::session::vars::{self, ENABLE_TIME_AT_TIME_ZONE};
41
42#[derive(Clone, Copy, Debug)]
44pub enum FuncSpec<'a> {
45 Func(&'a ResolvedItemName),
47 Op(&'a str),
49}
50
51impl<'a> fmt::Display for FuncSpec<'a> {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 match self {
54 FuncSpec::Func(n) => n.fmt(f),
55 FuncSpec::Op(o) => o.fmt(f),
56 }
57 }
58}
59
60impl TypeCategory {
61 pub fn from_type(typ: &ScalarType) -> Self {
73 match typ {
75 ScalarType::Array(..) | ScalarType::Int2Vector => Self::Array,
76 ScalarType::Bool => Self::Boolean,
77 ScalarType::AclItem
78 | ScalarType::Bytes
79 | ScalarType::Jsonb
80 | ScalarType::Uuid
81 | ScalarType::MzAclItem => Self::UserDefined,
82 ScalarType::Date
83 | ScalarType::Time
84 | ScalarType::Timestamp { .. }
85 | ScalarType::TimestampTz { .. } => Self::DateTime,
86 ScalarType::Float32
87 | ScalarType::Float64
88 | ScalarType::Int16
89 | ScalarType::Int32
90 | ScalarType::Int64
91 | ScalarType::UInt16
92 | ScalarType::UInt32
93 | ScalarType::UInt64
94 | ScalarType::Oid
95 | ScalarType::RegClass
96 | ScalarType::RegProc
97 | ScalarType::RegType
98 | ScalarType::Numeric { .. } => Self::Numeric,
99 ScalarType::Interval => Self::Timespan,
100 ScalarType::List { .. } => Self::List,
101 ScalarType::PgLegacyChar
102 | ScalarType::PgLegacyName
103 | ScalarType::String
104 | ScalarType::Char { .. }
105 | ScalarType::VarChar { .. } => Self::String,
106 ScalarType::Record { custom_id, .. } => {
107 if custom_id.is_some() {
108 Self::Composite
109 } else {
110 Self::Pseudo
111 }
112 }
113 ScalarType::Map { .. } => Self::Pseudo,
114 ScalarType::MzTimestamp => Self::Numeric,
115 ScalarType::Range { .. } => Self::Range,
116 }
117 }
118
119 pub fn from_param(param: &ParamType) -> Self {
120 match param {
121 ParamType::Any
122 | ParamType::AnyElement
123 | ParamType::ArrayAny
124 | ParamType::ArrayAnyCompatible
125 | ParamType::AnyCompatible
126 | ParamType::ListAny
127 | ParamType::ListAnyCompatible
128 | ParamType::ListElementAnyCompatible
129 | ParamType::Internal
130 | ParamType::NonVecAny
131 | ParamType::NonVecAnyCompatible
132 | ParamType::MapAny
133 | ParamType::MapAnyCompatible
134 | ParamType::RecordAny => Self::Pseudo,
135 ParamType::RangeAnyCompatible | ParamType::RangeAny => Self::Range,
136 ParamType::Plain(t) => Self::from_type(t),
137 }
138 }
139
140 pub fn from_catalog_type<T>(catalog_type: &CatalogType<T>) -> Self
144 where
145 T: TypeReference,
146 {
147 match catalog_type {
149 CatalogType::Array { .. } | CatalogType::Int2Vector => Self::Array,
150 CatalogType::Bool => Self::Boolean,
151 CatalogType::AclItem
152 | CatalogType::Bytes
153 | CatalogType::Jsonb
154 | CatalogType::Uuid
155 | CatalogType::MzAclItem => Self::UserDefined,
156 CatalogType::Date
157 | CatalogType::Time
158 | CatalogType::Timestamp
159 | CatalogType::TimestampTz => Self::DateTime,
160 CatalogType::Float32
161 | CatalogType::Float64
162 | CatalogType::Int16
163 | CatalogType::Int32
164 | CatalogType::Int64
165 | CatalogType::UInt16
166 | CatalogType::UInt32
167 | CatalogType::UInt64
168 | CatalogType::Oid
169 | CatalogType::RegClass
170 | CatalogType::RegProc
171 | CatalogType::RegType
172 | CatalogType::Numeric { .. } => Self::Numeric,
173 CatalogType::Interval => Self::Timespan,
174 CatalogType::List { .. } => Self::List,
175 CatalogType::PgLegacyChar
176 | CatalogType::PgLegacyName
177 | CatalogType::String
178 | CatalogType::Char { .. }
179 | CatalogType::VarChar { .. } => Self::String,
180 CatalogType::Record { .. } => TypeCategory::Composite,
181 CatalogType::Map { .. } | CatalogType::Pseudo => Self::Pseudo,
182 CatalogType::MzTimestamp => Self::String,
183 CatalogType::Range { .. } => Self::Range,
184 }
185 }
186
187 pub fn preferred_type(&self) -> Option<ScalarType> {
195 match self {
196 Self::Array
197 | Self::BitString
198 | Self::Composite
199 | Self::Enum
200 | Self::Geometric
201 | Self::List
202 | Self::NetworkAddress
203 | Self::Pseudo
204 | Self::Range
205 | Self::Unknown
206 | Self::UserDefined => None,
207 Self::Boolean => Some(ScalarType::Bool),
208 Self::DateTime => Some(ScalarType::TimestampTz { precision: None }),
209 Self::Numeric => Some(ScalarType::Float64),
210 Self::String => Some(ScalarType::String),
211 Self::Timespan => Some(ScalarType::Interval),
212 }
213 }
214}
215
216pub struct Operation<R>(
219 pub Box<
220 dyn Fn(
221 &ExprContext,
222 Vec<CoercibleScalarExpr>,
223 &ParamList,
224 Vec<ColumnOrder>,
225 ) -> Result<R, PlanError>
226 + Send
227 + Sync,
228 >,
229);
230
231impl<R> fmt::Debug for Operation<R> {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 f.debug_struct("Operation").finish()
234 }
235}
236
237impl Operation<HirScalarExpr> {
238 fn identity() -> Operation<HirScalarExpr> {
240 Operation::unary(|_ecx, e| Ok(e))
241 }
242}
243
244impl<R> Operation<R> {
245 fn new<F>(f: F) -> Operation<R>
246 where
247 F: Fn(
248 &ExprContext,
249 Vec<CoercibleScalarExpr>,
250 &ParamList,
251 Vec<ColumnOrder>,
252 ) -> Result<R, PlanError>
253 + Send
254 + Sync
255 + 'static,
256 {
257 Operation(Box::new(f))
258 }
259
260 fn nullary<F>(f: F) -> Operation<R>
262 where
263 F: Fn(&ExprContext) -> Result<R, PlanError> + Send + Sync + 'static,
264 {
265 Self::variadic(move |ecx, exprs| {
266 assert!(exprs.is_empty());
267 f(ecx)
268 })
269 }
270
271 fn unary<F>(f: F) -> Operation<R>
273 where
274 F: Fn(&ExprContext, HirScalarExpr) -> Result<R, PlanError> + Send + Sync + 'static,
275 {
276 Self::variadic(move |ecx, exprs| f(ecx, exprs.into_element()))
277 }
278
279 fn unary_ordered<F>(f: F) -> Operation<R>
281 where
282 F: Fn(&ExprContext, HirScalarExpr, Vec<ColumnOrder>) -> Result<R, PlanError>
283 + Send
284 + Sync
285 + 'static,
286 {
287 Self::new(move |ecx, cexprs, params, order_by| {
288 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
289 f(ecx, exprs.into_element(), order_by)
290 })
291 }
292
293 fn binary<F>(f: F) -> Operation<R>
295 where
296 F: Fn(&ExprContext, HirScalarExpr, HirScalarExpr) -> Result<R, PlanError>
297 + Send
298 + Sync
299 + 'static,
300 {
301 Self::variadic(move |ecx, exprs| {
302 assert_eq!(exprs.len(), 2);
303 let mut exprs = exprs.into_iter();
304 let left = exprs.next().unwrap();
305 let right = exprs.next().unwrap();
306 f(ecx, left, right)
307 })
308 }
309
310 fn binary_ordered<F>(f: F) -> Operation<R>
315 where
316 F: Fn(&ExprContext, HirScalarExpr, HirScalarExpr, Vec<ColumnOrder>) -> Result<R, PlanError>
317 + Send
318 + Sync
319 + 'static,
320 {
321 Self::new(move |ecx, cexprs, params, order_by| {
322 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
323 assert_eq!(exprs.len(), 2);
324 let mut exprs = exprs.into_iter();
325 let left = exprs.next().unwrap();
326 let right = exprs.next().unwrap();
327 f(ecx, left, right, order_by)
328 })
329 }
330
331 fn variadic<F>(f: F) -> Operation<R>
333 where
334 F: Fn(&ExprContext, Vec<HirScalarExpr>) -> Result<R, PlanError> + Send + Sync + 'static,
335 {
336 Self::new(move |ecx, cexprs, params, _order_by| {
337 let exprs = coerce_args_to_types(ecx, cexprs, params)?;
338 f(ecx, exprs)
339 })
340 }
341}
342
343pub fn sql_impl(
346 expr: &str,
347) -> impl Fn(&QueryContext, Vec<ScalarType>) -> Result<HirScalarExpr, PlanError> + use<> {
348 let expr = mz_sql_parser::parser::parse_expr(expr).unwrap_or_else(|e| {
349 panic!(
350 "static function definition failed to parse {}: {}",
351 expr.quoted(),
352 e,
353 )
354 });
355 move |qcx, types| {
356 let mut scx = qcx.scx.clone();
359 scx.param_types = RefCell::new(
360 types
361 .into_iter()
362 .enumerate()
363 .map(|(i, ty)| (i + 1, ty))
364 .collect(),
365 );
366 let qcx = QueryContext::root(&scx, qcx.lifetime);
367
368 let (mut expr, _) = names::resolve(qcx.scx.catalog, expr.clone())?;
369 transform_ast::transform(&scx, &mut expr)?;
371
372 let ecx = ExprContext {
373 qcx: &qcx,
374 name: "static function definition",
375 scope: &Scope::empty(),
376 relation_type: &RelationType::empty(),
377 allow_aggregates: false,
378 allow_subqueries: true,
379 allow_parameters: true,
380 allow_windows: false,
381 };
382
383 query::plan_expr(&ecx, &expr)?.type_as_any(&ecx)
385 }
386}
387
388fn sql_impl_func(expr: &str) -> Operation<HirScalarExpr> {
402 let invoke = sql_impl(expr);
403 Operation::variadic(move |ecx, args| {
404 let types = args.iter().map(|arg| ecx.scalar_type(arg)).collect();
405 let mut out = invoke(ecx.qcx, types)?;
406 out.splice_parameters(&args, 0);
407 Ok(out)
408 })
409}
410
411fn sql_impl_table_func_inner(
424 sql: &'static str,
425 feature_flag: Option<&'static vars::FeatureFlag>,
426) -> Operation<TableFuncPlan> {
427 let query = match mz_sql_parser::parser::parse_statements(sql)
428 .expect("static function definition failed to parse")
429 .expect_element(|| "static function definition must have exactly one statement")
430 .ast
431 {
432 Statement::Select(SelectStatement { query, as_of: None }) => query,
433 _ => panic!("static function definition expected SELECT statement"),
434 };
435 let invoke = move |qcx: &QueryContext, types: Vec<ScalarType>| {
436 let mut scx = qcx.scx.clone();
439 scx.param_types = RefCell::new(
440 types
441 .into_iter()
442 .enumerate()
443 .map(|(i, ty)| (i + 1, ty))
444 .collect(),
445 );
446 let mut qcx = QueryContext::root(&scx, qcx.lifetime);
447
448 let query = query.clone();
449 let (mut query, _) = names::resolve(qcx.scx.catalog, query)?;
450 transform_ast::transform(&scx, &mut query)?;
451
452 query::plan_nested_query(&mut qcx, &query)
453 };
454
455 Operation::variadic(move |ecx, args| {
456 if let Some(feature_flag) = feature_flag {
457 ecx.require_feature_flag(feature_flag)?;
458 }
459 let types = args.iter().map(|arg| ecx.scalar_type(arg)).collect();
460 let (mut expr, scope) = invoke(ecx.qcx, types)?;
461 expr.splice_parameters(&args, 0);
462 Ok(TableFuncPlan {
463 expr,
464 column_names: scope.column_names().cloned().collect(),
465 })
466 })
467}
468
469fn sql_impl_table_func(sql: &'static str) -> Operation<TableFuncPlan> {
470 sql_impl_table_func_inner(sql, None)
471}
472
473fn experimental_sql_impl_table_func(
474 feature: &'static vars::FeatureFlag,
475 sql: &'static str,
476) -> Operation<TableFuncPlan> {
477 sql_impl_table_func_inner(sql, Some(feature))
478}
479
480pub struct FuncImpl<R> {
482 pub oid: u32,
483 pub params: ParamList,
484 pub return_type: ReturnType,
485 pub op: Operation<R>,
486}
487
488#[derive(Debug)]
490pub struct FuncImplCatalogDetails {
491 pub oid: u32,
492 pub arg_typs: Vec<&'static str>,
493 pub variadic_typ: Option<&'static str>,
494 pub return_typ: Option<&'static str>,
495 pub return_is_set: bool,
496}
497
498impl<R> FuncImpl<R> {
499 pub fn details(&self) -> FuncImplCatalogDetails {
500 FuncImplCatalogDetails {
501 oid: self.oid,
502 arg_typs: self.params.arg_names(),
503 variadic_typ: self.params.variadic_name(),
504 return_typ: self.return_type.typ.as_ref().map(|t| t.name()),
505 return_is_set: self.return_type.is_set_of,
506 }
507 }
508}
509
510impl<R> fmt::Debug for FuncImpl<R> {
511 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
512 f.debug_struct("FuncImpl")
513 .field("oid", &self.oid)
514 .field("params", &self.params)
515 .field("ret", &self.return_type)
516 .field("op", &"<omitted>")
517 .finish()
518 }
519}
520
521impl From<UnmaterializableFunc> for Operation<HirScalarExpr> {
522 fn from(n: UnmaterializableFunc) -> Operation<HirScalarExpr> {
523 Operation::nullary(move |_ecx| Ok(HirScalarExpr::CallUnmaterializable(n.clone())))
524 }
525}
526
527impl From<UnaryFunc> for Operation<HirScalarExpr> {
528 fn from(u: UnaryFunc) -> Operation<HirScalarExpr> {
529 Operation::unary(move |_ecx, e| Ok(e.call_unary(u.clone())))
530 }
531}
532
533impl From<BinaryFunc> for Operation<HirScalarExpr> {
534 fn from(b: BinaryFunc) -> Operation<HirScalarExpr> {
535 Operation::binary(move |_ecx, left, right| Ok(left.call_binary(right, b.clone())))
536 }
537}
538
539impl From<VariadicFunc> for Operation<HirScalarExpr> {
540 fn from(v: VariadicFunc) -> Operation<HirScalarExpr> {
541 Operation::variadic(move |_ecx, exprs| {
542 Ok(HirScalarExpr::CallVariadic {
543 func: v.clone(),
544 exprs,
545 })
546 })
547 }
548}
549
550impl From<AggregateFunc> for Operation<(HirScalarExpr, AggregateFunc)> {
551 fn from(a: AggregateFunc) -> Operation<(HirScalarExpr, AggregateFunc)> {
552 Operation::unary(move |_ecx, e| Ok((e, a.clone())))
553 }
554}
555
556impl From<ScalarWindowFunc> for Operation<ScalarWindowFunc> {
557 fn from(a: ScalarWindowFunc) -> Operation<ScalarWindowFunc> {
558 Operation::nullary(move |_ecx| Ok(a.clone()))
559 }
560}
561
562impl From<ValueWindowFunc> for Operation<(HirScalarExpr, ValueWindowFunc)> {
563 fn from(a: ValueWindowFunc) -> Operation<(HirScalarExpr, ValueWindowFunc)> {
564 Operation::unary(move |_ecx, e| Ok((e, a.clone())))
565 }
566}
567
568#[derive(Debug, Clone, Eq, PartialEq, Hash)]
569pub enum ParamList {
573 Exact(Vec<ParamType>),
574 Variadic {
575 leading: Vec<ParamType>,
576 trailing: ParamType,
577 },
578}
579
580impl ParamList {
581 fn matches_argtypes(&self, ecx: &ExprContext, typs: &[CoercibleScalarType]) -> bool {
583 if !self.validate_arg_len(typs.len()) {
584 return false;
585 }
586
587 for (i, typ) in typs.iter().enumerate() {
588 let param = &self[i];
589 if let CoercibleScalarType::Coerced(typ) = typ {
590 if !param.accepts_type(ecx, typ) {
597 return false;
598 }
599 }
600 }
601
602 PolymorphicSolution::new(ecx, typs, self).is_some()
605 }
606
607 fn validate_arg_len(&self, input_len: usize) -> bool {
609 match self {
610 Self::Exact(p) => p.len() == input_len,
611 Self::Variadic { leading, .. } => input_len > leading.len(),
612 }
613 }
614
615 fn exact_match(&self, types: &[&ScalarType]) -> bool {
618 types.iter().enumerate().all(|(i, t)| self[i] == **t)
619 }
620
621 fn arg_names(&self) -> Vec<&'static str> {
623 match self {
624 ParamList::Exact(p) => p.iter().map(|p| p.name()).collect::<Vec<_>>(),
625 ParamList::Variadic { leading, trailing } => leading
626 .iter()
627 .chain([trailing])
628 .map(|p| p.name())
629 .collect::<Vec<_>>(),
630 }
631 }
632
633 fn variadic_name(&self) -> Option<&'static str> {
635 match self {
636 ParamList::Exact(_) => None,
637 ParamList::Variadic { trailing, .. } => Some(trailing.name()),
638 }
639 }
640}
641
642impl std::ops::Index<usize> for ParamList {
643 type Output = ParamType;
644
645 fn index(&self, i: usize) -> &Self::Output {
646 match self {
647 Self::Exact(p) => &p[i],
648 Self::Variadic { leading, trailing } => leading.get(i).unwrap_or(trailing),
649 }
650 }
651}
652
653impl From<Vec<ParamType>> for ParamList {
655 fn from(p: Vec<ParamType>) -> ParamList {
656 ParamList::Exact(p)
657 }
658}
659
660#[derive(Debug, Clone, Eq, PartialEq, Hash)]
661pub enum ParamType {
674 Any,
677 AnyCompatible,
680 AnyElement,
683 ArrayAny,
686 ArrayAnyCompatible,
689 ListAny,
692 ListAnyCompatible,
695 ListElementAnyCompatible,
700 MapAny,
703 MapAnyCompatible,
706 NonVecAny,
710 NonVecAnyCompatible,
714 Plain(ScalarType),
717 RecordAny,
720 RangeAny,
723 RangeAnyCompatible,
730 Internal,
733}
734
735impl ParamType {
736 fn accepts_type(&self, ecx: &ExprContext, t: &ScalarType) -> bool {
738 use ParamType::*;
739 use ScalarType::*;
740
741 match self {
742 Any | AnyElement | AnyCompatible | ListElementAnyCompatible => true,
743 ArrayAny | ArrayAnyCompatible => matches!(t, Array(..) | Int2Vector),
744 ListAny | ListAnyCompatible => matches!(t, List { .. }),
745 MapAny | MapAnyCompatible => matches!(t, Map { .. }),
746 RangeAny | RangeAnyCompatible => matches!(t, Range { .. }),
747 NonVecAny | NonVecAnyCompatible => !t.is_vec(),
748 Internal => false,
749 Plain(to) => typeconv::can_cast(ecx, CastContext::Implicit, t, to),
750 RecordAny => matches!(t, Record { .. }),
751 }
752 }
753
754 fn is_preferred_by(&self, t: &ScalarType) -> bool {
757 if let Some(pt) = TypeCategory::from_type(t).preferred_type() {
758 *self == pt
759 } else {
760 false
761 }
762 }
763
764 fn is_near_match(&self, t: &ScalarType) -> bool {
768 match (self, t.near_match()) {
769 (ParamType::Plain(t), Some(near_match)) => t.structural_eq(near_match),
770 _ => false,
771 }
772 }
773
774 fn prefers_self(&self) -> bool {
776 if let Some(pt) = TypeCategory::from_param(self).preferred_type() {
777 *self == pt
778 } else {
779 false
780 }
781 }
782
783 fn is_polymorphic(&self) -> bool {
784 use ParamType::*;
785 match self {
786 AnyElement
787 | ArrayAny
788 | ArrayAnyCompatible
789 | AnyCompatible
790 | ListAny
791 | ListAnyCompatible
792 | ListElementAnyCompatible
793 | MapAny
794 | MapAnyCompatible
795 | NonVecAny
796 | NonVecAnyCompatible
797 | RecordAny
801 | RangeAny
802 | RangeAnyCompatible => true,
803 Any | Internal | Plain(_) => false,
804 }
805 }
806
807 fn name(&self) -> &'static str {
808 match self {
809 ParamType::Plain(t) => {
810 assert!(
811 !t.is_custom_type(),
812 "custom types cannot currently be used as parameters; use a polymorphic parameter that accepts the custom type instead"
813 );
814 let t: mz_pgrepr::Type = t.into();
815 t.catalog_name()
816 }
817 ParamType::Any => "any",
818 ParamType::AnyCompatible => "anycompatible",
819 ParamType::AnyElement => "anyelement",
820 ParamType::ArrayAny => "anyarray",
821 ParamType::ArrayAnyCompatible => "anycompatiblearray",
822 ParamType::Internal => "internal",
823 ParamType::ListAny => "list",
824 ParamType::ListAnyCompatible => "anycompatiblelist",
825 ParamType::ListElementAnyCompatible => "anycompatible",
827 ParamType::MapAny => "map",
828 ParamType::MapAnyCompatible => "anycompatiblemap",
829 ParamType::NonVecAny => "anynonarray",
830 ParamType::NonVecAnyCompatible => "anycompatiblenonarray",
831 ParamType::RecordAny => "record",
832 ParamType::RangeAny => "anyrange",
833 ParamType::RangeAnyCompatible => "anycompatiblerange",
834 }
835 }
836}
837
838impl PartialEq<ScalarType> for ParamType {
839 fn eq(&self, other: &ScalarType) -> bool {
840 match self {
841 ParamType::Plain(s) => s.base_eq(other),
842 _ => false,
844 }
845 }
846}
847
848impl PartialEq<ParamType> for ScalarType {
849 fn eq(&self, other: &ParamType) -> bool {
850 other == self
851 }
852}
853
854impl From<ScalarType> for ParamType {
855 fn from(s: ScalarType) -> ParamType {
856 ParamType::Plain(s)
857 }
858}
859
860impl From<ScalarBaseType> for ParamType {
861 fn from(s: ScalarBaseType) -> ParamType {
862 use ScalarBaseType::*;
863 let s = match s {
864 Array | List | Map | Record | Range => {
865 panic!("use polymorphic parameters rather than {:?}", s);
866 }
867 AclItem => ScalarType::AclItem,
868 Bool => ScalarType::Bool,
869 Int16 => ScalarType::Int16,
870 Int32 => ScalarType::Int32,
871 Int64 => ScalarType::Int64,
872 UInt16 => ScalarType::UInt16,
873 UInt32 => ScalarType::UInt32,
874 UInt64 => ScalarType::UInt64,
875 Float32 => ScalarType::Float32,
876 Float64 => ScalarType::Float64,
877 Numeric => ScalarType::Numeric { max_scale: None },
878 Date => ScalarType::Date,
879 Time => ScalarType::Time,
880 Timestamp => ScalarType::Timestamp { precision: None },
881 TimestampTz => ScalarType::TimestampTz { precision: None },
882 Interval => ScalarType::Interval,
883 Bytes => ScalarType::Bytes,
884 String => ScalarType::String,
885 Char => ScalarType::Char { length: None },
886 VarChar => ScalarType::VarChar { max_length: None },
887 PgLegacyChar => ScalarType::PgLegacyChar,
888 PgLegacyName => ScalarType::PgLegacyName,
889 Jsonb => ScalarType::Jsonb,
890 Uuid => ScalarType::Uuid,
891 Oid => ScalarType::Oid,
892 RegClass => ScalarType::RegClass,
893 RegProc => ScalarType::RegProc,
894 RegType => ScalarType::RegType,
895 Int2Vector => ScalarType::Int2Vector,
896 MzTimestamp => ScalarType::MzTimestamp,
897 MzAclItem => ScalarType::MzAclItem,
898 };
899 ParamType::Plain(s)
900 }
901}
902
903#[derive(Debug, Clone, Eq, PartialEq, Hash)]
904pub struct ReturnType {
905 pub typ: Option<ParamType>,
906 pub is_set_of: bool,
907}
908
909impl ReturnType {
910 fn scalar(typ: ParamType) -> ReturnType {
912 ReturnType {
913 typ: Some(typ),
914 is_set_of: false,
915 }
916 }
917
918 fn set_of(typ: ParamType) -> ReturnType {
921 ReturnType {
922 typ: Some(typ),
923 is_set_of: true,
924 }
925 }
926
927 fn none(is_set_of: bool) -> ReturnType {
929 ReturnType {
930 typ: None,
931 is_set_of,
932 }
933 }
934}
935
936impl From<ParamType> for ReturnType {
937 fn from(typ: ParamType) -> ReturnType {
938 ReturnType::scalar(typ)
939 }
940}
941
942impl From<ScalarBaseType> for ReturnType {
943 fn from(s: ScalarBaseType) -> ReturnType {
944 ParamType::from(s).into()
945 }
946}
947
948impl From<ScalarType> for ReturnType {
949 fn from(s: ScalarType) -> ReturnType {
950 ParamType::Plain(s).into()
951 }
952}
953
954#[derive(Clone, Debug)]
955pub struct Candidate<'a, R> {
957 fimpl: &'a FuncImpl<R>,
959 exact_matches: usize,
960 preferred_types: usize,
961 near_matches: usize,
962}
963
964pub fn select_impl<R>(
978 ecx: &ExprContext,
979 spec: FuncSpec,
980 impls: &[FuncImpl<R>],
981 args: Vec<CoercibleScalarExpr>,
982 order_by: Vec<ColumnOrder>,
983) -> Result<R, PlanError>
984where
985 R: fmt::Debug,
986{
987 let name = spec.to_string();
988 let ecx = &ecx.with_name(&name);
989 let mut types: Vec<_> = args.iter().map(|e| ecx.scalar_type(e)).collect();
990
991 for ty in &mut types {
997 ty.force_coerced_if_record();
998 }
999
1000 let impls: Vec<_> = impls
1005 .iter()
1006 .filter(|i| i.params.matches_argtypes(ecx, &types))
1007 .collect();
1008
1009 let f = find_match(ecx, &types, impls).map_err(|candidates| {
1010 let arg_types: Vec<_> = types
1011 .into_iter()
1012 .map(|ty| match ty {
1013 CoercibleScalarType::Coerced(ty) => ecx.humanize_scalar_type(&ty, false),
1015 CoercibleScalarType::Record(_) => "record".to_string(),
1016 CoercibleScalarType::Uncoerced => "unknown".to_string(),
1017 })
1018 .collect();
1019
1020 if candidates == 0 {
1021 match spec {
1022 FuncSpec::Func(name) => PlanError::UnknownFunction {
1023 name: ecx
1024 .qcx
1025 .scx
1026 .humanize_resolved_name(name)
1027 .expect("resolved to object")
1028 .to_string(),
1029 arg_types,
1030 },
1031 FuncSpec::Op(name) => PlanError::UnknownOperator {
1032 name: name.to_string(),
1033 arg_types,
1034 },
1035 }
1036 } else {
1037 match spec {
1038 FuncSpec::Func(name) => PlanError::IndistinctFunction {
1039 name: ecx
1040 .qcx
1041 .scx
1042 .humanize_resolved_name(name)
1043 .expect("resolved to object")
1044 .to_string(),
1045 arg_types,
1046 },
1047 FuncSpec::Op(name) => PlanError::IndistinctOperator {
1048 name: name.to_string(),
1049 arg_types,
1050 },
1051 }
1052 }
1053 })?;
1054
1055 (f.op.0)(ecx, args, &f.params, order_by)
1056}
1057
1058fn find_match<'a, R: std::fmt::Debug>(
1064 ecx: &ExprContext,
1065 types: &[CoercibleScalarType],
1066 impls: Vec<&'a FuncImpl<R>>,
1067) -> Result<&'a FuncImpl<R>, usize> {
1068 let all_types_known = types.iter().all(|t| t.is_coerced());
1069
1070 if all_types_known {
1072 let known_types: Vec<_> = types.iter().filter_map(|t| t.as_coerced()).collect();
1073 let matching_impls: Vec<&FuncImpl<_>> = impls
1074 .iter()
1075 .filter(|i| i.params.exact_match(&known_types))
1076 .cloned()
1077 .collect();
1078
1079 if matching_impls.len() == 1 {
1080 return Ok(matching_impls[0]);
1081 }
1082 }
1083
1084 let mut candidates: Vec<Candidate<_>> = Vec::new();
1088 macro_rules! maybe_get_last_candidate {
1089 () => {
1090 if candidates.len() == 1 {
1091 return Ok(&candidates[0].fimpl);
1092 }
1093 };
1094 }
1095 let mut max_exact_matches = 0;
1096
1097 for fimpl in impls {
1098 let mut exact_matches = 0;
1099 let mut preferred_types = 0;
1100 let mut near_matches = 0;
1101
1102 for (i, arg_type) in types.iter().enumerate() {
1103 let param_type = &fimpl.params[i];
1104
1105 match arg_type {
1106 CoercibleScalarType::Coerced(arg_type) => {
1107 if param_type == arg_type {
1108 exact_matches += 1;
1109 }
1110 if param_type.is_preferred_by(arg_type) {
1111 preferred_types += 1;
1112 }
1113 if param_type.is_near_match(arg_type) {
1114 near_matches += 1;
1115 }
1116 }
1117 CoercibleScalarType::Record(_) | CoercibleScalarType::Uncoerced => {
1118 if param_type.prefers_self() {
1119 preferred_types += 1;
1120 }
1121 }
1122 }
1123 }
1124
1125 max_exact_matches = std::cmp::max(max_exact_matches, exact_matches);
1130 candidates.push(Candidate {
1131 fimpl,
1132 exact_matches,
1133 preferred_types,
1134 near_matches,
1135 });
1136 }
1137
1138 if candidates.is_empty() {
1139 return Err(0);
1140 }
1141
1142 maybe_get_last_candidate!();
1143
1144 candidates.retain(|c| c.exact_matches >= max_exact_matches);
1147
1148 maybe_get_last_candidate!();
1149
1150 let mut max_near_matches = 0;
1155 for c in &candidates {
1156 max_near_matches = std::cmp::max(max_near_matches, c.near_matches);
1157 }
1158 candidates.retain(|c| c.near_matches >= max_near_matches);
1159
1160 let mut max_preferred_types = 0;
1164 for c in &candidates {
1165 max_preferred_types = std::cmp::max(max_preferred_types, c.preferred_types);
1166 }
1167 candidates.retain(|c| c.preferred_types >= max_preferred_types);
1168
1169 maybe_get_last_candidate!();
1170
1171 if all_types_known {
1172 return Err(candidates.len());
1173 }
1174
1175 let mut found_known = false;
1176 let mut types_match = true;
1177 let mut common_type: Option<ScalarType> = None;
1178
1179 for (i, arg_type) in types.iter().enumerate() {
1180 let mut selected_category: Option<TypeCategory> = None;
1181 let mut categories_match = true;
1182
1183 match arg_type {
1184 CoercibleScalarType::Uncoerced | CoercibleScalarType::Record(_) => {
1188 for c in candidates.iter() {
1189 let this_category = TypeCategory::from_param(&c.fimpl.params[i]);
1190 if this_category == TypeCategory::String {
1195 selected_category = Some(TypeCategory::String);
1196 break;
1197 }
1198 match selected_category {
1199 Some(ref mut selected_category) => {
1200 categories_match =
1203 selected_category == &this_category && categories_match;
1204 }
1205 None => selected_category = Some(this_category.clone()),
1206 }
1207 }
1208
1209 if selected_category != Some(TypeCategory::String) && !categories_match {
1213 break;
1214 }
1215
1216 let selected_category = selected_category.unwrap();
1221
1222 let preferred_type = selected_category.preferred_type();
1223 let mut found_preferred_type_candidate = false;
1224 candidates.retain(|c| {
1225 if let Some(typ) = &preferred_type {
1226 found_preferred_type_candidate = c.fimpl.params[i].accepts_type(ecx, typ)
1227 || found_preferred_type_candidate;
1228 }
1229 selected_category == TypeCategory::from_param(&c.fimpl.params[i])
1230 });
1231
1232 if found_preferred_type_candidate {
1233 let preferred_type = preferred_type.unwrap();
1234 candidates.retain(|c| c.fimpl.params[i].accepts_type(ecx, &preferred_type));
1235 }
1236 }
1237 CoercibleScalarType::Coerced(typ) => {
1238 found_known = true;
1239 match common_type {
1242 Some(ref common_type) => types_match = common_type == typ && types_match,
1243 None => common_type = Some(typ.clone()),
1244 }
1245 }
1246 }
1247 }
1248
1249 maybe_get_last_candidate!();
1250
1251 if found_known && types_match {
1257 let common_type = common_type.unwrap();
1258 let common_typed: Vec<_> = types
1259 .iter()
1260 .map(|t| match t {
1261 CoercibleScalarType::Coerced(t) => CoercibleScalarType::Coerced(t.clone()),
1262 CoercibleScalarType::Uncoerced | CoercibleScalarType::Record(_) => {
1263 CoercibleScalarType::Coerced(common_type.clone())
1264 }
1265 })
1266 .collect();
1267
1268 candidates.retain(|c| c.fimpl.params.matches_argtypes(ecx, &common_typed));
1269
1270 maybe_get_last_candidate!();
1271 }
1272
1273 Err(candidates.len())
1274}
1275
1276#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1277enum PolymorphicCompatClass {
1278 Any,
1282 BestCommonAny,
1298 BestCommonList,
1307 BestCommonMap,
1312 StructuralEq,
1321}
1322
1323impl TryFrom<&ParamType> for PolymorphicCompatClass {
1324 type Error = ();
1325 fn try_from(param: &ParamType) -> Result<PolymorphicCompatClass, Self::Error> {
1326 use ParamType::*;
1327
1328 Ok(match param {
1329 AnyElement | ArrayAny | ListAny | MapAny | NonVecAny | RangeAny => {
1330 PolymorphicCompatClass::Any
1331 }
1332 ArrayAnyCompatible | AnyCompatible | RangeAnyCompatible | NonVecAnyCompatible => {
1333 PolymorphicCompatClass::BestCommonAny
1334 }
1335 ListAnyCompatible | ListElementAnyCompatible => PolymorphicCompatClass::BestCommonList,
1336 MapAnyCompatible => PolymorphicCompatClass::BestCommonMap,
1337 RecordAny => PolymorphicCompatClass::StructuralEq,
1338 _ => return Err(()),
1339 })
1340 }
1341}
1342
1343impl PolymorphicCompatClass {
1344 fn compatible(&self, ecx: &ExprContext, from: &ScalarType, to: &ScalarType) -> bool {
1345 use PolymorphicCompatClass::*;
1346 match self {
1347 StructuralEq => from.structural_eq(to),
1348 Any => from.base_eq(to),
1349 _ => typeconv::can_cast(ecx, CastContext::Implicit, from, to),
1350 }
1351 }
1352}
1353
1354#[derive(Debug)]
1357pub(crate) struct PolymorphicSolution {
1358 compat: Option<PolymorphicCompatClass>,
1361 seen: Vec<CoercibleScalarType>,
1362 key: Option<ScalarType>,
1364}
1365
1366impl PolymorphicSolution {
1367 fn new(
1374 ecx: &ExprContext,
1375 args: &[CoercibleScalarType],
1376 params: &ParamList,
1377 ) -> Option<PolymorphicSolution> {
1378 let mut r = PolymorphicSolution {
1379 compat: None,
1380 seen: vec![],
1381 key: None,
1382 };
1383
1384 for (i, scalar_type) in args.iter().cloned().enumerate() {
1385 r.track_seen(¶ms[i], scalar_type);
1386 }
1387
1388 if !r.determine_key(ecx) { None } else { Some(r) }
1389 }
1390
1391 fn track_seen(&mut self, param: &ParamType, seen: CoercibleScalarType) {
1394 use ParamType::*;
1395
1396 self.seen.push(match param {
1397 AnyElement | AnyCompatible | ListAnyCompatible | MapAnyCompatible | NonVecAny | RecordAny => seen,
1399 MapAny => seen.map_coerced(|array| array.unwrap_map_value_type().clone()),
1400 ListAny => seen.map_coerced(|array| array.unwrap_list_element_type().clone()),
1401 ArrayAny | ArrayAnyCompatible => seen.map_coerced(|array| array.unwrap_array_element_type().clone()),
1402 RangeAny | RangeAnyCompatible => seen.map_coerced(|range| range.unwrap_range_element_type().clone()),
1403 ListElementAnyCompatible => seen.map_coerced(|el| ScalarType::List {
1404 custom_id: None,
1405 element_type: Box::new(el),
1406 }),
1407 o => {
1408 assert!(
1409 !o.is_polymorphic(),
1410 "polymorphic parameters must track types they encounter to determine polymorphic solution"
1411 );
1412 return;
1413 }
1414 });
1415
1416 let compat_class = param
1417 .try_into()
1418 .expect("already returned for non-polymorphic params");
1419
1420 match &self.compat {
1421 None => self.compat = Some(compat_class),
1422 Some(c) => {
1423 assert_eq!(
1424 c, &compat_class,
1425 "do not know how to correlate polymorphic classes {:?} and {:?}",
1426 c, &compat_class,
1427 )
1428 }
1429 };
1430 }
1431
1432 fn determine_key(&mut self, ecx: &ExprContext) -> bool {
1436 self.key = if !self.seen.iter().any(|v| v.is_coerced()) {
1437 match &self.compat {
1438 None => None,
1440 Some(t) => match t {
1445 PolymorphicCompatClass::BestCommonAny => Some(ScalarType::String),
1446 PolymorphicCompatClass::BestCommonList => Some(ScalarType::List {
1447 custom_id: None,
1448 element_type: Box::new(ScalarType::String),
1449 }),
1450 PolymorphicCompatClass::BestCommonMap => Some(ScalarType::Map {
1451 value_type: Box::new(ScalarType::String),
1452 custom_id: None,
1453 }),
1454 PolymorphicCompatClass::StructuralEq | PolymorphicCompatClass::Any => None,
1456 },
1457 }
1458 } else {
1459 let compat = self.compat.as_ref().unwrap();
1462
1463 let r = match compat {
1464 PolymorphicCompatClass::Any => {
1465 let mut s = self
1466 .seen
1467 .iter()
1468 .filter_map(|f| f.as_coerced().cloned())
1469 .collect::<Vec<_>>();
1470 let (candiate, remaining) =
1471 s.split_first().expect("have at least one non-None element");
1472 if remaining.iter().all(|r| r.base_eq(candiate)) {
1473 s.remove(0)
1474 } else {
1475 return false;
1476 }
1477 }
1478 _ => match typeconv::guess_best_common_type(ecx, &self.seen) {
1479 Ok(r) => r,
1480 Err(_) => return false,
1481 },
1482 };
1483
1484 for t in self.seen.iter() {
1486 if let CoercibleScalarType::Coerced(t) = t {
1487 if !compat.compatible(ecx, t, &r) {
1488 return false;
1489 }
1490 }
1491 }
1492 Some(r)
1493 };
1494
1495 true
1496 }
1497
1498 fn target_for_param_type(&self, param: &ParamType) -> Option<ScalarType> {
1501 use ParamType::*;
1502 assert_eq!(
1503 self.compat,
1504 Some(
1505 param
1506 .try_into()
1507 .expect("target_for_param_type only supports polymorphic parameters")
1508 ),
1509 "cannot use polymorphic solution for different compatibility classes"
1510 );
1511
1512 assert!(
1513 !matches!(param, RecordAny),
1514 "RecordAny should not be cast to a target type"
1515 );
1516
1517 match param {
1518 AnyElement | AnyCompatible | ListAnyCompatible | MapAnyCompatible | NonVecAny => {
1519 self.key.clone()
1520 }
1521 ArrayAny | ArrayAnyCompatible => self
1522 .key
1523 .as_ref()
1524 .map(|key| ScalarType::Array(Box::new(key.clone()))),
1525 ListAny => self.key.as_ref().map(|key| ScalarType::List {
1526 element_type: Box::new(key.clone()),
1527 custom_id: None,
1528 }),
1529 MapAny => self.key.as_ref().map(|key| ScalarType::Map {
1530 value_type: Box::new(key.clone()),
1531 custom_id: None,
1532 }),
1533 RangeAny | RangeAnyCompatible => self.key.as_ref().map(|key| ScalarType::Range {
1534 element_type: Box::new(key.clone()),
1535 }),
1536 ListElementAnyCompatible => self
1537 .key
1538 .as_ref()
1539 .map(|key| key.unwrap_list_element_type().clone()),
1540 _ => unreachable!(
1541 "cannot use polymorphic solution to resolve target type for param {:?}",
1542 param,
1543 ),
1544 }
1545 }
1546}
1547
1548fn coerce_args_to_types(
1549 ecx: &ExprContext,
1550 args: Vec<CoercibleScalarExpr>,
1551 params: &ParamList,
1552) -> Result<Vec<HirScalarExpr>, PlanError> {
1553 use ParamType::*;
1554
1555 let mut scalar_types: Vec<_> = args.iter().map(|e| ecx.scalar_type(e)).collect();
1556
1557 for ty in &mut scalar_types {
1559 ty.force_coerced_if_record();
1560 }
1561
1562 let polymorphic_solution = PolymorphicSolution::new(ecx, &scalar_types, params)
1563 .expect("polymorphic solution previously determined to be valid");
1564
1565 let do_convert =
1566 |arg: CoercibleScalarExpr, ty: &ScalarType| arg.cast_to(ecx, CastContext::Implicit, ty);
1567
1568 let mut res_exprs = Vec::with_capacity(args.len());
1569 for (i, cexpr) in args.into_iter().enumerate() {
1570 let expr = match ¶ms[i] {
1571 Any => match cexpr {
1572 CoercibleScalarExpr::Parameter(n) => {
1573 sql_bail!("could not determine data type of parameter ${}", n)
1574 }
1575 _ => cexpr.type_as_any(ecx)?,
1576 },
1577 RecordAny => match cexpr {
1578 CoercibleScalarExpr::LiteralString(_) => {
1579 sql_bail!("input of anonymous composite types is not implemented");
1580 }
1581 _ => cexpr.type_as_any(ecx)?,
1585 },
1586 Plain(ty) => do_convert(cexpr, ty)?,
1587 Internal => return Err(PlanError::InternalFunctionCall),
1588 p => {
1589 let target = polymorphic_solution
1590 .target_for_param_type(p)
1591 .ok_or_else(|| {
1592 PlanError::UnsolvablePolymorphicFunctionInput
1601 })?;
1602 do_convert(cexpr, &target)?
1603 }
1604 };
1605 res_exprs.push(expr);
1606 }
1607
1608 Ok(res_exprs)
1609}
1610
1611macro_rules! params {
1613 ([$($p:expr),*], $v:ident...) => { ParamList::Variadic { leading: vec![$($p.into(),)*], trailing: $v.into() } };
1614 ($v:ident...) => { ParamList::Variadic { leading: vec![], trailing: $v.into() } };
1615 ($($p:expr),*) => { ParamList::Exact(vec![$($p.into(),)*]) };
1616}
1617
1618macro_rules! impl_def {
1619 ($params:expr, $op:expr, $return_type:expr, $oid:expr) => {{
1629 FuncImpl {
1630 oid: $oid,
1631 params: $params.into(),
1632 op: $op.into(),
1633 return_type: $return_type.into(),
1634 }
1635 }};
1636}
1637
1638macro_rules! builtins {
1640 {
1641 $(
1642 $name:expr => $ty:ident {
1643 $($params:expr => $op:expr => $return_type:expr, $oid:expr;)+
1644 }
1645 ),+
1646 } => {{
1647
1648 let mut builtins = BTreeMap::new();
1649 $(
1650 let impls = vec![$(impl_def!($params, $op, $return_type, $oid)),+];
1651 let func = Func::$ty(impls);
1652 let expect_set_return = matches!(&func, Func::Table(_));
1653 for imp in func.func_impls() {
1654 assert_eq!(imp.return_is_set, expect_set_return, "wrong set return value for func with oid {}", imp.oid);
1655 }
1656 let old = builtins.insert($name, func);
1657 mz_ore::assert_none!(old, "duplicate entry in builtins list");
1658 )+
1659 builtins
1660 }};
1661}
1662
1663#[derive(Debug)]
1664pub struct TableFuncPlan {
1665 pub expr: HirRelationExpr,
1666 pub column_names: Vec<ColumnName>,
1667}
1668
1669#[derive(Debug)]
1670pub enum Func {
1671 Scalar(Vec<FuncImpl<HirScalarExpr>>),
1672 Aggregate(Vec<FuncImpl<(HirScalarExpr, AggregateFunc)>>),
1673 Table(Vec<FuncImpl<TableFuncPlan>>),
1674 ScalarWindow(Vec<FuncImpl<ScalarWindowFunc>>),
1675 ValueWindow(Vec<FuncImpl<(HirScalarExpr, ValueWindowFunc)>>),
1676}
1677
1678impl Func {
1679 pub fn func_impls(&self) -> Vec<FuncImplCatalogDetails> {
1680 match self {
1681 Func::Scalar(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1682 Func::Aggregate(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1683 Func::Table(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1684 Func::ScalarWindow(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1685 Func::ValueWindow(impls) => impls.iter().map(|f| f.details()).collect::<Vec<_>>(),
1686 }
1687 }
1688
1689 pub fn class(&self) -> &str {
1690 match self {
1691 Func::Scalar(..) => "scalar",
1692 Func::Aggregate(..) => "aggregate",
1693 Func::Table(..) => "table",
1694 Func::ScalarWindow(..) => "window",
1695 Func::ValueWindow(..) => "window",
1696 }
1697 }
1698}
1699
1700macro_rules! catalog_name_only {
1704 ($name:expr) => {
1705 panic!(
1706 "{} should be planned away before reaching function selection",
1707 $name
1708 )
1709 };
1710}
1711
1712macro_rules! privilege_fn {
1714 ( $fn_name:expr, $catalog_tbl:expr ) => {
1715 {
1716 let fn_name = $fn_name;
1717 let catalog_tbl = $catalog_tbl;
1718 let public_role = RoleId::Public;
1719 format!(
1720 "
1721 CASE
1722 -- We need to validate the privileges to return a proper error before anything
1723 -- else.
1724 WHEN NOT mz_internal.mz_validate_privileges($3)
1725 OR $1 IS NULL
1726 OR $2 IS NULL
1727 OR $3 IS NULL
1728 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
1729 OR $2 NOT IN (SELECT oid FROM {catalog_tbl})
1730 THEN NULL
1731 ELSE COALESCE(
1732 (
1733 SELECT
1734 bool_or(
1735 mz_internal.mz_acl_item_contains_privilege(privilege, $3)
1736 )
1737 AS {fn_name}
1738 FROM
1739 (
1740 SELECT
1741 unnest(privileges)
1742 FROM
1743 {catalog_tbl}
1744 WHERE
1745 {catalog_tbl}.oid = $2
1746 )
1747 AS user_privs (privilege)
1748 LEFT JOIN mz_catalog.mz_roles ON
1749 mz_internal.mz_aclitem_grantee(privilege) = mz_roles.id
1750 WHERE
1751 mz_internal.mz_aclitem_grantee(privilege) = '{public_role}' OR pg_has_role($1, mz_roles.oid, 'USAGE')
1752 ),
1753 false
1754 )
1755 END
1756 ",
1757 )
1758 }
1759 };
1760}
1761
1762pub static PG_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
1764 use ParamType::*;
1765 use ScalarBaseType::*;
1766 let mut builtins = builtins! {
1767 "abs" => Scalar {
1780 params!(Int16) => UnaryFunc::AbsInt16(func::AbsInt16) => Int16, 1398;
1781 params!(Int32) => UnaryFunc::AbsInt32(func::AbsInt32) => Int32, 1397;
1782 params!(Int64) => UnaryFunc::AbsInt64(func::AbsInt64) => Int64, 1396;
1783 params!(Numeric) => UnaryFunc::AbsNumeric(func::AbsNumeric) => Numeric, 1705;
1784 params!(Float32) => UnaryFunc::AbsFloat32(func::AbsFloat32) => Float32, 1394;
1785 params!(Float64) => UnaryFunc::AbsFloat64(func::AbsFloat64) => Float64, 1395;
1786 },
1787 "aclexplode" => Table {
1788 params!(ScalarType::Array(Box::new(ScalarType::AclItem))) => Operation::unary(move |_ecx, aclitems| {
1789 Ok(TableFuncPlan {
1790 expr: HirRelationExpr::CallTable {
1791 func: TableFunc::AclExplode,
1792 exprs: vec![aclitems],
1793 },
1794 column_names: vec!["grantor".into(), "grantee".into(), "privilege_type".into(), "is_grantable".into()],
1795 })
1796 }) => ReturnType::set_of(RecordAny), 1689;
1797 },
1798 "array_cat" => Scalar {
1799 params!(ArrayAnyCompatible, ArrayAnyCompatible) => Operation::binary(|_ecx, lhs, rhs| {
1800 Ok(lhs.call_binary(rhs, BinaryFunc::ArrayArrayConcat))
1801 }) => ArrayAnyCompatible, 383;
1802 },
1803 "array_fill" => Scalar {
1804 params!(AnyElement, ScalarType::Array(Box::new(ScalarType::Int32))) => Operation::binary(|ecx, elem, dims| {
1805 let elem_type = ecx.scalar_type(&elem);
1806
1807 let elem_type = match elem_type.array_of_self_elem_type() {
1808 Ok(elem_type) => elem_type,
1809 Err(elem_type) => bail_unsupported!(
1810 format!("array_fill on {}", ecx.humanize_scalar_type(&elem_type, false))
1812 ),
1813 };
1814
1815 Ok(HirScalarExpr::CallVariadic { func: VariadicFunc::ArrayFill { elem_type }, exprs: vec![elem, dims] })
1816 }) => ArrayAny, 1193;
1817 params!(
1818 AnyElement,
1819 ScalarType::Array(Box::new(ScalarType::Int32)),
1820 ScalarType::Array(Box::new(ScalarType::Int32))
1821 ) => Operation::variadic(|ecx, exprs| {
1822 let elem_type = ecx.scalar_type(&exprs[0]);
1823
1824 let elem_type = match elem_type.array_of_self_elem_type() {
1825 Ok(elem_type) => elem_type,
1826 Err(elem_type) => bail_unsupported!(
1827 format!("array_fill on {}", ecx.humanize_scalar_type(&elem_type, false))
1828 ),
1829 };
1830
1831 Ok(HirScalarExpr::CallVariadic { func: VariadicFunc::ArrayFill { elem_type }, exprs })
1832 }) => ArrayAny, 1286;
1833 },
1834 "array_length" => Scalar {
1835 params![ArrayAny, Int64] => BinaryFunc::ArrayLength => Int32, 2176;
1836 },
1837 "array_lower" => Scalar {
1838 params!(ArrayAny, Int64) => BinaryFunc::ArrayLower => Int32, 2091;
1839 },
1840 "array_position" => Scalar {
1841 params!(ArrayAnyCompatible, AnyCompatible) => VariadicFunc::ArrayPosition => Int32, 3277;
1842 params!(ArrayAnyCompatible, AnyCompatible, Int32) => VariadicFunc::ArrayPosition => Int32, 3278;
1843 },
1844 "array_remove" => Scalar {
1845 params!(ArrayAnyCompatible, AnyCompatible) => BinaryFunc::ArrayRemove => ArrayAnyCompatible, 3167;
1846 },
1847 "array_to_string" => Scalar {
1848 params!(ArrayAny, String) => Operation::variadic(array_to_string) => String, 395;
1849 params!(ArrayAny, String, String) => Operation::variadic(array_to_string) => String, 384;
1850 },
1851 "array_upper" => Scalar {
1852 params!(ArrayAny, Int64) => BinaryFunc::ArrayUpper => Int32, 2092;
1853 },
1854 "ascii" => Scalar {
1855 params!(String) => UnaryFunc::Ascii(func::Ascii) => Int32, 1620;
1856 },
1857 "avg" => Scalar {
1858 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2100;
1859 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2101;
1860 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, 2102;
1861 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, oid::FUNC_AVG_UINT64_OID;
1862 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, oid::FUNC_AVG_UINT32_OID;
1863 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Numeric, oid::FUNC_AVG_UINT16_OID;
1864 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Float64, 2104;
1865 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Float64, 2105;
1866 params!(Interval) => Operation::nullary(|_ecx| catalog_name_only!("avg")) => Interval, 2106;
1867 },
1868 "bit_count" => Scalar {
1869 params!(Bytes) => UnaryFunc::BitCountBytes(func::BitCountBytes) => Int64, 6163;
1870 },
1871 "bit_length" => Scalar {
1872 params!(Bytes) => UnaryFunc::BitLengthBytes(func::BitLengthBytes) => Int32, 1810;
1873 params!(String) => UnaryFunc::BitLengthString(func::BitLengthString) => Int32, 1811;
1874 },
1875 "btrim" => Scalar {
1876 params!(String) => UnaryFunc::TrimWhitespace(func::TrimWhitespace) => String, 885;
1877 params!(String, String) => BinaryFunc::Trim => String, 884;
1878 },
1879 "cbrt" => Scalar {
1880 params!(Float64) => UnaryFunc::CbrtFloat64(func::CbrtFloat64) => Float64, 1345;
1881 },
1882 "ceil" => Scalar {
1883 params!(Float32) => UnaryFunc::CeilFloat32(func::CeilFloat32) => Float32, oid::FUNC_CEIL_F32_OID;
1884 params!(Float64) => UnaryFunc::CeilFloat64(func::CeilFloat64) => Float64, 2308;
1885 params!(Numeric) => UnaryFunc::CeilNumeric(func::CeilNumeric) => Numeric, 1711;
1886 },
1887 "ceiling" => Scalar {
1888 params!(Float32) => UnaryFunc::CeilFloat32(func::CeilFloat32) => Float32, oid::FUNC_CEILING_F32_OID;
1889 params!(Float64) => UnaryFunc::CeilFloat64(func::CeilFloat64) => Float64, 2320;
1890 params!(Numeric) => UnaryFunc::CeilNumeric(func::CeilNumeric) => Numeric, 2167;
1891 },
1892 "char_length" => Scalar {
1893 params!(String) => UnaryFunc::CharLength(func::CharLength) => Int32, 1381;
1894 },
1895 "col_description" => Scalar {
1897 params!(Oid, Int32) => sql_impl_func(
1898 "(SELECT description
1899 FROM pg_description
1900 WHERE objoid = $1 AND classoid = 'pg_class'::regclass AND objsubid = $2)"
1901 ) => String, 1216;
1902 },
1903 "concat" => Scalar {
1904 params!(Any...) => Operation::variadic(|ecx, cexprs| {
1905 if cexprs.is_empty() {
1906 sql_bail!("No function matches the given name and argument types. \
1907 You might need to add explicit type casts.")
1908 }
1909 let mut exprs = vec![];
1910 for expr in cexprs {
1911 exprs.push(match ecx.scalar_type(&expr) {
1912 ScalarType::Bool => expr.call_unary(UnaryFunc::CastBoolToStringNonstandard(func::CastBoolToStringNonstandard)),
1915 ScalarType::Char { length } => expr.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
1917 _ => typeconv::to_string(ecx, expr)
1918 });
1919 }
1920 Ok(HirScalarExpr::CallVariadic { func: VariadicFunc::Concat, exprs })
1921 }) => String, 3058;
1922 },
1923 "concat_ws" => Scalar {
1924 params!([String], Any...) => Operation::variadic(|ecx, cexprs| {
1925 if cexprs.len() < 2 {
1926 sql_bail!("No function matches the given name and argument types. \
1927 You might need to add explicit type casts.")
1928 }
1929 let mut exprs = vec![];
1930 for expr in cexprs {
1931 exprs.push(match ecx.scalar_type(&expr) {
1932 ScalarType::Bool => expr.call_unary(UnaryFunc::CastBoolToStringNonstandard(func::CastBoolToStringNonstandard)),
1935 ScalarType::Char { length } => expr.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
1937 _ => typeconv::to_string(ecx, expr)
1938 });
1939 }
1940 Ok(HirScalarExpr::CallVariadic { func: VariadicFunc::ConcatWs, exprs })
1941 }) => String, 3059;
1942 },
1943 "convert_from" => Scalar {
1944 params!(Bytes, String) => BinaryFunc::ConvertFrom => String, 1714;
1945 },
1946 "cos" => Scalar {
1947 params!(Float64) => UnaryFunc::Cos(func::Cos) => Float64, 1605;
1948 },
1949 "acos" => Scalar {
1950 params!(Float64) => UnaryFunc::Acos(func::Acos) => Float64, 1601;
1951 },
1952 "cosh" => Scalar {
1953 params!(Float64) => UnaryFunc::Cosh(func::Cosh) => Float64, 2463;
1954 },
1955 "acosh" => Scalar {
1956 params!(Float64) => UnaryFunc::Acosh(func::Acosh) => Float64, 2466;
1957 },
1958 "cot" => Scalar {
1959 params!(Float64) => UnaryFunc::Cot(func::Cot) => Float64, 1607;
1960 },
1961 "current_schema" => Scalar {
1962 params!() => UnmaterializableFunc::CurrentSchema => String, 1402;
1966 },
1967 "current_schemas" => Scalar {
1968 params!(Bool) => Operation::unary(|_ecx, e| {
1969 Ok(HirScalarExpr::If {
1970 cond: Box::new(e),
1971 then: Box::new(HirScalarExpr::CallUnmaterializable(UnmaterializableFunc::CurrentSchemasWithSystem)),
1972 els: Box::new(HirScalarExpr::CallUnmaterializable(UnmaterializableFunc::CurrentSchemasWithoutSystem)),
1973 })
1974 }) => ScalarType::Array(Box::new(ScalarType::String)), 1403;
1978 },
1979 "current_database" => Scalar {
1980 params!() => UnmaterializableFunc::CurrentDatabase => String, 861;
1981 },
1982 "current_catalog" => Scalar {
1983 params!() => UnmaterializableFunc::CurrentDatabase => String, oid::FUNC_CURRENT_CATALOG;
1984 },
1985 "current_setting" => Scalar {
1986 params!(String) => Operation::unary(|_ecx, name| {
1987 current_settings(name, HirScalarExpr::literal_false())
1988 }) => ScalarType::String, 2077;
1989 params!(String, Bool) => Operation::binary(|_ecx, name, missing_ok| {
1990 current_settings(name, missing_ok)
1991 }) => ScalarType::String, 3294;
1992 },
1993 "current_timestamp" => Scalar {
1994 params!() => UnmaterializableFunc::CurrentTimestamp => TimestampTz, oid::FUNC_CURRENT_TIMESTAMP_OID;
1995 },
1996 "current_user" => Scalar {
1997 params!() => UnmaterializableFunc::CurrentUser => String, 745;
1998 },
1999 "current_role" => Scalar {
2000 params!() => UnmaterializableFunc::CurrentUser => String, oid::FUNC_CURRENT_ROLE;
2001 },
2002 "user" => Scalar {
2003 params!() => UnmaterializableFunc::CurrentUser => String, oid::FUNC_USER;
2004 },
2005 "session_user" => Scalar {
2006 params!() => UnmaterializableFunc::SessionUser => String, 746;
2007 },
2008 "chr" => Scalar {
2009 params!(Int32) => UnaryFunc::Chr(func::Chr) => String, 1621;
2010 },
2011 "date" => Scalar {
2012 params!(String) => UnaryFunc::CastStringToDate(func::CastStringToDate) => Date, oid::FUNC_DATE_FROM_TEXT;
2013 params!(Timestamp) => UnaryFunc::CastTimestampToDate(func::CastTimestampToDate) => Date, 2029;
2014 params!(TimestampTz) => UnaryFunc::CastTimestampTzToDate(func::CastTimestampTzToDate) => Date, 1178;
2015 },
2016 "date_bin" => Scalar {
2017 params!(Interval, Timestamp) => Operation::binary(|ecx, stride, source| {
2018 ecx.require_feature_flag(&vars::ENABLE_BINARY_DATE_BIN)?;
2019 Ok(stride.call_binary(source, BinaryFunc::DateBinTimestamp))
2020 }) => Timestamp, oid::FUNC_MZ_DATE_BIN_UNIX_EPOCH_TS_OID;
2021 params!(Interval, TimestampTz) => Operation::binary(|ecx, stride, source| {
2022 ecx.require_feature_flag(&vars::ENABLE_BINARY_DATE_BIN)?;
2023 Ok(stride.call_binary(source, BinaryFunc::DateBinTimestampTz))
2024 }) => TimestampTz, oid::FUNC_MZ_DATE_BIN_UNIX_EPOCH_TSTZ_OID;
2025 params!(Interval, Timestamp, Timestamp) => VariadicFunc::DateBinTimestamp => Timestamp, 6177;
2026 params!(Interval, TimestampTz, TimestampTz) => VariadicFunc::DateBinTimestampTz => TimestampTz, 6178;
2027 },
2028 "extract" => Scalar {
2029 params!(String, Interval) => BinaryFunc::ExtractInterval => Numeric, 6204;
2030 params!(String, Time) => BinaryFunc::ExtractTime => Numeric, 6200;
2031 params!(String, Timestamp) => BinaryFunc::ExtractTimestamp => Numeric, 6202;
2032 params!(String, TimestampTz) => BinaryFunc::ExtractTimestampTz => Numeric, 6203;
2033 params!(String, Date) => BinaryFunc::ExtractDate => Numeric, 6199;
2034 },
2035 "date_part" => Scalar {
2036 params!(String, Interval) => BinaryFunc::DatePartInterval => Float64, 1172;
2037 params!(String, Time) => BinaryFunc::DatePartTime => Float64, 1385;
2038 params!(String, Timestamp) => BinaryFunc::DatePartTimestamp => Float64, 2021;
2039 params!(String, TimestampTz) => BinaryFunc::DatePartTimestampTz => Float64, 1171;
2040 },
2041 "date_trunc" => Scalar {
2042 params!(String, Timestamp) => BinaryFunc::DateTruncTimestamp => Timestamp, 2020;
2043 params!(String, TimestampTz) => BinaryFunc::DateTruncTimestampTz => TimestampTz, 1217;
2044 params!(String, Interval) => BinaryFunc::DateTruncInterval => Interval, 1218;
2045 },
2046 "daterange" => Scalar {
2047 params!(Date, Date) => Operation::variadic(|_ecx, mut exprs| {
2048 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2049 Ok(HirScalarExpr::CallVariadic {
2050 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Date },
2051 exprs
2052 })
2053 }) => ScalarType::Range { element_type: Box::new(ScalarType::Date)}, 3941;
2054 params!(Date, Date, String) => Operation::variadic(|_ecx, exprs| {
2055 Ok(HirScalarExpr::CallVariadic {
2056 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Date },
2057 exprs
2058 })
2059 }) => ScalarType::Range { element_type: Box::new(ScalarType::Date)}, 3942;
2060 },
2061 "degrees" => Scalar {
2062 params!(Float64) => UnaryFunc::Degrees(func::Degrees) => Float64, 1608;
2063 },
2064 "digest" => Scalar {
2065 params!(String, String) => BinaryFunc::DigestString => Bytes, oid::FUNC_PG_DIGEST_STRING;
2066 params!(Bytes, String) => BinaryFunc::DigestBytes => Bytes, oid::FUNC_PG_DIGEST_BYTES;
2067 },
2068 "exp" => Scalar {
2069 params!(Float64) => UnaryFunc::Exp(func::Exp) => Float64, 1347;
2070 params!(Numeric) => UnaryFunc::ExpNumeric(func::ExpNumeric) => Numeric, 1732;
2071 },
2072 "floor" => Scalar {
2073 params!(Float32) => UnaryFunc::FloorFloat32(func::FloorFloat32) => Float32, oid::FUNC_FLOOR_F32_OID;
2074 params!(Float64) => UnaryFunc::FloorFloat64(func::FloorFloat64) => Float64, 2309;
2075 params!(Numeric) => UnaryFunc::FloorNumeric(func::FloorNumeric) => Numeric, 1712;
2076 },
2077 "format_type" => Scalar {
2078 params!(Oid, Int32) => sql_impl_func(
2079 "CASE
2080 WHEN $1 IS NULL THEN NULL
2081 -- timestamp and timestamptz have the typmod in
2082 -- a nonstandard location that requires special
2083 -- handling.
2084 WHEN $1 = 1114 AND $2 >= 0 THEN 'timestamp(' || $2 || ') without time zone'
2085 WHEN $1 = 1184 AND $2 >= 0 THEN 'timestamp(' || $2 || ') with time zone'
2086 ELSE coalesce((SELECT pg_catalog.concat(coalesce(mz_internal.mz_type_name($1), name), mz_internal.mz_render_typmod($1, $2)) FROM mz_catalog.mz_types WHERE oid = $1), '???')
2087 END"
2088 ) => String, 1081;
2089 },
2090 "get_bit" => Scalar {
2091 params!(Bytes, Int32) => BinaryFunc::GetBit => Int32, 723;
2092 },
2093 "get_byte" => Scalar {
2094 params!(Bytes, Int32) => BinaryFunc::GetByte => Int32, 721;
2095 },
2096 "pg_get_ruledef" => Scalar {
2097 params!(Oid) => sql_impl_func("NULL::pg_catalog.text") => String, 1573;
2098 params!(Oid, Bool) => sql_impl_func("NULL::pg_catalog.text") => String, 2504;
2099 },
2100 "has_schema_privilege" => Scalar {
2101 params!(String, String, String) => sql_impl_func("has_schema_privilege(mz_internal.mz_role_oid($1), mz_internal.mz_schema_oid($2), $3)") => Bool, 2268;
2102 params!(String, Oid, String) => sql_impl_func("has_schema_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, 2269;
2103 params!(Oid, String, String) => sql_impl_func("has_schema_privilege($1, mz_internal.mz_schema_oid($2), $3)") => Bool, 2270;
2104 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_schema_privilege", "mz_schemas")) => Bool, 2271;
2105 params!(String, String) => sql_impl_func("has_schema_privilege(current_user, $1, $2)") => Bool, 2272;
2106 params!(Oid, String) => sql_impl_func("has_schema_privilege(current_user, $1, $2)") => Bool, 2273;
2107 },
2108 "has_database_privilege" => Scalar {
2109 params!(String, String, String) => sql_impl_func("has_database_privilege(mz_internal.mz_role_oid($1), mz_internal.mz_database_oid($2), $3)") => Bool, 2250;
2110 params!(String, Oid, String) => sql_impl_func("has_database_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, 2251;
2111 params!(Oid, String, String) => sql_impl_func("has_database_privilege($1, mz_internal.mz_database_oid($2), $3)") => Bool, 2252;
2112 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_database_privilege", "mz_databases")) => Bool, 2253;
2113 params!(String, String) => sql_impl_func("has_database_privilege(current_user, $1, $2)") => Bool, 2254;
2114 params!(Oid, String) => sql_impl_func("has_database_privilege(current_user, $1, $2)") => Bool, 2255;
2115 },
2116 "has_table_privilege" => Scalar {
2117 params!(String, String, String) => sql_impl_func("has_table_privilege(mz_internal.mz_role_oid($1), $2::regclass::oid, $3)") => Bool, 1922;
2118 params!(String, Oid, String) => sql_impl_func("has_table_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, 1923;
2119 params!(Oid, String, String) => sql_impl_func("has_table_privilege($1, $2::regclass::oid, $3)") => Bool, 1924;
2120 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_table_privilege", "mz_relations")) => Bool, 1925;
2121 params!(String, String) => sql_impl_func("has_table_privilege(current_user, $1, $2)") => Bool, 1926;
2122 params!(Oid, String) => sql_impl_func("has_table_privilege(current_user, $1, $2)") => Bool, 1927;
2123 },
2124 "hmac" => Scalar {
2125 params!(String, String, String) => VariadicFunc::HmacString => Bytes, oid::FUNC_PG_HMAC_STRING;
2126 params!(Bytes, Bytes, String) => VariadicFunc::HmacBytes => Bytes, oid::FUNC_PG_HMAC_BYTES;
2127 },
2128 "initcap" => Scalar {
2129 params!(String) => UnaryFunc::Initcap(func::Initcap) => String, 872;
2130 },
2131 "int4range" => Scalar {
2132 params!(Int32, Int32) => Operation::variadic(|_ecx, mut exprs| {
2133 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2134 Ok(HirScalarExpr::CallVariadic {
2135 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Int32 },
2136 exprs
2137 })
2138 }) => ScalarType::Range { element_type: Box::new(ScalarType::Int32)}, 3840;
2139 params!(Int32, Int32, String) => Operation::variadic(|_ecx, exprs| {
2140 Ok(HirScalarExpr::CallVariadic {
2141 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Int32 },
2142 exprs
2143 })
2144 }) => ScalarType::Range { element_type: Box::new(ScalarType::Int32)}, 3841;
2145 },
2146 "int8range" => Scalar {
2147 params!(Int64, Int64) => Operation::variadic(|_ecx, mut exprs| {
2148 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2149 Ok(HirScalarExpr::CallVariadic {
2150 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Int64 },
2151 exprs
2152 })
2153 }) => ScalarType::Range { element_type: Box::new(ScalarType::Int64)}, 3945;
2154 params!(Int64, Int64, String) => Operation::variadic(|_ecx, exprs| {
2155 Ok(HirScalarExpr::CallVariadic {
2156 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Int64 },
2157 exprs
2158 })
2159 }) => ScalarType::Range { element_type: Box::new(ScalarType::Int64)}, 3946;
2160 },
2161 "isempty" => Scalar {
2162 params!(RangeAny) => UnaryFunc::RangeEmpty(func::RangeEmpty) => Bool, 3850;
2163 },
2164 "jsonb_array_length" => Scalar {
2165 params!(Jsonb) => UnaryFunc::JsonbArrayLength(func::JsonbArrayLength) => Int32, 3207;
2166 },
2167 "jsonb_build_array" => Scalar {
2168 params!() => VariadicFunc::JsonbBuildArray => Jsonb, 3272;
2169 params!(Any...) => Operation::variadic(|ecx, exprs| Ok(HirScalarExpr::CallVariadic {
2170 func: VariadicFunc::JsonbBuildArray,
2171 exprs: exprs.into_iter().map(|e| typeconv::to_jsonb(ecx, e)).collect(),
2172 })) => Jsonb, 3271;
2173 },
2174 "jsonb_build_object" => Scalar {
2175 params!() => VariadicFunc::JsonbBuildObject => Jsonb, 3274;
2176 params!(Any...) => Operation::variadic(|ecx, exprs| {
2177 if exprs.len() % 2 != 0 {
2178 sql_bail!("argument list must have even number of elements")
2179 }
2180 Ok(HirScalarExpr::CallVariadic {
2181 func: VariadicFunc::JsonbBuildObject,
2182 exprs: exprs.into_iter().tuples().map(|(key, val)| {
2183 let key = typeconv::to_string(ecx, key);
2184 let val = typeconv::to_jsonb(ecx, val);
2185 vec![key, val]
2186 }).flatten().collect(),
2187 })
2188 }) => Jsonb, 3273;
2189 },
2190 "jsonb_pretty" => Scalar {
2191 params!(Jsonb) => UnaryFunc::JsonbPretty(func::JsonbPretty) => String, 3306;
2192 },
2193 "jsonb_strip_nulls" => Scalar {
2194 params!(Jsonb) => UnaryFunc::JsonbStripNulls(func::JsonbStripNulls) => Jsonb, 3262;
2195 },
2196 "jsonb_typeof" => Scalar {
2197 params!(Jsonb) => UnaryFunc::JsonbTypeof(func::JsonbTypeof) => String, 3210;
2198 },
2199 "justify_days" => Scalar {
2200 params!(Interval) => UnaryFunc::JustifyDays(func::JustifyDays) => Interval, 1295;
2201 },
2202 "justify_hours" => Scalar {
2203 params!(Interval) => UnaryFunc::JustifyHours(func::JustifyHours) => Interval, 1175;
2204 },
2205 "justify_interval" => Scalar {
2206 params!(Interval) => UnaryFunc::JustifyInterval(func::JustifyInterval) => Interval, 2711;
2207 },
2208 "left" => Scalar {
2209 params!(String, Int32) => BinaryFunc::Left => String, 3060;
2210 },
2211 "length" => Scalar {
2212 params!(Bytes) => UnaryFunc::ByteLengthBytes(func::ByteLengthBytes) => Int32, 2010;
2213 params!(String) => UnaryFunc::CharLength(func::CharLength) => Int32, 1317;
2215 params!(Bytes, String) => BinaryFunc::EncodedBytesCharLength => Int32, 1713;
2216 },
2217 "like_escape" => Scalar {
2218 params!(String, String) => BinaryFunc::LikeEscape => String, 1637;
2219 },
2220 "ln" => Scalar {
2221 params!(Float64) => UnaryFunc::Ln(func::Ln) => Float64, 1341;
2222 params!(Numeric) => UnaryFunc::LnNumeric(func::LnNumeric) => Numeric, 1734;
2223 },
2224 "log10" => Scalar {
2225 params!(Float64) => UnaryFunc::Log10(func::Log10) => Float64, 1194;
2226 params!(Numeric) => UnaryFunc::Log10Numeric(func::Log10Numeric) => Numeric, 1481;
2227 },
2228 "log" => Scalar {
2229 params!(Float64) => UnaryFunc::Log10(func::Log10) => Float64, 1340;
2230 params!(Numeric) => UnaryFunc::Log10Numeric(func::Log10Numeric) => Numeric, 1741;
2231 params!(Numeric, Numeric) => BinaryFunc::LogNumeric => Numeric, 1736;
2232 },
2233 "lower" => Scalar {
2234 params!(String) => UnaryFunc::Lower(func::Lower) => String, 870;
2235 params!(RangeAny) => UnaryFunc::RangeLower(func::RangeLower) => AnyElement, 3848;
2236 },
2237 "lower_inc" => Scalar {
2238 params!(RangeAny) => UnaryFunc::RangeLowerInc(func::RangeLowerInc) => Bool, 3851;
2239 },
2240 "lower_inf" => Scalar {
2241 params!(RangeAny) => UnaryFunc::RangeLowerInf(func::RangeLowerInf) => Bool, 3853;
2242 },
2243 "lpad" => Scalar {
2244 params!(String, Int32) => VariadicFunc::PadLeading => String, 879;
2245 params!(String, Int32, String) => VariadicFunc::PadLeading => String, 873;
2246 },
2247 "ltrim" => Scalar {
2248 params!(String) => UnaryFunc::TrimLeadingWhitespace(func::TrimLeadingWhitespace) => String, 881;
2249 params!(String, String) => BinaryFunc::TrimLeading => String, 875;
2250 },
2251 "makeaclitem" => Scalar {
2252 params!(Oid, Oid, String, Bool) => VariadicFunc::MakeAclItem => AclItem, 1365;
2253 },
2254 "make_timestamp" => Scalar {
2255 params!(Int64, Int64, Int64, Int64, Int64, Float64) => VariadicFunc::MakeTimestamp => Timestamp, 3461;
2256 },
2257 "md5" => Scalar {
2258 params!(String) => Operation::unary(move |_ecx, input| {
2259 let algorithm = HirScalarExpr::literal(Datum::String("md5"), ScalarType::String);
2260 let encoding = HirScalarExpr::literal(Datum::String("hex"), ScalarType::String);
2261 Ok(input.call_binary(algorithm, BinaryFunc::DigestString).call_binary(encoding, BinaryFunc::Encode))
2262 }) => String, 2311;
2263 params!(Bytes) => Operation::unary(move |_ecx, input| {
2264 let algorithm = HirScalarExpr::literal(Datum::String("md5"), ScalarType::String);
2265 let encoding = HirScalarExpr::literal(Datum::String("hex"), ScalarType::String);
2266 Ok(input.call_binary(algorithm, BinaryFunc::DigestBytes).call_binary(encoding, BinaryFunc::Encode))
2267 }) => String, 2321;
2268 },
2269 "mod" => Scalar {
2270 params!(Numeric, Numeric) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => Numeric, 1728;
2271 params!(Int16, Int16) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => Int16, 940;
2272 params!(Int32, Int32) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => Int32, 941;
2273 params!(Int64, Int64) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => Int64, 947;
2274 params!(UInt16, UInt16) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => UInt16, oid::FUNC_MOD_UINT16_OID;
2275 params!(UInt32, UInt32) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => UInt32, oid::FUNC_MOD_UINT32_OID;
2276 params!(UInt64, UInt64) => Operation::nullary(|_ecx| catalog_name_only!("mod")) => UInt64, oid::FUNC_MOD_UINT64_OID;
2277 },
2278 "now" => Scalar {
2279 params!() => UnmaterializableFunc::CurrentTimestamp => TimestampTz, 1299;
2280 },
2281 "numrange" => Scalar {
2282 params!(Numeric, Numeric) => Operation::variadic(|_ecx, mut exprs| {
2283 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2284 Ok(HirScalarExpr::CallVariadic {
2285 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Numeric { max_scale: None } },
2286 exprs
2287 })
2288 }) => ScalarType::Range { element_type: Box::new(ScalarType::Numeric { max_scale: None })}, 3844;
2289 params!(Numeric, Numeric, String) => Operation::variadic(|_ecx, exprs| {
2290 Ok(HirScalarExpr::CallVariadic {
2291 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Numeric { max_scale: None } },
2292 exprs
2293 })
2294 }) => ScalarType::Range { element_type: Box::new(ScalarType::Numeric { max_scale: None })}, 3845;
2295 },
2296 "octet_length" => Scalar {
2297 params!(Bytes) => UnaryFunc::ByteLengthBytes(func::ByteLengthBytes) => Int32, 720;
2298 params!(String) => UnaryFunc::ByteLengthString(func::ByteLengthString) => Int32, 1374;
2299 params!(Char) => Operation::unary(|ecx, e| {
2300 let length = ecx.scalar_type(&e).unwrap_char_length();
2301 Ok(e.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
2302 .call_unary(UnaryFunc::ByteLengthString(func::ByteLengthString))
2303 )
2304 }) => Int32, 1375;
2305 },
2306 "obj_description" => Scalar {
2310 params!(Oid, String) => sql_impl_func(&format!(
2311 "(SELECT description FROM pg_description
2312 WHERE objoid = $1
2313 AND classoid = (
2314 SELECT oid FROM pg_class WHERE relname = $2 AND relnamespace = {})
2315 AND objsubid = 0)",
2316 oid::SCHEMA_PG_CATALOG_OID
2317 )) => String, 1215;
2318 },
2319 "pg_column_size" => Scalar {
2320 params!(Any) => UnaryFunc::PgColumnSize(func::PgColumnSize) => Int32, 1269;
2321 },
2322 "pg_size_pretty" => Scalar {
2323 params!(Numeric) => UnaryFunc::PgSizePretty(func::PgSizePretty) => String, 3166;
2324 },
2325 "mz_row_size" => Scalar {
2326 params!(Any) => Operation::unary(|ecx, e| {
2327 let s = ecx.scalar_type(&e);
2328 if !matches!(s, ScalarType::Record{..}) {
2329 sql_bail!("mz_row_size requires a record type");
2330 }
2331 Ok(e.call_unary(UnaryFunc::MzRowSize(func::MzRowSize)))
2332 }) => Int32, oid::FUNC_MZ_ROW_SIZE;
2333 },
2334 "parse_ident" => Scalar {
2335 params!(String) => Operation::unary(|_ecx, ident| {
2336 Ok(ident.call_binary(HirScalarExpr::literal_true(), BinaryFunc::ParseIdent))
2337 }) => ScalarType::Array(Box::new(ScalarType::String)),
2338 oid::FUNC_PARSE_IDENT_DEFAULT_STRICT;
2339 params!(String, Bool) => BinaryFunc::ParseIdent
2340 => ScalarType::Array(Box::new(ScalarType::String)), 1268;
2341 },
2342 "pg_encoding_to_char" => Scalar {
2343 params!(Int64) => sql_impl_func("CASE WHEN $1 = 6 THEN 'UTF8' ELSE NULL END") => String, 1597;
2346 },
2347 "pg_backend_pid" => Scalar {
2348 params!() => UnmaterializableFunc::PgBackendPid => Int32, 2026;
2349 },
2350 "pg_get_constraintdef" => Scalar {
2356 params!(Oid) => Operation::unary(|_ecx, _oid|
2357 Ok(HirScalarExpr::literal_null(ScalarType::String))) => String, 1387;
2358 params!(Oid, Bool) => Operation::binary(|_ecx, _oid, _pretty|
2359 Ok(HirScalarExpr::literal_null(ScalarType::String))) => String, 2508;
2360 },
2361 "pg_get_indexdef" => Scalar {
2365 params!(Oid) => sql_impl_func(
2366 "(SELECT 'CREATE INDEX ' || i.name || ' ON ' || r.name || ' USING arrangement (' || (
2367 SELECT pg_catalog.string_agg(cols.col_exp, ',' ORDER BY cols.index_position)
2368 FROM (
2369 SELECT c.name AS col_exp, ic.index_position
2370 FROM mz_catalog.mz_index_columns AS ic
2371 JOIN mz_catalog.mz_indexes AS i2 ON ic.index_id = i2.id
2372 JOIN mz_catalog.mz_columns AS c ON i2.on_id = c.id AND ic.on_position = c.position
2373 WHERE ic.index_id = i.id AND ic.on_expression IS NULL
2374 UNION
2375 SELECT ic.on_expression AS col_exp, ic.index_position
2376 FROM mz_catalog.mz_index_columns AS ic
2377 WHERE ic.index_id = i.id AND ic.on_expression IS NOT NULL
2378 ) AS cols
2379 ) || ')'
2380 FROM mz_catalog.mz_indexes AS i
2381 JOIN mz_catalog.mz_relations AS r ON i.on_id = r.id
2382 WHERE i.oid = $1)"
2383 ) => String, 1643;
2384 params!(Oid, Int32, Bool) => sql_impl_func(
2387 "(SELECT CASE WHEN $2 = 0 THEN pg_catalog.pg_get_indexdef($1) ELSE
2388 (SELECT c.name
2389 FROM mz_catalog.mz_indexes AS i
2390 JOIN mz_catalog.mz_index_columns AS ic ON i.id = ic.index_id
2391 JOIN mz_catalog.mz_columns AS c ON i.on_id = c.id AND ic.on_position = c.position
2392 WHERE i.oid = $1 AND ic.on_expression IS NULL AND ic.index_position = $2
2393 UNION
2394 SELECT ic.on_expression
2395 FROM mz_catalog.mz_indexes AS i
2396 JOIN mz_catalog.mz_index_columns AS ic ON i.id = ic.index_id
2397 WHERE i.oid = $1 AND ic.on_expression IS NOT NULL AND ic.index_position = $2)
2398 END)"
2399 ) => String, 2507;
2400 },
2401 "pg_get_viewdef" => Scalar {
2404 params!(String) => sql_impl_func(
2405 "(SELECT definition FROM mz_catalog.mz_views WHERE name = $1)"
2406 ) => String, 1640;
2407 params!(Oid) => sql_impl_func(
2408 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2409 ) => String, 1641;
2410 params!(String, Bool) => sql_impl_func(
2411 "(SELECT definition FROM mz_catalog.mz_views WHERE name = $1)"
2412 ) => String, 2505;
2413 params!(Oid, Bool) => sql_impl_func(
2414 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2415 ) => String, 2506;
2416 params!(Oid, Int32) => sql_impl_func(
2417 "(SELECT definition FROM mz_catalog.mz_views WHERE oid = $1)"
2418 ) => String, 3159;
2419 },
2420 "pg_get_expr" => Scalar {
2428 params!(String, Oid) => Operation::binary(|_ecx, l, _r| Ok(l)) => String, 1716;
2429 params!(String, Oid, Bool) => Operation::variadic(move |_ecx, mut args| Ok(args.remove(0))) => String, 2509;
2430 },
2431 "pg_get_userbyid" => Scalar {
2432 params!(Oid) => sql_impl_func(
2433 "CASE \
2434 WHEN $1 IS NULL THEN NULL \
2435 ELSE COALESCE(\
2436 (SELECT name FROM mz_catalog.mz_roles WHERE oid = $1),\
2437 'unknown (OID=' || $1 || ')'\
2438 ) \
2439 END"
2440 ) => String, 1642;
2441 },
2442 "pg_has_role" => Scalar {
2449 params!(String, String, String) => sql_impl_func("pg_has_role(mz_internal.mz_role_oid($1), mz_internal.mz_role_oid($2), $3)") => Bool, 2705;
2450 params!(String, Oid, String) => sql_impl_func("pg_has_role(mz_internal.mz_role_oid($1), $2, $3)") => Bool, 2706;
2451 params!(Oid, String, String) => sql_impl_func("pg_has_role($1, mz_internal.mz_role_oid($2), $3)") => Bool, 2707;
2452 params!(Oid, Oid, String) => sql_impl_func(
2453 "CASE
2454 -- We need to validate the privilege to return a proper error before anything
2455 -- else.
2456 WHEN NOT mz_internal.mz_validate_role_privilege($3)
2457 OR $1 IS NULL
2458 OR $2 IS NULL
2459 OR $3 IS NULL
2460 THEN NULL
2461 WHEN $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
2462 OR $2 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
2463 THEN false
2464 ELSE $2::text IN (SELECT UNNEST(mz_internal.mz_role_oid_memberships() -> $1::text))
2465 END",
2466 ) => Bool, 2708;
2467 params!(String, String) => sql_impl_func("pg_has_role(current_user, $1, $2)") => Bool, 2709;
2468 params!(Oid, String) => sql_impl_func("pg_has_role(current_user, $1, $2)") => Bool, 2710;
2469 },
2470 "pg_is_in_recovery" => Scalar {
2473 params!() => Operation::nullary(|_ecx| {
2474 Ok(HirScalarExpr::literal_false())
2475 }) => Bool, 3810;
2476 },
2477 "pg_postmaster_start_time" => Scalar {
2478 params!() => UnmaterializableFunc::PgPostmasterStartTime => TimestampTz, 2560;
2479 },
2480 "pg_relation_size" => Scalar {
2481 params!(RegClass, String) => sql_impl_func("CASE WHEN $1 IS NULL OR $2 IS NULL THEN NULL ELSE -1::pg_catalog.int8 END") => Int64, 2332;
2482 params!(RegClass) => sql_impl_func("CASE WHEN $1 IS NULL THEN NULL ELSE -1::pg_catalog.int8 END") => Int64, 2325;
2483 },
2484 "pg_stat_get_numscans" => Scalar {
2485 params!(Oid) => sql_impl_func("CASE WHEN $1 IS NULL THEN NULL ELSE -1::pg_catalog.int8 END") => Int64, 1928;
2486 },
2487 "pg_table_is_visible" => Scalar {
2488 params!(Oid) => sql_impl_func(
2489 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2490 FROM mz_catalog.mz_objects o JOIN mz_catalog.mz_schemas s ON o.schema_id = s.id
2491 WHERE o.oid = $1)"
2492 ) => Bool, 2079;
2493 },
2494 "pg_type_is_visible" => Scalar {
2495 params!(Oid) => sql_impl_func(
2496 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2497 FROM mz_catalog.mz_types t JOIN mz_catalog.mz_schemas s ON t.schema_id = s.id
2498 WHERE t.oid = $1)"
2499 ) => Bool, 2080;
2500 },
2501 "pg_function_is_visible" => Scalar {
2502 params!(Oid) => sql_impl_func(
2503 "(SELECT s.name = ANY(pg_catalog.current_schemas(true))
2504 FROM mz_catalog.mz_functions f JOIN mz_catalog.mz_schemas s ON f.schema_id = s.id
2505 WHERE f.oid = $1)"
2506 ) => Bool, 2081;
2507 },
2508 "pg_tablespace_location" => Scalar {
2512 params!(Oid) => Operation::unary(|_ecx, _e| {
2513 Ok(HirScalarExpr::literal_null(ScalarType::String))
2514 }) => String, 3778;
2515 },
2516 "pg_typeof" => Scalar {
2517 params!(Any) => Operation::new(|ecx, exprs, params, _order_by| {
2518 let name = match ecx.scalar_type(&exprs[0]) {
2520 CoercibleScalarType::Uncoerced => "unknown".to_string(),
2521 CoercibleScalarType::Record(_) => "record".to_string(),
2522 CoercibleScalarType::Coerced(ty) => ecx.humanize_scalar_type(&ty, true),
2523 };
2524
2525 coerce_args_to_types(ecx, exprs, params)?;
2529
2530 Ok(HirScalarExpr::literal(Datum::String(&name), ScalarType::String))
2535 }) => String, 1619;
2536 },
2537 "position" => Scalar {
2538 params!(String, String) => BinaryFunc::Position => Int32, 849;
2539 },
2540 "pow" => Scalar {
2541 params!(Float64, Float64) => Operation::nullary(|_ecx| catalog_name_only!("pow")) => Float64, 1346;
2542 },
2543 "power" => Scalar {
2544 params!(Float64, Float64) => BinaryFunc::Power => Float64, 1368;
2545 params!(Numeric, Numeric) => BinaryFunc::PowerNumeric => Numeric, 2169;
2546 },
2547 "quote_ident" => Scalar {
2548 params!(String) => UnaryFunc::QuoteIdent(func::QuoteIdent) => String, 1282;
2549 },
2550 "radians" => Scalar {
2551 params!(Float64) => UnaryFunc::Radians(func::Radians) => Float64, 1609;
2552 },
2553 "repeat" => Scalar {
2554 params!(String, Int32) => BinaryFunc::RepeatString => String, 1622;
2555 },
2556 "regexp_match" => Scalar {
2557 params!(String, String) => VariadicFunc::RegexpMatch => ScalarType::Array(Box::new(ScalarType::String)), 3396;
2558 params!(String, String, String) => VariadicFunc::RegexpMatch => ScalarType::Array(Box::new(ScalarType::String)), 3397;
2559 },
2560 "replace" => Scalar {
2561 params!(String, String, String) => VariadicFunc::Replace => String, 2087;
2562 },
2563 "right" => Scalar {
2564 params!(String, Int32) => BinaryFunc::Right => String, 3061;
2565 },
2566 "round" => Scalar {
2567 params!(Float32) => UnaryFunc::RoundFloat32(func::RoundFloat32) => Float32, oid::FUNC_ROUND_F32_OID;
2568 params!(Float64) => UnaryFunc::RoundFloat64(func::RoundFloat64) => Float64, 1342;
2569 params!(Numeric) => UnaryFunc::RoundNumeric(func::RoundNumeric) => Numeric, 1708;
2570 params!(Numeric, Int32) => BinaryFunc::RoundNumeric => Numeric, 1707;
2571 },
2572 "rtrim" => Scalar {
2573 params!(String) => UnaryFunc::TrimTrailingWhitespace(func::TrimTrailingWhitespace) => String, 882;
2574 params!(String, String) => BinaryFunc::TrimTrailing => String, 876;
2575 },
2576 "sha224" => Scalar {
2577 params!(Bytes) => digest("sha224") => Bytes, 3419;
2578 },
2579 "sha256" => Scalar {
2580 params!(Bytes) => digest("sha256") => Bytes, 3420;
2581 },
2582 "sha384" => Scalar {
2583 params!(Bytes) => digest("sha384") => Bytes, 3421;
2584 },
2585 "sha512" => Scalar {
2586 params!(Bytes) => digest("sha512") => Bytes, 3422;
2587 },
2588 "sin" => Scalar {
2589 params!(Float64) => UnaryFunc::Sin(func::Sin) => Float64, 1604;
2590 },
2591 "asin" => Scalar {
2592 params!(Float64) => UnaryFunc::Asin(func::Asin) => Float64, 1600;
2593 },
2594 "sinh" => Scalar {
2595 params!(Float64) => UnaryFunc::Sinh(func::Sinh) => Float64, 2462;
2596 },
2597 "asinh" => Scalar {
2598 params!(Float64) => UnaryFunc::Asinh(func::Asinh) => Float64, 2465;
2599 },
2600 "split_part" => Scalar {
2601 params!(String, String, Int32) => VariadicFunc::SplitPart => String, 2088;
2602 },
2603 "stddev" => Scalar {
2604 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Float64, 2157;
2605 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Float64, 2158;
2606 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, 2156;
2607 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, 2155;
2608 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, 2154;
2609 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, oid::FUNC_STDDEV_UINT16_OID;
2610 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, oid::FUNC_STDDEV_UINT32_OID;
2611 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("stddev")) => Numeric, oid::FUNC_STDDEV_UINT64_OID;
2612 },
2613 "stddev_pop" => Scalar {
2614 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Float64, 2727;
2615 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Float64, 2728;
2616 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, 2726;
2617 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, 2725;
2618 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, 2724;
2619 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, oid::FUNC_STDDEV_POP_UINT16_OID;
2620 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, oid::FUNC_STDDEV_POP_UINT32_OID;
2621 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_pop")) => Numeric, oid::FUNC_STDDEV_POP_UINT64_OID;
2622 },
2623 "stddev_samp" => Scalar {
2624 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Float64, 2715;
2625 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Float64, 2716;
2626 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, 2714;
2627 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, 2713;
2628 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, 2712;
2629 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, oid::FUNC_STDDEV_SAMP_UINT16_OID;
2630 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, oid::FUNC_STDDEV_SAMP_UINT32_OID;
2631 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("stddev_samp")) => Numeric, oid::FUNC_STDDEV_SAMP_UINT64_OID;
2632 },
2633 "substr" => Scalar {
2634 params!(String, Int32) => VariadicFunc::Substr => String, 883;
2635 params!(String, Int32, Int32) => VariadicFunc::Substr => String, 877;
2636 },
2637 "substring" => Scalar {
2638 params!(String, Int32) => VariadicFunc::Substr => String, 937;
2639 params!(String, Int32, Int32) => VariadicFunc::Substr => String, 936;
2640 },
2641 "sqrt" => Scalar {
2642 params!(Float64) => UnaryFunc::SqrtFloat64(func::SqrtFloat64) => Float64, 1344;
2643 params!(Numeric) => UnaryFunc::SqrtNumeric(func::SqrtNumeric) => Numeric, 1730;
2644 },
2645 "tan" => Scalar {
2646 params!(Float64) => UnaryFunc::Tan(func::Tan) => Float64, 1606;
2647 },
2648 "atan" => Scalar {
2649 params!(Float64) => UnaryFunc::Atan(func::Atan) => Float64, 1602;
2650 },
2651 "tanh" => Scalar {
2652 params!(Float64) => UnaryFunc::Tanh(func::Tanh) => Float64, 2464;
2653 },
2654 "atanh" => Scalar {
2655 params!(Float64) => UnaryFunc::Atanh(func::Atanh) => Float64, 2467;
2656 },
2657 "age" => Scalar {
2658 params!(Timestamp, Timestamp) => BinaryFunc::AgeTimestamp => Interval, 2058;
2659 params!(TimestampTz, TimestampTz) => BinaryFunc::AgeTimestampTz => Interval, 1199;
2660 },
2661 "timezone" => Scalar {
2662 params!(String, Timestamp) => BinaryFunc::TimezoneTimestamp => TimestampTz, 2069;
2663 params!(String, TimestampTz) => BinaryFunc::TimezoneTimestampTz => Timestamp, 1159;
2664 params!(String, Time) => Operation::binary(|ecx, lhs, rhs| {
2666 ecx.require_feature_flag(&ENABLE_TIME_AT_TIME_ZONE)?;
2680 Ok(HirScalarExpr::CallVariadic {
2681 func: VariadicFunc::TimezoneTime,
2682 exprs: vec![
2683 lhs,
2684 rhs,
2685 HirScalarExpr::CallUnmaterializable(UnmaterializableFunc::CurrentTimestamp),
2686 ],
2687 })
2688 }) => Time, 2037;
2689 params!(Interval, Timestamp) => BinaryFunc::TimezoneIntervalTimestamp => TimestampTz, 2070;
2690 params!(Interval, TimestampTz) => BinaryFunc::TimezoneIntervalTimestampTz => Timestamp, 1026;
2691 params!(Interval, Time) => BinaryFunc::TimezoneIntervalTime => Time, 2038;
2693 },
2694 "to_char" => Scalar {
2695 params!(Timestamp, String) => BinaryFunc::ToCharTimestamp => String, 2049;
2696 params!(TimestampTz, String) => BinaryFunc::ToCharTimestampTz => String, 1770;
2697 },
2698 "to_jsonb" => Scalar {
2709 params!(Any) => Operation::unary(|ecx, e| {
2710 let e = match ecx.scalar_type(&e) {
2712 ScalarType::Char { length } => e.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
2713 _ => e,
2714 };
2715 Ok(typeconv::to_jsonb(ecx, e))
2716 }) => Jsonb, 3787;
2717 },
2718 "to_timestamp" => Scalar {
2719 params!(Float64) => UnaryFunc::ToTimestamp(func::ToTimestamp) => TimestampTz, 1158;
2720 },
2721 "translate" => Scalar {
2722 params!(String, String, String) => VariadicFunc::Translate => String, 878;
2723 },
2724 "trunc" => Scalar {
2725 params!(Float32) => UnaryFunc::TruncFloat32(func::TruncFloat32) => Float32, oid::FUNC_TRUNC_F32_OID;
2726 params!(Float64) => UnaryFunc::TruncFloat64(func::TruncFloat64) => Float64, 1343;
2727 params!(Numeric) => UnaryFunc::TruncNumeric(func::TruncNumeric) => Numeric, 1710;
2728 },
2729 "tsrange" => Scalar {
2730 params!(Timestamp, Timestamp) => Operation::variadic(|_ecx, mut exprs| {
2731 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2732 Ok(HirScalarExpr::CallVariadic {
2733 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Timestamp {precision: None}},
2734 exprs
2735 })
2736 }) => ScalarType::Range { element_type: Box::new(ScalarType::Timestamp { precision: None})}, 3933;
2737 params!(Timestamp, Timestamp, String) => Operation::variadic(|_ecx, exprs| {
2738 Ok(HirScalarExpr::CallVariadic {
2739 func: VariadicFunc::RangeCreate { elem_type: ScalarType::Timestamp {precision: None}},
2740 exprs
2741 })
2742 }) => ScalarType::Range { element_type: Box::new(ScalarType::Timestamp { precision: None})}, 3934;
2743 },
2744 "tstzrange" => Scalar {
2745 params!(TimestampTz, TimestampTz) => Operation::variadic(|_ecx, mut exprs| {
2746 exprs.push(HirScalarExpr::literal(Datum::String("[)"), ScalarType::String));
2747 Ok(HirScalarExpr::CallVariadic {
2748 func: VariadicFunc::RangeCreate { elem_type: ScalarType::TimestampTz {precision: None}},
2749 exprs
2750 })
2751 }) => ScalarType::Range { element_type: Box::new(ScalarType::TimestampTz { precision: None})}, 3937;
2752 params!(TimestampTz, TimestampTz, String) => Operation::variadic(|_ecx, exprs| {
2753 Ok(HirScalarExpr::CallVariadic {
2754 func: VariadicFunc::RangeCreate { elem_type: ScalarType::TimestampTz {precision: None}},
2755 exprs
2756 })
2757 }) => ScalarType::Range { element_type: Box::new(ScalarType::TimestampTz { precision: None})}, 3938;
2758 },
2759 "upper" => Scalar {
2760 params!(String) => UnaryFunc::Upper(func::Upper) => String, 871;
2761 params!(RangeAny) => UnaryFunc::RangeUpper(func::RangeUpper) => AnyElement, 3849;
2762 },
2763 "upper_inc" => Scalar {
2764 params!(RangeAny) => UnaryFunc::RangeUpperInc(func::RangeUpperInc) => Bool, 3852;
2765 },
2766 "upper_inf" => Scalar {
2767 params!(RangeAny) => UnaryFunc::RangeUpperInf(func::RangeUpperInf) => Bool, 3854;
2768 },
2769 "uuid_generate_v5" => Scalar {
2770 params!(Uuid, String) => BinaryFunc::UuidGenerateV5 => Uuid, oid::FUNC_PG_UUID_GENERATE_V5;
2771 },
2772 "variance" => Scalar {
2773 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Float64, 2151;
2774 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Float64, 2152;
2775 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, 2150;
2776 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, 2149;
2777 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, 2148;
2778 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, oid::FUNC_VARIANCE_UINT16_OID;
2779 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, oid::FUNC_VARIANCE_UINT32_OID;
2780 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("variance")) => Numeric, oid::FUNC_VARIANCE_UINT64_OID;
2781 },
2782 "var_pop" => Scalar {
2783 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Float64, 2721;
2784 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Float64, 2722;
2785 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, 2720;
2786 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, 2719;
2787 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, 2718;
2788 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, oid::FUNC_VAR_POP_UINT16_OID;
2789 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, oid::FUNC_VAR_POP_UINT32_OID;
2790 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("var_pop")) => Numeric, oid::FUNC_VAR_POP_UINT64_OID;
2791 },
2792 "var_samp" => Scalar {
2793 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Float64, 2644;
2794 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Float64, 2645;
2795 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, 2643;
2796 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, 2642;
2797 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, 2641;
2798 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, oid::FUNC_VAR_SAMP_UINT16_OID;
2799 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, oid::FUNC_VAR_SAMP_UINT32_OID;
2800 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("var_samp")) => Numeric, oid::FUNC_VAR_SAMP_UINT64_OID;
2801 },
2802 "version" => Scalar {
2803 params!() => UnmaterializableFunc::Version => String, 89;
2804 },
2805
2806 "aclitemin" => Scalar {
2808 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("aclitemin")) => AclItem, 1031;
2809 },
2810 "any_in" => Scalar {
2811 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("any_in")) => Any, 2294;
2812 },
2813 "anyarray_in" => Scalar {
2814 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anyarray_in")) => ArrayAny, 2296;
2815 },
2816 "anycompatible_in" => Scalar {
2817 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anycompatible_in")) => AnyCompatible, 5086;
2818 },
2819 "anycompatiblearray_in" => Scalar {
2820 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anycompatiblearray_in")) => ArrayAnyCompatible, 5088;
2821 },
2822 "anycompatiblenonarray_in" => Scalar {
2823 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anycompatiblenonarray_in")) => NonVecAnyCompatible, 5092;
2824 },
2825 "anycompatiblerange_in" => Scalar {
2826 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anycompatiblerange_in")) => RangeAnyCompatible, 5094;
2827 },
2828 "anyelement_in" => Scalar {
2829 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anyelement_in")) => AnyElement, 2312;
2830 },
2831 "anynonarray_in" => Scalar {
2832 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anynonarray_in")) => NonVecAny, 2777;
2833 },
2834 "anyrange_in" => Scalar {
2835 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("anyrange_in")) => RangeAny, 3832;
2836 },
2837 "array_in" => Scalar {
2838 params!(String, Oid, Int32) =>
2839 Operation::variadic(|_ecx, _exprs| bail_unsupported!("array_in")) => ArrayAny, 750;
2840 },
2841 "boolin" => Scalar {
2842 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("boolin")) => Bool, 1242;
2843 },
2844 "bpcharin" => Scalar {
2845 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("bpcharin")) => Char, 1044;
2846 },
2847 "byteain" => Scalar {
2848 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("byteain")) => Bytes, 1244;
2849 },
2850 "charin" => Scalar {
2851 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("charin")) => PgLegacyChar, 1245;
2852 },
2853 "date_in" => Scalar {
2854 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("date_in")) => Date, 1084;
2855 },
2856 "float4in" => Scalar {
2857 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("float4in")) => Float32, 200;
2858 },
2859 "float8in" => Scalar {
2860 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("float8in")) => Float64, 214;
2861 },
2862 "int2in" => Scalar {
2863 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("int2in")) => Int16, 38;
2864 },
2865 "int2vectorin" => Scalar {
2866 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("int2vectorin")) => Int2Vector, 40;
2867 },
2868 "int4in" => Scalar {
2869 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("int4in")) => Int32, 42;
2870 },
2871 "int8in" => Scalar {
2872 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("int8in")) => Int64, 460;
2873 },
2874 "internal_in" => Scalar {
2875 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("internal_in")) => Internal, 2304;
2876 },
2877 "interval_in" => Scalar {
2878 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("interval_in")) => Interval, 1160;
2879 },
2880 "jsonb_in" => Scalar {
2881 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("jsonb_in")) => Jsonb, 3806;
2882 },
2883 "namein" => Scalar {
2884 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("namein")) => PgLegacyName, 34;
2885 },
2886 "numeric_in" => Scalar {
2887 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("numeric_in")) => Numeric, 1701;
2888 },
2889 "oidin" => Scalar {
2890 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("oidin")) => Oid, 1798;
2891 },
2892 "range_in" => Scalar {
2893 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("range_in")) => RangeAny, 3834;
2894 },
2895 "record_in" => Scalar {
2896 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("record_in")) => RecordAny, 2290;
2897 },
2898 "regclassin" => Scalar {
2899 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("regclassin")) => RegClass, 2218;
2900 },
2901 "regprocin" => Scalar {
2902 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("regprocin")) => RegProc, 44;
2903 },
2904 "regtypein" => Scalar {
2905 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("regtypein")) => RegType, 2220;
2906 },
2907 "textin" => Scalar {
2908 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("textin")) => String, 46;
2909 },
2910 "time_in" => Scalar {
2911 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("time_in")) => Time, 1143;
2912 },
2913 "timestamp_in" => Scalar {
2914 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("timestamp_in")) => Timestamp, 1312;
2915 },
2916 "timestamptz_in" => Scalar {
2917 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("timestamptz_in")) => TimestampTz, 1150;
2918 },
2919 "varcharin" => Scalar {
2920 params!(String, Oid, Int32) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("varcharin")) => VarChar, 1046;
2921 },
2922 "uuid_in" => Scalar {
2923 params!(String) => Operation::variadic(|_ecx, _exprs| bail_unsupported!("uuid_in")) => Uuid, 2952;
2924 },
2925 "boolrecv" => Scalar {
2926 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("boolrecv")) => Bool, 2436;
2927 },
2928 "textrecv" => Scalar {
2929 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("textrecv")) => String, 2414;
2930 },
2931 "anyarray_recv" => Scalar {
2932 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("anyarray_recv")) => ArrayAny, 2502;
2933 },
2934 "bytearecv" => Scalar {
2935 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("bytearecv")) => Bytes, 2412;
2936 },
2937 "bpcharrecv" => Scalar {
2938 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("bpcharrecv")) => Char, 2430;
2939 },
2940 "charrecv" => Scalar {
2941 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("charrecv")) => PgLegacyChar, 2434;
2942 },
2943 "date_recv" => Scalar {
2944 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("date_recv")) => Date, 2468;
2945 },
2946 "float4recv" => Scalar {
2947 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("float4recv")) => Float32, 2424;
2948 },
2949 "float8recv" => Scalar {
2950 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("float8recv")) => Float64, 2426;
2951 },
2952 "int4recv" => Scalar {
2953 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("int4recv")) => Int32, 2406;
2954 },
2955 "int8recv" => Scalar {
2956 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("int8recv")) => Int64, 2408;
2957 },
2958 "interval_recv" => Scalar {
2959 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("interval_recv")) => Interval, 2478;
2960 },
2961 "jsonb_recv" => Scalar {
2962 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("jsonb_recv")) => Jsonb, 3805;
2963 },
2964 "namerecv" => Scalar {
2965 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("namerecv")) => PgLegacyName, 2422;
2966 },
2967 "numeric_recv" => Scalar {
2968 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("numeric_recv")) => Numeric, 2460;
2969 },
2970 "oidrecv" => Scalar {
2971 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("oidrecv")) => Oid, 2418;
2972 },
2973 "record_recv" => Scalar {
2974 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("recordrerecord_recvcv")) => RecordAny, 2402;
2975 },
2976 "regclassrecv" => Scalar {
2977 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("regclassrecv")) => RegClass, 2452;
2978 },
2979 "regprocrecv" => Scalar {
2980 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("regprocrecv")) => RegProc, 2444;
2981 },
2982 "regtyperecv" => Scalar {
2983 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("regtyperecv")) => RegType, 2454;
2984 },
2985 "int2recv" => Scalar {
2986 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("int2recv")) => Int16, 2404;
2987 },
2988 "time_recv" => Scalar {
2989 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("time_recv")) => Time, 2470;
2990 },
2991 "timestamp_recv" => Scalar {
2992 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("timestamp_recv")) => Timestamp, 2474;
2993 },
2994 "timestamptz_recv" => Scalar {
2995 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("timestamptz_recv")) => TimestampTz, 2476;
2996 },
2997 "uuid_recv" => Scalar {
2998 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("uuid_recv")) => Uuid, 2961;
2999 },
3000 "varcharrecv" => Scalar {
3001 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("varcharrecv")) => VarChar, 2432;
3002 },
3003 "int2vectorrecv" => Scalar {
3004 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("int2vectorrecv")) => Int2Vector, 2410;
3005 },
3006 "anycompatiblearray_recv" => Scalar {
3007 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("anycompatiblearray_recv")) => ArrayAnyCompatible, 5090;
3008 },
3009 "array_recv" => Scalar {
3010 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("array_recv")) => ArrayAny, 2400;
3011 },
3012 "range_recv" => Scalar {
3013 params!(Internal) => Operation::nullary(|_ecx| catalog_name_only!("range_recv")) => RangeAny, 3836;
3014 },
3015
3016
3017 "array_agg" => Aggregate {
3019 params!(NonVecAny) => Operation::unary_ordered(|ecx, e, order_by| {
3020 let elem_type = ecx.scalar_type(&e);
3021
3022 let elem_type = match elem_type.array_of_self_elem_type() {
3023 Ok(elem_type) => elem_type,
3024 Err(elem_type) => bail_unsupported!(
3025 format!("array_agg on {}", ecx.humanize_scalar_type(&elem_type, false))
3026 ),
3027 };
3028
3029 let e_arr = HirScalarExpr::CallVariadic{
3032 func: VariadicFunc::ArrayCreate { elem_type },
3033 exprs: vec![e],
3034 };
3035 Ok((e_arr, AggregateFunc::ArrayConcat { order_by }))
3036 }) => ArrayAny, 2335;
3037 params!(ArrayAny) => Operation::unary(|_ecx, _e| bail_unsupported!("array_agg on arrays")) => ArrayAny, 4053;
3038 },
3039 "bool_and" => Aggregate {
3040 params!(Bool) => Operation::nullary(|_ecx| catalog_name_only!("bool_and")) => Bool, 2517;
3041 },
3042 "bool_or" => Aggregate {
3043 params!(Bool) => Operation::nullary(|_ecx| catalog_name_only!("bool_or")) => Bool, 2518;
3044 },
3045 "count" => Aggregate {
3046 params!() => Operation::nullary(|_ecx| {
3047 Ok((HirScalarExpr::literal_true(), AggregateFunc::Count))
3051 }) => Int64, 2803;
3052 params!(Any) => AggregateFunc::Count => Int64, 2147;
3053 },
3054 "max" => Aggregate {
3055 params!(Bool) => AggregateFunc::MaxBool => Bool, oid::FUNC_MAX_BOOL_OID;
3056 params!(Int16) => AggregateFunc::MaxInt16 => Int16, 2117;
3057 params!(Int32) => AggregateFunc::MaxInt32 => Int32, 2116;
3058 params!(Int64) => AggregateFunc::MaxInt64 => Int64, 2115;
3059 params!(UInt16) => AggregateFunc::MaxUInt16 => UInt16, oid::FUNC_MAX_UINT16_OID;
3060 params!(UInt32) => AggregateFunc::MaxUInt32 => UInt32, oid::FUNC_MAX_UINT32_OID;
3061 params!(UInt64) => AggregateFunc::MaxUInt64 => UInt64, oid::FUNC_MAX_UINT64_OID;
3062 params!(MzTimestamp) => AggregateFunc::MaxMzTimestamp => MzTimestamp, oid::FUNC_MAX_MZ_TIMESTAMP_OID;
3063 params!(Float32) => AggregateFunc::MaxFloat32 => Float32, 2119;
3064 params!(Float64) => AggregateFunc::MaxFloat64 => Float64, 2120;
3065 params!(String) => AggregateFunc::MaxString => String, 2129;
3066 params!(Char) => AggregateFunc::MaxString => Char, 2244;
3068 params!(Date) => AggregateFunc::MaxDate => Date, 2122;
3069 params!(Timestamp) => AggregateFunc::MaxTimestamp => Timestamp, 2126;
3070 params!(TimestampTz) => AggregateFunc::MaxTimestampTz => TimestampTz, 2127;
3071 params!(Numeric) => AggregateFunc::MaxNumeric => Numeric, oid::FUNC_MAX_NUMERIC_OID;
3072 params!(Interval) => AggregateFunc::MaxInterval => Interval, 2128;
3073 params!(Time) => AggregateFunc::MaxTime => Time, 2123;
3074 },
3075 "min" => Aggregate {
3076 params!(Bool) => AggregateFunc::MinBool => Bool, oid::FUNC_MIN_BOOL_OID;
3077 params!(Int16) => AggregateFunc::MinInt16 => Int16, 2133;
3078 params!(Int32) => AggregateFunc::MinInt32 => Int32, 2132;
3079 params!(Int64) => AggregateFunc::MinInt64 => Int64, 2131;
3080 params!(UInt16) => AggregateFunc::MinUInt16 => UInt16, oid::FUNC_MIN_UINT16_OID;
3081 params!(UInt32) => AggregateFunc::MinUInt32 => UInt32, oid::FUNC_MIN_UINT32_OID;
3082 params!(UInt64) => AggregateFunc::MinUInt64 => UInt64, oid::FUNC_MIN_UINT64_OID;
3083 params!(MzTimestamp) => AggregateFunc::MinMzTimestamp => MzTimestamp, oid::FUNC_MIN_MZ_TIMESTAMP_OID;
3084 params!(Float32) => AggregateFunc::MinFloat32 => Float32, 2135;
3085 params!(Float64) => AggregateFunc::MinFloat64 => Float64, 2136;
3086 params!(String) => AggregateFunc::MinString => String, 2145;
3087 params!(Char) => AggregateFunc::MinString => Char, 2245;
3089 params!(Date) => AggregateFunc::MinDate => Date, 2138;
3090 params!(Timestamp) => AggregateFunc::MinTimestamp => Timestamp, 2142;
3091 params!(TimestampTz) => AggregateFunc::MinTimestampTz => TimestampTz, 2143;
3092 params!(Numeric) => AggregateFunc::MinNumeric => Numeric, oid::FUNC_MIN_NUMERIC_OID;
3093 params!(Interval) => AggregateFunc::MinInterval => Interval, 2144;
3094 params!(Time) => AggregateFunc::MinTime => Time, 2139;
3095 },
3096 "jsonb_agg" => Aggregate {
3097 params!(Any) => Operation::unary_ordered(|ecx, e, order_by| {
3098 let e = match ecx.scalar_type(&e) {
3100 ScalarType::Char { length } => e.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
3101 _ => e,
3102 };
3103 let json_null = HirScalarExpr::literal(Datum::JsonNull, ScalarType::Jsonb);
3109 let e = HirScalarExpr::CallVariadic {
3110 func: VariadicFunc::Coalesce,
3111 exprs: vec![typeconv::to_jsonb(ecx, e), json_null],
3112 };
3113 Ok((e, AggregateFunc::JsonbAgg { order_by }))
3114 }) => Jsonb, 3267;
3115 },
3116 "jsonb_object_agg" => Aggregate {
3117 params!(Any, Any) => Operation::binary_ordered(|ecx, key, val, order_by| {
3118 let key = match ecx.scalar_type(&key) {
3120 ScalarType::Char { length } => key.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
3121 _ => key,
3122 };
3123 let val = match ecx.scalar_type(&val) {
3124 ScalarType::Char { length } => val.call_unary(UnaryFunc::PadChar(func::PadChar { length })),
3125 _ => val,
3126 };
3127
3128 let json_null = HirScalarExpr::literal(Datum::JsonNull, ScalarType::Jsonb);
3129 let key = typeconv::to_string(ecx, key);
3130 let val = HirScalarExpr::CallVariadic {
3137 func: VariadicFunc::Coalesce,
3138 exprs: vec![typeconv::to_jsonb(ecx, val), json_null],
3139 };
3140 let e = HirScalarExpr::CallVariadic {
3141 func: VariadicFunc::RecordCreate {
3142 field_names: vec![ColumnName::from("key"), ColumnName::from("val")],
3143 },
3144 exprs: vec![key, val],
3145 };
3146 Ok((e, AggregateFunc::JsonbObjectAgg { order_by }))
3147 }) => Jsonb, 3270;
3148 },
3149 "string_agg" => Aggregate {
3150 params!(String, String) => Operation::binary_ordered(|_ecx, value, sep, order_by| {
3151 let e = HirScalarExpr::CallVariadic {
3152 func: VariadicFunc::RecordCreate {
3153 field_names: vec![ColumnName::from("value"), ColumnName::from("sep")],
3154 },
3155 exprs: vec![value, sep],
3156 };
3157 Ok((e, AggregateFunc::StringAgg { order_by }))
3158 }) => String, 3538;
3159 params!(Bytes, Bytes) => Operation::binary(|_ecx, _l, _r| bail_unsupported!("string_agg on BYTEA")) => Bytes, 3545;
3160 },
3161 "string_to_array" => Scalar {
3162 params!(String, String) => VariadicFunc::StringToArray => ScalarType::Array(Box::new(ScalarType::String)), 376;
3163 params!(String, String, String) => VariadicFunc::StringToArray => ScalarType::Array(Box::new(ScalarType::String)), 394;
3164 },
3165 "sum" => Aggregate {
3166 params!(Int16) => AggregateFunc::SumInt16 => Int64, 2109;
3167 params!(Int32) => AggregateFunc::SumInt32 => Int64, 2108;
3168 params!(Int64) => AggregateFunc::SumInt64 => Numeric, 2107;
3169 params!(UInt16) => AggregateFunc::SumUInt16 => UInt64, oid::FUNC_SUM_UINT16_OID;
3170 params!(UInt32) => AggregateFunc::SumUInt32 => UInt64, oid::FUNC_SUM_UINT32_OID;
3171 params!(UInt64) => AggregateFunc::SumUInt64 => Numeric, oid::FUNC_SUM_UINT64_OID;
3172 params!(Float32) => AggregateFunc::SumFloat32 => Float32, 2110;
3173 params!(Float64) => AggregateFunc::SumFloat64 => Float64, 2111;
3174 params!(Numeric) => AggregateFunc::SumNumeric => Numeric, 2114;
3175 params!(Interval) => Operation::unary(|_ecx, _e| {
3176 bail_unsupported!("sum(interval)");
3181 }) => Interval, 2113;
3182 },
3183
3184 "row_number" => ScalarWindow {
3186 params!() => ScalarWindowFunc::RowNumber => Int64, 3100;
3187 },
3188 "rank" => ScalarWindow {
3189 params!() => ScalarWindowFunc::Rank => Int64, 3101;
3190 },
3191 "dense_rank" => ScalarWindow {
3192 params!() => ScalarWindowFunc::DenseRank => Int64, 3102;
3193 },
3194 "lag" => ValueWindow {
3195 params!(AnyElement) => Operation::unary(|ecx, e| {
3197 let typ = ecx.scalar_type(&e);
3198 let e = HirScalarExpr::CallVariadic {
3199 func: VariadicFunc::RecordCreate {
3200 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3201 },
3202 exprs: vec![e, HirScalarExpr::literal(Datum::Int32(1), ScalarType::Int32), HirScalarExpr::literal_null(typ)],
3203 };
3204 Ok((e, ValueWindowFunc::Lag))
3205 }) => AnyElement, 3106;
3206 params!(AnyElement, Int32) => Operation::binary(|ecx, e, offset| {
3207 let typ = ecx.scalar_type(&e);
3208 let e = HirScalarExpr::CallVariadic {
3209 func: VariadicFunc::RecordCreate {
3210 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3211 },
3212 exprs: vec![e, offset, HirScalarExpr::literal_null(typ)],
3213 };
3214 Ok((e, ValueWindowFunc::Lag))
3215 }) => AnyElement, 3107;
3216 params!(AnyCompatible, Int32, AnyCompatible) => Operation::variadic(|_ecx, exprs| {
3217 let e = HirScalarExpr::CallVariadic {
3218 func: VariadicFunc::RecordCreate {
3219 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3220 },
3221 exprs,
3222 };
3223 Ok((e, ValueWindowFunc::Lag))
3224 }) => AnyCompatible, 3108;
3225 },
3226 "lead" => ValueWindow {
3227 params!(AnyElement) => Operation::unary(|ecx, e| {
3229 let typ = ecx.scalar_type(&e);
3230 let e = HirScalarExpr::CallVariadic {
3231 func: VariadicFunc::RecordCreate {
3232 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3233 },
3234 exprs: vec![e, HirScalarExpr::literal(Datum::Int32(1), ScalarType::Int32), HirScalarExpr::literal_null(typ)],
3235 };
3236 Ok((e, ValueWindowFunc::Lead))
3237 }) => AnyElement, 3109;
3238 params!(AnyElement, Int32) => Operation::binary(|ecx, e, offset| {
3239 let typ = ecx.scalar_type(&e);
3240 let e = HirScalarExpr::CallVariadic {
3241 func: VariadicFunc::RecordCreate {
3242 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3243 },
3244 exprs: vec![e, offset, HirScalarExpr::literal_null(typ)],
3245 };
3246 Ok((e, ValueWindowFunc::Lead))
3247 }) => AnyElement, 3110;
3248 params!(AnyCompatible, Int32, AnyCompatible) => Operation::variadic(|_ecx, exprs| {
3249 let e = HirScalarExpr::CallVariadic {
3250 func: VariadicFunc::RecordCreate {
3251 field_names: vec![ColumnName::from("expr"), ColumnName::from("offset"), ColumnName::from("default")]
3252 },
3253 exprs,
3254 };
3255 Ok((e, ValueWindowFunc::Lead))
3256 }) => AnyCompatible, 3111;
3257 },
3258 "first_value" => ValueWindow {
3259 params!(AnyElement) => ValueWindowFunc::FirstValue => AnyElement, 3112;
3260 },
3261 "last_value" => ValueWindow {
3262 params!(AnyElement) => ValueWindowFunc::LastValue => AnyElement, 3113;
3263 },
3264
3265 "generate_series" => Table {
3267 params!(Int32, Int32, Int32) => Operation::variadic(move |_ecx, exprs| {
3268 Ok(TableFuncPlan {
3269 expr: HirRelationExpr::CallTable {
3270 func: TableFunc::GenerateSeriesInt32,
3271 exprs,
3272 },
3273 column_names: vec!["generate_series".into()],
3274 })
3275 }) => ReturnType::set_of(Int32.into()), 1066;
3276 params!(Int32, Int32) => Operation::binary(move |_ecx, start, stop| {
3277 Ok(TableFuncPlan {
3278 expr: HirRelationExpr::CallTable {
3279 func: TableFunc::GenerateSeriesInt32,
3280 exprs: vec![start, stop, HirScalarExpr::literal(Datum::Int32(1), ScalarType::Int32)],
3281 },
3282 column_names: vec!["generate_series".into()],
3283 })
3284 }) => ReturnType::set_of(Int32.into()), 1067;
3285 params!(Int64, Int64, Int64) => Operation::variadic(move |_ecx, exprs| {
3286 Ok(TableFuncPlan {
3287 expr: HirRelationExpr::CallTable {
3288 func: TableFunc::GenerateSeriesInt64,
3289 exprs,
3290 },
3291 column_names: vec!["generate_series".into()],
3292 })
3293 }) => ReturnType::set_of(Int64.into()), 1068;
3294 params!(Int64, Int64) => Operation::binary(move |_ecx, start, stop| {
3295 let row = Row::pack([Datum::Int64(1)]);
3296 let column_type = ColumnType { scalar_type: ScalarType::Int64, nullable: false };
3297 Ok(TableFuncPlan {
3298 expr: HirRelationExpr::CallTable {
3299 func: TableFunc::GenerateSeriesInt64,
3300 exprs: vec![start, stop, HirScalarExpr::Literal(row, column_type)],
3301 },
3302 column_names: vec!["generate_series".into()],
3303 })
3304 }) => ReturnType::set_of(Int64.into()), 1069;
3305 params!(Timestamp, Timestamp, Interval) => Operation::variadic(move |_ecx, exprs| {
3306 Ok(TableFuncPlan {
3307 expr: HirRelationExpr::CallTable {
3308 func: TableFunc::GenerateSeriesTimestamp,
3309 exprs,
3310 },
3311 column_names: vec!["generate_series".into()],
3312 })
3313 }) => ReturnType::set_of(Timestamp.into()), 938;
3314 params!(TimestampTz, TimestampTz, Interval) => Operation::variadic(move |_ecx, exprs| {
3315 Ok(TableFuncPlan {
3316 expr: HirRelationExpr::CallTable {
3317 func: TableFunc::GenerateSeriesTimestampTz,
3318 exprs,
3319 },
3320 column_names: vec!["generate_series".into()],
3321 })
3322 }) => ReturnType::set_of(TimestampTz.into()), 939;
3323 },
3324
3325 "generate_subscripts" => Table {
3326 params!(ArrayAny, Int32) => Operation::variadic(move |_ecx, exprs| {
3327 Ok(TableFuncPlan {
3328 expr: HirRelationExpr::CallTable {
3329 func: TableFunc::GenerateSubscriptsArray,
3330 exprs,
3331 },
3332 column_names: vec!["generate_subscripts".into()],
3333 })
3334 }) => ReturnType::set_of(Int32.into()), 1192;
3335 },
3336
3337 "jsonb_array_elements" => Table {
3338 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
3339 Ok(TableFuncPlan {
3340 expr: HirRelationExpr::CallTable {
3341 func: TableFunc::JsonbArrayElements { stringify: false },
3342 exprs: vec![jsonb],
3343 },
3344 column_names: vec!["value".into()],
3345 })
3346 }) => ReturnType::set_of(Jsonb.into()), 3219;
3347 },
3348 "jsonb_array_elements_text" => Table {
3349 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
3350 Ok(TableFuncPlan {
3351 expr: HirRelationExpr::CallTable {
3352 func: TableFunc::JsonbArrayElements { stringify: true },
3353 exprs: vec![jsonb],
3354 },
3355 column_names: vec!["value".into()],
3356 })
3357 }) => ReturnType::set_of(String.into()), 3465;
3358 },
3359 "jsonb_each" => Table {
3360 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
3361 Ok(TableFuncPlan {
3362 expr: HirRelationExpr::CallTable {
3363 func: TableFunc::JsonbEach { stringify: false },
3364 exprs: vec![jsonb],
3365 },
3366 column_names: vec!["key".into(), "value".into()],
3367 })
3368 }) => ReturnType::set_of(RecordAny), 3208;
3369 },
3370 "jsonb_each_text" => Table {
3371 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
3372 Ok(TableFuncPlan {
3373 expr: HirRelationExpr::CallTable {
3374 func: TableFunc::JsonbEach { stringify: true },
3375 exprs: vec![jsonb],
3376 },
3377 column_names: vec!["key".into(), "value".into()],
3378 })
3379 }) => ReturnType::set_of(RecordAny), 3932;
3380 },
3381 "jsonb_object_keys" => Table {
3382 params!(Jsonb) => Operation::unary(move |_ecx, jsonb| {
3383 Ok(TableFuncPlan {
3384 expr: HirRelationExpr::CallTable {
3385 func: TableFunc::JsonbObjectKeys,
3386 exprs: vec![jsonb],
3387 },
3388 column_names: vec!["jsonb_object_keys".into()],
3389 })
3390 }) => ReturnType::set_of(String.into()), 3931;
3391 },
3392 "date_bin_hopping" => Table {
3396 params!(Interval, Interval, Timestamp) => experimental_sql_impl_table_func(&vars::ENABLE_DATE_BIN_HOPPING, "
3398 SELECT *
3399 FROM pg_catalog.generate_series(
3400 pg_catalog.date_bin($1, $3 + $1, '1970-01-01') - $2, $3, $1
3401 ) AS dbh(date_bin_hopping)
3402 ") => ReturnType::set_of(Timestamp.into()), oid::FUNC_MZ_DATE_BIN_HOPPING_UNIX_EPOCH_TS_OID;
3403 params!(Interval, Interval, TimestampTz) => experimental_sql_impl_table_func(&vars::ENABLE_DATE_BIN_HOPPING, "
3405 SELECT *
3406 FROM pg_catalog.generate_series(
3407 pg_catalog.date_bin($1, $3 + $1, '1970-01-01') - $2, $3, $1
3408 ) AS dbh(date_bin_hopping)
3409 ") => ReturnType::set_of(TimestampTz.into()), oid::FUNC_MZ_DATE_BIN_HOPPING_UNIX_EPOCH_TSTZ_OID;
3410 params!(Interval, Interval, Timestamp, Timestamp) => experimental_sql_impl_table_func(&vars::ENABLE_DATE_BIN_HOPPING, "
3412 SELECT *
3413 FROM pg_catalog.generate_series(
3414 pg_catalog.date_bin($1, $3 + $1, $4) - $2, $3, $1
3415 ) AS dbh(date_bin_hopping)
3416 ") => ReturnType::set_of(Timestamp.into()), oid::FUNC_MZ_DATE_BIN_HOPPING_TS_OID;
3417 params!(Interval, Interval, TimestampTz, TimestampTz) => experimental_sql_impl_table_func(&vars::ENABLE_DATE_BIN_HOPPING, "
3419 SELECT *
3420 FROM pg_catalog.generate_series(
3421 pg_catalog.date_bin($1, $3 + $1, $4) - $2, $3, $1
3422 ) AS dbh(date_bin_hopping)
3423 ") => ReturnType::set_of(TimestampTz.into()), oid::FUNC_MZ_DATE_BIN_HOPPING_TSTZ_OID;
3424 },
3425 "encode" => Scalar {
3426 params!(Bytes, String) => BinaryFunc::Encode => String, 1946;
3427 },
3428 "decode" => Scalar {
3429 params!(String, String) => BinaryFunc::Decode => Bytes, 1947;
3430 },
3431 "regexp_split_to_array" => Scalar {
3432 params!(String, String) => VariadicFunc::RegexpSplitToArray => ScalarType::Array(Box::new(ScalarType::String)), 2767;
3433 params!(String, String, String) => VariadicFunc::RegexpSplitToArray => ScalarType::Array(Box::new(ScalarType::String)), 2768;
3434 },
3435 "regexp_split_to_table" => Table {
3436 params!(String, String) => sql_impl_table_func("
3437 SELECT unnest(regexp_split_to_array($1, $2))
3438 ") => ReturnType::set_of(String.into()), 2765;
3439 params!(String, String, String) => sql_impl_table_func("
3440 SELECT unnest(regexp_split_to_array($1, $2, $3))
3441 ") => ReturnType::set_of(String.into()), 2766;
3442 },
3443 "regexp_replace" => Scalar {
3444 params!(String, String, String) => VariadicFunc::RegexpReplace => String, 2284;
3445 params!(String, String, String, String) => VariadicFunc::RegexpReplace => String, 2285;
3446 },
3449 "regexp_matches" => Table {
3450 params!(String, String) => Operation::variadic(move |_ecx, exprs| {
3451 let column_names = vec!["regexp_matches".into()];
3452 Ok(TableFuncPlan {
3453 expr: HirRelationExpr::CallTable {
3454 func: TableFunc::RegexpMatches,
3455 exprs: vec![exprs[0].clone(), exprs[1].clone()],
3456 },
3457 column_names,
3458 })
3459 }) => ReturnType::set_of(ScalarType::Array(Box::new(ScalarType::String)).into()), 2763;
3460 params!(String, String, String) => Operation::variadic(move |_ecx, exprs| {
3461 let column_names = vec!["regexp_matches".into()];
3462 Ok(TableFuncPlan {
3463 expr: HirRelationExpr::CallTable {
3464 func: TableFunc::RegexpMatches,
3465 exprs: vec![exprs[0].clone(), exprs[1].clone(), exprs[2].clone()],
3466 },
3467 column_names,
3468 })
3469 }) => ReturnType::set_of(ScalarType::Array(Box::new(ScalarType::String)).into()), 2764;
3470 },
3471 "reverse" => Scalar {
3472 params!(String) => UnaryFunc::Reverse(func::Reverse) => String, 3062;
3473 }
3474 };
3475
3476 for sef_builtin in PG_CATALOG_SEF_BUILTINS.values() {
3480 builtins.insert(
3481 sef_builtin.name,
3482 Func::Scalar(vec![FuncImpl {
3483 oid: sef_builtin.oid,
3484 params: ParamList::Exact(
3485 sef_builtin
3486 .param_types
3487 .iter()
3488 .map(|t| ParamType::from(t.clone()))
3489 .collect(),
3490 ),
3491 return_type: ReturnType::scalar(ParamType::from(
3492 sef_builtin.return_type.scalar_type.clone(),
3493 )),
3494 op: Operation::variadic(|_ecx, _e| {
3495 bail_unsupported!(format!("{} in this position", sef_builtin.name))
3496 }),
3497 }]),
3498 );
3499 }
3500
3501 builtins
3502});
3503
3504pub static INFORMATION_SCHEMA_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> =
3505 LazyLock::new(|| {
3506 use ParamType::*;
3507 builtins! {
3508 "_pg_expandarray" => Table {
3509 params!(ArrayAny) => sql_impl_table_func("
3511 SELECT
3512 $1[s] AS x,
3513 s - pg_catalog.array_lower($1, 1) + 1 AS n
3514 FROM pg_catalog.generate_series(
3515 pg_catalog.array_lower($1, 1),
3516 pg_catalog.array_upper($1, 1),
3517 1) as g(s)
3518 ") => ReturnType::set_of(RecordAny), oid::FUNC_PG_EXPAND_ARRAY;
3519 }
3520 }
3521 });
3522
3523pub static MZ_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
3524 use ParamType::*;
3525 use ScalarBaseType::*;
3526 builtins! {
3527 "constant_time_eq" => Scalar {
3528 params!(Bytes, Bytes) => BinaryFunc::ConstantTimeEqBytes => Bool, oid::FUNC_CONSTANT_TIME_EQ_BYTES_OID;
3529 params!(String, String) => BinaryFunc::ConstantTimeEqString => Bool, oid::FUNC_CONSTANT_TIME_EQ_STRING_OID;
3530 },
3531 "avg_internal_v1" => Scalar {
3539 params!(Int64) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_INT64_OID;
3540 params!(Int32) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_INT32_OID;
3541 params!(Int16) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_INT16_OID;
3542 params!(UInt64) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_UINT64_OID;
3543 params!(UInt32) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_UINT32_OID;
3544 params!(UInt16) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Numeric, oid::FUNC_AVG_INTERNAL_V1_UINT16_OID;
3545 params!(Float32) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Float64, oid::FUNC_AVG_INTERNAL_V1_FLOAT32_OID;
3546 params!(Float64) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Float64, oid::FUNC_AVG_INTERNAL_V1_FLOAT64_OID;
3547 params!(Interval) => Operation::nullary(|_ecx| catalog_name_only!("avg_internal_v1")) => Interval, oid::FUNC_AVG_INTERNAL_V1_INTERVAL_OID;
3548 },
3549 "csv_extract" => Table {
3550 params!(Int64, String) => Operation::binary(move |_ecx, ncols, input| {
3551 const MAX_EXTRACT_COLUMNS: i64 = 8192;
3552 const TOO_MANY_EXTRACT_COLUMNS: i64 = MAX_EXTRACT_COLUMNS + 1;
3553
3554 let ncols = match ncols.into_literal_int64() {
3555 None | Some(i64::MIN..=0) => {
3556 sql_bail!("csv_extract number of columns must be a positive integer literal");
3557 },
3558 Some(ncols @ 1..=MAX_EXTRACT_COLUMNS) => ncols,
3559 Some(ncols @ TOO_MANY_EXTRACT_COLUMNS..) => {
3560 return Err(PlanError::TooManyColumns {
3561 max_num_columns: usize::try_from(MAX_EXTRACT_COLUMNS).unwrap_or(usize::MAX),
3562 req_num_columns: usize::try_from(ncols).unwrap_or(usize::MAX),
3563 });
3564 },
3565 };
3566 let ncols = usize::try_from(ncols).expect("known to be greater than zero");
3567
3568 let column_names = (1..=ncols).map(|i| format!("column{}", i).into()).collect();
3569 Ok(TableFuncPlan {
3570 expr: HirRelationExpr::CallTable {
3571 func: TableFunc::CsvExtract(ncols),
3572 exprs: vec![input],
3573 },
3574 column_names,
3575 })
3576 }) => ReturnType::set_of(RecordAny), oid::FUNC_CSV_EXTRACT_OID;
3577 },
3578 "concat_agg" => Aggregate {
3579 params!(Any) => Operation::unary(|_ecx, _e| bail_unsupported!("concat_agg")) => String, oid::FUNC_CONCAT_AGG_OID;
3580 },
3581 "crc32" => Scalar {
3582 params!(String) => UnaryFunc::Crc32String(func::Crc32String) => UInt32, oid::FUNC_CRC32_STRING_OID;
3583 params!(Bytes) => UnaryFunc::Crc32Bytes(func::Crc32Bytes) => UInt32, oid::FUNC_CRC32_BYTES_OID;
3584 },
3585 "datediff" => Scalar {
3586 params!(String, Timestamp, Timestamp) => VariadicFunc::DateDiffTimestamp => Int64, oid::FUNC_DATEDIFF_TIMESTAMP;
3587 params!(String, TimestampTz, TimestampTz) => VariadicFunc::DateDiffTimestampTz => Int64, oid::FUNC_DATEDIFF_TIMESTAMPTZ;
3588 params!(String, Date, Date) => VariadicFunc::DateDiffDate => Int64, oid::FUNC_DATEDIFF_DATE;
3589 params!(String, Time, Time) => VariadicFunc::DateDiffTime => Int64, oid::FUNC_DATEDIFF_TIME;
3590 },
3591 "has_cluster_privilege" => Scalar {
3594 params!(String, String, String) => sql_impl_func("has_cluster_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_TEXT_TEXT_TEXT_OID;
3595 params!(Oid, String, String) => sql_impl_func(&format!("
3596 CASE
3597 -- We must first check $2 to avoid a potentially null error message (an error itself).
3598 WHEN $2 IS NULL
3599 THEN NULL
3600 -- Validate the cluster name in order to return a proper error.
3601 WHEN NOT EXISTS (SELECT name FROM mz_clusters WHERE name = $2)
3602 THEN mz_unsafe.mz_error_if_null(NULL::boolean, 'error cluster \"' || $2 || '\" does not exist')
3603 -- Validate the privileges and other arguments.
3604 WHEN NOT mz_internal.mz_validate_privileges($3)
3605 OR $1 IS NULL
3606 OR $3 IS NULL
3607 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
3608 THEN NULL
3609 ELSE COALESCE(
3610 (
3611 SELECT
3612 bool_or(
3613 mz_internal.mz_acl_item_contains_privilege(privilege, $3)
3614 )
3615 AS has_cluster_privilege
3616 FROM
3617 (
3618 SELECT
3619 unnest(privileges)
3620 FROM
3621 mz_clusters
3622 WHERE
3623 mz_clusters.name = $2
3624 )
3625 AS user_privs (privilege)
3626 LEFT JOIN mz_catalog.mz_roles ON
3627 mz_internal.mz_aclitem_grantee(privilege) = mz_roles.id
3628 WHERE
3629 mz_internal.mz_aclitem_grantee(privilege) = '{}' OR pg_has_role($1, mz_roles.oid, 'USAGE')
3630 ),
3631 false
3632 )
3633 END
3634 ", RoleId::Public)) => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_OID_TEXT_TEXT_OID;
3635 params!(String, String) => sql_impl_func("has_cluster_privilege(current_user, $1, $2)") => Bool, oid::FUNC_HAS_CLUSTER_PRIVILEGE_TEXT_TEXT_OID;
3636 },
3637 "has_connection_privilege" => Scalar {
3638 params!(String, String, String) => sql_impl_func("has_connection_privilege(mz_internal.mz_role_oid($1), mz_internal.mz_connection_oid($2), $3)") => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_TEXT_TEXT_OID;
3639 params!(String, Oid, String) => sql_impl_func("has_connection_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_OID_TEXT_OID;
3640 params!(Oid, String, String) => sql_impl_func("has_connection_privilege($1, mz_internal.mz_connection_oid($2), $3)") => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_TEXT_TEXT_OID;
3641 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_connection_privilege", "mz_connections")) => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_OID_TEXT_OID;
3642 params!(String, String) => sql_impl_func("has_connection_privilege(current_user, $1, $2)") => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_TEXT_TEXT_OID;
3643 params!(Oid, String) => sql_impl_func("has_connection_privilege(current_user, $1, $2)") => Bool, oid::FUNC_HAS_CONNECTION_PRIVILEGE_OID_TEXT_OID;
3644 },
3645 "has_role" => Scalar {
3646 params!(String, String, String) => sql_impl_func("pg_has_role($1, $2, $3)") => Bool, oid::FUNC_HAS_ROLE_TEXT_TEXT_TEXT_OID;
3647 params!(String, Oid, String) => sql_impl_func("pg_has_role($1, $2, $3)") => Bool, oid::FUNC_HAS_ROLE_TEXT_OID_TEXT_OID;
3648 params!(Oid, String, String) => sql_impl_func("pg_has_role($1, $2, $3)") => Bool, oid::FUNC_HAS_ROLE_OID_TEXT_TEXT_OID;
3649 params!(Oid, Oid, String) => sql_impl_func("pg_has_role($1, $2, $3)") => Bool, oid::FUNC_HAS_ROLE_OID_OID_TEXT_OID;
3650 params!(String, String) => sql_impl_func("pg_has_role($1, $2)") => Bool, oid::FUNC_HAS_ROLE_TEXT_TEXT_OID;
3651 params!(Oid, String) => sql_impl_func("pg_has_role($1, $2)") => Bool, oid::FUNC_HAS_ROLE_OID_TEXT_OID;
3652 },
3653 "has_secret_privilege" => Scalar {
3654 params!(String, String, String) => sql_impl_func("has_secret_privilege(mz_internal.mz_role_oid($1), mz_internal.mz_secret_oid($2), $3)") => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_TEXT_TEXT_OID;
3655 params!(String, Oid, String) => sql_impl_func("has_secret_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_OID_TEXT_OID;
3656 params!(Oid, String, String) => sql_impl_func("has_secret_privilege($1, mz_internal.mz_secret_oid($2), $3)") => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_OID_TEXT_TEXT_OID;
3657 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_secret_privilege", "mz_secrets")) => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_OID_OID_TEXT_OID;
3658 params!(String, String) => sql_impl_func("has_secret_privilege(current_user, $1, $2)") => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_TEXT_TEXT_OID;
3659 params!(Oid, String) => sql_impl_func("has_secret_privilege(current_user, $1, $2)") => Bool, oid::FUNC_HAS_SECRET_PRIVILEGE_OID_TEXT_OID;
3660 },
3661 "has_system_privilege" => Scalar {
3662 params!(String, String) => sql_impl_func("has_system_privilege(mz_internal.mz_role_oid($1), $2)") => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_TEXT_TEXT_OID;
3663 params!(Oid, String) => sql_impl_func(&format!("
3664 CASE
3665 -- We need to validate the privileges to return a proper error before
3666 -- anything else.
3667 WHEN NOT mz_internal.mz_validate_privileges($2)
3668 OR $1 IS NULL
3669 OR $2 IS NULL
3670 OR $1 NOT IN (SELECT oid FROM mz_catalog.mz_roles)
3671 THEN NULL
3672 ELSE COALESCE(
3673 (
3674 SELECT
3675 bool_or(
3676 mz_internal.mz_acl_item_contains_privilege(privileges, $2)
3677 )
3678 AS has_system_privilege
3679 FROM mz_catalog.mz_system_privileges
3680 LEFT JOIN mz_catalog.mz_roles ON
3681 mz_internal.mz_aclitem_grantee(privileges) = mz_roles.id
3682 WHERE
3683 mz_internal.mz_aclitem_grantee(privileges) = '{}' OR pg_has_role($1, mz_roles.oid, 'USAGE')
3684 ),
3685 false
3686 )
3687 END
3688 ", RoleId::Public)) => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_OID_TEXT_OID;
3689 params!(String) => sql_impl_func("has_system_privilege(current_user, $1)") => Bool, oid::FUNC_HAS_SYSTEM_PRIVILEGE_TEXT_OID;
3690 },
3691 "has_type_privilege" => Scalar {
3692 params!(String, String, String) => sql_impl_func("has_type_privilege(mz_internal.mz_role_oid($1), $2::regtype::oid, $3)") => Bool, 3138;
3693 params!(String, Oid, String) => sql_impl_func("has_type_privilege(mz_internal.mz_role_oid($1), $2, $3)") => Bool, 3139;
3694 params!(Oid, String, String) => sql_impl_func("has_type_privilege($1, $2::regtype::oid, $3)") => Bool, 3140;
3695 params!(Oid, Oid, String) => sql_impl_func(&privilege_fn!("has_type_privilege", "mz_types")) => Bool, 3141;
3696 params!(String, String) => sql_impl_func("has_type_privilege(current_user, $1, $2)") => Bool, 3142;
3697 params!(Oid, String) => sql_impl_func("has_type_privilege(current_user, $1, $2)") => Bool, 3143;
3698 },
3699 "kafka_murmur2" => Scalar {
3700 params!(String) => UnaryFunc::KafkaMurmur2String(func::KafkaMurmur2String) => Int32, oid::FUNC_KAFKA_MURMUR2_STRING_OID;
3701 params!(Bytes) => UnaryFunc::KafkaMurmur2Bytes(func::KafkaMurmur2Bytes) => Int32, oid::FUNC_KAFKA_MURMUR2_BYTES_OID;
3702 },
3703 "list_agg" => Aggregate {
3704 params!(Any) => Operation::unary_ordered(|ecx, e, order_by| {
3705 if let ScalarType::Char {.. } = ecx.scalar_type(&e) {
3706 bail_unsupported!("list_agg on char");
3707 };
3708 let e_arr = HirScalarExpr::CallVariadic{
3711 func: VariadicFunc::ListCreate { elem_type: ecx.scalar_type(&e) },
3712 exprs: vec![e],
3713 };
3714 Ok((e_arr, AggregateFunc::ListConcat { order_by }))
3715 }) => ListAnyCompatible, oid::FUNC_LIST_AGG_OID;
3716 },
3717 "list_append" => Scalar {
3718 vec![ListAnyCompatible, ListElementAnyCompatible] => BinaryFunc::ListElementConcat => ListAnyCompatible, oid::FUNC_LIST_APPEND_OID;
3719 },
3720 "list_cat" => Scalar {
3721 vec![ListAnyCompatible, ListAnyCompatible] => BinaryFunc::ListListConcat => ListAnyCompatible, oid::FUNC_LIST_CAT_OID;
3722 },
3723 "list_n_layers" => Scalar {
3724 vec![ListAny] => Operation::unary(|ecx, e| {
3725 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_N_LAYERS)?;
3726 let d = ecx.scalar_type(&e).unwrap_list_n_layers();
3727 match i32::try_from(d) {
3728 Ok(d) => Ok(HirScalarExpr::literal(Datum::Int32(d), ScalarType::Int32)),
3729 Err(_) => sql_bail!("list has more than {} layers", i32::MAX),
3730 }
3731
3732 }) => Int32, oid::FUNC_LIST_N_LAYERS_OID;
3733 },
3734 "list_length" => Scalar {
3735 vec![ListAny] => UnaryFunc::ListLength(func::ListLength) => Int32, oid::FUNC_LIST_LENGTH_OID;
3736 },
3737 "list_length_max" => Scalar {
3738 vec![ListAny, Plain(ScalarType::Int64)] => Operation::binary(|ecx, lhs, rhs| {
3739 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_LENGTH_MAX)?;
3740 let max_layer = ecx.scalar_type(&lhs).unwrap_list_n_layers();
3741 Ok(lhs.call_binary(rhs, BinaryFunc::ListLengthMax { max_layer }))
3742 }) => Int32, oid::FUNC_LIST_LENGTH_MAX_OID;
3743 },
3744 "list_prepend" => Scalar {
3745 vec![ListElementAnyCompatible, ListAnyCompatible] => BinaryFunc::ElementListConcat => ListAnyCompatible, oid::FUNC_LIST_PREPEND_OID;
3746 },
3747 "list_remove" => Scalar {
3748 vec![ListAnyCompatible, ListElementAnyCompatible] => Operation::binary(|ecx, lhs, rhs| {
3749 ecx.require_feature_flag(&crate::session::vars::ENABLE_LIST_REMOVE)?;
3750 Ok(lhs.call_binary(rhs, BinaryFunc::ListRemove))
3751 }) => ListAnyCompatible, oid::FUNC_LIST_REMOVE_OID;
3752 },
3753 "map_agg" => Aggregate {
3754 params!(String, Any) => Operation::binary_ordered(|ecx, key, val, order_by| {
3755 let (value_type, val) = match ecx.scalar_type(&val) {
3756 ScalarType::Char { length } => (ScalarType::Char { length }, val.call_unary(UnaryFunc::PadChar(func::PadChar { length }))),
3758 typ => (typ, val),
3759 };
3760
3761 let e = HirScalarExpr::CallVariadic {
3762 func: VariadicFunc::RecordCreate {
3763 field_names: vec![ColumnName::from("key"), ColumnName::from("val")],
3764 },
3765 exprs: vec![key, val],
3766 };
3767
3768 Ok((e, AggregateFunc::MapAgg { order_by, value_type }))
3769 }) => MapAny, oid::FUNC_MAP_AGG;
3770 },
3771 "map_build" => Scalar {
3772 params!(ListAny) => Operation::unary(|ecx, expr| {
3783 let ty = ecx.scalar_type(&expr);
3784
3785 let err = || {
3788 Err(sql_err!(
3789 "function map_build({}) does not exist",
3790 ecx.humanize_scalar_type(&ty.clone(), false)
3791 ))
3792 };
3793
3794 let value_type = match &ty {
3797 ScalarType::List { element_type, .. } => match &**element_type {
3798 ScalarType::Record { fields, .. } if fields.len() == 2 => {
3799 if fields[0].1.scalar_type != ScalarType::String {
3800 return err();
3801 }
3802
3803 fields[1].1.scalar_type.clone()
3804 }
3805 _ => return err(),
3806 },
3807 _ => unreachable!("input guaranteed to be list"),
3808 };
3809
3810 Ok(expr.call_unary(UnaryFunc::MapBuildFromRecordList(
3811 func::MapBuildFromRecordList { value_type },
3812 )))
3813 }) => MapAny, oid::FUNC_MAP_BUILD;
3814 },
3815 "map_length" => Scalar {
3816 params![MapAny] => UnaryFunc::MapLength(func::MapLength) => Int32, oid::FUNC_MAP_LENGTH_OID;
3817 },
3818 "mz_environment_id" => Scalar {
3819 params!() => UnmaterializableFunc::MzEnvironmentId => String, oid::FUNC_MZ_ENVIRONMENT_ID_OID;
3820 },
3821 "mz_is_superuser" => Scalar {
3822 params!() => UnmaterializableFunc::MzIsSuperuser => ScalarType::Bool, oid::FUNC_MZ_IS_SUPERUSER;
3823 },
3824 "mz_logical_timestamp" => Scalar {
3825 params!() => Operation::nullary(|_ecx| sql_bail!("mz_logical_timestamp() has been renamed to mz_now()")) => MzTimestamp, oid::FUNC_MZ_LOGICAL_TIMESTAMP_OID;
3826 },
3827 "mz_now" => Scalar {
3828 params!() => UnmaterializableFunc::MzNow => MzTimestamp, oid::FUNC_MZ_NOW_OID;
3829 },
3830 "mz_uptime" => Scalar {
3831 params!() => UnmaterializableFunc::MzUptime => Interval, oid::FUNC_MZ_UPTIME_OID;
3832 },
3833 "mz_version" => Scalar {
3834 params!() => UnmaterializableFunc::MzVersion => String, oid::FUNC_MZ_VERSION_OID;
3835 },
3836 "mz_version_num" => Scalar {
3837 params!() => UnmaterializableFunc::MzVersionNum => Int32, oid::FUNC_MZ_VERSION_NUM_OID;
3838 },
3839 "pretty_sql" => Scalar {
3840 params!(String, Int32) => BinaryFunc::PrettySql => String, oid::FUNC_PRETTY_SQL;
3841 params!(String) => Operation::unary(|_ecx, s| {
3842 let width = HirScalarExpr::literal(Datum::Int32(mz_sql_pretty::DEFAULT_WIDTH.try_into().expect("must fit")), ScalarType::Int32);
3843 Ok(s.call_binary(width, BinaryFunc::PrettySql))
3844 }) => String, oid::FUNC_PRETTY_SQL_NOWIDTH;
3845 },
3846 "regexp_extract" => Table {
3847 params!(String, String) => Operation::binary(move |_ecx, regex, haystack| {
3848 let regex = match regex.into_literal_string() {
3849 None => sql_bail!("regexp_extract requires a string literal as its first argument"),
3850 Some(regex) => mz_expr::AnalyzedRegex::new(®ex, mz_expr::AnalyzedRegexOpts::default()).map_err(|e| sql_err!("analyzing regex: {}", e))?,
3851 };
3852 let column_names = regex
3853 .capture_groups_iter()
3854 .map(|cg| {
3855 cg.name.clone().unwrap_or_else(|| format!("column{}", cg.index)).into()
3856 })
3857 .collect::<Vec<_>>();
3858 if column_names.is_empty(){
3859 sql_bail!("regexp_extract must specify at least one capture group");
3860 }
3861 Ok(TableFuncPlan {
3862 expr: HirRelationExpr::CallTable {
3863 func: TableFunc::RegexpExtract(regex),
3864 exprs: vec![haystack],
3865 },
3866 column_names,
3867 })
3868 }) => ReturnType::set_of(RecordAny), oid::FUNC_REGEXP_EXTRACT_OID;
3869 },
3870 "repeat_row" => Table {
3871 params!(Int64) => Operation::unary(move |ecx, n| {
3872 ecx.require_feature_flag(&crate::session::vars::ENABLE_REPEAT_ROW)?;
3873 Ok(TableFuncPlan {
3874 expr: HirRelationExpr::CallTable {
3875 func: TableFunc::Repeat,
3876 exprs: vec![n],
3877 },
3878 column_names: vec![]
3879 })
3880 }) => ReturnType::none(true), oid::FUNC_REPEAT_OID;
3881 },
3882 "seahash" => Scalar {
3883 params!(String) => UnaryFunc::SeahashString(func::SeahashString) => UInt32, oid::FUNC_SEAHASH_STRING_OID;
3884 params!(Bytes) => UnaryFunc::SeahashBytes(func::SeahashBytes) => UInt32, oid::FUNC_SEAHASH_BYTES_OID;
3885 },
3886 "starts_with" => Scalar {
3887 params!(String, String) => BinaryFunc::StartsWith => Bool, 3696;
3888 },
3889 "timezone_offset" => Scalar {
3890 params!(String, TimestampTz) => BinaryFunc::TimezoneOffset => RecordAny, oid::FUNC_TIMEZONE_OFFSET;
3891 },
3892 "try_parse_monotonic_iso8601_timestamp" => Scalar {
3893 params!(String) => Operation::unary(move |_ecx, e| {
3894 Ok(e.call_unary(UnaryFunc::TryParseMonotonicIso8601Timestamp(func::TryParseMonotonicIso8601Timestamp)))
3895 }) => Timestamp, oid::FUNC_TRY_PARSE_MONOTONIC_ISO8601_TIMESTAMP;
3896 },
3897 "unnest" => Table {
3898 vec![ArrayAny] => Operation::unary(move |ecx, e| {
3899 let el_typ = ecx.scalar_type(&e).unwrap_array_element_type().clone();
3900 Ok(TableFuncPlan {
3901 expr: HirRelationExpr::CallTable {
3902 func: TableFunc::UnnestArray { el_typ },
3903 exprs: vec![e],
3904 },
3905 column_names: vec!["unnest".into()],
3906 })
3907 }) =>
3908 ReturnType::set_of(AnyElement), 2331;
3910 vec![ListAny] => Operation::unary(move |ecx, e| {
3911 let el_typ = ecx.scalar_type(&e).unwrap_list_element_type().clone();
3912 Ok(TableFuncPlan {
3913 expr: HirRelationExpr::CallTable {
3914 func: TableFunc::UnnestList { el_typ },
3915 exprs: vec![e],
3916 },
3917 column_names: vec!["unnest".into()],
3918 })
3919 }) =>
3920 ReturnType::set_of(Any), oid::FUNC_UNNEST_LIST_OID;
3922 vec![MapAny] => Operation::unary(move |ecx, e| {
3923 let value_type = ecx.scalar_type(&e).unwrap_map_value_type().clone();
3924 Ok(TableFuncPlan {
3925 expr: HirRelationExpr::CallTable {
3926 func: TableFunc::UnnestMap { value_type },
3927 exprs: vec![e],
3928 },
3929 column_names: vec!["key".into(), "value".into()],
3930 })
3931 }) =>
3932 ReturnType::set_of(Any), oid::FUNC_UNNEST_MAP_OID;
3934 }
3935 }
3936});
3937
3938pub static MZ_INTERNAL_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
3939 use ParamType::*;
3940 use ScalarBaseType::*;
3941 builtins! {
3942 "aclitem_grantor" => Scalar {
3943 params!(AclItem) => UnaryFunc::AclItemGrantor(func::AclItemGrantor) => Oid, oid::FUNC_ACL_ITEM_GRANTOR_OID;
3944 },
3945 "aclitem_grantee" => Scalar {
3946 params!(AclItem) => UnaryFunc::AclItemGrantee(func::AclItemGrantee) => Oid, oid::FUNC_ACL_ITEM_GRANTEE_OID;
3947 },
3948 "aclitem_privileges" => Scalar {
3949 params!(AclItem) => UnaryFunc::AclItemPrivileges(func::AclItemPrivileges) => String, oid::FUNC_ACL_ITEM_PRIVILEGES_OID;
3950 },
3951 "is_rbac_enabled" => Scalar {
3952 params!() => UnmaterializableFunc::IsRbacEnabled => Bool, oid::FUNC_IS_RBAC_ENABLED_OID;
3953 },
3954 "make_mz_aclitem" => Scalar {
3955 params!(String, String, String) => VariadicFunc::MakeMzAclItem => MzAclItem, oid::FUNC_MAKE_MZ_ACL_ITEM_OID;
3956 },
3957 "mz_acl_item_contains_privilege" => Scalar {
3958 params!(MzAclItem, String) => BinaryFunc::MzAclItemContainsPrivilege => Bool, oid::FUNC_MZ_ACL_ITEM_CONTAINS_PRIVILEGE_OID;
3959 },
3960 "mz_aclexplode" => Table {
3961 params!(ScalarType::Array(Box::new(ScalarType::MzAclItem))) => Operation::unary(move |_ecx, mz_aclitems| {
3962 Ok(TableFuncPlan {
3963 expr: HirRelationExpr::CallTable {
3964 func: TableFunc::MzAclExplode,
3965 exprs: vec![mz_aclitems],
3966 },
3967 column_names: vec!["grantor".into(), "grantee".into(), "privilege_type".into(), "is_grantable".into()],
3968 })
3969 }) => ReturnType::set_of(RecordAny), oid::FUNC_MZ_ACL_ITEM_EXPLODE_OID;
3970 },
3971 "mz_aclitem_grantor" => Scalar {
3972 params!(MzAclItem) => UnaryFunc::MzAclItemGrantor(func::MzAclItemGrantor) => String, oid::FUNC_MZ_ACL_ITEM_GRANTOR_OID;
3973 },
3974 "mz_aclitem_grantee" => Scalar {
3975 params!(MzAclItem) => UnaryFunc::MzAclItemGrantee(func::MzAclItemGrantee) => String, oid::FUNC_MZ_ACL_ITEM_GRANTEE_OID;
3976 },
3977 "mz_aclitem_privileges" => Scalar {
3978 params!(MzAclItem) => UnaryFunc::MzAclItemPrivileges(func::MzAclItemPrivileges) => String, oid::FUNC_MZ_ACL_ITEM_PRIVILEGES_OID;
3979 },
3980 "mz_connection_oid" => Scalar {
3985 params!(String) => sql_impl_func("
3986 CASE
3987 WHEN $1 IS NULL THEN NULL
3988 ELSE (
3989 mz_unsafe.mz_error_if_null(
3990 (SELECT oid FROM mz_catalog.mz_objects WHERE name = $1 AND type = 'connection'),
3991 'connection \"' || $1 || '\" does not exist'
3992 )
3993 )
3994 END
3995 ") => Oid, oid::FUNC_CONNECTION_OID_OID;
3996 },
3997 "mz_format_privileges" => Scalar {
3998 params!(String) => UnaryFunc::MzFormatPrivileges(func::MzFormatPrivileges) => ScalarType::Array(Box::new(ScalarType::String)), oid::FUNC_MZ_FORMAT_PRIVILEGES_OID;
3999 },
4000 "mz_name_rank" => Table {
4001 params!(
4004 String,
4006 ParamType::Plain(ScalarType::Array(Box::new(ScalarType::String))),
4008 String,
4010 String
4012 ) =>
4013 sql_impl_table_func("
4015 -- The best ranked name is the one that belongs to the schema correlated with the lowest
4016 -- index in the search path
4017 SELECT id, name, count, min(schema_pref) OVER () = schema_pref AS best_ranked FROM (
4018 SELECT DISTINCT
4019 o.id,
4020 ARRAY[CASE WHEN s.database_id IS NULL THEN NULL ELSE d.name END, s.name, o.name]
4021 AS name,
4022 o.count,
4023 pg_catalog.array_position($2, s.name) AS schema_pref
4024 FROM
4025 (
4026 SELECT
4027 o.id,
4028 o.schema_id,
4029 o.name,
4030 count(*)
4031 FROM mz_catalog.mz_objects AS o
4032 JOIN mz_internal.mz_object_oid_alias AS a
4033 ON o.type = a.object_type
4034 WHERE o.name = CAST($3 AS pg_catalog.text) AND a.oid_alias = $4
4035 GROUP BY 1, 2, 3
4036 )
4037 AS o
4038 JOIN mz_catalog.mz_schemas AS s ON o.schema_id = s.id
4039 JOIN
4040 unnest($2) AS search_schema (name)
4041 ON search_schema.name = s.name
4042 JOIN
4043 (
4044 SELECT id, name FROM mz_catalog.mz_databases
4045 -- If the provided database does not exist, add a row for it so that it
4046 -- can still join against ambient schemas.
4047 UNION ALL
4048 SELECT '', $1 WHERE $1 NOT IN (SELECT name FROM mz_catalog.mz_databases)
4049 ) AS d
4050 ON d.id = COALESCE(s.database_id, d.id)
4051 WHERE d.name = CAST($1 AS pg_catalog.text)
4052 );
4053 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_NAME_RANK;
4054 },
4055 "mz_resolve_object_name" => Table {
4056 params!(String, String) =>
4057 sql_impl_table_func("
4060 SELECT
4061 o.id, o.oid, o.schema_id, o.name, o.type, o.owner_id, o.privileges
4062 FROM
4063 (SELECT mz_internal.mz_normalize_object_name($2))
4064 AS normalized (n),
4065 mz_internal.mz_name_rank(
4066 COALESCE(n[1], pg_catalog.current_database()),
4067 CASE
4068 WHEN n[2] IS NULL
4069 THEN pg_catalog.current_schemas(true)
4070 ELSE
4071 ARRAY[n[2]]
4072 END,
4073 n[3],
4074 $1
4075 ) AS r,
4076 mz_catalog.mz_objects AS o
4077 WHERE r.id = o.id AND r.best_ranked;
4078 ") => ReturnType::set_of(RecordAny), oid::FUNC_MZ_RESOLVE_OBJECT_NAME;
4079 },
4080 "mz_minimal_name_qualification" => Scalar {
4092 params!(ScalarType::Array(Box::new(ScalarType::String)), String) => {
4093 sql_impl_func("(
4094 SELECT
4095 CASE
4096 WHEN $1::pg_catalog.text[] IS NULL
4097 THEN NULL
4098 -- If DB doesn't match, requires full qual
4099 WHEN $1[1] != pg_catalog.current_database()
4100 THEN $1
4101 -- If not in currently searchable schema, must be schema qualified
4102 WHEN NOT $1[2] = ANY(pg_catalog.current_schemas(true))
4103 THEN ARRAY[$1[2], $1[3]]
4104 ELSE
4105 minimal_name
4106 END
4107 FROM (
4108 -- Subquery so we return one null row in the cases where
4109 -- there are no matches.
4110 SELECT (
4111 SELECT DISTINCT
4112 CASE
4113 -- If there is only one item with this name and it's rank 1,
4114 -- it is uniquely nameable with just the final element
4115 WHEN best_ranked AND count = 1
4116 THEN ARRAY[r.name[3]]
4117 -- Otherwise, it is findable in the search path, so does not
4118 -- need database qualification
4119 ELSE
4120 ARRAY[r.name[2], r.name[3]]
4121 END AS minimal_name
4122 FROM mz_catalog.mz_objects AS o
4123 JOIN mz_internal.mz_object_oid_alias AS a
4124 ON o.type = a.object_type,
4125 -- implied lateral to put the OID alias into scope
4126 mz_internal.mz_name_rank(
4127 pg_catalog.current_database(),
4128 pg_catalog.current_schemas(true),
4129 $1[3],
4130 a.oid_alias
4131 ) AS r
4132 WHERE o.id = $2 AND r.id = $2
4133 )
4134 )
4135 )")
4136 } => ScalarType::Array(Box::new(ScalarType::String)), oid::FUNC_MZ_MINIMINAL_NAME_QUALIFICATION;
4137 },
4138 "mz_global_id_to_name" => Scalar {
4139 params!(String) => sql_impl_func("
4140 CASE
4141 WHEN $1 IS NULL THEN NULL
4142 ELSE (
4143 SELECT array_to_string(minimal_name, '.')
4144 FROM (
4145 SELECT mz_unsafe.mz_error_if_null(
4146 (
4147 -- Return the fully-qualified name
4148 SELECT DISTINCT ARRAY[qual.d, qual.s, item.name]
4149 FROM
4150 mz_catalog.mz_objects AS item
4151 JOIN
4152 (
4153 SELECT
4154 d.name AS d,
4155 s.name AS s,
4156 s.id AS schema_id
4157 FROM
4158 mz_catalog.mz_schemas AS s
4159 LEFT JOIN
4160 (SELECT id, name FROM mz_catalog.mz_databases)
4161 AS d
4162 ON s.database_id = d.id
4163 ) AS qual
4164 ON qual.schema_id = item.schema_id
4165 WHERE item.id = CAST($1 AS text)
4166 ),
4167 'global ID ' || $1 || ' does not exist'
4168 )
4169 ) AS n (fqn),
4170 LATERAL (
4171 -- Get the minimal qualification of the fully qualified name
4172 SELECT mz_internal.mz_minimal_name_qualification(fqn, $1)
4173 ) AS m (minimal_name)
4174 )
4175 END
4176 ") => String, oid::FUNC_MZ_GLOBAL_ID_TO_NAME;
4177 },
4178 "mz_normalize_object_name" => Scalar {
4179 params!(String) => sql_impl_func("
4180 (
4181 SELECT
4182 CASE
4183 WHEN $1 IS NULL THEN NULL
4184 WHEN pg_catalog.array_length(ident, 1) > 3
4185 THEN mz_unsafe.mz_error_if_null(
4186 NULL::pg_catalog.text[],
4187 'improper relation name (too many dotted names): ' || $1
4188 )
4189 ELSE pg_catalog.array_cat(
4190 pg_catalog.array_fill(
4191 CAST(NULL AS pg_catalog.text),
4192 ARRAY[3 - pg_catalog.array_length(ident, 1)]
4193 ),
4194 ident
4195 )
4196 END
4197 FROM (
4198 SELECT pg_catalog.parse_ident($1) AS ident
4199 ) AS i
4200 )") => ScalarType::Array(Box::new(ScalarType::String)), oid::FUNC_MZ_NORMALIZE_OBJECT_NAME;
4201 },
4202 "mz_normalize_schema_name" => Scalar {
4203 params!(String) => sql_impl_func("
4204 (
4205 SELECT
4206 CASE
4207 WHEN $1 IS NULL THEN NULL
4208 WHEN pg_catalog.array_length(ident, 1) > 2
4209 THEN mz_unsafe.mz_error_if_null(
4210 NULL::pg_catalog.text[],
4211 'improper schema name (too many dotted names): ' || $1
4212 )
4213 ELSE pg_catalog.array_cat(
4214 pg_catalog.array_fill(
4215 CAST(NULL AS pg_catalog.text),
4216 ARRAY[2 - pg_catalog.array_length(ident, 1)]
4217 ),
4218 ident
4219 )
4220 END
4221 FROM (
4222 SELECT pg_catalog.parse_ident($1) AS ident
4223 ) AS i
4224 )") => ScalarType::Array(Box::new(ScalarType::String)), oid::FUNC_MZ_NORMALIZE_SCHEMA_NAME;
4225 },
4226 "mz_render_typmod" => Scalar {
4227 params!(Oid, Int32) => BinaryFunc::MzRenderTypmod => String, oid::FUNC_MZ_RENDER_TYPMOD_OID;
4228 },
4229 "mz_role_oid_memberships" => Scalar {
4230 params!() => UnmaterializableFunc::MzRoleOidMemberships => ScalarType::Map{ value_type: Box::new(ScalarType::Array(Box::new(ScalarType::String))), custom_id: None }, oid::FUNC_MZ_ROLE_OID_MEMBERSHIPS;
4231 },
4232 "mz_database_oid" => Scalar {
4234 params!(String) => sql_impl_func("
4235 CASE
4236 WHEN $1 IS NULL THEN NULL
4237 ELSE (
4238 mz_unsafe.mz_error_if_null(
4239 (SELECT oid FROM mz_databases WHERE name = $1),
4240 'database \"' || $1 || '\" does not exist'
4241 )
4242 )
4243 END
4244 ") => Oid, oid::FUNC_DATABASE_OID_OID;
4245 },
4246 "mz_schema_oid" => Scalar {
4248 params!(String) => sql_impl_func("
4249 CASE
4250 WHEN $1 IS NULL THEN NULL
4251 ELSE
4252 mz_unsafe.mz_error_if_null(
4253 (
4254 SELECT
4255 (
4256 SELECT s.oid
4257 FROM mz_catalog.mz_schemas AS s
4258 LEFT JOIN mz_databases AS d ON s.database_id = d.id
4259 WHERE
4260 (
4261 -- Filter to only schemas in the named database or the
4262 -- current database if no database was specified.
4263 d.name = COALESCE(n[1], pg_catalog.current_database())
4264 -- Always include all ambient schemas.
4265 OR s.database_id IS NULL
4266 )
4267 AND s.name = n[2]
4268 )
4269 FROM mz_internal.mz_normalize_schema_name($1) AS n
4270 ),
4271 'schema \"' || $1 || '\" does not exist'
4272 )
4273 END
4274 ") => Oid, oid::FUNC_SCHEMA_OID_OID;
4275 },
4276 "mz_role_oid" => Scalar {
4278 params!(String) => sql_impl_func("
4279 CASE
4280 WHEN $1 IS NULL THEN NULL
4281 ELSE (
4282 mz_unsafe.mz_error_if_null(
4283 (SELECT oid FROM mz_catalog.mz_roles WHERE name = $1),
4284 'role \"' || $1 || '\" does not exist'
4285 )
4286 )
4287 END
4288 ") => Oid, oid::FUNC_ROLE_OID_OID;
4289 },
4290 "mz_secret_oid" => Scalar {
4295 params!(String) => sql_impl_func("
4296 CASE
4297 WHEN $1 IS NULL THEN NULL
4298 ELSE (
4299 mz_unsafe.mz_error_if_null(
4300 (SELECT oid FROM mz_catalog.mz_objects WHERE name = $1 AND type = 'secret'),
4301 'secret \"' || $1 || '\" does not exist'
4302 )
4303 )
4304 END
4305 ") => Oid, oid::FUNC_SECRET_OID_OID;
4306 },
4307 "mz_session_id" => Scalar {
4311 params!() => UnmaterializableFunc::MzSessionId => Uuid, oid::FUNC_MZ_SESSION_ID_OID;
4312 },
4313 "mz_type_name" => Scalar {
4314 params!(Oid) => UnaryFunc::MzTypeName(func::MzTypeName) => String, oid::FUNC_MZ_TYPE_NAME;
4315 },
4316 "mz_validate_privileges" => Scalar {
4317 params!(String) => UnaryFunc::MzValidatePrivileges(func::MzValidatePrivileges) => Bool, oid::FUNC_MZ_VALIDATE_PRIVILEGES_OID;
4318 },
4319 "mz_validate_role_privilege" => Scalar {
4320 params!(String) => UnaryFunc::MzValidateRolePrivilege(func::MzValidateRolePrivilege) => Bool, oid::FUNC_MZ_VALIDATE_ROLE_PRIVILEGE_OID;
4321 }
4322 }
4323});
4324
4325pub static MZ_UNSAFE_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
4326 use ParamType::*;
4327 use ScalarBaseType::*;
4328 builtins! {
4329 "mz_all" => Aggregate {
4330 params!(Any) => AggregateFunc::All => Bool, oid::FUNC_MZ_ALL_OID;
4331 },
4332 "mz_any" => Aggregate {
4333 params!(Any) => AggregateFunc::Any => Bool, oid::FUNC_MZ_ANY_OID;
4334 },
4335 "mz_avg_promotion_internal_v1" => Scalar {
4336 params!(Float32) => Operation::identity() => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID_INTERNAL_V1;
4342 params!(Float64) => Operation::identity() => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID_INTERNAL_V1;
4343 params!(Int16) => Operation::unary(|ecx, e| {
4344 typeconv::plan_cast(
4345 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4346 )
4347 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID_INTERNAL_V1;
4348 params!(Int32) => Operation::unary(|ecx, e| {
4349 typeconv::plan_cast(
4350 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4351 )
4352 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID_INTERNAL_V1;
4353 params!(UInt16) => Operation::unary(|ecx, e| {
4354 typeconv::plan_cast(
4355 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4356 )
4357 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID_INTERNAL_V1;
4358 params!(UInt32) => Operation::unary(|ecx, e| {
4359 typeconv::plan_cast(
4360 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4361 )
4362 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID_INTERNAL_V1;
4363 },
4364 "mz_avg_promotion" => Scalar {
4365 params!(Float32) => Operation::identity() => Float32, oid::FUNC_MZ_AVG_PROMOTION_F32_OID;
4371 params!(Float64) => Operation::identity() => Float64, oid::FUNC_MZ_AVG_PROMOTION_F64_OID;
4372 params!(Int16) => Operation::unary(|ecx, e| {
4373 typeconv::plan_cast(
4374 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4375 )
4376 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I16_OID;
4377 params!(Int32) => Operation::unary(|ecx, e| {
4378 typeconv::plan_cast(
4379 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4380 )
4381 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I32_OID;
4382 params!(Int64) => Operation::unary(|ecx, e| {
4383 typeconv::plan_cast(
4384 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4385 )
4386 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_I64_OID;
4387 params!(UInt16) => Operation::unary(|ecx, e| {
4388 typeconv::plan_cast(
4389 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4390 )
4391 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U16_OID;
4392 params!(UInt32) => Operation::unary(|ecx, e| {
4393 typeconv::plan_cast(
4394 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4395 )
4396 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U32_OID;
4397 params!(UInt64) => Operation::unary(|ecx, e| {
4398 typeconv::plan_cast(
4399 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4400 )
4401 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_U64_OID;
4402 params!(Numeric) => Operation::unary(|ecx, e| {
4403 typeconv::plan_cast(
4404 ecx, CastContext::Explicit, e, &ScalarType::Numeric {max_scale: None},
4405 )
4406 }) => Numeric, oid::FUNC_MZ_AVG_PROMOTION_NUMERIC_OID;
4407 },
4408 "mz_error_if_null" => Scalar {
4409 params!(Any, String) => VariadicFunc::ErrorIfNull => Any, oid::FUNC_MZ_ERROR_IF_NULL_OID;
4412 },
4413 "mz_sleep" => Scalar {
4414 params!(Float64) => UnaryFunc::Sleep(func::Sleep) => TimestampTz, oid::FUNC_MZ_SLEEP_OID;
4415 },
4416 "mz_panic" => Scalar {
4417 params!(String) => UnaryFunc::Panic(func::Panic) => String, oid::FUNC_MZ_PANIC_OID;
4418 }
4419 }
4420});
4421
4422fn digest(algorithm: &'static str) -> Operation<HirScalarExpr> {
4423 Operation::unary(move |_ecx, input| {
4424 let algorithm = HirScalarExpr::literal(Datum::String(algorithm), ScalarType::String);
4425 Ok(input.call_binary(algorithm, BinaryFunc::DigestBytes))
4426 })
4427}
4428
4429fn array_to_string(
4430 ecx: &ExprContext,
4431 exprs: Vec<HirScalarExpr>,
4432) -> Result<HirScalarExpr, PlanError> {
4433 let elem_type = match ecx.scalar_type(&exprs[0]) {
4434 ScalarType::Array(elem_type) => *elem_type,
4435 _ => unreachable!("array_to_string is guaranteed to receive array as first argument"),
4436 };
4437 Ok(HirScalarExpr::CallVariadic {
4438 func: VariadicFunc::ArrayToString { elem_type },
4439 exprs,
4440 })
4441}
4442
4443pub static OP_IMPLS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
4445 use BinaryFunc::*;
4446 use ParamType::*;
4447 use ScalarBaseType::*;
4448 builtins! {
4449 "+" => Scalar {
4472 params!(Any) => Operation::new(|ecx, exprs, _params, _order_by| {
4473 typeconv::plan_coerce(ecx, exprs.into_element(), &ScalarType::Float64)
4486 }) => Any, oid::OP_UNARY_PLUS_OID;
4487 params!(Int16, Int16) => AddInt16 => Int16, 550;
4488 params!(Int32, Int32) => AddInt32 => Int32, 551;
4489 params!(Int64, Int64) => AddInt64 => Int64, 684;
4490 params!(UInt16, UInt16) => AddUInt16 => UInt16, oid::FUNC_ADD_UINT16;
4491 params!(UInt32, UInt32) => AddUInt32 => UInt32, oid::FUNC_ADD_UINT32;
4492 params!(UInt64, UInt64) => AddUInt64 => UInt64, oid::FUNC_ADD_UINT64;
4493 params!(Float32, Float32) => AddFloat32 => Float32, 586;
4494 params!(Float64, Float64) => AddFloat64 => Float64, 591;
4495 params!(Interval, Interval) => AddInterval => Interval, 1337;
4496 params!(Timestamp, Interval) => AddTimestampInterval => Timestamp, 2066;
4497 params!(Interval, Timestamp) => {
4498 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, AddTimestampInterval)))
4499 } => Timestamp, 2553;
4500 params!(TimestampTz, Interval) => AddTimestampTzInterval => TimestampTz, 1327;
4501 params!(Interval, TimestampTz) => {
4502 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, AddTimestampTzInterval)))
4503 } => TimestampTz, 2554;
4504 params!(Date, Interval) => AddDateInterval => Timestamp, 1076;
4505 params!(Interval, Date) => {
4506 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, AddDateInterval)))
4507 } => Timestamp, 2551;
4508 params!(Date, Time) => AddDateTime => Timestamp, 1360;
4509 params!(Time, Date) => {
4510 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, AddDateTime)))
4511 } => Timestamp, 1363;
4512 params!(Time, Interval) => AddTimeInterval => Time, 1800;
4513 params!(Interval, Time) => {
4514 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, AddTimeInterval)))
4515 } => Time, 1849;
4516 params!(Numeric, Numeric) => AddNumeric => Numeric, 1758;
4517 params!(RangeAny, RangeAny) => RangeUnion => RangeAny, 3898;
4518 },
4519 "-" => Scalar {
4520 params!(Int16) => UnaryFunc::NegInt16(func::NegInt16) => Int16, 559;
4521 params!(Int32) => UnaryFunc::NegInt32(func::NegInt32) => Int32, 558;
4522 params!(Int64) => UnaryFunc::NegInt64(func::NegInt64) => Int64, 484;
4523 params!(Float32) => UnaryFunc::NegFloat32(func::NegFloat32) => Float32, 584;
4524 params!(Float64) => UnaryFunc::NegFloat64(func::NegFloat64) => Float64, 585;
4525 params!(Numeric) => UnaryFunc::NegNumeric(func::NegNumeric) => Numeric, 17510;
4526 params!(Interval) => UnaryFunc::NegInterval(func::NegInterval) => Interval, 1336;
4527 params!(Int32, Int32) => SubInt32 => Int32, 555;
4528 params!(Int64, Int64) => SubInt64 => Int64, 685;
4529 params!(UInt16, UInt16) => SubUInt16 => UInt16, oid::FUNC_SUB_UINT16;
4530 params!(UInt32, UInt32) => SubUInt32 => UInt32, oid::FUNC_SUB_UINT32;
4531 params!(UInt64, UInt64) => SubUInt64 => UInt64, oid::FUNC_SUB_UINT64;
4532 params!(Float32, Float32) => SubFloat32 => Float32, 587;
4533 params!(Float64, Float64) => SubFloat64 => Float64, 592;
4534 params!(Numeric, Numeric) => SubNumeric => Numeric, 17590;
4535 params!(Interval, Interval) => SubInterval => Interval, 1338;
4536 params!(Timestamp, Timestamp) => SubTimestamp => Interval, 2067;
4537 params!(TimestampTz, TimestampTz) => SubTimestampTz => Interval, 1328;
4538 params!(Timestamp, Interval) => SubTimestampInterval => Timestamp, 2068;
4539 params!(TimestampTz, Interval) => SubTimestampTzInterval => TimestampTz, 1329;
4540 params!(Date, Date) => SubDate => Int32, 1099;
4541 params!(Date, Interval) => SubDateInterval => Timestamp, 1077;
4542 params!(Time, Time) => SubTime => Interval, 1399;
4543 params!(Time, Interval) => SubTimeInterval => Time, 1801;
4544 params!(Jsonb, Int64) => JsonbDeleteInt64 => Jsonb, 3286;
4545 params!(Jsonb, String) => JsonbDeleteString => Jsonb, 3285;
4546 params!(RangeAny, RangeAny) => RangeDifference => RangeAny, 3899;
4547 },
4550 "*" => Scalar {
4551 params!(Int16, Int16) => MulInt16 => Int16, 526;
4552 params!(Int32, Int32) => MulInt32 => Int32, 514;
4553 params!(Int64, Int64) => MulInt64 => Int64, 686;
4554 params!(UInt16, UInt16) => MulUInt16 => UInt16, oid::FUNC_MUL_UINT16;
4555 params!(UInt32, UInt32) => MulUInt32 => UInt32, oid::FUNC_MUL_UINT32;
4556 params!(UInt64, UInt64) => MulUInt64 => UInt64, oid::FUNC_MUL_UINT64;
4557 params!(Float32, Float32) => MulFloat32 => Float32, 589;
4558 params!(Float64, Float64) => MulFloat64 => Float64, 594;
4559 params!(Interval, Float64) => MulInterval => Interval, 1583;
4560 params!(Float64, Interval) => {
4561 Operation::binary(|_ecx, lhs, rhs| Ok(rhs.call_binary(lhs, MulInterval)))
4562 } => Interval, 1584;
4563 params!(Numeric, Numeric) => MulNumeric => Numeric, 1760;
4564 params!(RangeAny, RangeAny) => RangeIntersection => RangeAny, 3900;
4565 },
4566 "/" => Scalar {
4567 params!(Int16, Int16) => DivInt16 => Int16, 527;
4568 params!(Int32, Int32) => DivInt32 => Int32, 528;
4569 params!(Int64, Int64) => DivInt64 => Int64, 687;
4570 params!(UInt16, UInt16) => DivUInt16 => UInt16, oid::FUNC_DIV_UINT16;
4571 params!(UInt32, UInt32) => DivUInt32 => UInt32, oid::FUNC_DIV_UINT32;
4572 params!(UInt64, UInt64) => DivUInt64 => UInt64, oid::FUNC_DIV_UINT64;
4573 params!(Float32, Float32) => DivFloat32 => Float32, 588;
4574 params!(Float64, Float64) => DivFloat64 => Float64, 593;
4575 params!(Interval, Float64) => DivInterval => Interval, 1585;
4576 params!(Numeric, Numeric) => DivNumeric => Numeric, 1761;
4577 },
4578 "%" => Scalar {
4579 params!(Int16, Int16) => ModInt16 => Int16, 529;
4580 params!(Int32, Int32) => ModInt32 => Int32, 530;
4581 params!(Int64, Int64) => ModInt64 => Int64, 439;
4582 params!(UInt16, UInt16) => ModUInt16 => UInt16, oid::FUNC_MOD_UINT16;
4583 params!(UInt32, UInt32) => ModUInt32 => UInt32, oid::FUNC_MOD_UINT32;
4584 params!(UInt64, UInt64) => ModUInt64 => UInt64, oid::FUNC_MOD_UINT64;
4585 params!(Float32, Float32) => ModFloat32 => Float32, oid::OP_MOD_F32_OID;
4586 params!(Float64, Float64) => ModFloat64 => Float64, oid::OP_MOD_F64_OID;
4587 params!(Numeric, Numeric) => ModNumeric => Numeric, 1762;
4588 },
4589 "&" => Scalar {
4590 params!(Int16, Int16) => BitAndInt16 => Int16, 1874;
4591 params!(Int32, Int32) => BitAndInt32 => Int32, 1880;
4592 params!(Int64, Int64) => BitAndInt64 => Int64, 1886;
4593 params!(UInt16, UInt16) => BitAndUInt16 => UInt16, oid::FUNC_AND_UINT16;
4594 params!(UInt32, UInt32) => BitAndUInt32 => UInt32, oid::FUNC_AND_UINT32;
4595 params!(UInt64, UInt64) => BitAndUInt64 => UInt64, oid::FUNC_AND_UINT64;
4596 },
4597 "|" => Scalar {
4598 params!(Int16, Int16) => BitOrInt16 => Int16, 1875;
4599 params!(Int32, Int32) => BitOrInt32 => Int32, 1881;
4600 params!(Int64, Int64) => BitOrInt64 => Int64, 1887;
4601 params!(UInt16, UInt16) => BitOrUInt16 => UInt16, oid::FUNC_OR_UINT16;
4602 params!(UInt32, UInt32) => BitOrUInt32 => UInt32, oid::FUNC_OR_UINT32;
4603 params!(UInt64, UInt64) => BitOrUInt64 => UInt64, oid::FUNC_OR_UINT64;
4604 },
4605 "#" => Scalar {
4606 params!(Int16, Int16) => BitXorInt16 => Int16, 1876;
4607 params!(Int32, Int32) => BitXorInt32 => Int32, 1882;
4608 params!(Int64, Int64) => BitXorInt64 => Int64, 1888;
4609 params!(UInt16, UInt16) => BitXorUInt16 => UInt16, oid::FUNC_XOR_UINT16;
4610 params!(UInt32, UInt32) => BitXorUInt32 => UInt32, oid::FUNC_XOR_UINT32;
4611 params!(UInt64, UInt64) => BitXorUInt64 => UInt64, oid::FUNC_XOR_UINT64;
4612 },
4613 "<<" => Scalar {
4614 params!(Int16, Int32) => BitShiftLeftInt16 => Int16, 1878;
4615 params!(Int32, Int32) => BitShiftLeftInt32 => Int32, 1884;
4616 params!(Int64, Int32) => BitShiftLeftInt64 => Int64, 1890;
4617 params!(UInt16, UInt32) => BitShiftLeftUInt16 => UInt16, oid::FUNC_SHIFT_LEFT_UINT16;
4618 params!(UInt32, UInt32) => BitShiftLeftUInt32 => UInt32, oid::FUNC_SHIFT_LEFT_UINT32;
4619 params!(UInt64, UInt32) => BitShiftLeftUInt64 => UInt64, oid::FUNC_SHIFT_LEFT_UINT64;
4620 params!(RangeAny, RangeAny) => RangeBefore => Bool, 3893;
4621 },
4622 ">>" => Scalar {
4623 params!(Int16, Int32) => BitShiftRightInt16 => Int16, 1879;
4624 params!(Int32, Int32) => BitShiftRightInt32 => Int32, 1885;
4625 params!(Int64, Int32) => BitShiftRightInt64 => Int64, 1891;
4626 params!(UInt16, UInt32) => BitShiftRightUInt16 => UInt16, oid::FUNC_SHIFT_RIGHT_UINT16;
4627 params!(UInt32, UInt32) => BitShiftRightUInt32 => UInt32, oid::FUNC_SHIFT_RIGHT_UINT32;
4628 params!(UInt64, UInt32) => BitShiftRightUInt64 => UInt64, oid::FUNC_SHIFT_RIGHT_UINT64;
4629 params!(RangeAny, RangeAny) => RangeAfter => Bool, 3894;
4630 },
4631
4632 "~~*" => Scalar {
4634 params!(String, String) => IsLikeMatch { case_insensitive: true } => Bool, 1627;
4635 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4636 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4637 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4638 .call_binary(rhs, IsLikeMatch { case_insensitive: true })
4639 )
4640 }) => Bool, 1629;
4641 },
4642 "!~~*" => Scalar {
4643 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
4644 Ok(lhs
4645 .call_binary(rhs, IsLikeMatch { case_insensitive: true })
4646 .call_unary(UnaryFunc::Not(func::Not)))
4647 }) => Bool, 1628;
4648 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4649 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4650 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4651 .call_binary(rhs, IsLikeMatch { case_insensitive: true })
4652 .call_unary(UnaryFunc::Not(func::Not))
4653 )
4654 }) => Bool, 1630;
4655 },
4656
4657
4658 "~~" => Scalar {
4660 params!(String, String) => IsLikeMatch { case_insensitive: false } => Bool, 1209;
4661 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4662 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4663 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4664 .call_binary(rhs, IsLikeMatch { case_insensitive: false })
4665 )
4666 }) => Bool, 1211;
4667 },
4668 "!~~" => Scalar {
4669 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
4670 Ok(lhs
4671 .call_binary(rhs, IsLikeMatch { case_insensitive: false })
4672 .call_unary(UnaryFunc::Not(func::Not)))
4673 }) => Bool, 1210;
4674 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4675 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4676 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4677 .call_binary(rhs, IsLikeMatch { case_insensitive: false })
4678 .call_unary(UnaryFunc::Not(func::Not))
4679 )
4680 }) => Bool, 1212;
4681 },
4682
4683 "~" => Scalar {
4685 params!(Int16) => UnaryFunc::BitNotInt16(func::BitNotInt16) => Int16, 1877;
4686 params!(Int32) => UnaryFunc::BitNotInt32(func::BitNotInt32) => Int32, 1883;
4687 params!(Int64) => UnaryFunc::BitNotInt64(func::BitNotInt64) => Int64, 1889;
4688 params!(UInt16) => UnaryFunc::BitNotUint16(func::BitNotUint16) => UInt16, oid::FUNC_BIT_NOT_UINT16_OID;
4689 params!(UInt32) => UnaryFunc::BitNotUint32(func::BitNotUint32) => UInt32, oid::FUNC_BIT_NOT_UINT32_OID;
4690 params!(UInt64) => UnaryFunc::BitNotUint64(func::BitNotUint64) => UInt64, oid::FUNC_BIT_NOT_UINT64_OID;
4691 params!(String, String) => IsRegexpMatch { case_insensitive: false } => Bool, 641;
4692 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4693 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4694 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4695 .call_binary(rhs, IsRegexpMatch { case_insensitive: false })
4696 )
4697 }) => Bool, 1055;
4698 },
4699 "~*" => Scalar {
4700 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
4701 Ok(lhs.call_binary(rhs, IsRegexpMatch { case_insensitive: true }))
4702 }) => Bool, 1228;
4703 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4704 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4705 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4706 .call_binary(rhs, IsRegexpMatch { case_insensitive: true })
4707 )
4708 }) => Bool, 1234;
4709 },
4710 "!~" => Scalar {
4711 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
4712 Ok(lhs
4713 .call_binary(rhs, IsRegexpMatch { case_insensitive: false })
4714 .call_unary(UnaryFunc::Not(func::Not)))
4715 }) => Bool, 642;
4716 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4717 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4718 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4719 .call_binary(rhs, IsRegexpMatch { case_insensitive: false })
4720 .call_unary(UnaryFunc::Not(func::Not))
4721 )
4722 }) => Bool, 1056;
4723 },
4724 "!~*" => Scalar {
4725 params!(String, String) => Operation::binary(|_ecx, lhs, rhs| {
4726 Ok(lhs
4727 .call_binary(rhs, IsRegexpMatch { case_insensitive: true })
4728 .call_unary(UnaryFunc::Not(func::Not)))
4729 }) => Bool, 1229;
4730 params!(Char, String) => Operation::binary(|ecx, lhs, rhs| {
4731 let length = ecx.scalar_type(&lhs).unwrap_char_length();
4732 Ok(lhs.call_unary(UnaryFunc::PadChar(func::PadChar { length }))
4733 .call_binary(rhs, IsRegexpMatch { case_insensitive: true })
4734 .call_unary(UnaryFunc::Not(func::Not))
4735 )
4736 }) => Bool, 1235;
4737 },
4738
4739 "||" => Scalar {
4741 params!(String, NonVecAny) => Operation::binary(|ecx, lhs, rhs| {
4742 let rhs = typeconv::plan_cast(
4743 ecx,
4744 CastContext::Explicit,
4745 rhs,
4746 &ScalarType::String,
4747 )?;
4748 Ok(lhs.call_binary(rhs, TextConcat))
4749 }) => String, 2779;
4750 params!(NonVecAny, String) => Operation::binary(|ecx, lhs, rhs| {
4751 let lhs = typeconv::plan_cast(
4752 ecx,
4753 CastContext::Explicit,
4754 lhs,
4755 &ScalarType::String,
4756 )?;
4757 Ok(lhs.call_binary(rhs, TextConcat))
4758 }) => String, 2780;
4759 params!(String, String) => TextConcat => String, 654;
4760 params!(Jsonb, Jsonb) => JsonbConcat => Jsonb, 3284;
4761 params!(ArrayAnyCompatible, ArrayAnyCompatible) => ArrayArrayConcat => ArrayAnyCompatible, 375;
4762 params!(ListAnyCompatible, ListAnyCompatible) => ListListConcat => ListAnyCompatible, oid::OP_CONCAT_LIST_LIST_OID;
4763 params!(ListAnyCompatible, ListElementAnyCompatible) => ListElementConcat => ListAnyCompatible, oid::OP_CONCAT_LIST_ELEMENT_OID;
4764 params!(ListElementAnyCompatible, ListAnyCompatible) => ElementListConcat => ListAnyCompatible, oid::OP_CONCAT_ELEMENY_LIST_OID;
4765 },
4766
4767 "->" => Scalar {
4769 params!(Jsonb, Int64) => JsonbGetInt64 => Jsonb, 3212;
4770 params!(Jsonb, String) => JsonbGetString => Jsonb, 3211;
4771 params!(MapAny, String) => MapGetValue => Any, oid::OP_GET_VALUE_MAP_OID;
4772 },
4773 "->>" => Scalar {
4774 params!(Jsonb, Int64) => JsonbGetInt64Stringify => String, 3481;
4775 params!(Jsonb, String) => JsonbGetStringStringify => String, 3477;
4776 },
4777 "#>" => Scalar {
4778 params!(Jsonb, ScalarType::Array(Box::new(ScalarType::String))) => JsonbGetPath => Jsonb, 3213;
4779 },
4780 "#>>" => Scalar {
4781 params!(Jsonb, ScalarType::Array(Box::new(ScalarType::String))) => JsonbGetPathStringify => String, 3206;
4782 },
4783 "@>" => Scalar {
4784 params!(Jsonb, Jsonb) => JsonbContainsJsonb => Bool, 3246;
4785 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
4786 Ok(lhs.call_binary(
4787 rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
4788 JsonbContainsJsonb,
4789 ))
4790 }) => Bool, oid::OP_CONTAINS_JSONB_STRING_OID;
4791 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
4792 Ok(lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
4793 .call_binary(rhs, JsonbContainsJsonb))
4794 }) => Bool, oid::OP_CONTAINS_STRING_JSONB_OID;
4795 params!(MapAnyCompatible, MapAnyCompatible) => MapContainsMap => Bool, oid::OP_CONTAINS_MAP_MAP_OID;
4796 params!(RangeAny, AnyElement) => Operation::binary(|ecx, lhs, rhs| {
4797 let elem_type = ecx.scalar_type(&lhs).unwrap_range_element_type().clone();
4798 Ok(lhs.call_binary(rhs, BinaryFunc::RangeContainsElem { elem_type, rev: false }))
4799 }) => Bool, 3889;
4800 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
4801 Ok(lhs.call_binary(rhs, BinaryFunc::RangeContainsRange { rev: false }))
4802 }) => Bool, 3890;
4803 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
4804 Ok(lhs.call_binary(rhs, BinaryFunc::ArrayContainsArray { rev: false }))
4805 }) => Bool, 2751;
4806 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
4807 Ok(lhs.call_binary(rhs, BinaryFunc::ListContainsList { rev: false }))
4808 }) => Bool, oid::OP_CONTAINS_LIST_LIST_OID;
4809 },
4810 "<@" => Scalar {
4811 params!(Jsonb, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
4812 Ok(rhs.call_binary(
4813 lhs,
4814 JsonbContainsJsonb
4815 ))
4816 }) => Bool, 3250;
4817 params!(Jsonb, String) => Operation::binary(|_ecx, lhs, rhs| {
4818 Ok(rhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb))
4819 .call_binary(lhs, BinaryFunc::JsonbContainsJsonb))
4820 }) => Bool, oid::OP_CONTAINED_JSONB_STRING_OID;
4821 params!(String, Jsonb) => Operation::binary(|_ecx, lhs, rhs| {
4822 Ok(rhs.call_binary(
4823 lhs.call_unary(UnaryFunc::CastStringToJsonb(func::CastStringToJsonb)),
4824 BinaryFunc::JsonbContainsJsonb,
4825 ))
4826 }) => Bool, oid::OP_CONTAINED_STRING_JSONB_OID;
4827 params!(MapAnyCompatible, MapAnyCompatible) => Operation::binary(|_ecx, lhs, rhs| {
4828 Ok(rhs.call_binary(lhs, MapContainsMap))
4829 }) => Bool, oid::OP_CONTAINED_MAP_MAP_OID;
4830 params!(AnyElement, RangeAny) => Operation::binary(|ecx, lhs, rhs| {
4831 let elem_type = ecx.scalar_type(&rhs).unwrap_range_element_type().clone();
4832 Ok(rhs.call_binary(lhs, BinaryFunc::RangeContainsElem { elem_type, rev: true }))
4833 }) => Bool, 3891;
4834 params!(RangeAny, RangeAny) => Operation::binary(|_ecx, lhs, rhs| {
4835 Ok(rhs.call_binary(lhs, BinaryFunc::RangeContainsRange { rev: true }))
4836 }) => Bool, 3892;
4837 params!(ArrayAny, ArrayAny) => Operation::binary(|_ecx, lhs, rhs| {
4838 Ok(lhs.call_binary(rhs, BinaryFunc::ArrayContainsArray { rev: true }))
4839 }) => Bool, 2752;
4840 params!(ListAny, ListAny) => Operation::binary(|_ecx, lhs, rhs| {
4841 Ok(lhs.call_binary(rhs, BinaryFunc::ListContainsList { rev: true }))
4842 }) => Bool, oid::OP_IS_CONTAINED_LIST_LIST_OID;
4843 },
4844 "?" => Scalar {
4845 params!(Jsonb, String) => JsonbContainsString => Bool, 3247;
4846 params!(MapAny, String) => MapContainsKey => Bool, oid::OP_CONTAINS_KEY_MAP_OID;
4847 },
4848 "?&" => Scalar {
4849 params!(MapAny, ScalarType::Array(Box::new(ScalarType::String))) => MapContainsAllKeys => Bool, oid::OP_CONTAINS_ALL_KEYS_MAP_OID;
4850 },
4851 "?|" => Scalar {
4852 params!(MapAny, ScalarType::Array(Box::new(ScalarType::String))) => MapContainsAnyKeys => Bool, oid::OP_CONTAINS_ANY_KEYS_MAP_OID;
4853 },
4854 "&&" => Scalar {
4855 params!(RangeAny, RangeAny) => BinaryFunc::RangeOverlaps => Bool, 3888;
4856 },
4857 "&<" => Scalar {
4858 params!(RangeAny, RangeAny) => BinaryFunc::RangeOverleft => Bool, 3895;
4859 },
4860 "&>" => Scalar {
4861 params!(RangeAny, RangeAny) => BinaryFunc::RangeOverright => Bool, 3896;
4862 },
4863 "-|-" => Scalar {
4864 params!(RangeAny, RangeAny) => BinaryFunc::RangeAdjacent => Bool, 3897;
4865 },
4866
4867 "<" => Scalar {
4869 params!(Numeric, Numeric) => BinaryFunc::Lt => Bool, 1754;
4870 params!(Bool, Bool) => BinaryFunc::Lt => Bool, 58;
4871 params!(Int16, Int16) => BinaryFunc::Lt => Bool, 95;
4872 params!(Int32, Int32) => BinaryFunc::Lt => Bool, 97;
4873 params!(Int64, Int64) => BinaryFunc::Lt => Bool, 412;
4874 params!(UInt16, UInt16) => BinaryFunc::Lt => Bool, oid::FUNC_LT_UINT16_OID;
4875 params!(UInt32, UInt32) => BinaryFunc::Lt => Bool, oid::FUNC_LT_UINT32_OID;
4876 params!(UInt64, UInt64) => BinaryFunc::Lt => Bool, oid::FUNC_LT_UINT64_OID;
4877 params!(Float32, Float32) => BinaryFunc::Lt => Bool, 622;
4878 params!(Float64, Float64) => BinaryFunc::Lt => Bool, 672;
4879 params!(Oid, Oid) => BinaryFunc::Lt => Bool, 609;
4880 params!(Date, Date) => BinaryFunc::Lt => Bool, 1095;
4881 params!(Time, Time) => BinaryFunc::Lt => Bool, 1110;
4882 params!(Timestamp, Timestamp) => BinaryFunc::Lt => Bool, 2062;
4883 params!(TimestampTz, TimestampTz) => BinaryFunc::Lt => Bool, 1322;
4884 params!(Uuid, Uuid) => BinaryFunc::Lt => Bool, 2974;
4885 params!(Interval, Interval) => BinaryFunc::Lt => Bool, 1332;
4886 params!(Bytes, Bytes) => BinaryFunc::Lt => Bool, 1957;
4887 params!(String, String) => BinaryFunc::Lt => Bool, 664;
4888 params!(Char, Char) => BinaryFunc::Lt => Bool, 1058;
4889 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::Lt => Bool, 631;
4890 params!(PgLegacyName, PgLegacyName) => BinaryFunc::Lt => Bool, 660;
4891 params!(Jsonb, Jsonb) => BinaryFunc::Lt => Bool, 3242;
4892 params!(ArrayAny, ArrayAny) => BinaryFunc::Lt => Bool, 1072;
4893 params!(RecordAny, RecordAny) => BinaryFunc::Lt => Bool, 2990;
4894 params!(MzTimestamp, MzTimestamp)=>BinaryFunc::Lt =>Bool, oid::FUNC_MZ_TIMESTAMP_LT_MZ_TIMESTAMP_OID;
4895 params!(RangeAny, RangeAny) => BinaryFunc::Lt => Bool, 3884;
4896 },
4897 "<=" => Scalar {
4898 params!(Numeric, Numeric) => BinaryFunc::Lte => Bool, 1755;
4899 params!(Bool, Bool) => BinaryFunc::Lte => Bool, 1694;
4900 params!(Int16, Int16) => BinaryFunc::Lte => Bool, 522;
4901 params!(Int32, Int32) => BinaryFunc::Lte => Bool, 523;
4902 params!(Int64, Int64) => BinaryFunc::Lte => Bool, 414;
4903 params!(UInt16, UInt16) => BinaryFunc::Lte => Bool, oid::FUNC_LTE_UINT16_OID;
4904 params!(UInt32, UInt32) => BinaryFunc::Lte => Bool, oid::FUNC_LTE_UINT32_OID;
4905 params!(UInt64, UInt64) => BinaryFunc::Lte => Bool, oid::FUNC_LTE_UINT64_OID;
4906 params!(Float32, Float32) => BinaryFunc::Lte => Bool, 624;
4907 params!(Float64, Float64) => BinaryFunc::Lte => Bool, 673;
4908 params!(Oid, Oid) => BinaryFunc::Lte => Bool, 611;
4909 params!(Date, Date) => BinaryFunc::Lte => Bool, 1096;
4910 params!(Time, Time) => BinaryFunc::Lte => Bool, 1111;
4911 params!(Timestamp, Timestamp) => BinaryFunc::Lte => Bool, 2063;
4912 params!(TimestampTz, TimestampTz) => BinaryFunc::Lte => Bool, 1323;
4913 params!(Uuid, Uuid) => BinaryFunc::Lte => Bool, 2976;
4914 params!(Interval, Interval) => BinaryFunc::Lte => Bool, 1333;
4915 params!(Bytes, Bytes) => BinaryFunc::Lte => Bool, 1958;
4916 params!(String, String) => BinaryFunc::Lte => Bool, 665;
4917 params!(Char, Char) => BinaryFunc::Lte => Bool, 1059;
4918 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::Lte => Bool, 632;
4919 params!(PgLegacyName, PgLegacyName) => BinaryFunc::Lte => Bool, 661;
4920 params!(Jsonb, Jsonb) => BinaryFunc::Lte => Bool, 3244;
4921 params!(ArrayAny, ArrayAny) => BinaryFunc::Lte => Bool, 1074;
4922 params!(RecordAny, RecordAny) => BinaryFunc::Lte => Bool, 2992;
4923 params!(MzTimestamp, MzTimestamp)=>BinaryFunc::Lte =>Bool, oid::FUNC_MZ_TIMESTAMP_LTE_MZ_TIMESTAMP_OID;
4924 params!(RangeAny, RangeAny) => BinaryFunc::Lte => Bool, 3885;
4925 },
4926 ">" => Scalar {
4927 params!(Numeric, Numeric) => BinaryFunc::Gt => Bool, 1756;
4928 params!(Bool, Bool) => BinaryFunc::Gt => Bool, 59;
4929 params!(Int16, Int16) => BinaryFunc::Gt => Bool, 520;
4930 params!(Int32, Int32) => BinaryFunc::Gt => Bool, 521;
4931 params!(Int64, Int64) => BinaryFunc::Gt => Bool, 413;
4932 params!(UInt16, UInt16) => BinaryFunc::Gt => Bool, oid::FUNC_GT_UINT16_OID;
4933 params!(UInt32, UInt32) => BinaryFunc::Gt => Bool, oid::FUNC_GT_UINT32_OID;
4934 params!(UInt64, UInt64) => BinaryFunc::Gt => Bool, oid::FUNC_GT_UINT64_OID;
4935 params!(Float32, Float32) => BinaryFunc::Gt => Bool, 623;
4936 params!(Float64, Float64) => BinaryFunc::Gt => Bool, 674;
4937 params!(Oid, Oid) => BinaryFunc::Gt => Bool, 610;
4938 params!(Date, Date) => BinaryFunc::Gt => Bool, 1097;
4939 params!(Time, Time) => BinaryFunc::Gt => Bool, 1112;
4940 params!(Timestamp, Timestamp) => BinaryFunc::Gt => Bool, 2064;
4941 params!(TimestampTz, TimestampTz) => BinaryFunc::Gt => Bool, 1324;
4942 params!(Uuid, Uuid) => BinaryFunc::Gt => Bool, 2975;
4943 params!(Interval, Interval) => BinaryFunc::Gt => Bool, 1334;
4944 params!(Bytes, Bytes) => BinaryFunc::Gt => Bool, 1959;
4945 params!(String, String) => BinaryFunc::Gt => Bool, 666;
4946 params!(Char, Char) => BinaryFunc::Gt => Bool, 1060;
4947 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::Gt => Bool, 633;
4948 params!(PgLegacyName, PgLegacyName) => BinaryFunc::Gt => Bool, 662;
4949 params!(Jsonb, Jsonb) => BinaryFunc::Gt => Bool, 3243;
4950 params!(ArrayAny, ArrayAny) => BinaryFunc::Gt => Bool, 1073;
4951 params!(RecordAny, RecordAny) => BinaryFunc::Gt => Bool, 2991;
4952 params!(MzTimestamp, MzTimestamp)=>BinaryFunc::Gt =>Bool, oid::FUNC_MZ_TIMESTAMP_GT_MZ_TIMESTAMP_OID;
4953 params!(RangeAny, RangeAny) => BinaryFunc::Gt => Bool, 3887;
4954 },
4955 ">=" => Scalar {
4956 params!(Numeric, Numeric) => BinaryFunc::Gte => Bool, 1757;
4957 params!(Bool, Bool) => BinaryFunc::Gte => Bool, 1695;
4958 params!(Int16, Int16) => BinaryFunc::Gte => Bool, 524;
4959 params!(Int32, Int32) => BinaryFunc::Gte => Bool, 525;
4960 params!(Int64, Int64) => BinaryFunc::Gte => Bool, 415;
4961 params!(UInt16, UInt16) => BinaryFunc::Gte => Bool, oid::FUNC_GTE_UINT16_OID;
4962 params!(UInt32, UInt32) => BinaryFunc::Gte => Bool, oid::FUNC_GTE_UINT32_OID;
4963 params!(UInt64, UInt64) => BinaryFunc::Gte => Bool, oid::FUNC_GTE_UINT64_OID;
4964 params!(Float32, Float32) => BinaryFunc::Gte => Bool, 625;
4965 params!(Float64, Float64) => BinaryFunc::Gte => Bool, 675;
4966 params!(Oid, Oid) => BinaryFunc::Gte => Bool, 612;
4967 params!(Date, Date) => BinaryFunc::Gte => Bool, 1098;
4968 params!(Time, Time) => BinaryFunc::Gte => Bool, 1113;
4969 params!(Timestamp, Timestamp) => BinaryFunc::Gte => Bool, 2065;
4970 params!(TimestampTz, TimestampTz) => BinaryFunc::Gte => Bool, 1325;
4971 params!(Uuid, Uuid) => BinaryFunc::Gte => Bool, 2977;
4972 params!(Interval, Interval) => BinaryFunc::Gte => Bool, 1335;
4973 params!(Bytes, Bytes) => BinaryFunc::Gte => Bool, 1960;
4974 params!(String, String) => BinaryFunc::Gte => Bool, 667;
4975 params!(Char, Char) => BinaryFunc::Gte => Bool, 1061;
4976 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::Gte => Bool, 634;
4977 params!(PgLegacyName, PgLegacyName) => BinaryFunc::Gte => Bool, 663;
4978 params!(Jsonb, Jsonb) => BinaryFunc::Gte => Bool, 3245;
4979 params!(ArrayAny, ArrayAny) => BinaryFunc::Gte => Bool, 1075;
4980 params!(RecordAny, RecordAny) => BinaryFunc::Gte => Bool, 2993;
4981 params!(MzTimestamp, MzTimestamp)=>BinaryFunc::Gte =>Bool, oid::FUNC_MZ_TIMESTAMP_GTE_MZ_TIMESTAMP_OID;
4982 params!(RangeAny, RangeAny) => BinaryFunc::Gte => Bool, 3886;
4983 },
4984 "=" => Scalar {
4994 params!(Numeric, Numeric) => BinaryFunc::Eq => Bool, 1752;
4995 params!(Bool, Bool) => BinaryFunc::Eq => Bool, 91;
4996 params!(Int16, Int16) => BinaryFunc::Eq => Bool, 94;
4997 params!(Int32, Int32) => BinaryFunc::Eq => Bool, 96;
4998 params!(Int64, Int64) => BinaryFunc::Eq => Bool, 410;
4999 params!(UInt16, UInt16) => BinaryFunc::Eq => Bool, oid::FUNC_EQ_UINT16_OID;
5000 params!(UInt32, UInt32) => BinaryFunc::Eq => Bool, oid::FUNC_EQ_UINT32_OID;
5001 params!(UInt64, UInt64) => BinaryFunc::Eq => Bool, oid::FUNC_EQ_UINT64_OID;
5002 params!(Float32, Float32) => BinaryFunc::Eq => Bool, 620;
5003 params!(Float64, Float64) => BinaryFunc::Eq => Bool, 670;
5004 params!(Oid, Oid) => BinaryFunc::Eq => Bool, 607;
5005 params!(Date, Date) => BinaryFunc::Eq => Bool, 1093;
5006 params!(Time, Time) => BinaryFunc::Eq => Bool, 1108;
5007 params!(Timestamp, Timestamp) => BinaryFunc::Eq => Bool, 2060;
5008 params!(TimestampTz, TimestampTz) => BinaryFunc::Eq => Bool, 1320;
5009 params!(Uuid, Uuid) => BinaryFunc::Eq => Bool, 2972;
5010 params!(Interval, Interval) => BinaryFunc::Eq => Bool, 1330;
5011 params!(Bytes, Bytes) => BinaryFunc::Eq => Bool, 1955;
5012 params!(String, String) => BinaryFunc::Eq => Bool, 98;
5013 params!(Char, Char) => BinaryFunc::Eq => Bool, 1054;
5014 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::Eq => Bool, 92;
5015 params!(PgLegacyName, PgLegacyName) => BinaryFunc::Eq => Bool, 93;
5016 params!(Jsonb, Jsonb) => BinaryFunc::Eq => Bool, 3240;
5017 params!(ListAny, ListAny) => BinaryFunc::Eq => Bool, oid::FUNC_LIST_EQ_OID;
5018 params!(ArrayAny, ArrayAny) => BinaryFunc::Eq => Bool, 1070;
5019 params!(RecordAny, RecordAny) => BinaryFunc::Eq => Bool, 2988;
5020 params!(MzTimestamp, MzTimestamp) => BinaryFunc::Eq => Bool, oid::FUNC_MZ_TIMESTAMP_EQ_MZ_TIMESTAMP_OID;
5021 params!(RangeAny, RangeAny) => BinaryFunc::Eq => Bool, 3882;
5022 params!(MzAclItem, MzAclItem) => BinaryFunc::Eq => Bool, oid::FUNC_MZ_ACL_ITEM_EQ_MZ_ACL_ITEM_OID;
5023 params!(AclItem, AclItem) => BinaryFunc::Eq => Bool, 974;
5024 },
5025 "<>" => Scalar {
5026 params!(Numeric, Numeric) => BinaryFunc::NotEq => Bool, 1753;
5027 params!(Bool, Bool) => BinaryFunc::NotEq => Bool, 85;
5028 params!(Int16, Int16) => BinaryFunc::NotEq => Bool, 519;
5029 params!(Int32, Int32) => BinaryFunc::NotEq => Bool, 518;
5030 params!(Int64, Int64) => BinaryFunc::NotEq => Bool, 411;
5031 params!(UInt16, UInt16) => BinaryFunc::NotEq => Bool, oid::FUNC_NOT_EQ_UINT16_OID;
5032 params!(UInt32, UInt32) => BinaryFunc::NotEq => Bool, oid::FUNC_NOT_EQ_UINT32_OID;
5033 params!(UInt64, UInt64) => BinaryFunc::NotEq => Bool, oid::FUNC_NOT_EQ_UINT64_OID;
5034 params!(Float32, Float32) => BinaryFunc::NotEq => Bool, 621;
5035 params!(Float64, Float64) => BinaryFunc::NotEq => Bool, 671;
5036 params!(Oid, Oid) => BinaryFunc::NotEq => Bool, 608;
5037 params!(Date, Date) => BinaryFunc::NotEq => Bool, 1094;
5038 params!(Time, Time) => BinaryFunc::NotEq => Bool, 1109;
5039 params!(Timestamp, Timestamp) => BinaryFunc::NotEq => Bool, 2061;
5040 params!(TimestampTz, TimestampTz) => BinaryFunc::NotEq => Bool, 1321;
5041 params!(Uuid, Uuid) => BinaryFunc::NotEq => Bool, 2973;
5042 params!(Interval, Interval) => BinaryFunc::NotEq => Bool, 1331;
5043 params!(Bytes, Bytes) => BinaryFunc::NotEq => Bool, 1956;
5044 params!(String, String) => BinaryFunc::NotEq => Bool, 531;
5045 params!(Char, Char) => BinaryFunc::NotEq => Bool, 1057;
5046 params!(PgLegacyChar, PgLegacyChar) => BinaryFunc::NotEq => Bool, 630;
5047 params!(PgLegacyName, PgLegacyName) => BinaryFunc::NotEq => Bool, 643;
5048 params!(Jsonb, Jsonb) => BinaryFunc::NotEq => Bool, 3241;
5049 params!(ArrayAny, ArrayAny) => BinaryFunc::NotEq => Bool, 1071;
5050 params!(RecordAny, RecordAny) => BinaryFunc::NotEq => Bool, 2989;
5051 params!(MzTimestamp, MzTimestamp) => BinaryFunc::NotEq => Bool, oid::FUNC_MZ_TIMESTAMP_NOT_EQ_MZ_TIMESTAMP_OID;
5052 params!(RangeAny, RangeAny) => BinaryFunc::NotEq => Bool, 3883;
5053 params!(MzAclItem, MzAclItem) => BinaryFunc::NotEq => Bool, oid::FUNC_MZ_ACL_ITEM_NOT_EQ_MZ_ACL_ITEM_OID;
5054 }
5055 }
5056});
5057
5058pub fn resolve_op(op: &str) -> Result<&'static [FuncImpl<HirScalarExpr>], PlanError> {
5060 match OP_IMPLS.get(op) {
5061 Some(Func::Scalar(impls)) => Ok(impls),
5062 Some(_) => unreachable!("all operators must be scalar functions"),
5063 None => bail_unsupported!(format!("[{}]", op)),
5073 }
5074}
5075
5076fn current_settings(
5079 name: HirScalarExpr,
5080 missing_ok: HirScalarExpr,
5081) -> Result<HirScalarExpr, PlanError> {
5082 let expr = HirScalarExpr::call_binary(
5084 HirScalarExpr::CallUnmaterializable(UnmaterializableFunc::ViewableVariables),
5085 HirScalarExpr::call_unary(name, UnaryFunc::Lower(func::Lower)),
5086 BinaryFunc::MapGetValue,
5087 );
5088 let expr = HirScalarExpr::If {
5089 cond: Box::new(missing_ok),
5090 then: Box::new(expr.clone()),
5091 els: Box::new(HirScalarExpr::CallVariadic {
5092 func: VariadicFunc::ErrorIfNull,
5093 exprs: vec![
5094 expr,
5095 HirScalarExpr::literal(
5096 Datum::String("unrecognized configuration parameter"),
5097 ScalarType::String,
5098 ),
5099 ],
5100 }),
5101 };
5102 Ok(expr)
5103}