1use std::borrow::Cow;
15use std::cmp::{self, Ordering};
16use std::convert::{TryFrom, TryInto};
17use std::ops::Deref;
18use std::str::FromStr;
19use std::{fmt, iter, str};
20
21use ::encoding::DecoderTrap;
22use ::encoding::label::encoding_from_whatwg_label;
23use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, TimeZone, Timelike, Utc};
24use chrono_tz::{OffsetComponents, OffsetName, Tz};
25use dec::OrderedDecimal;
26use fallible_iterator::FallibleIterator;
27use hmac::{Hmac, Mac};
28use itertools::Itertools;
29use md5::{Digest, Md5};
30use mz_expr_derive::sqlfunc;
31use mz_lowertest::MzReflect;
32use mz_ore::cast::{self, CastFrom, ReinterpretCast};
33use mz_ore::fmt::FormatBuffer;
34use mz_ore::lex::LexBuf;
35use mz_ore::option::OptionExt;
36use mz_ore::result::ResultExt;
37use mz_ore::soft_assert_eq_or_log;
38use mz_ore::str::StrExt;
39use mz_pgrepr::Type;
40use mz_pgtz::timezone::{Timezone, TimezoneSpec};
41use mz_proto::chrono::any_naive_datetime;
42use mz_proto::{IntoRustIfSome, ProtoType, RustType, TryFromProtoError};
43use mz_repr::adt::array::ArrayDimension;
44use mz_repr::adt::date::Date;
45use mz_repr::adt::interval::{Interval, RoundBehavior};
46use mz_repr::adt::jsonb::JsonbRef;
47use mz_repr::adt::mz_acl_item::{AclItem, AclMode, MzAclItem};
48use mz_repr::adt::numeric::{self, DecimalLike, Numeric, NumericMaxScale};
49use mz_repr::adt::range::{self, Range, RangeBound, RangeOps};
50use mz_repr::adt::regex::{Regex, any_regex};
51use mz_repr::adt::system::Oid;
52use mz_repr::adt::timestamp::{CheckedTimestamp, TimestampLike};
53use mz_repr::role_id::RoleId;
54use mz_repr::{ColumnName, ColumnType, Datum, DatumType, Row, RowArena, ScalarType, strconv};
55use mz_sql_parser::ast::display::FormatMode;
56use mz_sql_pretty::{PrettyConfig, pretty_str};
57use num::traits::CheckedNeg;
58use proptest::prelude::*;
59use proptest::strategy::*;
60use proptest_derive::Arbitrary;
61use serde::{Deserialize, Serialize};
62use sha1::Sha1;
63use sha2::{Sha224, Sha256, Sha384, Sha512};
64use subtle::ConstantTimeEq;
65
66use crate::scalar::func::format::DateTimeFormat;
67use crate::scalar::{
68 ProtoBinaryFunc, ProtoUnaryFunc, ProtoUnmaterializableFunc, ProtoVariadicFunc,
69};
70use crate::{EvalError, MirScalarExpr, like_pattern};
71
72#[macro_use]
73mod macros;
74mod binary;
75mod encoding;
76pub(crate) mod format;
77pub(crate) mod impls;
78
79pub use impls::*;
80
81const MAX_STRING_BYTES: usize = 1024 * 1024 * 100;
85
86#[derive(
87 Arbitrary, Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect,
88)]
89pub enum UnmaterializableFunc {
90 CurrentDatabase,
91 CurrentSchema,
92 CurrentSchemasWithSystem,
93 CurrentSchemasWithoutSystem,
94 CurrentTimestamp,
95 CurrentUser,
96 IsRbacEnabled,
97 MzEnvironmentId,
98 MzIsSuperuser,
99 MzNow,
100 MzRoleOidMemberships,
101 MzSessionId,
102 MzUptime,
103 MzVersion,
104 MzVersionNum,
105 PgBackendPid,
106 PgPostmasterStartTime,
107 SessionUser,
108 Version,
109 ViewableVariables,
110}
111
112impl UnmaterializableFunc {
113 pub fn output_type(&self) -> ColumnType {
114 match self {
115 UnmaterializableFunc::CurrentDatabase => ScalarType::String.nullable(false),
116 UnmaterializableFunc::CurrentSchema => ScalarType::String.nullable(true),
120 UnmaterializableFunc::CurrentSchemasWithSystem => {
125 ScalarType::Array(Box::new(ScalarType::String)).nullable(false)
126 }
127 UnmaterializableFunc::CurrentSchemasWithoutSystem => {
128 ScalarType::Array(Box::new(ScalarType::String)).nullable(false)
129 }
130 UnmaterializableFunc::CurrentTimestamp => {
131 ScalarType::TimestampTz { precision: None }.nullable(false)
132 }
133 UnmaterializableFunc::CurrentUser => ScalarType::String.nullable(false),
134 UnmaterializableFunc::IsRbacEnabled => ScalarType::Bool.nullable(false),
135 UnmaterializableFunc::MzEnvironmentId => ScalarType::String.nullable(false),
136 UnmaterializableFunc::MzIsSuperuser => ScalarType::Bool.nullable(false),
137 UnmaterializableFunc::MzNow => ScalarType::MzTimestamp.nullable(false),
138 UnmaterializableFunc::MzRoleOidMemberships => ScalarType::Map {
139 value_type: Box::new(ScalarType::Array(Box::new(ScalarType::String))),
140 custom_id: None,
141 }
142 .nullable(false),
143 UnmaterializableFunc::MzSessionId => ScalarType::Uuid.nullable(false),
144 UnmaterializableFunc::MzUptime => ScalarType::Interval.nullable(true),
145 UnmaterializableFunc::MzVersion => ScalarType::String.nullable(false),
146 UnmaterializableFunc::MzVersionNum => ScalarType::Int32.nullable(false),
147 UnmaterializableFunc::PgBackendPid => ScalarType::Int32.nullable(false),
148 UnmaterializableFunc::PgPostmasterStartTime => {
149 ScalarType::TimestampTz { precision: None }.nullable(false)
150 }
151 UnmaterializableFunc::SessionUser => ScalarType::String.nullable(false),
152 UnmaterializableFunc::Version => ScalarType::String.nullable(false),
153 UnmaterializableFunc::ViewableVariables => ScalarType::Map {
154 value_type: Box::new(ScalarType::String),
155 custom_id: None,
156 }
157 .nullable(false),
158 }
159 }
160}
161
162impl fmt::Display for UnmaterializableFunc {
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 match self {
165 UnmaterializableFunc::CurrentDatabase => f.write_str("current_database"),
166 UnmaterializableFunc::CurrentSchema => f.write_str("current_schema"),
167 UnmaterializableFunc::CurrentSchemasWithSystem => f.write_str("current_schemas(true)"),
168 UnmaterializableFunc::CurrentSchemasWithoutSystem => {
169 f.write_str("current_schemas(false)")
170 }
171 UnmaterializableFunc::CurrentTimestamp => f.write_str("current_timestamp"),
172 UnmaterializableFunc::CurrentUser => f.write_str("current_user"),
173 UnmaterializableFunc::IsRbacEnabled => f.write_str("is_rbac_enabled"),
174 UnmaterializableFunc::MzEnvironmentId => f.write_str("mz_environment_id"),
175 UnmaterializableFunc::MzIsSuperuser => f.write_str("mz_is_superuser"),
176 UnmaterializableFunc::MzNow => f.write_str("mz_now"),
177 UnmaterializableFunc::MzRoleOidMemberships => f.write_str("mz_role_oid_memberships"),
178 UnmaterializableFunc::MzSessionId => f.write_str("mz_session_id"),
179 UnmaterializableFunc::MzUptime => f.write_str("mz_uptime"),
180 UnmaterializableFunc::MzVersion => f.write_str("mz_version"),
181 UnmaterializableFunc::MzVersionNum => f.write_str("mz_version_num"),
182 UnmaterializableFunc::PgBackendPid => f.write_str("pg_backend_pid"),
183 UnmaterializableFunc::PgPostmasterStartTime => f.write_str("pg_postmaster_start_time"),
184 UnmaterializableFunc::SessionUser => f.write_str("session_user"),
185 UnmaterializableFunc::Version => f.write_str("version"),
186 UnmaterializableFunc::ViewableVariables => f.write_str("viewable_variables"),
187 }
188 }
189}
190
191impl RustType<ProtoUnmaterializableFunc> for UnmaterializableFunc {
192 fn into_proto(&self) -> ProtoUnmaterializableFunc {
193 use crate::scalar::proto_unmaterializable_func::Kind::*;
194 let kind = match self {
195 UnmaterializableFunc::CurrentDatabase => CurrentDatabase(()),
196 UnmaterializableFunc::CurrentSchema => CurrentSchema(()),
197 UnmaterializableFunc::CurrentSchemasWithSystem => CurrentSchemasWithSystem(()),
198 UnmaterializableFunc::CurrentSchemasWithoutSystem => CurrentSchemasWithoutSystem(()),
199 UnmaterializableFunc::ViewableVariables => CurrentSetting(()),
200 UnmaterializableFunc::CurrentTimestamp => CurrentTimestamp(()),
201 UnmaterializableFunc::CurrentUser => CurrentUser(()),
202 UnmaterializableFunc::IsRbacEnabled => IsRbacEnabled(()),
203 UnmaterializableFunc::MzEnvironmentId => MzEnvironmentId(()),
204 UnmaterializableFunc::MzIsSuperuser => MzIsSuperuser(()),
205 UnmaterializableFunc::MzNow => MzNow(()),
206 UnmaterializableFunc::MzRoleOidMemberships => MzRoleOidMemberships(()),
207 UnmaterializableFunc::MzSessionId => MzSessionId(()),
208 UnmaterializableFunc::MzUptime => MzUptime(()),
209 UnmaterializableFunc::MzVersion => MzVersion(()),
210 UnmaterializableFunc::MzVersionNum => MzVersionNum(()),
211 UnmaterializableFunc::PgBackendPid => PgBackendPid(()),
212 UnmaterializableFunc::PgPostmasterStartTime => PgPostmasterStartTime(()),
213 UnmaterializableFunc::SessionUser => SessionUser(()),
214 UnmaterializableFunc::Version => Version(()),
215 };
216 ProtoUnmaterializableFunc { kind: Some(kind) }
217 }
218
219 fn from_proto(proto: ProtoUnmaterializableFunc) -> Result<Self, TryFromProtoError> {
220 use crate::scalar::proto_unmaterializable_func::Kind::*;
221 if let Some(kind) = proto.kind {
222 match kind {
223 CurrentDatabase(()) => Ok(UnmaterializableFunc::CurrentDatabase),
224 CurrentSchema(()) => Ok(UnmaterializableFunc::CurrentSchema),
225 CurrentSchemasWithSystem(()) => Ok(UnmaterializableFunc::CurrentSchemasWithSystem),
226 CurrentSchemasWithoutSystem(()) => {
227 Ok(UnmaterializableFunc::CurrentSchemasWithoutSystem)
228 }
229 CurrentTimestamp(()) => Ok(UnmaterializableFunc::CurrentTimestamp),
230 CurrentSetting(()) => Ok(UnmaterializableFunc::ViewableVariables),
231 CurrentUser(()) => Ok(UnmaterializableFunc::CurrentUser),
232 IsRbacEnabled(()) => Ok(UnmaterializableFunc::IsRbacEnabled),
233 MzEnvironmentId(()) => Ok(UnmaterializableFunc::MzEnvironmentId),
234 MzIsSuperuser(()) => Ok(UnmaterializableFunc::MzIsSuperuser),
235 MzNow(()) => Ok(UnmaterializableFunc::MzNow),
236 MzRoleOidMemberships(()) => Ok(UnmaterializableFunc::MzRoleOidMemberships),
237 MzSessionId(()) => Ok(UnmaterializableFunc::MzSessionId),
238 MzUptime(()) => Ok(UnmaterializableFunc::MzUptime),
239 MzVersion(()) => Ok(UnmaterializableFunc::MzVersion),
240 MzVersionNum(()) => Ok(UnmaterializableFunc::MzVersionNum),
241 PgBackendPid(()) => Ok(UnmaterializableFunc::PgBackendPid),
242 PgPostmasterStartTime(()) => Ok(UnmaterializableFunc::PgPostmasterStartTime),
243 SessionUser(()) => Ok(UnmaterializableFunc::SessionUser),
244 Version(()) => Ok(UnmaterializableFunc::Version),
245 }
246 } else {
247 Err(TryFromProtoError::missing_field(
248 "`ProtoUnmaterializableFunc::kind`",
249 ))
250 }
251 }
252}
253
254pub fn and<'a>(
255 datums: &[Datum<'a>],
256 temp_storage: &'a RowArena,
257 exprs: &'a [MirScalarExpr],
258) -> Result<Datum<'a>, EvalError> {
259 let mut null = false;
261 let mut err = None;
262 for expr in exprs {
263 match expr.eval(datums, temp_storage) {
264 Ok(Datum::False) => return Ok(Datum::False), Ok(Datum::True) => {}
266 Ok(Datum::Null) => null = true,
268 Err(this_err) => err = std::cmp::max(err.take(), Some(this_err)),
269 _ => unreachable!(),
270 }
271 }
272 match (err, null) {
273 (Some(err), _) => Err(err),
274 (None, true) => Ok(Datum::Null),
275 (None, false) => Ok(Datum::True),
276 }
277}
278
279pub fn or<'a>(
280 datums: &[Datum<'a>],
281 temp_storage: &'a RowArena,
282 exprs: &'a [MirScalarExpr],
283) -> Result<Datum<'a>, EvalError> {
284 let mut null = false;
286 let mut err = None;
287 for expr in exprs {
288 match expr.eval(datums, temp_storage) {
289 Ok(Datum::False) => {}
290 Ok(Datum::True) => return Ok(Datum::True), Ok(Datum::Null) => null = true,
293 Err(this_err) => err = std::cmp::max(err.take(), Some(this_err)),
294 _ => unreachable!(),
295 }
296 }
297 match (err, null) {
298 (Some(err), _) => Err(err),
299 (None, true) => Ok(Datum::Null),
300 (None, false) => Ok(Datum::False),
301 }
302}
303
304pub fn jsonb_stringify<'a>(a: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
305 match a {
306 Datum::JsonNull => Datum::Null,
307 Datum::String(_) => a,
308 _ => {
309 let s = cast_jsonb_to_string(JsonbRef::from_datum(a));
310 Datum::String(temp_storage.push_string(s))
311 }
312 }
313}
314
315#[sqlfunc(
316 is_monotone = "(true, true)",
317 output_type = "i16",
318 is_infix_op = true,
319 sqlname = "+",
320 propagates_nulls = true
321)]
322fn add_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
323 a.unwrap_int16()
324 .checked_add(b.unwrap_int16())
325 .ok_or(EvalError::NumericFieldOverflow)
326 .map(Datum::from)
327}
328
329#[sqlfunc(
330 is_monotone = "(true, true)",
331 output_type = "i32",
332 is_infix_op = true,
333 sqlname = "+",
334 propagates_nulls = true
335)]
336fn add_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
337 a.unwrap_int32()
338 .checked_add(b.unwrap_int32())
339 .ok_or(EvalError::NumericFieldOverflow)
340 .map(Datum::from)
341}
342
343#[sqlfunc(
344 is_monotone = "(true, true)",
345 output_type = "i64",
346 is_infix_op = true,
347 sqlname = "+",
348 propagates_nulls = true
349)]
350fn add_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
351 a.unwrap_int64()
352 .checked_add(b.unwrap_int64())
353 .ok_or(EvalError::NumericFieldOverflow)
354 .map(Datum::from)
355}
356
357#[sqlfunc(
358 is_monotone = "(true, true)",
359 output_type = "u16",
360 is_infix_op = true,
361 sqlname = "+",
362 propagates_nulls = true
363)]
364fn add_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
365 a.unwrap_uint16()
366 .checked_add(b.unwrap_uint16())
367 .ok_or_else(|| EvalError::UInt16OutOfRange(format!("{a} + {b}").into()))
368 .map(Datum::from)
369}
370
371#[sqlfunc(
372 is_monotone = "(true, true)",
373 output_type = "u32",
374 is_infix_op = true,
375 sqlname = "+",
376 propagates_nulls = true
377)]
378fn add_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
379 a.unwrap_uint32()
380 .checked_add(b.unwrap_uint32())
381 .ok_or_else(|| EvalError::UInt32OutOfRange(format!("{a} + {b}").into()))
382 .map(Datum::from)
383}
384
385#[sqlfunc(
386 is_monotone = "(true, true)",
387 output_type = "u64",
388 is_infix_op = true,
389 sqlname = "+",
390 propagates_nulls = true
391)]
392fn add_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
393 a.unwrap_uint64()
394 .checked_add(b.unwrap_uint64())
395 .ok_or_else(|| EvalError::UInt64OutOfRange(format!("{a} + {b}").into()))
396 .map(Datum::from)
397}
398
399#[sqlfunc(
400 is_monotone = "(true, true)",
401 output_type = "f32",
402 is_infix_op = true,
403 sqlname = "+",
404 propagates_nulls = true
405)]
406fn add_float32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
407 let a = a.unwrap_float32();
408 let b = b.unwrap_float32();
409 let sum = a + b;
410 if sum.is_infinite() && !a.is_infinite() && !b.is_infinite() {
411 Err(EvalError::FloatOverflow)
412 } else {
413 Ok(Datum::from(sum))
414 }
415}
416
417#[sqlfunc(
418 is_monotone = "(true, true)",
419 output_type = "f64",
420 is_infix_op = true,
421 sqlname = "+",
422 propagates_nulls = true
423)]
424fn add_float64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
425 let a = a.unwrap_float64();
426 let b = b.unwrap_float64();
427 let sum = a + b;
428 if sum.is_infinite() && !a.is_infinite() && !b.is_infinite() {
429 Err(EvalError::FloatOverflow)
430 } else {
431 Ok(Datum::from(sum))
432 }
433}
434
435fn add_timestamplike_interval<'a, T>(
436 a: CheckedTimestamp<T>,
437 b: Interval,
438) -> Result<Datum<'a>, EvalError>
439where
440 T: TimestampLike,
441{
442 let dt = a.date_time();
443 let dt = add_timestamp_months(&dt, b.months)?;
444 let dt = dt
445 .checked_add_signed(b.duration_as_chrono())
446 .ok_or(EvalError::TimestampOutOfRange)?;
447 T::from_date_time(dt).try_into().err_into()
448}
449
450fn sub_timestamplike_interval<'a, T>(
451 a: CheckedTimestamp<T>,
452 b: Datum,
453) -> Result<Datum<'a>, EvalError>
454where
455 T: TimestampLike,
456{
457 neg_interval_inner(b).and_then(|i| add_timestamplike_interval(a, i))
458}
459
460#[sqlfunc(
461 is_monotone = "(true, true)",
462 output_type = "CheckedTimestamp<NaiveDateTime>",
463 is_infix_op = true,
464 sqlname = "+",
465 propagates_nulls = true
466)]
467fn add_date_time<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
468 let date = a.unwrap_date();
469 let time = b.unwrap_time();
470
471 let dt = NaiveDate::from(date)
472 .and_hms_nano_opt(time.hour(), time.minute(), time.second(), time.nanosecond())
473 .unwrap();
474 Ok(dt.try_into()?)
475}
476
477#[sqlfunc(
478 is_monotone = "(true, true)",
479 output_type = "CheckedTimestamp<NaiveDateTime>",
480 is_infix_op = true,
481 sqlname = "+",
482 propagates_nulls = true
483)]
484fn add_date_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
485 let date = a.unwrap_date();
486 let interval = b.unwrap_interval();
487
488 let dt = NaiveDate::from(date).and_hms_opt(0, 0, 0).unwrap();
489 let dt = add_timestamp_months(&dt, interval.months)?;
490 let dt = dt
491 .checked_add_signed(interval.duration_as_chrono())
492 .ok_or(EvalError::TimestampOutOfRange)?;
493 Ok(dt.try_into()?)
494}
495
496#[sqlfunc(
497 is_monotone = "(true, true)",
498 output_type = "CheckedTimestamp<chrono::DateTime<Utc>>",
499 is_infix_op = true,
500 sqlname = "+",
501 propagates_nulls = true
502)]
503fn add_time_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
504 let time = a.unwrap_time();
505 let interval = b.unwrap_interval();
506 let (t, _) = time.overflowing_add_signed(interval.duration_as_chrono());
507 Datum::Time(t)
508}
509
510#[sqlfunc(
511 is_monotone = "(true, false)",
512 output_type = "Numeric",
513 sqlname = "round",
514 propagates_nulls = true
515)]
516fn round_numeric_binary<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
517 let mut a = a.unwrap_numeric().0;
518 let mut b = b.unwrap_int32();
519 let mut cx = numeric::cx_datum();
520 let a_exp = a.exponent();
521 if a_exp > 0 && b > 0 || a_exp < 0 && -a_exp < b {
522 let max_remaining_scale = u32::from(numeric::NUMERIC_DATUM_MAX_PRECISION)
530 - (numeric::get_precision(&a) - numeric::get_scale(&a));
531 b = match i32::try_from(max_remaining_scale) {
532 Ok(max_remaining_scale) => std::cmp::min(b, max_remaining_scale),
533 Err(_) => b,
534 };
535 cx.rescale(&mut a, &numeric::Numeric::from(-b));
536 } else {
537 const MAX_P_LIMIT: i32 = 1 + cast::u8_to_i32(numeric::NUMERIC_DATUM_MAX_PRECISION);
540 b = std::cmp::min(MAX_P_LIMIT, b);
541 b = std::cmp::max(-MAX_P_LIMIT, b);
542 let mut b = numeric::Numeric::from(b);
543 cx.scaleb(&mut a, &b);
545 cx.round(&mut a);
546 cx.neg(&mut b);
548 cx.scaleb(&mut a, &b);
549 }
550
551 if cx.status().overflow() {
552 Err(EvalError::FloatOverflow)
553 } else if a.is_zero() {
554 Ok(Datum::from(numeric::Numeric::zero()))
558 } else {
559 numeric::munge_numeric(&mut a).unwrap();
560 Ok(Datum::from(a))
561 }
562}
563
564#[sqlfunc(
565 output_type = "String",
566 sqlname = "convert_from",
567 propagates_nulls = true
568)]
569fn convert_from<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
570 let encoding_name = b
576 .unwrap_str()
577 .to_lowercase()
578 .replace('_', "-")
579 .into_boxed_str();
580
581 if encoding_from_whatwg_label(&encoding_name).map(|e| e.name()) != Some("utf-8") {
583 return Err(EvalError::InvalidEncodingName(encoding_name));
584 }
585
586 match str::from_utf8(a.unwrap_bytes()) {
587 Ok(from) => Ok(Datum::String(from)),
588 Err(e) => Err(EvalError::InvalidByteSequence {
589 byte_sequence: e.to_string().into(),
590 encoding_name,
591 }),
592 }
593}
594
595#[sqlfunc(output_type = "String", propagates_nulls = true)]
596fn encode<'a>(
597 bytes: Datum<'a>,
598 format: Datum<'a>,
599 temp_storage: &'a RowArena,
600) -> Result<Datum<'a>, EvalError> {
601 let format = encoding::lookup_format(format.unwrap_str())?;
602 let out = format.encode(bytes.unwrap_bytes());
603 Ok(Datum::from(temp_storage.push_string(out)))
604}
605
606#[sqlfunc(output_type = "Vec<u8>", propagates_nulls = true)]
607fn decode<'a>(
608 string: Datum<'a>,
609 format: Datum<'a>,
610 temp_storage: &'a RowArena,
611) -> Result<Datum<'a>, EvalError> {
612 let format = encoding::lookup_format(format.unwrap_str())?;
613 let out = format.decode(string.unwrap_str())?;
614 Ok(Datum::from(temp_storage.push_bytes(out)))
615}
616
617#[sqlfunc(output_type = "i32", sqlname = "length", propagates_nulls = true)]
618fn encoded_bytes_char_length<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
619 let encoding_name = b
625 .unwrap_str()
626 .to_lowercase()
627 .replace('_', "-")
628 .into_boxed_str();
629
630 let enc = match encoding_from_whatwg_label(&encoding_name) {
631 Some(enc) => enc,
632 None => return Err(EvalError::InvalidEncodingName(encoding_name)),
633 };
634
635 let decoded_string = match enc.decode(a.unwrap_bytes(), DecoderTrap::Strict) {
636 Ok(s) => s,
637 Err(e) => {
638 return Err(EvalError::InvalidByteSequence {
639 byte_sequence: e.into(),
640 encoding_name,
641 });
642 }
643 };
644
645 let count = decoded_string.chars().count();
646 match i32::try_from(count) {
647 Ok(l) => Ok(Datum::from(l)),
648 Err(_) => Err(EvalError::Int32OutOfRange(count.to_string().into())),
649 }
650}
651
652#[allow(clippy::as_conversions)]
654pub fn add_timestamp_months<T: TimestampLike>(
655 dt: &T,
656 mut months: i32,
657) -> Result<CheckedTimestamp<T>, EvalError> {
658 if months == 0 {
659 return Ok(CheckedTimestamp::from_timestamplike(dt.clone())?);
660 }
661
662 let (mut year, mut month, mut day) = (dt.year(), dt.month0() as i32, dt.day());
663 let years = months / 12;
664 year = year
665 .checked_add(years)
666 .ok_or(EvalError::TimestampOutOfRange)?;
667
668 months %= 12;
669 if months < 0 {
671 year -= 1;
672 months += 12;
673 }
674 year += (month + months) / 12;
675 month = (month + months) % 12;
676 month += 1;
678
679 let mut new_d = chrono::NaiveDate::from_ymd_opt(year, month as u32, day);
681 while new_d.is_none() {
682 if day < 28 {
685 return Err(EvalError::TimestampOutOfRange);
686 }
687 day -= 1;
688 new_d = chrono::NaiveDate::from_ymd_opt(year, month as u32, day);
689 }
690 let new_d = new_d.unwrap();
691
692 let new_dt = new_d
697 .and_hms_nano_opt(dt.hour(), dt.minute(), dt.second(), dt.nanosecond())
698 .unwrap();
699 let new_dt = T::from_date_time(new_dt);
700 Ok(CheckedTimestamp::from_timestamplike(new_dt)?)
701}
702
703#[sqlfunc(
704 is_monotone = "(true, true)",
705 output_type = "Numeric",
706 is_infix_op = true,
707 sqlname = "+",
708 propagates_nulls = true
709)]
710fn add_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
711 let mut cx = numeric::cx_datum();
712 let mut a = a.unwrap_numeric().0;
713 cx.add(&mut a, &b.unwrap_numeric().0);
714 if cx.status().overflow() {
715 Err(EvalError::FloatOverflow)
716 } else {
717 Ok(Datum::from(a))
718 }
719}
720
721#[sqlfunc(
722 is_monotone = "(true, true)",
723 output_type = "Interval",
724 is_infix_op = true,
725 sqlname = "+",
726 propagates_nulls = true
727)]
728fn add_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
729 a.unwrap_interval()
730 .checked_add(&b.unwrap_interval())
731 .ok_or_else(|| EvalError::IntervalOutOfRange(format!("{a} + {b}").into()))
732 .map(Datum::from)
733}
734
735#[sqlfunc(
736 output_type = "i16",
737 is_infix_op = true,
738 sqlname = "&",
739 propagates_nulls = true
740)]
741fn bit_and_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
742 Datum::from(a.unwrap_int16() & b.unwrap_int16())
743}
744
745#[sqlfunc(
746 output_type = "i32",
747 is_infix_op = true,
748 sqlname = "&",
749 propagates_nulls = true
750)]
751fn bit_and_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
752 Datum::from(a.unwrap_int32() & b.unwrap_int32())
753}
754
755#[sqlfunc(
756 output_type = "i64",
757 is_infix_op = true,
758 sqlname = "&",
759 propagates_nulls = true
760)]
761fn bit_and_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
762 Datum::from(a.unwrap_int64() & b.unwrap_int64())
763}
764
765#[sqlfunc(
766 output_type = "u16",
767 is_infix_op = true,
768 sqlname = "&",
769 propagates_nulls = true
770)]
771fn bit_and_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
772 Datum::from(a.unwrap_uint16() & b.unwrap_uint16())
773}
774
775#[sqlfunc(
776 output_type = "u32",
777 is_infix_op = true,
778 sqlname = "&",
779 propagates_nulls = true
780)]
781fn bit_and_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
782 Datum::from(a.unwrap_uint32() & b.unwrap_uint32())
783}
784
785#[sqlfunc(
786 output_type = "u64",
787 is_infix_op = true,
788 sqlname = "&",
789 propagates_nulls = true
790)]
791fn bit_and_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
792 Datum::from(a.unwrap_uint64() & b.unwrap_uint64())
793}
794
795#[sqlfunc(
796 output_type = "i16",
797 is_infix_op = true,
798 sqlname = "|",
799 propagates_nulls = true
800)]
801fn bit_or_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
802 Datum::from(a.unwrap_int16() | b.unwrap_int16())
803}
804
805#[sqlfunc(
806 output_type = "i32",
807 is_infix_op = true,
808 sqlname = "|",
809 propagates_nulls = true
810)]
811fn bit_or_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
812 Datum::from(a.unwrap_int32() | b.unwrap_int32())
813}
814
815#[sqlfunc(
816 output_type = "i64",
817 is_infix_op = true,
818 sqlname = "|",
819 propagates_nulls = true
820)]
821fn bit_or_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
822 Datum::from(a.unwrap_int64() | b.unwrap_int64())
823}
824
825#[sqlfunc(
826 output_type = "u16",
827 is_infix_op = true,
828 sqlname = "|",
829 propagates_nulls = true
830)]
831fn bit_or_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
832 Datum::from(a.unwrap_uint16() | b.unwrap_uint16())
833}
834
835#[sqlfunc(
836 output_type = "u32",
837 is_infix_op = true,
838 sqlname = "|",
839 propagates_nulls = true
840)]
841fn bit_or_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
842 Datum::from(a.unwrap_uint32() | b.unwrap_uint32())
843}
844
845#[sqlfunc(
846 output_type = "u64",
847 is_infix_op = true,
848 sqlname = "|",
849 propagates_nulls = true
850)]
851fn bit_or_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
852 Datum::from(a.unwrap_uint64() | b.unwrap_uint64())
853}
854
855#[sqlfunc(
856 output_type = "i16",
857 is_infix_op = true,
858 sqlname = "#",
859 propagates_nulls = true
860)]
861fn bit_xor_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
862 Datum::from(a.unwrap_int16() ^ b.unwrap_int16())
863}
864
865#[sqlfunc(
866 output_type = "i32",
867 is_infix_op = true,
868 sqlname = "#",
869 propagates_nulls = true
870)]
871fn bit_xor_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
872 Datum::from(a.unwrap_int32() ^ b.unwrap_int32())
873}
874
875#[sqlfunc(
876 output_type = "i64",
877 is_infix_op = true,
878 sqlname = "#",
879 propagates_nulls = true
880)]
881fn bit_xor_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
882 Datum::from(a.unwrap_int64() ^ b.unwrap_int64())
883}
884
885#[sqlfunc(
886 output_type = "u16",
887 is_infix_op = true,
888 sqlname = "#",
889 propagates_nulls = true
890)]
891fn bit_xor_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
892 Datum::from(a.unwrap_uint16() ^ b.unwrap_uint16())
893}
894
895#[sqlfunc(
896 output_type = "u32",
897 is_infix_op = true,
898 sqlname = "#",
899 propagates_nulls = true
900)]
901fn bit_xor_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
902 Datum::from(a.unwrap_uint32() ^ b.unwrap_uint32())
903}
904
905#[sqlfunc(
906 output_type = "u64",
907 is_infix_op = true,
908 sqlname = "#",
909 propagates_nulls = true
910)]
911fn bit_xor_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
912 Datum::from(a.unwrap_uint64() ^ b.unwrap_uint64())
913}
914
915#[sqlfunc(
916 output_type = "i16",
917 is_infix_op = true,
918 sqlname = "<<",
919 propagates_nulls = true
920)]
921#[allow(clippy::as_conversions)]
923fn bit_shift_left_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
924 let lhs: i32 = a.unwrap_int16() as i32;
928 let rhs: u32 = b.unwrap_int32() as u32;
929 Datum::from(lhs.wrapping_shl(rhs) as i16)
930}
931
932#[sqlfunc(
933 output_type = "i32",
934 is_infix_op = true,
935 sqlname = "<<",
936 propagates_nulls = true
937)]
938#[allow(clippy::as_conversions)]
940fn bit_shift_left_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
941 let lhs = a.unwrap_int32();
942 let rhs = b.unwrap_int32() as u32;
943 Datum::from(lhs.wrapping_shl(rhs))
944}
945
946#[sqlfunc(
947 output_type = "i64",
948 is_infix_op = true,
949 sqlname = "<<",
950 propagates_nulls = true
951)]
952#[allow(clippy::as_conversions)]
954fn bit_shift_left_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
955 let lhs = a.unwrap_int64();
956 let rhs = b.unwrap_int32() as u32;
957 Datum::from(lhs.wrapping_shl(rhs))
958}
959
960#[sqlfunc(
961 output_type = "u16",
962 is_infix_op = true,
963 sqlname = "<<",
964 propagates_nulls = true
965)]
966#[allow(clippy::as_conversions)]
968fn bit_shift_left_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
969 let lhs: u32 = a.unwrap_uint16() as u32;
973 let rhs: u32 = b.unwrap_uint32();
974 Datum::from(lhs.wrapping_shl(rhs) as u16)
975}
976
977#[sqlfunc(
978 output_type = "u32",
979 is_infix_op = true,
980 sqlname = "<<",
981 propagates_nulls = true
982)]
983fn bit_shift_left_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
984 let lhs = a.unwrap_uint32();
985 let rhs = b.unwrap_uint32();
986 Datum::from(lhs.wrapping_shl(rhs))
987}
988
989#[sqlfunc(
990 output_type = "u64",
991 is_infix_op = true,
992 sqlname = "<<",
993 propagates_nulls = true
994)]
995fn bit_shift_left_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
996 let lhs = a.unwrap_uint64();
997 let rhs = b.unwrap_uint32();
998 Datum::from(lhs.wrapping_shl(rhs))
999}
1000
1001#[sqlfunc(
1002 output_type = "i16",
1003 is_infix_op = true,
1004 sqlname = ">>",
1005 propagates_nulls = true
1006)]
1007#[allow(clippy::as_conversions)]
1009fn bit_shift_right_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1010 let lhs = a.unwrap_int16() as i32;
1014 let rhs = b.unwrap_int32() as u32;
1015 Datum::from(lhs.wrapping_shr(rhs) as i16)
1016}
1017
1018#[sqlfunc(
1019 output_type = "i32",
1020 is_infix_op = true,
1021 sqlname = ">>",
1022 propagates_nulls = true
1023)]
1024#[allow(clippy::as_conversions)]
1026fn bit_shift_right_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1027 let lhs = a.unwrap_int32();
1028 let rhs = b.unwrap_int32() as u32;
1029 Datum::from(lhs.wrapping_shr(rhs))
1030}
1031
1032#[sqlfunc(
1033 output_type = "i64",
1034 is_infix_op = true,
1035 sqlname = ">>",
1036 propagates_nulls = true
1037)]
1038#[allow(clippy::as_conversions)]
1040fn bit_shift_right_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1041 let lhs = a.unwrap_int64();
1042 let rhs = b.unwrap_int32() as u32;
1043 Datum::from(lhs.wrapping_shr(rhs))
1044}
1045
1046#[sqlfunc(
1047 output_type = "u16",
1048 is_infix_op = true,
1049 sqlname = ">>",
1050 propagates_nulls = true
1051)]
1052#[allow(clippy::as_conversions)]
1054fn bit_shift_right_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1055 let lhs = a.unwrap_uint16() as u32;
1059 let rhs = b.unwrap_uint32();
1060 Datum::from(lhs.wrapping_shr(rhs) as u16)
1061}
1062
1063#[sqlfunc(
1064 output_type = "u32",
1065 is_infix_op = true,
1066 sqlname = ">>",
1067 propagates_nulls = true
1068)]
1069fn bit_shift_right_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1070 let lhs = a.unwrap_uint32();
1071 let rhs = b.unwrap_uint32();
1072 Datum::from(lhs.wrapping_shr(rhs))
1073}
1074
1075#[sqlfunc(
1076 output_type = "u64",
1077 is_infix_op = true,
1078 sqlname = ">>",
1079 propagates_nulls = true
1080)]
1081fn bit_shift_right_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1082 let lhs = a.unwrap_uint64();
1083 let rhs = b.unwrap_uint32();
1084 Datum::from(lhs.wrapping_shr(rhs))
1085}
1086
1087#[sqlfunc(
1088 is_monotone = "(true, true)",
1089 output_type = "i16",
1090 is_infix_op = true,
1091 sqlname = "-",
1092 propagates_nulls = true
1093)]
1094fn sub_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1095 a.unwrap_int16()
1096 .checked_sub(b.unwrap_int16())
1097 .ok_or(EvalError::NumericFieldOverflow)
1098 .map(Datum::from)
1099}
1100
1101#[sqlfunc(
1102 is_monotone = "(true, true)",
1103 output_type = "i32",
1104 is_infix_op = true,
1105 sqlname = "-",
1106 propagates_nulls = true
1107)]
1108fn sub_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1109 a.unwrap_int32()
1110 .checked_sub(b.unwrap_int32())
1111 .ok_or(EvalError::NumericFieldOverflow)
1112 .map(Datum::from)
1113}
1114
1115#[sqlfunc(
1116 is_monotone = "(true, true)",
1117 output_type = "i64",
1118 is_infix_op = true,
1119 sqlname = "-",
1120 propagates_nulls = true
1121)]
1122fn sub_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1123 a.unwrap_int64()
1124 .checked_sub(b.unwrap_int64())
1125 .ok_or(EvalError::NumericFieldOverflow)
1126 .map(Datum::from)
1127}
1128
1129#[sqlfunc(
1130 is_monotone = "(true, true)",
1131 output_type = "u16",
1132 is_infix_op = true,
1133 sqlname = "-",
1134 propagates_nulls = true
1135)]
1136fn sub_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1137 a.unwrap_uint16()
1138 .checked_sub(b.unwrap_uint16())
1139 .ok_or_else(|| EvalError::UInt16OutOfRange(format!("{a} - {b}").into()))
1140 .map(Datum::from)
1141}
1142
1143#[sqlfunc(
1144 is_monotone = "(true, true)",
1145 output_type = "u32",
1146 is_infix_op = true,
1147 sqlname = "-",
1148 propagates_nulls = true
1149)]
1150fn sub_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1151 a.unwrap_uint32()
1152 .checked_sub(b.unwrap_uint32())
1153 .ok_or_else(|| EvalError::UInt32OutOfRange(format!("{a} - {b}").into()))
1154 .map(Datum::from)
1155}
1156
1157#[sqlfunc(
1158 is_monotone = "(true, true)",
1159 output_type = "u64",
1160 is_infix_op = true,
1161 sqlname = "-",
1162 propagates_nulls = true
1163)]
1164fn sub_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1165 a.unwrap_uint64()
1166 .checked_sub(b.unwrap_uint64())
1167 .ok_or_else(|| EvalError::UInt64OutOfRange(format!("{a} - {b}").into()))
1168 .map(Datum::from)
1169}
1170
1171#[sqlfunc(
1172 is_monotone = "(true, true)",
1173 output_type = "f32",
1174 is_infix_op = true,
1175 sqlname = "-",
1176 propagates_nulls = true
1177)]
1178fn sub_float32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1179 let a = a.unwrap_float32();
1180 let b = b.unwrap_float32();
1181 let difference = a - b;
1182 if difference.is_infinite() && !a.is_infinite() && !b.is_infinite() {
1183 Err(EvalError::FloatOverflow)
1184 } else {
1185 Ok(Datum::from(difference))
1186 }
1187}
1188
1189#[sqlfunc(
1190 is_monotone = "(true, true)",
1191 output_type = "f64",
1192 is_infix_op = true,
1193 sqlname = "-",
1194 propagates_nulls = true
1195)]
1196fn sub_float64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1197 let a = a.unwrap_float64();
1198 let b = b.unwrap_float64();
1199 let difference = a - b;
1200 if difference.is_infinite() && !a.is_infinite() && !b.is_infinite() {
1201 Err(EvalError::FloatOverflow)
1202 } else {
1203 Ok(Datum::from(difference))
1204 }
1205}
1206
1207#[sqlfunc(
1208 is_monotone = "(true, true)",
1209 output_type = "Numeric",
1210 is_infix_op = true,
1211 sqlname = "-",
1212 propagates_nulls = true
1213)]
1214fn sub_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1215 let mut cx = numeric::cx_datum();
1216 let mut a = a.unwrap_numeric().0;
1217 cx.sub(&mut a, &b.unwrap_numeric().0);
1218 if cx.status().overflow() {
1219 Err(EvalError::FloatOverflow)
1220 } else {
1221 Ok(Datum::from(a))
1222 }
1223}
1224
1225#[sqlfunc(
1226 is_monotone = "(true, true)",
1227 output_type = "Interval",
1228 sqlname = "age",
1229 propagates_nulls = true
1230)]
1231fn age_timestamp<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1232 let a_ts = a.unwrap_timestamp();
1233 let b_ts = b.unwrap_timestamp();
1234 let age = a_ts.age(&b_ts)?;
1235
1236 Ok(Datum::from(age))
1237}
1238
1239#[sqlfunc(
1240 is_monotone = "(true, true)",
1241 output_type = "Interval",
1242 sqlname = "age",
1243 propagates_nulls = true
1244)]
1245fn age_timestamptz<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1246 let a_ts = a.unwrap_timestamptz();
1247 let b_ts = b.unwrap_timestamptz();
1248 let age = a_ts.age(&b_ts)?;
1249
1250 Ok(Datum::from(age))
1251}
1252
1253#[sqlfunc(
1254 is_monotone = "(true, true)",
1255 output_type = "Interval",
1256 is_infix_op = true,
1257 sqlname = "-",
1258 propagates_nulls = true
1259)]
1260fn sub_timestamp<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1261 Datum::from(a.unwrap_timestamp() - b.unwrap_timestamp())
1262}
1263
1264#[sqlfunc(
1265 is_monotone = "(true, true)",
1266 output_type = "Interval",
1267 is_infix_op = true,
1268 sqlname = "-",
1269 propagates_nulls = true
1270)]
1271fn sub_timestamptz<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1272 Datum::from(a.unwrap_timestamptz() - b.unwrap_timestamptz())
1273}
1274
1275#[sqlfunc(
1276 is_monotone = "(true, true)",
1277 output_type = "i32",
1278 is_infix_op = true,
1279 sqlname = "-",
1280 propagates_nulls = true
1281)]
1282fn sub_date<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1283 Datum::from(a.unwrap_date() - b.unwrap_date())
1284}
1285
1286#[sqlfunc(
1287 is_monotone = "(true, true)",
1288 output_type = "Interval",
1289 is_infix_op = true,
1290 sqlname = "-",
1291 propagates_nulls = true
1292)]
1293fn sub_time<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1294 Datum::from(a.unwrap_time() - b.unwrap_time())
1295}
1296
1297#[sqlfunc(
1298 is_monotone = "(true, true)",
1299 output_type = "Interval",
1300 is_infix_op = true,
1301 sqlname = "-",
1302 propagates_nulls = true
1303)]
1304fn sub_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1305 b.unwrap_interval()
1306 .checked_neg()
1307 .and_then(|b| b.checked_add(&a.unwrap_interval()))
1308 .ok_or_else(|| EvalError::IntervalOutOfRange(format!("{a} - {b}").into()))
1309 .map(Datum::from)
1310}
1311
1312#[sqlfunc(
1313 is_monotone = "(true, true)",
1314 output_type = "CheckedTimestamp<NaiveDateTime>",
1315 is_infix_op = true,
1316 sqlname = "-",
1317 propagates_nulls = true
1318)]
1319fn sub_date_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1320 let date = a.unwrap_date();
1321 let interval = b.unwrap_interval();
1322
1323 let dt = NaiveDate::from(date).and_hms_opt(0, 0, 0).unwrap();
1324 let dt = interval
1325 .months
1326 .checked_neg()
1327 .ok_or_else(|| EvalError::IntervalOutOfRange(interval.months.to_string().into()))
1328 .and_then(|months| add_timestamp_months(&dt, months))?;
1329 let dt = dt
1330 .checked_sub_signed(interval.duration_as_chrono())
1331 .ok_or(EvalError::TimestampOutOfRange)?;
1332 Ok(dt.try_into()?)
1333}
1334
1335#[sqlfunc(
1336 is_monotone = "(true, true)",
1337 output_type = "chrono::NaiveTime",
1338 is_infix_op = true,
1339 sqlname = "-",
1340 propagates_nulls = true
1341)]
1342fn sub_time_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1343 let time = a.unwrap_time();
1344 let interval = b.unwrap_interval();
1345 let (t, _) = time.overflowing_sub_signed(interval.duration_as_chrono());
1346 Datum::Time(t)
1347}
1348
1349#[sqlfunc(
1350 is_monotone = "(true, true)",
1351 output_type = "i16",
1352 is_infix_op = true,
1353 sqlname = "*",
1354 propagates_nulls = true
1355)]
1356fn mul_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1357 a.unwrap_int16()
1358 .checked_mul(b.unwrap_int16())
1359 .ok_or(EvalError::NumericFieldOverflow)
1360 .map(Datum::from)
1361}
1362
1363#[sqlfunc(
1364 is_monotone = "(true, true)",
1365 output_type = "i32",
1366 is_infix_op = true,
1367 sqlname = "*",
1368 propagates_nulls = true
1369)]
1370fn mul_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1371 a.unwrap_int32()
1372 .checked_mul(b.unwrap_int32())
1373 .ok_or(EvalError::NumericFieldOverflow)
1374 .map(Datum::from)
1375}
1376
1377#[sqlfunc(
1378 is_monotone = "(true, true)",
1379 output_type = "i64",
1380 is_infix_op = true,
1381 sqlname = "*",
1382 propagates_nulls = true
1383)]
1384fn mul_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1385 a.unwrap_int64()
1386 .checked_mul(b.unwrap_int64())
1387 .ok_or(EvalError::NumericFieldOverflow)
1388 .map(Datum::from)
1389}
1390
1391#[sqlfunc(
1392 is_monotone = "(true, true)",
1393 output_type = "u16",
1394 is_infix_op = true,
1395 sqlname = "*",
1396 propagates_nulls = true
1397)]
1398fn mul_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1399 a.unwrap_uint16()
1400 .checked_mul(b.unwrap_uint16())
1401 .ok_or_else(|| EvalError::UInt16OutOfRange(format!("{a} * {b}").into()))
1402 .map(Datum::from)
1403}
1404
1405#[sqlfunc(
1406 is_monotone = "(true, true)",
1407 output_type = "u32",
1408 is_infix_op = true,
1409 sqlname = "*",
1410 propagates_nulls = true
1411)]
1412fn mul_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1413 a.unwrap_uint32()
1414 .checked_mul(b.unwrap_uint32())
1415 .ok_or_else(|| EvalError::UInt32OutOfRange(format!("{a} * {b}").into()))
1416 .map(Datum::from)
1417}
1418
1419#[sqlfunc(
1420 is_monotone = "(true, true)",
1421 output_type = "u64",
1422 is_infix_op = true,
1423 sqlname = "*",
1424 propagates_nulls = true
1425)]
1426fn mul_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1427 a.unwrap_uint64()
1428 .checked_mul(b.unwrap_uint64())
1429 .ok_or_else(|| EvalError::UInt64OutOfRange(format!("{a} * {b}").into()))
1430 .map(Datum::from)
1431}
1432
1433#[sqlfunc(
1434 is_monotone = "(true, true)",
1435 output_type = "f32",
1436 is_infix_op = true,
1437 sqlname = "*",
1438 propagates_nulls = true
1439)]
1440fn mul_float32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1441 let a = a.unwrap_float32();
1442 let b = b.unwrap_float32();
1443 let product = a * b;
1444 if product.is_infinite() && !a.is_infinite() && !b.is_infinite() {
1445 Err(EvalError::FloatOverflow)
1446 } else if product == 0.0f32 && a != 0.0f32 && b != 0.0f32 {
1447 Err(EvalError::FloatUnderflow)
1448 } else {
1449 Ok(Datum::from(product))
1450 }
1451}
1452
1453#[sqlfunc(
1454 is_monotone = "(true, true)",
1455 output_type = "f64",
1456 is_infix_op = true,
1457 sqlname = "*",
1458 propagates_nulls = true
1459)]
1460fn mul_float64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1461 let a = a.unwrap_float64();
1462 let b = b.unwrap_float64();
1463 let product = a * b;
1464 if product.is_infinite() && !a.is_infinite() && !b.is_infinite() {
1465 Err(EvalError::FloatOverflow)
1466 } else if product == 0.0f64 && a != 0.0f64 && b != 0.0f64 {
1467 Err(EvalError::FloatUnderflow)
1468 } else {
1469 Ok(Datum::from(product))
1470 }
1471}
1472
1473#[sqlfunc(
1474 is_monotone = "(true, true)",
1475 output_type = "Numeric",
1476 is_infix_op = true,
1477 sqlname = "*",
1478 propagates_nulls = true
1479)]
1480fn mul_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1481 let mut cx = numeric::cx_datum();
1482 let mut a = a.unwrap_numeric().0;
1483 cx.mul(&mut a, &b.unwrap_numeric().0);
1484 let cx_status = cx.status();
1485 if cx_status.overflow() {
1486 Err(EvalError::FloatOverflow)
1487 } else if cx_status.subnormal() {
1488 Err(EvalError::FloatUnderflow)
1489 } else {
1490 numeric::munge_numeric(&mut a).unwrap();
1491 Ok(Datum::from(a))
1492 }
1493}
1494
1495#[sqlfunc(
1496 is_monotone = "(true, true)",
1497 output_type = "Interval",
1498 is_infix_op = true,
1499 sqlname = "*",
1500 propagates_nulls = true
1501)]
1502fn mul_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1503 a.unwrap_interval()
1504 .checked_mul(b.unwrap_float64())
1505 .ok_or_else(|| EvalError::IntervalOutOfRange(format!("{a} * {b}").into()))
1506 .map(Datum::from)
1507}
1508
1509#[sqlfunc(
1510 is_monotone = "(true, false)",
1511 output_type = "i16",
1512 is_infix_op = true,
1513 sqlname = "/",
1514 propagates_nulls = true
1515)]
1516fn div_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1517 let b = b.unwrap_int16();
1518 if b == 0 {
1519 Err(EvalError::DivisionByZero)
1520 } else {
1521 a.unwrap_int16()
1522 .checked_div(b)
1523 .map(Datum::from)
1524 .ok_or_else(|| EvalError::Int16OutOfRange(format!("{a} / {b}").into()))
1525 }
1526}
1527
1528#[sqlfunc(
1529 is_monotone = "(true, false)",
1530 output_type = "i32",
1531 is_infix_op = true,
1532 sqlname = "/",
1533 propagates_nulls = true
1534)]
1535fn div_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1536 let b = b.unwrap_int32();
1537 if b == 0 {
1538 Err(EvalError::DivisionByZero)
1539 } else {
1540 a.unwrap_int32()
1541 .checked_div(b)
1542 .map(Datum::from)
1543 .ok_or_else(|| EvalError::Int32OutOfRange(format!("{a} / {b}").into()))
1544 }
1545}
1546
1547#[sqlfunc(
1548 is_monotone = "(true, false)",
1549 output_type = "i64",
1550 is_infix_op = true,
1551 sqlname = "/",
1552 propagates_nulls = true
1553)]
1554fn div_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1555 let b = b.unwrap_int64();
1556 if b == 0 {
1557 Err(EvalError::DivisionByZero)
1558 } else {
1559 a.unwrap_int64()
1560 .checked_div(b)
1561 .map(Datum::from)
1562 .ok_or_else(|| EvalError::Int64OutOfRange(format!("{a} / {b}").into()))
1563 }
1564}
1565
1566#[sqlfunc(
1567 is_monotone = "(true, false)",
1568 output_type = "u16",
1569 is_infix_op = true,
1570 sqlname = "/",
1571 propagates_nulls = true
1572)]
1573fn div_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1574 let b = b.unwrap_uint16();
1575 if b == 0 {
1576 Err(EvalError::DivisionByZero)
1577 } else {
1578 Ok(Datum::from(a.unwrap_uint16() / b))
1579 }
1580}
1581
1582#[sqlfunc(
1583 is_monotone = "(true, false)",
1584 output_type = "u32",
1585 is_infix_op = true,
1586 sqlname = "/",
1587 propagates_nulls = true
1588)]
1589fn div_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1590 let b = b.unwrap_uint32();
1591 if b == 0 {
1592 Err(EvalError::DivisionByZero)
1593 } else {
1594 Ok(Datum::from(a.unwrap_uint32() / b))
1595 }
1596}
1597
1598#[sqlfunc(
1599 is_monotone = "(true, false)",
1600 output_type = "u64",
1601 is_infix_op = true,
1602 sqlname = "/",
1603 propagates_nulls = true
1604)]
1605fn div_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1606 let b = b.unwrap_uint64();
1607 if b == 0 {
1608 Err(EvalError::DivisionByZero)
1609 } else {
1610 Ok(Datum::from(a.unwrap_uint64() / b))
1611 }
1612}
1613
1614#[sqlfunc(
1615 is_monotone = "(true, false)",
1616 output_type = "f32",
1617 is_infix_op = true,
1618 sqlname = "/",
1619 propagates_nulls = true
1620)]
1621fn div_float32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1622 let a = a.unwrap_float32();
1623 let b = b.unwrap_float32();
1624 if b == 0.0f32 && !a.is_nan() {
1625 Err(EvalError::DivisionByZero)
1626 } else {
1627 let quotient = a / b;
1628 if quotient.is_infinite() && !a.is_infinite() {
1629 Err(EvalError::FloatOverflow)
1630 } else if quotient == 0.0f32 && a != 0.0f32 && !b.is_infinite() {
1631 Err(EvalError::FloatUnderflow)
1632 } else {
1633 Ok(Datum::from(quotient))
1634 }
1635 }
1636}
1637
1638#[sqlfunc(
1639 is_monotone = "(true, false)",
1640 output_type = "f64",
1641 is_infix_op = true,
1642 sqlname = "/",
1643 propagates_nulls = true
1644)]
1645fn div_float64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1646 let a = a.unwrap_float64();
1647 let b = b.unwrap_float64();
1648 if b == 0.0f64 && !a.is_nan() {
1649 Err(EvalError::DivisionByZero)
1650 } else {
1651 let quotient = a / b;
1652 if quotient.is_infinite() && !a.is_infinite() {
1653 Err(EvalError::FloatOverflow)
1654 } else if quotient == 0.0f64 && a != 0.0f64 && !b.is_infinite() {
1655 Err(EvalError::FloatUnderflow)
1656 } else {
1657 Ok(Datum::from(quotient))
1658 }
1659 }
1660}
1661
1662#[sqlfunc(
1663 is_monotone = "(true, false)",
1664 output_type = "Numeric",
1665 is_infix_op = true,
1666 sqlname = "/",
1667 propagates_nulls = true
1668)]
1669fn div_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1670 let mut cx = numeric::cx_datum();
1671 let mut a = a.unwrap_numeric().0;
1672 let b = b.unwrap_numeric().0;
1673
1674 cx.div(&mut a, &b);
1675 let cx_status = cx.status();
1676
1677 if b.is_zero() {
1680 Err(EvalError::DivisionByZero)
1681 } else if cx_status.overflow() {
1682 Err(EvalError::FloatOverflow)
1683 } else if cx_status.subnormal() {
1684 Err(EvalError::FloatUnderflow)
1685 } else {
1686 numeric::munge_numeric(&mut a).unwrap();
1687 Ok(Datum::from(a))
1688 }
1689}
1690
1691#[sqlfunc(
1692 is_monotone = "(true, false)",
1693 output_type = "Interval",
1694 is_infix_op = true,
1695 sqlname = "/",
1696 propagates_nulls = true
1697)]
1698fn div_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1699 let b = b.unwrap_float64();
1700 if b == 0.0 {
1701 Err(EvalError::DivisionByZero)
1702 } else {
1703 a.unwrap_interval()
1704 .checked_div(b)
1705 .ok_or_else(|| EvalError::IntervalOutOfRange(format!("{a} / {b}").into()))
1706 .map(Datum::from)
1707 }
1708}
1709
1710#[sqlfunc(
1711 output_type = "i16",
1712 is_infix_op = true,
1713 sqlname = "%",
1714 propagates_nulls = true
1715)]
1716fn mod_int16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1717 let b = b.unwrap_int16();
1718 if b == 0 {
1719 Err(EvalError::DivisionByZero)
1720 } else {
1721 Ok(Datum::from(a.unwrap_int16().checked_rem(b).unwrap_or(0)))
1722 }
1723}
1724
1725#[sqlfunc(
1726 output_type = "i32",
1727 is_infix_op = true,
1728 sqlname = "%",
1729 propagates_nulls = true
1730)]
1731fn mod_int32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1732 let b = b.unwrap_int32();
1733 if b == 0 {
1734 Err(EvalError::DivisionByZero)
1735 } else {
1736 Ok(Datum::from(a.unwrap_int32().checked_rem(b).unwrap_or(0)))
1737 }
1738}
1739
1740#[sqlfunc(
1741 output_type = "i64",
1742 is_infix_op = true,
1743 sqlname = "%",
1744 propagates_nulls = true
1745)]
1746fn mod_int64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1747 let b = b.unwrap_int64();
1748 if b == 0 {
1749 Err(EvalError::DivisionByZero)
1750 } else {
1751 Ok(Datum::from(a.unwrap_int64().checked_rem(b).unwrap_or(0)))
1752 }
1753}
1754
1755#[sqlfunc(
1756 output_type = "u16",
1757 is_infix_op = true,
1758 sqlname = "%",
1759 propagates_nulls = true
1760)]
1761fn mod_uint16<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1762 let b = b.unwrap_uint16();
1763 if b == 0 {
1764 Err(EvalError::DivisionByZero)
1765 } else {
1766 Ok(Datum::from(a.unwrap_uint16() % b))
1767 }
1768}
1769
1770#[sqlfunc(
1771 output_type = "u32",
1772 is_infix_op = true,
1773 sqlname = "%",
1774 propagates_nulls = true
1775)]
1776fn mod_uint32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1777 let b = b.unwrap_uint32();
1778 if b == 0 {
1779 Err(EvalError::DivisionByZero)
1780 } else {
1781 Ok(Datum::from(a.unwrap_uint32() % b))
1782 }
1783}
1784
1785#[sqlfunc(
1786 output_type = "u64",
1787 is_infix_op = true,
1788 sqlname = "%",
1789 propagates_nulls = true
1790)]
1791fn mod_uint64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1792 let b = b.unwrap_uint64();
1793 if b == 0 {
1794 Err(EvalError::DivisionByZero)
1795 } else {
1796 Ok(Datum::from(a.unwrap_uint64() % b))
1797 }
1798}
1799
1800#[sqlfunc(
1801 output_type = "f32",
1802 is_infix_op = true,
1803 sqlname = "%",
1804 propagates_nulls = true
1805)]
1806fn mod_float32<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1807 let b = b.unwrap_float32();
1808 if b == 0.0 {
1809 Err(EvalError::DivisionByZero)
1810 } else {
1811 Ok(Datum::from(a.unwrap_float32() % b))
1812 }
1813}
1814
1815#[sqlfunc(
1816 output_type = "f64",
1817 is_infix_op = true,
1818 sqlname = "%",
1819 propagates_nulls = true
1820)]
1821fn mod_float64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1822 let b = b.unwrap_float64();
1823 if b == 0.0 {
1824 Err(EvalError::DivisionByZero)
1825 } else {
1826 Ok(Datum::from(a.unwrap_float64() % b))
1827 }
1828}
1829
1830#[sqlfunc(
1831 output_type = "Numeric",
1832 is_infix_op = true,
1833 sqlname = "%",
1834 propagates_nulls = true
1835)]
1836fn mod_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1837 let mut a = a.unwrap_numeric();
1838 let b = b.unwrap_numeric();
1839 if b.0.is_zero() {
1840 return Err(EvalError::DivisionByZero);
1841 }
1842 let mut cx = numeric::cx_datum();
1843 cx.rem(&mut a.0, &b.0);
1845 numeric::munge_numeric(&mut a.0).unwrap();
1846 Ok(Datum::Numeric(a))
1847}
1848
1849fn neg_interval_inner(a: Datum) -> Result<Interval, EvalError> {
1850 a.unwrap_interval()
1851 .checked_neg()
1852 .ok_or_else(|| EvalError::IntervalOutOfRange(a.to_string().into()))
1853}
1854
1855fn log_guard_numeric(val: &Numeric, function_name: &str) -> Result<(), EvalError> {
1856 if val.is_negative() {
1857 return Err(EvalError::NegativeOutOfDomain(function_name.into()));
1858 }
1859 if val.is_zero() {
1860 return Err(EvalError::ZeroOutOfDomain(function_name.into()));
1861 }
1862 Ok(())
1863}
1864
1865#[sqlfunc(output_type = "Numeric", sqlname = "log", propagates_nulls = true)]
1866fn log_base_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1867 let mut a = a.unwrap_numeric().0;
1868 log_guard_numeric(&a, "log")?;
1869 let mut b = b.unwrap_numeric().0;
1870 log_guard_numeric(&b, "log")?;
1871 let mut cx = numeric::cx_datum();
1872 cx.ln(&mut a);
1873 cx.ln(&mut b);
1874 cx.div(&mut b, &a);
1875 if a.is_zero() {
1876 Err(EvalError::DivisionByZero)
1877 } else {
1878 cx.set_precision(usize::from(numeric::NUMERIC_DATUM_MAX_PRECISION - 1))
1883 .expect("reducing precision below max always succeeds");
1884 let mut integral_check = b.clone();
1885
1886 cx.reduce(&mut integral_check);
1890
1891 let mut b = if integral_check.exponent() >= 0 {
1893 integral_check
1895 } else {
1896 b
1897 };
1898
1899 numeric::munge_numeric(&mut b).unwrap();
1900 Ok(Datum::from(b))
1901 }
1902}
1903
1904#[sqlfunc(output_type = "f64", propagates_nulls = true)]
1905fn power<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1906 let a = a.unwrap_float64();
1907 let b = b.unwrap_float64();
1908 if a == 0.0 && b.is_sign_negative() {
1909 return Err(EvalError::Undefined(
1910 "zero raised to a negative power".into(),
1911 ));
1912 }
1913 if a.is_sign_negative() && b.fract() != 0.0 {
1914 return Err(EvalError::ComplexOutOfRange("pow".into()));
1917 }
1918 let res = a.powf(b);
1919 if res.is_infinite() {
1920 return Err(EvalError::FloatOverflow);
1921 }
1922 if res == 0.0 && a != 0.0 {
1923 return Err(EvalError::FloatUnderflow);
1924 }
1925 Ok(Datum::from(res))
1926}
1927
1928#[sqlfunc(output_type = "uuid::Uuid", propagates_nulls = true)]
1929fn uuid_generate_v5<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
1930 let a = a.unwrap_uuid();
1931 let b = b.unwrap_str();
1932 let res = uuid::Uuid::new_v5(&a, b.as_bytes());
1933 Datum::Uuid(res)
1934}
1935
1936#[sqlfunc(output_type = "Numeric", propagates_nulls = true)]
1937fn power_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1938 let mut a = a.unwrap_numeric().0;
1939 let b = b.unwrap_numeric().0;
1940 if a.is_zero() {
1941 if b.is_zero() {
1942 return Ok(Datum::from(Numeric::from(1)));
1943 }
1944 if b.is_negative() {
1945 return Err(EvalError::Undefined(
1946 "zero raised to a negative power".into(),
1947 ));
1948 }
1949 }
1950 if a.is_negative() && b.exponent() < 0 {
1951 return Err(EvalError::ComplexOutOfRange("pow".into()));
1954 }
1955 let mut cx = numeric::cx_datum();
1956 cx.pow(&mut a, &b);
1957 let cx_status = cx.status();
1958 if cx_status.overflow() || (cx_status.invalid_operation() && !b.is_negative()) {
1959 Err(EvalError::FloatOverflow)
1960 } else if cx_status.subnormal() || cx_status.invalid_operation() {
1961 Err(EvalError::FloatUnderflow)
1962 } else {
1963 numeric::munge_numeric(&mut a).unwrap();
1964 Ok(Datum::from(a))
1965 }
1966}
1967
1968#[sqlfunc(output_type = "i32", propagates_nulls = true)]
1969fn get_bit<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1970 let bytes = a.unwrap_bytes();
1971 let index = b.unwrap_int32();
1972 let err = EvalError::IndexOutOfRange {
1973 provided: index,
1974 valid_end: i32::try_from(bytes.len().saturating_mul(8)).unwrap() - 1,
1975 };
1976
1977 let index = usize::try_from(index).map_err(|_| err.clone())?;
1978
1979 let byte_index = index / 8;
1980 let bit_index = index % 8;
1981
1982 let i = bytes
1983 .get(byte_index)
1984 .map(|b| (*b >> bit_index) & 1)
1985 .ok_or(err)?;
1986 assert!(i == 0 || i == 1);
1987 Ok(Datum::from(i32::from(i)))
1988}
1989
1990#[sqlfunc(output_type = "i32", propagates_nulls = true)]
1991fn get_byte<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
1992 let bytes = a.unwrap_bytes();
1993 let index = b.unwrap_int32();
1994 let err = EvalError::IndexOutOfRange {
1995 provided: index,
1996 valid_end: i32::try_from(bytes.len()).unwrap() - 1,
1997 };
1998 let i: &u8 = bytes
1999 .get(usize::try_from(index).map_err(|_| err.clone())?)
2000 .ok_or(err)?;
2001 Ok(Datum::from(i32::from(*i)))
2002}
2003
2004#[sqlfunc(
2005 output_type = "bool",
2006 sqlname = "constant_time_compare_bytes",
2007 propagates_nulls = true
2008)]
2009pub fn constant_time_eq_bytes<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2010 let a_bytes = a.unwrap_bytes();
2011 let b_bytes = b.unwrap_bytes();
2012 Ok(Datum::from(bool::from(a_bytes.ct_eq(b_bytes))))
2013}
2014
2015#[sqlfunc(
2016 output_type = "bool",
2017 sqlname = "constant_time_compare_strings",
2018 propagates_nulls = true
2019)]
2020pub fn constant_time_eq_string<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2021 let a = a.unwrap_str();
2022 let b = b.unwrap_str();
2023 Ok(Datum::from(bool::from(a.as_bytes().ct_eq(b.as_bytes()))))
2024}
2025
2026fn contains_range_elem<'a, R: RangeOps<'a>>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a>
2027where
2028 <R as TryFrom<Datum<'a>>>::Error: std::fmt::Debug,
2029{
2030 let range = a.unwrap_range();
2031 let elem = R::try_from(b).expect("type checking must produce correct R");
2032 Datum::from(range.contains_elem(&elem))
2033}
2034
2035#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2036#[allow(dead_code)]
2037fn range_contains_i32<'a>(a: Range<Datum<'a>>, b: i32) -> bool {
2038 a.contains_elem(&b)
2039}
2040
2041#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2042#[allow(dead_code)]
2043fn range_contains_i64<'a>(a: Range<Datum<'a>>, elem: i64) -> bool {
2044 a.contains_elem(&elem)
2045}
2046
2047#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2048#[allow(dead_code)]
2049fn range_contains_date<'a>(a: Range<Datum<'a>>, elem: Date) -> bool {
2050 a.contains_elem(&elem)
2051}
2052
2053#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2054#[allow(dead_code)]
2055fn range_contains_numeric<'a>(a: Range<Datum<'a>>, elem: OrderedDecimal<Numeric>) -> bool {
2056 a.contains_elem(&elem)
2057}
2058
2059#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2060#[allow(dead_code)]
2061fn range_contains_timestamp<'a>(
2062 a: Range<Datum<'a>>,
2063 elem: CheckedTimestamp<NaiveDateTime>,
2064) -> bool {
2065 a.contains_elem(&elem)
2066}
2067
2068#[sqlfunc(is_infix_op = true, sqlname = "@>", propagates_nulls = true)]
2069#[allow(dead_code)]
2070fn range_contains_timestamp_tz<'a>(
2071 a: Range<Datum<'a>>,
2072 elem: CheckedTimestamp<DateTime<Utc>>,
2073) -> bool {
2074 a.contains_elem(&elem)
2075}
2076
2077#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2078#[allow(dead_code)]
2079fn range_contains_i32_rev<'a>(a: Range<Datum<'a>>, b: i32) -> bool {
2080 a.contains_elem(&b)
2081}
2082
2083#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2084#[allow(dead_code)]
2085fn range_contains_i64_rev<'a>(a: Range<Datum<'a>>, elem: i64) -> bool {
2086 a.contains_elem(&elem)
2087}
2088
2089#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2090#[allow(dead_code)]
2091fn range_contains_date_rev<'a>(a: Range<Datum<'a>>, elem: Date) -> bool {
2092 a.contains_elem(&elem)
2093}
2094
2095#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2096#[allow(dead_code)]
2097fn range_contains_numeric_rev<'a>(a: Range<Datum<'a>>, elem: OrderedDecimal<Numeric>) -> bool {
2098 a.contains_elem(&elem)
2099}
2100
2101#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2102#[allow(dead_code)]
2103fn range_contains_timestamp_rev<'a>(
2104 a: Range<Datum<'a>>,
2105 elem: CheckedTimestamp<NaiveDateTime>,
2106) -> bool {
2107 a.contains_elem(&elem)
2108}
2109
2110#[sqlfunc(is_infix_op = true, sqlname = "<@", propagates_nulls = true)]
2111#[allow(dead_code)]
2112fn range_contains_timestamp_tz_rev<'a>(
2113 a: Range<Datum<'a>>,
2114 elem: CheckedTimestamp<DateTime<Utc>>,
2115) -> bool {
2116 a.contains_elem(&elem)
2117}
2118
2119macro_rules! range_fn {
2125 ($fn:expr, $range_fn:expr, $sqlname:expr) => {
2126 paste::paste! {
2127
2128 #[sqlfunc(
2129 output_type = "bool",
2130 is_infix_op = true,
2131 sqlname = $sqlname,
2132 propagates_nulls = true
2133 )]
2134 fn [< range_ $fn >]<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a>
2135 {
2136 let l = a.unwrap_range();
2137 let r = b.unwrap_range();
2138 Datum::from(Range::<Datum<'a>>::$range_fn(&l, &r))
2139 }
2140 }
2141 };
2142}
2143
2144range_fn!(contains_range, contains_range, "@>");
2147range_fn!(contains_range_rev, contains_range, "<@");
2148range_fn!(overlaps, overlaps, "&&");
2149range_fn!(after, after, ">>");
2150range_fn!(before, before, "<<");
2151range_fn!(overleft, overleft, "&<");
2152range_fn!(overright, overright, "&>");
2153range_fn!(adjacent, adjacent, "-|-");
2154
2155#[sqlfunc(
2156 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
2157 is_infix_op = true,
2158 sqlname = "+",
2159 propagates_nulls = true,
2160 introduces_nulls = false
2161)]
2162fn range_union<'a>(
2163 a: Datum<'a>,
2164 b: Datum<'a>,
2165 temp_storage: &'a RowArena,
2166) -> Result<Datum<'a>, EvalError> {
2167 let l = a.unwrap_range();
2168 let r = b.unwrap_range();
2169 l.union(&r)?.into_result(temp_storage)
2170}
2171
2172#[sqlfunc(
2173 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
2174 is_infix_op = true,
2175 sqlname = "*",
2176 propagates_nulls = true,
2177 introduces_nulls = false
2178)]
2179fn range_intersection<'a>(
2180 a: Datum<'a>,
2181 b: Datum<'a>,
2182 temp_storage: &'a RowArena,
2183) -> Result<Datum<'a>, EvalError> {
2184 let l = a.unwrap_range();
2185 let r = b.unwrap_range();
2186 l.intersection(&r).into_result(temp_storage)
2187}
2188
2189#[sqlfunc(
2190 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
2191 is_infix_op = true,
2192 sqlname = "-",
2193 propagates_nulls = true,
2194 introduces_nulls = false
2195)]
2196fn range_difference<'a>(
2197 a: Datum<'a>,
2198 b: Datum<'a>,
2199 temp_storage: &'a RowArena,
2200) -> Result<Datum<'a>, EvalError> {
2201 let l = a.unwrap_range();
2202 let r = b.unwrap_range();
2203 l.difference(&r)?.into_result(temp_storage)
2204}
2205
2206#[sqlfunc(
2207 output_type = "bool",
2208 is_infix_op = true,
2209 sqlname = "=",
2210 propagates_nulls = true
2211)]
2212fn eq<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2213 Datum::from(a == b)
2217}
2218
2219#[sqlfunc(
2220 output_type = "bool",
2221 is_infix_op = true,
2222 sqlname = "!=",
2223 propagates_nulls = true
2224)]
2225fn not_eq<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2226 Datum::from(a != b)
2227}
2228
2229#[sqlfunc(
2230 is_monotone = "(true, true)",
2231 output_type = "bool",
2232 is_infix_op = true,
2233 sqlname = "<",
2234 propagates_nulls = true
2235)]
2236fn lt<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2237 Datum::from(a < b)
2238}
2239
2240#[sqlfunc(
2241 is_monotone = "(true, true)",
2242 output_type = "bool",
2243 is_infix_op = true,
2244 sqlname = "<=",
2245 propagates_nulls = true
2246)]
2247fn lte<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2248 Datum::from(a <= b)
2249}
2250
2251#[sqlfunc(
2252 is_monotone = "(true, true)",
2253 output_type = "bool",
2254 is_infix_op = true,
2255 sqlname = ">",
2256 propagates_nulls = true
2257)]
2258fn gt<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2259 Datum::from(a > b)
2260}
2261
2262#[sqlfunc(
2263 is_monotone = "(true, true)",
2264 output_type = "bool",
2265 is_infix_op = true,
2266 sqlname = ">=",
2267 propagates_nulls = true
2268)]
2269fn gte<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2270 Datum::from(a >= b)
2271}
2272
2273fn to_char_timestamplike<'a, T>(ts: &T, format: &str, temp_storage: &'a RowArena) -> Datum<'a>
2274where
2275 T: TimestampLike,
2276{
2277 let fmt = DateTimeFormat::compile(format);
2278 Datum::String(temp_storage.push_string(fmt.render(ts)))
2279}
2280
2281#[sqlfunc(output_type = "String", sqlname = "tocharts", propagates_nulls = true)]
2282#[allow(dead_code)]
2283fn to_char_timestamp_format<'a>(a: Datum<'a>, format: &str) -> String {
2284 let ts = a.unwrap_timestamp();
2285 let fmt = DateTimeFormat::compile(format);
2286 fmt.render(&*ts)
2287}
2288
2289#[sqlfunc(
2290 output_type = "String",
2291 sqlname = "tochartstz",
2292 propagates_nulls = true
2293)]
2294#[allow(dead_code)]
2295fn to_char_timestamp_tz_format<'a>(a: Datum<'a>, format: &str) -> String {
2296 let ts = a.unwrap_timestamptz();
2297 let fmt = DateTimeFormat::compile(format);
2298 fmt.render(&*ts)
2299}
2300
2301fn jsonb_get_int64<'a>(
2302 a: Datum<'a>,
2303 b: Datum<'a>,
2304 temp_storage: &'a RowArena,
2305 stringify: bool,
2306) -> Datum<'a> {
2307 let i = b.unwrap_int64();
2308 match a {
2309 Datum::List(list) => {
2310 let i = if i >= 0 {
2311 usize::cast_from(i.unsigned_abs())
2312 } else {
2313 let i = usize::cast_from(i.unsigned_abs());
2315 (list.iter().count()).wrapping_sub(i)
2316 };
2317 match list.iter().nth(i) {
2318 Some(d) if stringify => jsonb_stringify(d, temp_storage),
2319 Some(d) => d,
2320 None => Datum::Null,
2321 }
2322 }
2323 Datum::Map(_) => Datum::Null,
2324 _ => {
2325 if i == 0 || i == -1 {
2326 if stringify {
2328 jsonb_stringify(a, temp_storage)
2329 } else {
2330 a
2331 }
2332 } else {
2333 Datum::Null
2334 }
2335 }
2336 }
2337}
2338
2339fn jsonb_get_string<'a>(
2340 a: Datum<'a>,
2341 b: Datum<'a>,
2342 temp_storage: &'a RowArena,
2343 stringify: bool,
2344) -> Datum<'a> {
2345 let k = b.unwrap_str();
2346 match a {
2347 Datum::Map(dict) => match dict.iter().find(|(k2, _v)| k == *k2) {
2348 Some((_k, v)) if stringify => jsonb_stringify(v, temp_storage),
2349 Some((_k, v)) => v,
2350 None => Datum::Null,
2351 },
2352 _ => Datum::Null,
2353 }
2354}
2355
2356fn jsonb_get_path<'a>(
2357 a: Datum<'a>,
2358 b: Datum<'a>,
2359 temp_storage: &'a RowArena,
2360 stringify: bool,
2361) -> Datum<'a> {
2362 let mut json = a;
2363 let path = b.unwrap_array().elements();
2364 for key in path.iter() {
2365 let key = match key {
2366 Datum::String(s) => s,
2367 Datum::Null => return Datum::Null,
2368 _ => unreachable!("keys in jsonb_get_path known to be strings"),
2369 };
2370 json = match json {
2371 Datum::Map(map) => match map.iter().find(|(k, _)| key == *k) {
2372 Some((_k, v)) => v,
2373 None => return Datum::Null,
2374 },
2375 Datum::List(list) => match strconv::parse_int64(key) {
2376 Ok(i) => {
2377 let i = if i >= 0 {
2378 usize::cast_from(i.unsigned_abs())
2379 } else {
2380 let i = usize::cast_from(i.unsigned_abs());
2382 (list.iter().count()).wrapping_sub(i)
2383 };
2384 match list.iter().nth(i) {
2385 Some(e) => e,
2386 None => return Datum::Null,
2387 }
2388 }
2389 Err(_) => return Datum::Null,
2390 },
2391 _ => return Datum::Null,
2392 }
2393 }
2394 if stringify {
2395 jsonb_stringify(json, temp_storage)
2396 } else {
2397 json
2398 }
2399}
2400
2401#[sqlfunc(
2402 output_type = "bool",
2403 is_infix_op = true,
2404 sqlname = "?",
2405 propagates_nulls = true
2406)]
2407fn jsonb_contains_string<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2408 let k = b.unwrap_str();
2409 match a {
2411 Datum::List(list) => list.iter().any(|k2| b == k2).into(),
2412 Datum::Map(dict) => dict.iter().any(|(k2, _v)| k == k2).into(),
2413 Datum::String(string) => (string == k).into(),
2414 _ => false.into(),
2415 }
2416}
2417
2418#[sqlfunc(
2419 output_type = "bool",
2420 is_infix_op = true,
2421 sqlname = "?",
2422 propagates_nulls = true
2423)]
2424fn map_contains_key<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2425 let map = a.unwrap_map();
2426 let k = b.unwrap_str(); map.iter().any(|(k2, _v)| k == k2).into()
2428}
2429
2430#[sqlfunc(
2431 output_type = "bool",
2432 is_infix_op = true,
2433 sqlname = "?&",
2434 propagates_nulls = true
2435)]
2436fn map_contains_all_keys<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2437 let map = a.unwrap_map();
2438 let keys = b.unwrap_array();
2439
2440 keys.elements()
2441 .iter()
2442 .all(|key| !key.is_null() && map.iter().any(|(k, _v)| k == key.unwrap_str()))
2443 .into()
2444}
2445
2446#[sqlfunc(
2447 output_type = "bool",
2448 is_infix_op = true,
2449 sqlname = "?|",
2450 propagates_nulls = true
2451)]
2452fn map_contains_any_keys<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2453 let map = a.unwrap_map();
2454 let keys = b.unwrap_array();
2455
2456 keys.elements()
2457 .iter()
2458 .any(|key| !key.is_null() && map.iter().any(|(k, _v)| k == key.unwrap_str()))
2459 .into()
2460}
2461
2462#[sqlfunc(
2463 output_type = "bool",
2464 is_infix_op = true,
2465 sqlname = "@>",
2466 propagates_nulls = true
2467)]
2468fn map_contains_map<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2469 let map_a = a.unwrap_map();
2470 b.unwrap_map()
2471 .iter()
2472 .all(|(b_key, b_val)| {
2473 map_a
2474 .iter()
2475 .any(|(a_key, a_val)| (a_key == b_key) && (a_val == b_val))
2476 })
2477 .into()
2478}
2479
2480#[sqlfunc(
2481 output_type_expr = "input_type_a.scalar_type.unwrap_map_value_type().clone().nullable(true)",
2482 is_infix_op = true,
2483 sqlname = "->",
2484 propagates_nulls = true,
2485 introduces_nulls = true
2486)]
2487fn map_get_value<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2488 let target_key = b.unwrap_str();
2489 match a.unwrap_map().iter().find(|(key, _v)| target_key == *key) {
2490 Some((_k, v)) => v,
2491 None => Datum::Null,
2492 }
2493}
2494
2495#[sqlfunc(
2496 output_type = "bool",
2497 is_infix_op = true,
2498 sqlname = "@>",
2499 propagates_nulls = true,
2500 introduces_nulls = false
2501)]
2502fn list_contains_list<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2503 let a = a.unwrap_list();
2504 let b = b.unwrap_list();
2505
2506 if b.iter().contains(&Datum::Null) {
2508 Datum::False
2509 } else {
2510 b.iter()
2511 .all(|item_b| a.iter().any(|item_a| item_a == item_b))
2512 .into()
2513 }
2514}
2515
2516#[sqlfunc(
2517 output_type = "bool",
2518 is_infix_op = true,
2519 sqlname = "<@",
2520 propagates_nulls = true,
2521 introduces_nulls = false
2522)]
2523#[allow(dead_code)]
2524fn list_contains_list_rev<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2525 list_contains_list(b, a)
2526}
2527
2528#[sqlfunc(
2530 output_type = "bool",
2531 is_infix_op = true,
2532 sqlname = "@>",
2533 propagates_nulls = true
2534)]
2535fn jsonb_contains_jsonb<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
2536 fn contains(a: Datum, b: Datum, at_top_level: bool) -> bool {
2538 match (a, b) {
2539 (Datum::JsonNull, Datum::JsonNull) => true,
2540 (Datum::False, Datum::False) => true,
2541 (Datum::True, Datum::True) => true,
2542 (Datum::Numeric(a), Datum::Numeric(b)) => a == b,
2543 (Datum::String(a), Datum::String(b)) => a == b,
2544 (Datum::List(a), Datum::List(b)) => b
2545 .iter()
2546 .all(|b_elem| a.iter().any(|a_elem| contains(a_elem, b_elem, false))),
2547 (Datum::Map(a), Datum::Map(b)) => b.iter().all(|(b_key, b_val)| {
2548 a.iter()
2549 .any(|(a_key, a_val)| (a_key == b_key) && contains(a_val, b_val, false))
2550 }),
2551
2552 (Datum::List(a), b) => {
2554 at_top_level && a.iter().any(|a_elem| contains(a_elem, b, false))
2555 }
2556
2557 _ => false,
2558 }
2559 }
2560 contains(a, b, true).into()
2561}
2562
2563#[sqlfunc(
2564 output_type_expr = "ScalarType::Jsonb.nullable(true)",
2565 is_infix_op = true,
2566 sqlname = "||",
2567 propagates_nulls = true,
2568 introduces_nulls = true
2569)]
2570fn jsonb_concat<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
2571 match (a, b) {
2572 (Datum::Map(dict_a), Datum::Map(dict_b)) => {
2573 let mut pairs = dict_b.iter().chain(dict_a.iter()).collect::<Vec<_>>();
2574 pairs.sort_by(|(k1, _v1), (k2, _v2)| k1.cmp(k2));
2576 pairs.dedup_by(|(k1, _v1), (k2, _v2)| k1 == k2);
2577 temp_storage.make_datum(|packer| packer.push_dict(pairs))
2578 }
2579 (Datum::List(list_a), Datum::List(list_b)) => {
2580 let elems = list_a.iter().chain(list_b.iter());
2581 temp_storage.make_datum(|packer| packer.push_list(elems))
2582 }
2583 (Datum::List(list_a), b) => {
2584 let elems = list_a.iter().chain(Some(b));
2585 temp_storage.make_datum(|packer| packer.push_list(elems))
2586 }
2587 (a, Datum::List(list_b)) => {
2588 let elems = Some(a).into_iter().chain(list_b.iter());
2589 temp_storage.make_datum(|packer| packer.push_list(elems))
2590 }
2591 _ => Datum::Null,
2592 }
2593}
2594
2595#[sqlfunc(
2596 output_type_expr = "ScalarType::Jsonb.nullable(true)",
2597 is_infix_op = true,
2598 sqlname = "-",
2599 propagates_nulls = true,
2600 introduces_nulls = true
2601)]
2602fn jsonb_delete_int64<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
2603 let i = b.unwrap_int64();
2604 match a {
2605 Datum::List(list) => {
2606 let i = if i >= 0 {
2607 usize::cast_from(i.unsigned_abs())
2608 } else {
2609 let i = usize::cast_from(i.unsigned_abs());
2611 (list.iter().count()).wrapping_sub(i)
2612 };
2613 let elems = list
2614 .iter()
2615 .enumerate()
2616 .filter(|(i2, _e)| i != *i2)
2617 .map(|(_, e)| e);
2618 temp_storage.make_datum(|packer| packer.push_list(elems))
2619 }
2620 _ => Datum::Null,
2621 }
2622}
2623
2624#[sqlfunc(
2625 output_type_expr = "ScalarType::Jsonb.nullable(true)",
2626 is_infix_op = true,
2627 sqlname = "-",
2628 propagates_nulls = true,
2629 introduces_nulls = true
2630)]
2631fn jsonb_delete_string<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
2632 match a {
2633 Datum::List(list) => {
2634 let elems = list.iter().filter(|e| b != *e);
2635 temp_storage.make_datum(|packer| packer.push_list(elems))
2636 }
2637 Datum::Map(dict) => {
2638 let k = b.unwrap_str();
2639 let pairs = dict.iter().filter(|(k2, _v)| k != *k2);
2640 temp_storage.make_datum(|packer| packer.push_dict(pairs))
2641 }
2642 _ => Datum::Null,
2643 }
2644}
2645
2646fn date_part_interval<'a, D>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError>
2647where
2648 D: DecimalLike + Into<Datum<'static>>,
2649{
2650 let units = a.unwrap_str();
2651 match units.parse() {
2652 Ok(units) => Ok(date_part_interval_inner::<D>(units, b.unwrap_interval())?.into()),
2653 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2654 }
2655}
2656
2657#[sqlfunc(
2658 output_type = "Numeric",
2659 sqlname = "extractiv",
2660 propagates_nulls = true,
2661 introduces_nulls = false
2662)]
2663#[allow(dead_code)]
2664fn date_part_interval_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2665 let units = a.unwrap_str();
2666 match units.parse() {
2667 Ok(units) => Ok(date_part_interval_inner::<Numeric>(units, b.unwrap_interval())?.into()),
2668 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2669 }
2670}
2671
2672#[sqlfunc(
2673 output_type = "f64",
2674 sqlname = "date_partiv",
2675 propagates_nulls = true,
2676 introduces_nulls = false
2677)]
2678#[allow(dead_code)]
2679fn date_part_interval_f64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2680 let units = a.unwrap_str();
2681 match units.parse() {
2682 Ok(units) => Ok(date_part_interval_inner::<f64>(units, b.unwrap_interval())?.into()),
2683 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2684 }
2685}
2686
2687fn date_part_time<'a, D>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError>
2688where
2689 D: DecimalLike + Into<Datum<'a>>,
2690{
2691 let units = a.unwrap_str();
2692 match units.parse() {
2693 Ok(units) => Ok(date_part_time_inner::<D>(units, b.unwrap_time())?.into()),
2694 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2695 }
2696}
2697
2698#[sqlfunc(
2699 output_type = "Numeric",
2700 sqlname = "extractt",
2701 propagates_nulls = true,
2702 introduces_nulls = false
2703)]
2704#[allow(dead_code)]
2705fn date_part_time_numeric<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2706 let units = a.unwrap_str();
2707 match units.parse() {
2708 Ok(units) => Ok(date_part_time_inner::<Numeric>(units, b.unwrap_time())?.into()),
2709 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2710 }
2711}
2712
2713#[sqlfunc(
2714 output_type = "f64",
2715 sqlname = "date_partt",
2716 propagates_nulls = true,
2717 introduces_nulls = false
2718)]
2719#[allow(dead_code)]
2720fn date_part_time_f64<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2721 let units = a.unwrap_str();
2722 match units.parse() {
2723 Ok(units) => Ok(date_part_time_inner::<f64>(units, b.unwrap_time())?.into()),
2724 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2725 }
2726}
2727
2728fn date_part_timestamp<'a, T, D>(a: Datum<'a>, ts: &T) -> Result<Datum<'a>, EvalError>
2729where
2730 T: TimestampLike,
2731 D: DecimalLike + Into<Datum<'a>>,
2732{
2733 let units = a.unwrap_str();
2734 match units.parse() {
2735 Ok(units) => Ok(date_part_timestamp_inner::<_, D>(units, ts)?.into()),
2736 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2737 }
2738}
2739
2740#[sqlfunc(
2741 output_type = "Numeric",
2742 sqlname = "extractts",
2743 propagates_nulls = true
2744)]
2745#[allow(dead_code)]
2746fn date_part_timestamp_timestamp_numeric<'a>(
2747 units: &str,
2748 ts: CheckedTimestamp<NaiveDateTime>,
2749) -> Result<Datum<'a>, EvalError> {
2750 match units.parse() {
2751 Ok(units) => Ok(date_part_timestamp_inner::<_, Numeric>(units, &*ts)?.into()),
2752 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2753 }
2754}
2755
2756#[sqlfunc(
2757 output_type = "Numeric",
2758 sqlname = "extracttstz",
2759 propagates_nulls = true
2760)]
2761#[allow(dead_code)]
2762fn date_part_timestamp_timestamp_tz_numeric<'a>(
2763 units: &str,
2764 ts: CheckedTimestamp<DateTime<Utc>>,
2765) -> Result<Datum<'a>, EvalError> {
2766 match units.parse() {
2767 Ok(units) => Ok(date_part_timestamp_inner::<_, Numeric>(units, &*ts)?.into()),
2768 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2769 }
2770}
2771
2772#[sqlfunc(sqlname = "date_partts", propagates_nulls = true)]
2773#[allow(dead_code)]
2774fn date_part_timestamp_timestamp_f64(
2775 units: &str,
2776 ts: CheckedTimestamp<NaiveDateTime>,
2777) -> Result<f64, EvalError> {
2778 match units.parse() {
2779 Ok(units) => date_part_timestamp_inner(units, &*ts),
2780 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2781 }
2782}
2783
2784#[sqlfunc(sqlname = "date_parttstz", propagates_nulls = true)]
2785#[allow(dead_code)]
2786fn date_part_timestamp_timestamp_tz_f64(
2787 units: &str,
2788 ts: CheckedTimestamp<DateTime<Utc>>,
2789) -> Result<f64, EvalError> {
2790 match units.parse() {
2791 Ok(units) => date_part_timestamp_inner(units, &*ts),
2792 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2793 }
2794}
2795
2796#[sqlfunc(output_type = "Numeric", sqlname = "extractd", propagates_nulls = true)]
2797fn extract_date_units<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2798 let units = a.unwrap_str();
2799 match units.parse() {
2800 Ok(units) => Ok(extract_date_inner(units, b.unwrap_date().into())?.into()),
2801 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2802 }
2803}
2804
2805pub fn date_bin<'a, T>(
2806 stride: Interval,
2807 source: CheckedTimestamp<T>,
2808 origin: CheckedTimestamp<T>,
2809) -> Result<Datum<'a>, EvalError>
2810where
2811 T: TimestampLike,
2812{
2813 if stride.months != 0 {
2814 return Err(EvalError::DateBinOutOfRange(
2815 "timestamps cannot be binned into intervals containing months or years".into(),
2816 ));
2817 }
2818
2819 let stride_ns = match stride.duration_as_chrono().num_nanoseconds() {
2820 Some(ns) if ns <= 0 => Err(EvalError::DateBinOutOfRange(
2821 "stride must be greater than zero".into(),
2822 )),
2823 Some(ns) => Ok(ns),
2824 None => Err(EvalError::DateBinOutOfRange(
2825 format!("stride cannot exceed {}/{} nanoseconds", i64::MAX, i64::MIN,).into(),
2826 )),
2827 }?;
2828
2829 let sub_stride = origin > source;
2833
2834 let tm_diff = (source - origin.clone()).num_nanoseconds().ok_or_else(|| {
2835 EvalError::DateBinOutOfRange(
2836 "source and origin must not differ more than 2^63 nanoseconds".into(),
2837 )
2838 })?;
2839
2840 let mut tm_delta = tm_diff - tm_diff % stride_ns;
2841
2842 if sub_stride {
2843 tm_delta -= stride_ns;
2844 }
2845
2846 let res = origin
2847 .checked_add_signed(Duration::nanoseconds(tm_delta))
2848 .ok_or(EvalError::TimestampOutOfRange)?;
2849 Ok(res.try_into()?)
2850}
2851
2852#[sqlfunc(
2853 is_monotone = "(true, true)",
2854 output_type = "CheckedTimestamp<NaiveDateTime>",
2855 sqlname = "bin_unix_epoch_timestamp",
2856 propagates_nulls = true
2857)]
2858#[allow(dead_code)]
2859fn date_bin_timestamp<'a>(
2860 stride: Interval,
2861 source: CheckedTimestamp<NaiveDateTime>,
2862) -> Result<Datum<'a>, EvalError> {
2863 let origin =
2864 CheckedTimestamp::from_timestamplike(DateTime::from_timestamp(0, 0).unwrap().naive_utc())
2865 .expect("must fit");
2866 date_bin(stride, source, origin)
2867}
2868
2869#[sqlfunc(
2870 is_monotone = "(true, true)",
2871 output_type = "CheckedTimestamp<DateTime<Utc>>",
2872 sqlname = "bin_unix_epoch_timestamptz",
2873 propagates_nulls = true
2874)]
2875#[allow(dead_code)]
2876fn date_bin_timestamp_tz<'a>(
2877 stride: Interval,
2878 source: CheckedTimestamp<DateTime<Utc>>,
2879) -> Result<Datum<'a>, EvalError> {
2880 let origin = CheckedTimestamp::from_timestamplike(DateTime::from_timestamp(0, 0).unwrap())
2881 .expect("must fit");
2882 date_bin(stride, source, origin)
2883}
2884
2885fn date_trunc<'a, T>(a: Datum<'a>, ts: &T) -> Result<Datum<'a>, EvalError>
2886where
2887 T: TimestampLike,
2888{
2889 let units = a.unwrap_str();
2890 match units.parse() {
2891 Ok(units) => Ok(date_trunc_inner(units, ts)?.try_into()?),
2892 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2893 }
2894}
2895
2896#[sqlfunc(sqlname = "date_truncts", propagates_nulls = true)]
2897#[allow(dead_code)]
2898fn date_trunc_units_timestamp(
2899 units: &str,
2900 ts: CheckedTimestamp<NaiveDateTime>,
2901) -> Result<CheckedTimestamp<NaiveDateTime>, EvalError> {
2902 match units.parse() {
2903 Ok(units) => Ok(date_trunc_inner(units, &*ts)?.try_into()?),
2904 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2905 }
2906}
2907
2908#[sqlfunc(sqlname = "date_trunctstz", propagates_nulls = true)]
2909#[allow(dead_code)]
2910fn date_trunc_units_timestamp_tz(
2911 units: &str,
2912 ts: CheckedTimestamp<DateTime<Utc>>,
2913) -> Result<CheckedTimestamp<DateTime<Utc>>, EvalError> {
2914 match units.parse() {
2915 Ok(units) => Ok(date_trunc_inner(units, &*ts)?.try_into()?),
2916 Err(_) => Err(EvalError::UnknownUnits(units.into())),
2917 }
2918}
2919
2920#[sqlfunc(
2921 output_type = "Interval",
2922 sqlname = "date_trunciv",
2923 propagates_nulls = true
2924)]
2925fn date_trunc_interval<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
2926 let mut interval = b.unwrap_interval();
2927 let units = a.unwrap_str();
2928 let dtf = units
2929 .parse()
2930 .map_err(|_| EvalError::UnknownUnits(units.into()))?;
2931
2932 interval
2933 .truncate_low_fields(dtf, Some(0), RoundBehavior::Truncate)
2934 .expect(
2935 "truncate_low_fields should not fail with max_precision 0 and RoundBehavior::Truncate",
2936 );
2937 Ok(interval.into())
2938}
2939
2940fn date_diff_timestamp<'a>(unit: Datum, a: Datum, b: Datum) -> Result<Datum<'a>, EvalError> {
2941 let unit = unit.unwrap_str();
2942 let unit = unit
2943 .parse()
2944 .map_err(|_| EvalError::InvalidDatePart(unit.into()))?;
2945
2946 let a = a.unwrap_timestamp();
2947 let b = b.unwrap_timestamp();
2948 let diff = b.diff_as(&a, unit)?;
2949
2950 Ok(Datum::Int64(diff))
2951}
2952
2953fn date_diff_timestamptz<'a>(unit: Datum, a: Datum, b: Datum) -> Result<Datum<'a>, EvalError> {
2954 let unit = unit.unwrap_str();
2955 let unit = unit
2956 .parse()
2957 .map_err(|_| EvalError::InvalidDatePart(unit.into()))?;
2958
2959 let a = a.unwrap_timestamptz();
2960 let b = b.unwrap_timestamptz();
2961 let diff = b.diff_as(&a, unit)?;
2962
2963 Ok(Datum::Int64(diff))
2964}
2965
2966fn date_diff_date<'a>(unit: Datum, a: Datum, b: Datum) -> Result<Datum<'a>, EvalError> {
2967 let unit = unit.unwrap_str();
2968 let unit = unit
2969 .parse()
2970 .map_err(|_| EvalError::InvalidDatePart(unit.into()))?;
2971
2972 let a = a.unwrap_date();
2973 let b = b.unwrap_date();
2974
2975 let a_ts = CheckedTimestamp::try_from(NaiveDate::from(a).and_hms_opt(0, 0, 0).unwrap())?;
2977 let b_ts = CheckedTimestamp::try_from(NaiveDate::from(b).and_hms_opt(0, 0, 0).unwrap())?;
2978 let diff = b_ts.diff_as(&a_ts, unit)?;
2979
2980 Ok(Datum::Int64(diff))
2981}
2982
2983fn date_diff_time<'a>(unit: Datum, a: Datum, b: Datum) -> Result<Datum<'a>, EvalError> {
2984 let unit = unit.unwrap_str();
2985 let unit = unit
2986 .parse()
2987 .map_err(|_| EvalError::InvalidDatePart(unit.into()))?;
2988
2989 let a = a.unwrap_time();
2990 let b = b.unwrap_time();
2991
2992 let a_ts =
2994 CheckedTimestamp::try_from(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_time(a))?;
2995 let b_ts =
2996 CheckedTimestamp::try_from(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_time(b))?;
2997 let diff = b_ts.diff_as(&a_ts, unit)?;
2998
2999 Ok(Datum::Int64(diff))
3000}
3001
3002pub(crate) fn parse_timezone(tz: &str, spec: TimezoneSpec) -> Result<Timezone, EvalError> {
3007 Timezone::parse(tz, spec).map_err(|_| EvalError::InvalidTimezone(tz.into()))
3008}
3009
3010fn timezone_interval_time(a: Datum<'_>, b: Datum<'_>) -> Result<Datum<'static>, EvalError> {
3014 let interval = a.unwrap_interval();
3015 if interval.months != 0 {
3016 Err(EvalError::InvalidTimezoneInterval)
3017 } else {
3018 Ok(b.unwrap_time()
3019 .overflowing_add_signed(interval.duration_as_chrono())
3020 .0
3021 .into())
3022 }
3023}
3024
3025fn timezone_interval_timestamp(a: Datum<'_>, b: Datum<'_>) -> Result<Datum<'static>, EvalError> {
3029 let interval = a.unwrap_interval();
3030 if interval.months != 0 {
3031 Err(EvalError::InvalidTimezoneInterval)
3032 } else {
3033 match b
3034 .unwrap_timestamp()
3035 .checked_sub_signed(interval.duration_as_chrono())
3036 {
3037 Some(sub) => Ok(DateTime::from_naive_utc_and_offset(sub, Utc).try_into()?),
3038 None => Err(EvalError::TimestampOutOfRange),
3039 }
3040 }
3041}
3042
3043fn timezone_interval_timestamptz(a: Datum<'_>, b: Datum<'_>) -> Result<Datum<'static>, EvalError> {
3047 let interval = a.unwrap_interval();
3048 if interval.months != 0 {
3049 return Err(EvalError::InvalidTimezoneInterval);
3050 }
3051 match b
3052 .unwrap_timestamptz()
3053 .naive_utc()
3054 .checked_add_signed(interval.duration_as_chrono())
3055 {
3056 Some(dt) => Ok(dt.try_into()?),
3057 None => Err(EvalError::TimestampOutOfRange),
3058 }
3059}
3060
3061#[sqlfunc(
3062 output_type_expr = r#"ScalarType::Record {
3063 fields: [
3064 ("abbrev".into(), ScalarType::String.nullable(false)),
3065 ("base_utc_offset".into(), ScalarType::Interval.nullable(false)),
3066 ("dst_offset".into(), ScalarType::Interval.nullable(false)),
3067 ].into(),
3068 custom_id: None,
3069 }.nullable(true)"#,
3070 propagates_nulls = true,
3071 introduces_nulls = false
3072)]
3073fn timezone_offset<'a>(
3074 a: Datum<'a>,
3075 b: Datum<'a>,
3076 temp_storage: &'a RowArena,
3077) -> Result<Datum<'a>, EvalError> {
3078 let tz_str = a.unwrap_str();
3079 let tz = match Tz::from_str_insensitive(tz_str) {
3080 Ok(tz) => tz,
3081 Err(_) => return Err(EvalError::InvalidIanaTimezoneId(tz_str.into())),
3082 };
3083 let offset = tz.offset_from_utc_datetime(&b.unwrap_timestamptz().naive_utc());
3084 Ok(temp_storage.make_datum(|packer| {
3085 packer.push_list_with(|packer| {
3086 packer.push(Datum::from(offset.abbreviation()));
3087 packer.push(Datum::from(offset.base_utc_offset()));
3088 packer.push(Datum::from(offset.dst_offset()));
3089 });
3090 }))
3091}
3092
3093#[sqlfunc(
3096 sqlname = "mz_aclitem_contains_privilege",
3097 output_type = "bool",
3098 propagates_nulls = true
3099)]
3100fn mz_acl_item_contains_privilege<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
3101 let mz_acl_item = a.unwrap_mz_acl_item();
3102 let privileges = b.unwrap_str();
3103 let acl_mode = AclMode::parse_multiple_privileges(privileges)
3104 .map_err(|e: anyhow::Error| EvalError::InvalidPrivileges(e.to_string().into()))?;
3105 let contains = !mz_acl_item.acl_mode.intersection(acl_mode).is_empty();
3106 Ok(contains.into())
3107}
3108
3109#[sqlfunc(
3110 output_type = "mz_repr::ArrayRustType<String>",
3111 propagates_nulls = true
3112)]
3113fn parse_ident<'a>(
3115 a: Datum<'a>,
3116 b: Datum<'a>,
3117 temp_storage: &'a RowArena,
3118) -> Result<Datum<'a>, EvalError> {
3119 fn is_ident_start(c: char) -> bool {
3120 matches!(c, 'A'..='Z' | 'a'..='z' | '_' | '\u{80}'..=char::MAX)
3121 }
3122
3123 fn is_ident_cont(c: char) -> bool {
3124 matches!(c, '0'..='9' | '$') || is_ident_start(c)
3125 }
3126
3127 let ident = a.unwrap_str();
3128 let strict = b.unwrap_bool();
3129
3130 let mut elems = vec![];
3131 let buf = &mut LexBuf::new(ident);
3132
3133 let mut after_dot = false;
3134
3135 buf.take_while(|ch| ch.is_ascii_whitespace());
3136
3137 loop {
3138 let mut missing_ident = true;
3139
3140 let c = buf.next();
3141
3142 if c == Some('"') {
3143 let s = buf.take_while(|ch| !matches!(ch, '"'));
3144
3145 if buf.next() != Some('"') {
3146 return Err(EvalError::InvalidIdentifier {
3147 ident: ident.into(),
3148 detail: Some("String has unclosed double quotes.".into()),
3149 });
3150 }
3151 elems.push(Datum::String(s));
3152 missing_ident = false;
3153 } else if c.map(is_ident_start).unwrap_or(false) {
3154 buf.prev();
3155 let s = buf.take_while(is_ident_cont);
3156 let s = temp_storage.push_string(s.to_ascii_lowercase());
3157 elems.push(Datum::String(s));
3158 missing_ident = false;
3159 }
3160
3161 if missing_ident {
3162 if c == Some('.') {
3163 return Err(EvalError::InvalidIdentifier {
3164 ident: ident.into(),
3165 detail: Some("No valid identifier before \".\".".into()),
3166 });
3167 } else if after_dot {
3168 return Err(EvalError::InvalidIdentifier {
3169 ident: ident.into(),
3170 detail: Some("No valid identifier after \".\".".into()),
3171 });
3172 } else {
3173 return Err(EvalError::InvalidIdentifier {
3174 ident: ident.into(),
3175 detail: None,
3176 });
3177 }
3178 }
3179
3180 buf.take_while(|ch| ch.is_ascii_whitespace());
3181
3182 match buf.next() {
3183 Some('.') => {
3184 after_dot = true;
3185
3186 buf.take_while(|ch| ch.is_ascii_whitespace());
3187 }
3188 Some(_) if strict => {
3189 return Err(EvalError::InvalidIdentifier {
3190 ident: ident.into(),
3191 detail: None,
3192 });
3193 }
3194 _ => break,
3195 }
3196 }
3197
3198 Ok(temp_storage.try_make_datum(|packer| {
3199 packer.try_push_array(
3200 &[ArrayDimension {
3201 lower_bound: 1,
3202 length: elems.len(),
3203 }],
3204 elems,
3205 )
3206 })?)
3207}
3208
3209fn string_to_array<'a>(
3210 string_datum: Datum<'a>,
3211 delimiter: Datum<'a>,
3212 null_string: Datum<'a>,
3213 temp_storage: &'a RowArena,
3214) -> Result<Datum<'a>, EvalError> {
3215 if string_datum.is_null() {
3216 return Ok(Datum::Null);
3217 }
3218
3219 let string = string_datum.unwrap_str();
3220
3221 if string.is_empty() {
3222 let mut row = Row::default();
3223 let mut packer = row.packer();
3224 packer.try_push_array(&[], std::iter::empty::<Datum>())?;
3225
3226 return Ok(temp_storage.push_unary_row(row));
3227 }
3228
3229 if delimiter.is_null() {
3230 let split_all_chars_delimiter = "";
3231 return string_to_array_impl(string, split_all_chars_delimiter, null_string, temp_storage);
3232 }
3233
3234 let delimiter = delimiter.unwrap_str();
3235
3236 if delimiter.is_empty() {
3237 let mut row = Row::default();
3238 let mut packer = row.packer();
3239 packer.try_push_array(
3240 &[ArrayDimension {
3241 lower_bound: 1,
3242 length: 1,
3243 }],
3244 vec![string].into_iter().map(Datum::String),
3245 )?;
3246
3247 Ok(temp_storage.push_unary_row(row))
3248 } else {
3249 string_to_array_impl(string, delimiter, null_string, temp_storage)
3250 }
3251}
3252
3253fn string_to_array_impl<'a>(
3254 string: &str,
3255 delimiter: &str,
3256 null_string: Datum<'a>,
3257 temp_storage: &'a RowArena,
3258) -> Result<Datum<'a>, EvalError> {
3259 let mut row = Row::default();
3260 let mut packer = row.packer();
3261
3262 let result = string.split(delimiter);
3263 let found: Vec<&str> = if delimiter.is_empty() {
3264 result.filter(|s| !s.is_empty()).collect()
3265 } else {
3266 result.collect()
3267 };
3268 let array_dimensions = [ArrayDimension {
3269 lower_bound: 1,
3270 length: found.len(),
3271 }];
3272
3273 if null_string.is_null() {
3274 packer.try_push_array(&array_dimensions, found.into_iter().map(Datum::String))?;
3275 } else {
3276 let null_string = null_string.unwrap_str();
3277 let found_datums = found.into_iter().map(|chunk| {
3278 if chunk.eq(null_string) {
3279 Datum::Null
3280 } else {
3281 Datum::String(chunk)
3282 }
3283 });
3284
3285 packer.try_push_array(&array_dimensions, found_datums)?;
3286 }
3287
3288 Ok(temp_storage.push_unary_row(row))
3289}
3290
3291fn regexp_split_to_array<'a>(
3292 text: Datum<'a>,
3293 regexp: Datum<'a>,
3294 flags: Datum<'a>,
3295 temp_storage: &'a RowArena,
3296) -> Result<Datum<'a>, EvalError> {
3297 let text = text.unwrap_str();
3298 let regexp = regexp.unwrap_str();
3299 let flags = flags.unwrap_str();
3300 let regexp = build_regex(regexp, flags)?;
3301 regexp_split_to_array_re(text, ®exp, temp_storage)
3302}
3303
3304fn regexp_split_to_array_re<'a>(
3305 text: &str,
3306 regexp: &Regex,
3307 temp_storage: &'a RowArena,
3308) -> Result<Datum<'a>, EvalError> {
3309 let found = mz_regexp::regexp_split_to_array(text, regexp);
3310 let mut row = Row::default();
3311 let mut packer = row.packer();
3312 packer.try_push_array(
3313 &[ArrayDimension {
3314 lower_bound: 1,
3315 length: found.len(),
3316 }],
3317 found.into_iter().map(Datum::String),
3318 )?;
3319 Ok(temp_storage.push_unary_row(row))
3320}
3321
3322#[sqlfunc(output_type = "String", propagates_nulls = true)]
3323fn pretty_sql<'a>(
3324 sql: Datum<'a>,
3325 width: Datum<'a>,
3326 temp_storage: &'a RowArena,
3327) -> Result<Datum<'a>, EvalError> {
3328 let sql = sql.unwrap_str();
3329 let width = width.unwrap_int32();
3330 let width =
3331 usize::try_from(width).map_err(|_| EvalError::PrettyError("invalid width".into()))?;
3332 let pretty = pretty_str(
3333 sql,
3334 PrettyConfig {
3335 width,
3336 format_mode: FormatMode::Simple,
3337 },
3338 )
3339 .map_err(|e| EvalError::PrettyError(e.to_string().into()))?;
3340 let pretty = temp_storage.push_string(pretty);
3341 Ok(Datum::String(pretty))
3342}
3343
3344#[sqlfunc(output_type = "bool", propagates_nulls = true)]
3345fn starts_with<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
3346 let a = a.unwrap_str();
3347 let b = b.unwrap_str();
3348 Datum::from(a.starts_with(b))
3349}
3350
3351#[derive(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
3352pub enum BinaryFunc {
3353 AddInt16,
3354 AddInt32,
3355 AddInt64,
3356 AddUInt16,
3357 AddUInt32,
3358 AddUInt64,
3359 AddFloat32,
3360 AddFloat64,
3361 AddInterval,
3362 AddTimestampInterval,
3363 AddTimestampTzInterval,
3364 AddDateInterval,
3365 AddDateTime,
3366 AddTimeInterval,
3367 AddNumeric,
3368 AgeTimestamp,
3369 AgeTimestampTz,
3370 BitAndInt16,
3371 BitAndInt32,
3372 BitAndInt64,
3373 BitAndUInt16,
3374 BitAndUInt32,
3375 BitAndUInt64,
3376 BitOrInt16,
3377 BitOrInt32,
3378 BitOrInt64,
3379 BitOrUInt16,
3380 BitOrUInt32,
3381 BitOrUInt64,
3382 BitXorInt16,
3383 BitXorInt32,
3384 BitXorInt64,
3385 BitXorUInt16,
3386 BitXorUInt32,
3387 BitXorUInt64,
3388 BitShiftLeftInt16,
3389 BitShiftLeftInt32,
3390 BitShiftLeftInt64,
3391 BitShiftLeftUInt16,
3392 BitShiftLeftUInt32,
3393 BitShiftLeftUInt64,
3394 BitShiftRightInt16,
3395 BitShiftRightInt32,
3396 BitShiftRightInt64,
3397 BitShiftRightUInt16,
3398 BitShiftRightUInt32,
3399 BitShiftRightUInt64,
3400 SubInt16,
3401 SubInt32,
3402 SubInt64,
3403 SubUInt16,
3404 SubUInt32,
3405 SubUInt64,
3406 SubFloat32,
3407 SubFloat64,
3408 SubInterval,
3409 SubTimestamp,
3410 SubTimestampTz,
3411 SubTimestampInterval,
3412 SubTimestampTzInterval,
3413 SubDate,
3414 SubDateInterval,
3415 SubTime,
3416 SubTimeInterval,
3417 SubNumeric,
3418 MulInt16,
3419 MulInt32,
3420 MulInt64,
3421 MulUInt16,
3422 MulUInt32,
3423 MulUInt64,
3424 MulFloat32,
3425 MulFloat64,
3426 MulNumeric,
3427 MulInterval,
3428 DivInt16,
3429 DivInt32,
3430 DivInt64,
3431 DivUInt16,
3432 DivUInt32,
3433 DivUInt64,
3434 DivFloat32,
3435 DivFloat64,
3436 DivNumeric,
3437 DivInterval,
3438 ModInt16,
3439 ModInt32,
3440 ModInt64,
3441 ModUInt16,
3442 ModUInt32,
3443 ModUInt64,
3444 ModFloat32,
3445 ModFloat64,
3446 ModNumeric,
3447 RoundNumeric,
3448 Eq,
3449 NotEq,
3450 Lt,
3451 Lte,
3452 Gt,
3453 Gte,
3454 LikeEscape,
3455 IsLikeMatch { case_insensitive: bool },
3456 IsRegexpMatch { case_insensitive: bool },
3457 ToCharTimestamp,
3458 ToCharTimestampTz,
3459 DateBinTimestamp,
3460 DateBinTimestampTz,
3461 ExtractInterval,
3462 ExtractTime,
3463 ExtractTimestamp,
3464 ExtractTimestampTz,
3465 ExtractDate,
3466 DatePartInterval,
3467 DatePartTime,
3468 DatePartTimestamp,
3469 DatePartTimestampTz,
3470 DateTruncTimestamp,
3471 DateTruncTimestampTz,
3472 DateTruncInterval,
3473 TimezoneTimestamp,
3474 TimezoneTimestampTz,
3475 TimezoneIntervalTimestamp,
3476 TimezoneIntervalTimestampTz,
3477 TimezoneIntervalTime,
3478 TimezoneOffset,
3479 TextConcat,
3480 JsonbGetInt64,
3481 JsonbGetInt64Stringify,
3482 JsonbGetString,
3483 JsonbGetStringStringify,
3484 JsonbGetPath,
3485 JsonbGetPathStringify,
3486 JsonbContainsString,
3487 JsonbConcat,
3488 JsonbContainsJsonb,
3489 JsonbDeleteInt64,
3490 JsonbDeleteString,
3491 MapContainsKey,
3492 MapGetValue,
3493 MapContainsAllKeys,
3494 MapContainsAnyKeys,
3495 MapContainsMap,
3496 ConvertFrom,
3497 Left,
3498 Position,
3499 Right,
3500 RepeatString,
3501 Trim,
3502 TrimLeading,
3503 TrimTrailing,
3504 EncodedBytesCharLength,
3505 ListLengthMax { max_layer: usize },
3506 ArrayContains,
3507 ArrayContainsArray { rev: bool },
3508 ArrayLength,
3509 ArrayLower,
3510 ArrayRemove,
3511 ArrayUpper,
3512 ArrayArrayConcat,
3513 ListListConcat,
3514 ListElementConcat,
3515 ElementListConcat,
3516 ListRemove,
3517 ListContainsList { rev: bool },
3518 DigestString,
3519 DigestBytes,
3520 MzRenderTypmod,
3521 Encode,
3522 Decode,
3523 LogNumeric,
3524 Power,
3525 PowerNumeric,
3526 GetBit,
3527 GetByte,
3528 ConstantTimeEqBytes,
3529 ConstantTimeEqString,
3530 RangeContainsElem { elem_type: ScalarType, rev: bool },
3531 RangeContainsRange { rev: bool },
3532 RangeOverlaps,
3533 RangeAfter,
3534 RangeBefore,
3535 RangeOverleft,
3536 RangeOverright,
3537 RangeAdjacent,
3538 RangeUnion,
3539 RangeIntersection,
3540 RangeDifference,
3541 UuidGenerateV5,
3542 MzAclItemContainsPrivilege,
3543 ParseIdent,
3544 PrettySql,
3545 RegexpReplace { regex: Regex, limit: usize },
3546 StartsWith,
3547}
3548
3549impl BinaryFunc {
3550 pub fn eval<'a>(
3551 &'a self,
3552 datums: &[Datum<'a>],
3553 temp_storage: &'a RowArena,
3554 a_expr: &'a MirScalarExpr,
3555 b_expr: &'a MirScalarExpr,
3556 ) -> Result<Datum<'a>, EvalError> {
3557 let a = a_expr.eval(datums, temp_storage)?;
3558 let b = b_expr.eval(datums, temp_storage)?;
3559 if self.propagates_nulls() && (a.is_null() || b.is_null()) {
3560 return Ok(Datum::Null);
3561 }
3562 match self {
3563 BinaryFunc::AddInt16 => add_int16(a, b),
3564 BinaryFunc::AddInt32 => add_int32(a, b),
3565 BinaryFunc::AddInt64 => add_int64(a, b),
3566 BinaryFunc::AddUInt16 => add_uint16(a, b),
3567 BinaryFunc::AddUInt32 => add_uint32(a, b),
3568 BinaryFunc::AddUInt64 => add_uint64(a, b),
3569 BinaryFunc::AddFloat32 => add_float32(a, b),
3570 BinaryFunc::AddFloat64 => add_float64(a, b),
3571 BinaryFunc::AddTimestampInterval => {
3572 add_timestamplike_interval(a.unwrap_timestamp(), b.unwrap_interval())
3573 }
3574 BinaryFunc::AddTimestampTzInterval => {
3575 add_timestamplike_interval(a.unwrap_timestamptz(), b.unwrap_interval())
3576 }
3577 BinaryFunc::AddDateTime => add_date_time(a, b),
3578 BinaryFunc::AddDateInterval => add_date_interval(a, b),
3579 BinaryFunc::AddTimeInterval => Ok(add_time_interval(a, b)),
3580 BinaryFunc::AddNumeric => add_numeric(a, b),
3581 BinaryFunc::AddInterval => add_interval(a, b),
3582 BinaryFunc::AgeTimestamp => age_timestamp(a, b),
3583 BinaryFunc::AgeTimestampTz => age_timestamptz(a, b),
3584 BinaryFunc::BitAndInt16 => Ok(bit_and_int16(a, b)),
3585 BinaryFunc::BitAndInt32 => Ok(bit_and_int32(a, b)),
3586 BinaryFunc::BitAndInt64 => Ok(bit_and_int64(a, b)),
3587 BinaryFunc::BitAndUInt16 => Ok(bit_and_uint16(a, b)),
3588 BinaryFunc::BitAndUInt32 => Ok(bit_and_uint32(a, b)),
3589 BinaryFunc::BitAndUInt64 => Ok(bit_and_uint64(a, b)),
3590 BinaryFunc::BitOrInt16 => Ok(bit_or_int16(a, b)),
3591 BinaryFunc::BitOrInt32 => Ok(bit_or_int32(a, b)),
3592 BinaryFunc::BitOrInt64 => Ok(bit_or_int64(a, b)),
3593 BinaryFunc::BitOrUInt16 => Ok(bit_or_uint16(a, b)),
3594 BinaryFunc::BitOrUInt32 => Ok(bit_or_uint32(a, b)),
3595 BinaryFunc::BitOrUInt64 => Ok(bit_or_uint64(a, b)),
3596 BinaryFunc::BitXorInt16 => Ok(bit_xor_int16(a, b)),
3597 BinaryFunc::BitXorInt32 => Ok(bit_xor_int32(a, b)),
3598 BinaryFunc::BitXorInt64 => Ok(bit_xor_int64(a, b)),
3599 BinaryFunc::BitXorUInt16 => Ok(bit_xor_uint16(a, b)),
3600 BinaryFunc::BitXorUInt32 => Ok(bit_xor_uint32(a, b)),
3601 BinaryFunc::BitXorUInt64 => Ok(bit_xor_uint64(a, b)),
3602 BinaryFunc::BitShiftLeftInt16 => Ok(bit_shift_left_int16(a, b)),
3603 BinaryFunc::BitShiftLeftInt32 => Ok(bit_shift_left_int32(a, b)),
3604 BinaryFunc::BitShiftLeftInt64 => Ok(bit_shift_left_int64(a, b)),
3605 BinaryFunc::BitShiftLeftUInt16 => Ok(bit_shift_left_uint16(a, b)),
3606 BinaryFunc::BitShiftLeftUInt32 => Ok(bit_shift_left_uint32(a, b)),
3607 BinaryFunc::BitShiftLeftUInt64 => Ok(bit_shift_left_uint64(a, b)),
3608 BinaryFunc::BitShiftRightInt16 => Ok(bit_shift_right_int16(a, b)),
3609 BinaryFunc::BitShiftRightInt32 => Ok(bit_shift_right_int32(a, b)),
3610 BinaryFunc::BitShiftRightInt64 => Ok(bit_shift_right_int64(a, b)),
3611 BinaryFunc::BitShiftRightUInt16 => Ok(bit_shift_right_uint16(a, b)),
3612 BinaryFunc::BitShiftRightUInt32 => Ok(bit_shift_right_uint32(a, b)),
3613 BinaryFunc::BitShiftRightUInt64 => Ok(bit_shift_right_uint64(a, b)),
3614 BinaryFunc::SubInt16 => sub_int16(a, b),
3615 BinaryFunc::SubInt32 => sub_int32(a, b),
3616 BinaryFunc::SubInt64 => sub_int64(a, b),
3617 BinaryFunc::SubUInt16 => sub_uint16(a, b),
3618 BinaryFunc::SubUInt32 => sub_uint32(a, b),
3619 BinaryFunc::SubUInt64 => sub_uint64(a, b),
3620 BinaryFunc::SubFloat32 => sub_float32(a, b),
3621 BinaryFunc::SubFloat64 => sub_float64(a, b),
3622 BinaryFunc::SubTimestamp => Ok(sub_timestamp(a, b)),
3623 BinaryFunc::SubTimestampTz => Ok(sub_timestamptz(a, b)),
3624 BinaryFunc::SubTimestampInterval => sub_timestamplike_interval(a.unwrap_timestamp(), b),
3625 BinaryFunc::SubTimestampTzInterval => {
3626 sub_timestamplike_interval(a.unwrap_timestamptz(), b)
3627 }
3628 BinaryFunc::SubInterval => sub_interval(a, b),
3629 BinaryFunc::SubDate => Ok(sub_date(a, b)),
3630 BinaryFunc::SubDateInterval => sub_date_interval(a, b),
3631 BinaryFunc::SubTime => Ok(sub_time(a, b)),
3632 BinaryFunc::SubTimeInterval => Ok(sub_time_interval(a, b)),
3633 BinaryFunc::SubNumeric => sub_numeric(a, b),
3634 BinaryFunc::MulInt16 => mul_int16(a, b),
3635 BinaryFunc::MulInt32 => mul_int32(a, b),
3636 BinaryFunc::MulInt64 => mul_int64(a, b),
3637 BinaryFunc::MulUInt16 => mul_uint16(a, b),
3638 BinaryFunc::MulUInt32 => mul_uint32(a, b),
3639 BinaryFunc::MulUInt64 => mul_uint64(a, b),
3640 BinaryFunc::MulFloat32 => mul_float32(a, b),
3641 BinaryFunc::MulFloat64 => mul_float64(a, b),
3642 BinaryFunc::MulNumeric => mul_numeric(a, b),
3643 BinaryFunc::MulInterval => mul_interval(a, b),
3644 BinaryFunc::DivInt16 => div_int16(a, b),
3645 BinaryFunc::DivInt32 => div_int32(a, b),
3646 BinaryFunc::DivInt64 => div_int64(a, b),
3647 BinaryFunc::DivUInt16 => div_uint16(a, b),
3648 BinaryFunc::DivUInt32 => div_uint32(a, b),
3649 BinaryFunc::DivUInt64 => div_uint64(a, b),
3650 BinaryFunc::DivFloat32 => div_float32(a, b),
3651 BinaryFunc::DivFloat64 => div_float64(a, b),
3652 BinaryFunc::DivNumeric => div_numeric(a, b),
3653 BinaryFunc::DivInterval => div_interval(a, b),
3654 BinaryFunc::ModInt16 => mod_int16(a, b),
3655 BinaryFunc::ModInt32 => mod_int32(a, b),
3656 BinaryFunc::ModInt64 => mod_int64(a, b),
3657 BinaryFunc::ModUInt16 => mod_uint16(a, b),
3658 BinaryFunc::ModUInt32 => mod_uint32(a, b),
3659 BinaryFunc::ModUInt64 => mod_uint64(a, b),
3660 BinaryFunc::ModFloat32 => mod_float32(a, b),
3661 BinaryFunc::ModFloat64 => mod_float64(a, b),
3662 BinaryFunc::ModNumeric => mod_numeric(a, b),
3663 BinaryFunc::Eq => Ok(eq(a, b)),
3664 BinaryFunc::NotEq => Ok(not_eq(a, b)),
3665 BinaryFunc::Lt => Ok(lt(a, b)),
3666 BinaryFunc::Lte => Ok(lte(a, b)),
3667 BinaryFunc::Gt => Ok(gt(a, b)),
3668 BinaryFunc::Gte => Ok(gte(a, b)),
3669 BinaryFunc::LikeEscape => like_escape(a, b, temp_storage),
3670 BinaryFunc::IsLikeMatch { case_insensitive } => {
3671 is_like_match_dynamic(a, b, *case_insensitive)
3672 }
3673 BinaryFunc::IsRegexpMatch { case_insensitive } => {
3674 is_regexp_match_dynamic(a, b, *case_insensitive)
3675 }
3676 BinaryFunc::ToCharTimestamp => Ok(to_char_timestamplike(
3677 a.unwrap_timestamp().deref(),
3678 b.unwrap_str(),
3679 temp_storage,
3680 )),
3681 BinaryFunc::ToCharTimestampTz => Ok(to_char_timestamplike(
3682 a.unwrap_timestamptz().deref(),
3683 b.unwrap_str(),
3684 temp_storage,
3685 )),
3686 BinaryFunc::DateBinTimestamp => date_bin(
3687 a.unwrap_interval(),
3688 b.unwrap_timestamp(),
3689 CheckedTimestamp::from_timestamplike(
3690 DateTime::from_timestamp(0, 0).unwrap().naive_utc(),
3691 )
3692 .expect("must fit"),
3693 ),
3694 BinaryFunc::DateBinTimestampTz => date_bin(
3695 a.unwrap_interval(),
3696 b.unwrap_timestamptz(),
3697 CheckedTimestamp::from_timestamplike(DateTime::from_timestamp(0, 0).unwrap())
3698 .expect("must fit"),
3699 ),
3700 BinaryFunc::ExtractInterval => date_part_interval::<Numeric>(a, b),
3701 BinaryFunc::ExtractTime => date_part_time::<Numeric>(a, b),
3702 BinaryFunc::ExtractTimestamp => {
3703 date_part_timestamp::<_, Numeric>(a, b.unwrap_timestamp().deref())
3704 }
3705 BinaryFunc::ExtractTimestampTz => {
3706 date_part_timestamp::<_, Numeric>(a, b.unwrap_timestamptz().deref())
3707 }
3708 BinaryFunc::ExtractDate => extract_date_units(a, b),
3709 BinaryFunc::DatePartInterval => date_part_interval::<f64>(a, b),
3710 BinaryFunc::DatePartTime => date_part_time::<f64>(a, b),
3711 BinaryFunc::DatePartTimestamp => {
3712 date_part_timestamp::<_, f64>(a, b.unwrap_timestamp().deref())
3713 }
3714 BinaryFunc::DatePartTimestampTz => {
3715 date_part_timestamp::<_, f64>(a, b.unwrap_timestamptz().deref())
3716 }
3717 BinaryFunc::DateTruncTimestamp => date_trunc(a, b.unwrap_timestamp().deref()),
3718 BinaryFunc::DateTruncInterval => date_trunc_interval(a, b),
3719 BinaryFunc::DateTruncTimestampTz => date_trunc(a, b.unwrap_timestamptz().deref()),
3720 BinaryFunc::TimezoneTimestamp => parse_timezone(a.unwrap_str(), TimezoneSpec::Posix)
3721 .and_then(|tz| timezone_timestamp(tz, b.unwrap_timestamp().into()).map(Into::into)),
3722 BinaryFunc::TimezoneTimestampTz => parse_timezone(a.unwrap_str(), TimezoneSpec::Posix)
3723 .and_then(|tz| {
3724 Ok(timezone_timestamptz(tz, b.unwrap_timestamptz().into())?.try_into()?)
3725 }),
3726 BinaryFunc::TimezoneIntervalTimestamp => timezone_interval_timestamp(a, b),
3727 BinaryFunc::TimezoneIntervalTimestampTz => timezone_interval_timestamptz(a, b),
3728 BinaryFunc::TimezoneIntervalTime => timezone_interval_time(a, b),
3729 BinaryFunc::TimezoneOffset => timezone_offset(a, b, temp_storage),
3730 BinaryFunc::TextConcat => Ok(text_concat_binary(a, b, temp_storage)),
3731 BinaryFunc::JsonbGetInt64 => Ok(jsonb_get_int64(a, b, temp_storage, false)),
3732 BinaryFunc::JsonbGetInt64Stringify => Ok(jsonb_get_int64(a, b, temp_storage, true)),
3733 BinaryFunc::JsonbGetString => Ok(jsonb_get_string(a, b, temp_storage, false)),
3734 BinaryFunc::JsonbGetStringStringify => Ok(jsonb_get_string(a, b, temp_storage, true)),
3735 BinaryFunc::JsonbGetPath => Ok(jsonb_get_path(a, b, temp_storage, false)),
3736 BinaryFunc::JsonbGetPathStringify => Ok(jsonb_get_path(a, b, temp_storage, true)),
3737 BinaryFunc::JsonbContainsString => Ok(jsonb_contains_string(a, b)),
3738 BinaryFunc::JsonbConcat => Ok(jsonb_concat(a, b, temp_storage)),
3739 BinaryFunc::JsonbContainsJsonb => Ok(jsonb_contains_jsonb(a, b)),
3740 BinaryFunc::JsonbDeleteInt64 => Ok(jsonb_delete_int64(a, b, temp_storage)),
3741 BinaryFunc::JsonbDeleteString => Ok(jsonb_delete_string(a, b, temp_storage)),
3742 BinaryFunc::MapContainsKey => Ok(map_contains_key(a, b)),
3743 BinaryFunc::MapGetValue => Ok(map_get_value(a, b)),
3744 BinaryFunc::MapContainsAllKeys => Ok(map_contains_all_keys(a, b)),
3745 BinaryFunc::MapContainsAnyKeys => Ok(map_contains_any_keys(a, b)),
3746 BinaryFunc::MapContainsMap => Ok(map_contains_map(a, b)),
3747 BinaryFunc::RoundNumeric => round_numeric_binary(a, b),
3748 BinaryFunc::ConvertFrom => convert_from(a, b),
3749 BinaryFunc::Encode => encode(a, b, temp_storage),
3750 BinaryFunc::Decode => decode(a, b, temp_storage),
3751 BinaryFunc::Left => left(a, b),
3752 BinaryFunc::Position => position(a, b),
3753 BinaryFunc::Right => right(a, b),
3754 BinaryFunc::Trim => Ok(trim(a, b)),
3755 BinaryFunc::TrimLeading => Ok(trim_leading(a, b)),
3756 BinaryFunc::TrimTrailing => Ok(trim_trailing(a, b)),
3757 BinaryFunc::EncodedBytesCharLength => encoded_bytes_char_length(a, b),
3758 BinaryFunc::ListLengthMax { max_layer } => list_length_max(a, b, *max_layer),
3759 BinaryFunc::ArrayLength => array_length(a, b),
3760 BinaryFunc::ArrayContains => Ok(array_contains(a, b)),
3761 BinaryFunc::ArrayContainsArray { rev: false } => Ok(array_contains_array(a, b)),
3762 BinaryFunc::ArrayContainsArray { rev: true } => Ok(array_contains_array(b, a)),
3763 BinaryFunc::ArrayLower => Ok(array_lower(a, b)),
3764 BinaryFunc::ArrayRemove => array_remove(a, b, temp_storage),
3765 BinaryFunc::ArrayUpper => array_upper(a, b),
3766 BinaryFunc::ArrayArrayConcat => array_array_concat(a, b, temp_storage),
3767 BinaryFunc::ListListConcat => Ok(list_list_concat(a, b, temp_storage)),
3768 BinaryFunc::ListElementConcat => Ok(list_element_concat(a, b, temp_storage)),
3769 BinaryFunc::ElementListConcat => Ok(element_list_concat(a, b, temp_storage)),
3770 BinaryFunc::ListRemove => Ok(list_remove(a, b, temp_storage)),
3771 BinaryFunc::ListContainsList { rev: false } => Ok(list_contains_list(a, b)),
3772 BinaryFunc::ListContainsList { rev: true } => Ok(list_contains_list(b, a)),
3773 BinaryFunc::DigestString => digest_string(a, b, temp_storage),
3774 BinaryFunc::DigestBytes => digest_bytes(a, b, temp_storage),
3775 BinaryFunc::MzRenderTypmod => mz_render_typmod(a, b, temp_storage),
3776 BinaryFunc::LogNumeric => log_base_numeric(a, b),
3777 BinaryFunc::Power => power(a, b),
3778 BinaryFunc::PowerNumeric => power_numeric(a, b),
3779 BinaryFunc::RepeatString => repeat_string(a, b, temp_storage),
3780 BinaryFunc::GetBit => get_bit(a, b),
3781 BinaryFunc::GetByte => get_byte(a, b),
3782 BinaryFunc::ConstantTimeEqBytes => constant_time_eq_bytes(a, b),
3783 BinaryFunc::ConstantTimeEqString => constant_time_eq_string(a, b),
3784 BinaryFunc::RangeContainsElem { elem_type, rev: _ } => Ok(match elem_type {
3785 ScalarType::Int32 => contains_range_elem::<i32>(a, b),
3786 ScalarType::Int64 => contains_range_elem::<i64>(a, b),
3787 ScalarType::Date => contains_range_elem::<Date>(a, b),
3788 ScalarType::Numeric { .. } => contains_range_elem::<OrderedDecimal<Numeric>>(a, b),
3789 ScalarType::Timestamp { .. } => {
3790 contains_range_elem::<CheckedTimestamp<NaiveDateTime>>(a, b)
3791 }
3792 ScalarType::TimestampTz { .. } => {
3793 contains_range_elem::<CheckedTimestamp<DateTime<Utc>>>(a, b)
3794 }
3795 _ => unreachable!(),
3796 }),
3797 BinaryFunc::RangeContainsRange { rev: false } => Ok(range_contains_range(a, b)),
3798 BinaryFunc::RangeContainsRange { rev: true } => Ok(range_contains_range_rev(a, b)),
3799 BinaryFunc::RangeOverlaps => Ok(range_overlaps(a, b)),
3800 BinaryFunc::RangeAfter => Ok(range_after(a, b)),
3801 BinaryFunc::RangeBefore => Ok(range_before(a, b)),
3802 BinaryFunc::RangeOverleft => Ok(range_overleft(a, b)),
3803 BinaryFunc::RangeOverright => Ok(range_overright(a, b)),
3804 BinaryFunc::RangeAdjacent => Ok(range_adjacent(a, b)),
3805 BinaryFunc::RangeUnion => range_union(a, b, temp_storage),
3806 BinaryFunc::RangeIntersection => range_intersection(a, b, temp_storage),
3807 BinaryFunc::RangeDifference => range_difference(a, b, temp_storage),
3808 BinaryFunc::UuidGenerateV5 => Ok(uuid_generate_v5(a, b)),
3809 BinaryFunc::MzAclItemContainsPrivilege => mz_acl_item_contains_privilege(a, b),
3810 BinaryFunc::ParseIdent => parse_ident(a, b, temp_storage),
3811 BinaryFunc::PrettySql => pretty_sql(a, b, temp_storage),
3812 BinaryFunc::RegexpReplace { regex, limit } => {
3813 regexp_replace_static(a, b, regex, *limit, temp_storage)
3814 }
3815 BinaryFunc::StartsWith => Ok(starts_with(a, b)),
3816 }
3817 }
3818
3819 pub fn output_type(&self, input1_type: ColumnType, input2_type: ColumnType) -> ColumnType {
3820 use BinaryFunc::*;
3821 let in_nullable = input1_type.nullable || input2_type.nullable;
3822 match self {
3823 Eq
3824 | NotEq
3825 | Lt
3826 | Lte
3827 | Gt
3828 | Gte
3829 | ArrayContains
3830 | ArrayContainsArray { .. }
3831 | IsLikeMatch { .. }
3833 | IsRegexpMatch { .. } => ScalarType::Bool.nullable(in_nullable),
3834
3835 ToCharTimestamp | ToCharTimestampTz | ConvertFrom | Left | Right | Trim
3836 | TrimLeading | TrimTrailing | LikeEscape => ScalarType::String.nullable(in_nullable),
3837
3838 AddInt16 | SubInt16 | MulInt16 | DivInt16 | ModInt16 | BitAndInt16 | BitOrInt16
3839 | BitXorInt16 | BitShiftLeftInt16 | BitShiftRightInt16 => {
3840 ScalarType::Int16.nullable(in_nullable)
3841 }
3842
3843 AddInt32
3844 | SubInt32
3845 | MulInt32
3846 | DivInt32
3847 | ModInt32
3848 | BitAndInt32
3849 | BitOrInt32
3850 | BitXorInt32
3851 | BitShiftLeftInt32
3852 | BitShiftRightInt32
3853 | EncodedBytesCharLength
3854 | SubDate => ScalarType::Int32.nullable(in_nullable),
3855
3856 AddInt64 | SubInt64 | MulInt64 | DivInt64 | ModInt64 | BitAndInt64 | BitOrInt64
3857 | BitXorInt64 | BitShiftLeftInt64 | BitShiftRightInt64 => {
3858 ScalarType::Int64.nullable(in_nullable)
3859 }
3860
3861 AddUInt16 | SubUInt16 | MulUInt16 | DivUInt16 | ModUInt16 | BitAndUInt16
3862 | BitOrUInt16 | BitXorUInt16 | BitShiftLeftUInt16 | BitShiftRightUInt16 => {
3863 ScalarType::UInt16.nullable(in_nullable)
3864 }
3865
3866 AddUInt32 | SubUInt32 | MulUInt32 | DivUInt32 | ModUInt32 | BitAndUInt32
3867 | BitOrUInt32 | BitXorUInt32 | BitShiftLeftUInt32 | BitShiftRightUInt32 => {
3868 ScalarType::UInt32.nullable(in_nullable)
3869 }
3870
3871 AddUInt64 | SubUInt64 | MulUInt64 | DivUInt64 | ModUInt64 | BitAndUInt64
3872 | BitOrUInt64 | BitXorUInt64 | BitShiftLeftUInt64 | BitShiftRightUInt64 => {
3873 ScalarType::UInt64.nullable(in_nullable)
3874 }
3875
3876 AddFloat32 | SubFloat32 | MulFloat32 | DivFloat32 | ModFloat32 => {
3877 ScalarType::Float32.nullable(in_nullable)
3878 }
3879
3880 AddFloat64 | SubFloat64 | MulFloat64 | DivFloat64 | ModFloat64 => {
3881 ScalarType::Float64.nullable(in_nullable)
3882 }
3883
3884 AddInterval | SubInterval | SubTimestamp | SubTimestampTz | MulInterval
3885 | DivInterval => ScalarType::Interval.nullable(in_nullable),
3886
3887 AgeTimestamp | AgeTimestampTz => ScalarType::Interval.nullable(in_nullable),
3888
3889 AddTimestampInterval
3890 | SubTimestampInterval
3891 | AddTimestampTzInterval
3892 | SubTimestampTzInterval
3893 | AddTimeInterval
3894 | SubTimeInterval => input1_type.nullable(in_nullable),
3895
3896 AddDateInterval | SubDateInterval | AddDateTime | DateBinTimestamp
3897 | DateTruncTimestamp => ScalarType::Timestamp { precision: None }.nullable(in_nullable),
3898
3899 DateTruncInterval => ScalarType::Interval.nullable(in_nullable),
3900
3901 TimezoneTimestampTz | TimezoneIntervalTimestampTz => {
3902 ScalarType::Timestamp { precision: None }.nullable(in_nullable)
3903 }
3904
3905 ExtractInterval | ExtractTime | ExtractTimestamp | ExtractTimestampTz | ExtractDate => {
3906 ScalarType::Numeric { max_scale: None }.nullable(in_nullable)
3907 }
3908
3909 DatePartInterval | DatePartTime | DatePartTimestamp | DatePartTimestampTz => {
3910 ScalarType::Float64.nullable(in_nullable)
3911 }
3912
3913 DateBinTimestampTz | DateTruncTimestampTz => ScalarType::TimestampTz { precision: None }.nullable(in_nullable),
3914
3915 TimezoneTimestamp | TimezoneIntervalTimestamp => {
3916 ScalarType::TimestampTz { precision: None }.nullable(in_nullable)
3917 }
3918
3919 TimezoneIntervalTime => ScalarType::Time.nullable(in_nullable),
3920
3921 TimezoneOffset => ScalarType::Record {
3922 fields: [
3923 ("abbrev".into(), ScalarType::String.nullable(false)),
3924 ("base_utc_offset".into(), ScalarType::Interval.nullable(false)),
3925 ("dst_offset".into(), ScalarType::Interval.nullable(false)),
3926 ].into(),
3927 custom_id: None,
3928 }.nullable(true),
3929
3930 SubTime => ScalarType::Interval.nullable(in_nullable),
3931
3932 MzRenderTypmod | TextConcat => ScalarType::String.nullable(in_nullable),
3933
3934 JsonbGetInt64Stringify
3935 | JsonbGetStringStringify
3936 | JsonbGetPathStringify => ScalarType::String.nullable(true),
3937
3938 JsonbGetInt64
3939 | JsonbGetString
3940 | JsonbGetPath
3941 | JsonbConcat
3942 | JsonbDeleteInt64
3943 | JsonbDeleteString => ScalarType::Jsonb.nullable(true),
3944
3945 JsonbContainsString | JsonbContainsJsonb | MapContainsKey | MapContainsAllKeys
3946 | MapContainsAnyKeys | MapContainsMap => ScalarType::Bool.nullable(in_nullable),
3947
3948 MapGetValue => input1_type
3949 .scalar_type
3950 .unwrap_map_value_type()
3951 .clone()
3952 .nullable(true),
3953
3954 ArrayLength | ArrayLower | ArrayUpper => ScalarType::Int32.nullable(true),
3955
3956 ListLengthMax { .. } => ScalarType::Int32.nullable(true),
3957
3958 ArrayArrayConcat | ArrayRemove | ListListConcat | ListElementConcat | ListRemove => {
3959 input1_type.scalar_type.without_modifiers().nullable(true)
3960 }
3961
3962 ElementListConcat => input2_type.scalar_type.without_modifiers().nullable(true),
3963
3964 ListContainsList { .. } => ScalarType::Bool.nullable(in_nullable),
3965
3966 DigestString | DigestBytes => ScalarType::Bytes.nullable(in_nullable),
3967 Position => ScalarType::Int32.nullable(in_nullable),
3968 Encode => ScalarType::String.nullable(in_nullable),
3969 Decode => ScalarType::Bytes.nullable(in_nullable),
3970 Power => ScalarType::Float64.nullable(in_nullable),
3971 RepeatString => input1_type.scalar_type.nullable(in_nullable),
3972
3973 AddNumeric | DivNumeric | LogNumeric | ModNumeric | MulNumeric | PowerNumeric
3974 | RoundNumeric | SubNumeric => {
3975 ScalarType::Numeric { max_scale: None }.nullable(in_nullable)
3976 }
3977
3978 GetBit => ScalarType::Int32.nullable(in_nullable),
3979 GetByte => ScalarType::Int32.nullable(in_nullable),
3980
3981 ConstantTimeEqBytes | ConstantTimeEqString => {
3982 ScalarType::Bool.nullable(in_nullable)
3983 },
3984
3985 UuidGenerateV5 => ScalarType::Uuid.nullable(in_nullable),
3986
3987 RangeContainsElem { .. }
3988 | RangeContainsRange { .. }
3989 | RangeOverlaps
3990 | RangeAfter
3991 | RangeBefore
3992 | RangeOverleft
3993 | RangeOverright
3994 | RangeAdjacent => ScalarType::Bool.nullable(in_nullable),
3995
3996 RangeUnion | RangeIntersection | RangeDifference => {
3997 soft_assert_eq_or_log!(
3998 input1_type.scalar_type.without_modifiers(),
3999 input2_type.scalar_type.without_modifiers()
4000 );
4001 input1_type.scalar_type.without_modifiers().nullable(true)
4002 }
4003
4004 MzAclItemContainsPrivilege => ScalarType::Bool.nullable(in_nullable),
4005
4006 ParseIdent => ScalarType::Array(Box::new(ScalarType::String)).nullable(in_nullable),
4007 PrettySql => ScalarType::String.nullable(in_nullable),
4008 RegexpReplace { .. } => ScalarType::String.nullable(in_nullable),
4009
4010 StartsWith => ScalarType::Bool.nullable(in_nullable),
4011 }
4012 }
4013
4014 pub fn propagates_nulls(&self) -> bool {
4016 !matches!(
4019 self,
4020 BinaryFunc::ArrayArrayConcat
4021 | BinaryFunc::ListListConcat
4022 | BinaryFunc::ListElementConcat
4023 | BinaryFunc::ElementListConcat
4024 | BinaryFunc::ArrayRemove
4025 | BinaryFunc::ListRemove
4026 )
4027 }
4028
4029 pub fn introduces_nulls(&self) -> bool {
4035 use BinaryFunc::*;
4036 match self {
4037 AddInt16
4038 | AddInt32
4039 | AddInt64
4040 | AddUInt16
4041 | AddUInt32
4042 | AddUInt64
4043 | AddFloat32
4044 | AddFloat64
4045 | AddInterval
4046 | AddTimestampInterval
4047 | AddTimestampTzInterval
4048 | AddDateInterval
4049 | AddDateTime
4050 | AddTimeInterval
4051 | AddNumeric
4052 | AgeTimestamp
4053 | AgeTimestampTz
4054 | BitAndInt16
4055 | BitAndInt32
4056 | BitAndInt64
4057 | BitAndUInt16
4058 | BitAndUInt32
4059 | BitAndUInt64
4060 | BitOrInt16
4061 | BitOrInt32
4062 | BitOrInt64
4063 | BitOrUInt16
4064 | BitOrUInt32
4065 | BitOrUInt64
4066 | BitXorInt16
4067 | BitXorInt32
4068 | BitXorInt64
4069 | BitXorUInt16
4070 | BitXorUInt32
4071 | BitXorUInt64
4072 | BitShiftLeftInt16
4073 | BitShiftLeftInt32
4074 | BitShiftLeftInt64
4075 | BitShiftLeftUInt16
4076 | BitShiftLeftUInt32
4077 | BitShiftLeftUInt64
4078 | BitShiftRightInt16
4079 | BitShiftRightInt32
4080 | BitShiftRightInt64
4081 | BitShiftRightUInt16
4082 | BitShiftRightUInt32
4083 | BitShiftRightUInt64
4084 | SubInt16
4085 | SubInt32
4086 | SubInt64
4087 | SubUInt16
4088 | SubUInt32
4089 | SubUInt64
4090 | SubFloat32
4091 | SubFloat64
4092 | SubInterval
4093 | SubTimestamp
4094 | SubTimestampTz
4095 | SubTimestampInterval
4096 | SubTimestampTzInterval
4097 | SubDate
4098 | SubDateInterval
4099 | SubTime
4100 | SubTimeInterval
4101 | SubNumeric
4102 | MulInt16
4103 | MulInt32
4104 | MulInt64
4105 | MulUInt16
4106 | MulUInt32
4107 | MulUInt64
4108 | MulFloat32
4109 | MulFloat64
4110 | MulNumeric
4111 | MulInterval
4112 | DivInt16
4113 | DivInt32
4114 | DivInt64
4115 | DivUInt16
4116 | DivUInt32
4117 | DivUInt64
4118 | DivFloat32
4119 | DivFloat64
4120 | DivNumeric
4121 | DivInterval
4122 | ModInt16
4123 | ModInt32
4124 | ModInt64
4125 | ModUInt16
4126 | ModUInt32
4127 | ModUInt64
4128 | ModFloat32
4129 | ModFloat64
4130 | ModNumeric
4131 | RoundNumeric
4132 | Eq
4133 | NotEq
4134 | Lt
4135 | Lte
4136 | Gt
4137 | Gte
4138 | LikeEscape
4139 | IsLikeMatch { .. }
4140 | IsRegexpMatch { .. }
4141 | ToCharTimestamp
4142 | ToCharTimestampTz
4143 | ConstantTimeEqBytes
4144 | ConstantTimeEqString
4145 | DateBinTimestamp
4146 | DateBinTimestampTz
4147 | ExtractInterval
4148 | ExtractTime
4149 | ExtractTimestamp
4150 | ExtractTimestampTz
4151 | ExtractDate
4152 | DatePartInterval
4153 | DatePartTime
4154 | DatePartTimestamp
4155 | DatePartTimestampTz
4156 | DateTruncTimestamp
4157 | DateTruncTimestampTz
4158 | DateTruncInterval
4159 | TimezoneTimestamp
4160 | TimezoneTimestampTz
4161 | TimezoneIntervalTimestamp
4162 | TimezoneIntervalTimestampTz
4163 | TimezoneIntervalTime
4164 | TimezoneOffset
4165 | TextConcat
4166 | JsonbContainsString
4167 | JsonbContainsJsonb
4168 | MapContainsKey
4169 | MapContainsAllKeys
4170 | MapContainsAnyKeys
4171 | MapContainsMap
4172 | ConvertFrom
4173 | Left
4174 | Position
4175 | Right
4176 | RepeatString
4177 | Trim
4178 | TrimLeading
4179 | TrimTrailing
4180 | EncodedBytesCharLength
4181 | ArrayContains
4182 | ArrayRemove
4183 | ArrayContainsArray { .. }
4184 | ArrayArrayConcat
4185 | ListListConcat
4186 | ListElementConcat
4187 | ElementListConcat
4188 | ListContainsList { .. }
4189 | ListRemove
4190 | DigestString
4191 | DigestBytes
4192 | MzRenderTypmod
4193 | Encode
4194 | Decode
4195 | LogNumeric
4196 | Power
4197 | PowerNumeric
4198 | GetBit
4199 | GetByte
4200 | RangeContainsElem { .. }
4201 | RangeContainsRange { .. }
4202 | RangeOverlaps
4203 | RangeAfter
4204 | RangeBefore
4205 | RangeOverleft
4206 | RangeOverright
4207 | RangeAdjacent
4208 | RangeUnion
4209 | RangeIntersection
4210 | RangeDifference
4211 | UuidGenerateV5
4212 | MzAclItemContainsPrivilege
4213 | ParseIdent
4214 | PrettySql
4215 | RegexpReplace { .. }
4216 | StartsWith => false,
4217
4218 JsonbGetInt64
4219 | JsonbGetInt64Stringify
4220 | JsonbGetString
4221 | JsonbGetStringStringify
4222 | JsonbGetPath
4223 | JsonbGetPathStringify
4224 | JsonbConcat
4225 | JsonbDeleteInt64
4226 | JsonbDeleteString
4227 | MapGetValue
4228 | ListLengthMax { .. }
4229 | ArrayLength
4230 | ArrayLower
4231 | ArrayUpper => true,
4232 }
4233 }
4234
4235 pub fn is_infix_op(&self) -> bool {
4236 use BinaryFunc::*;
4237 match self {
4238 AddInt16
4239 | AddInt32
4240 | AddInt64
4241 | AddUInt16
4242 | AddUInt32
4243 | AddUInt64
4244 | AddFloat32
4245 | AddFloat64
4246 | AddTimestampInterval
4247 | AddTimestampTzInterval
4248 | AddDateTime
4249 | AddDateInterval
4250 | AddTimeInterval
4251 | AddInterval
4252 | BitAndInt16
4253 | BitAndInt32
4254 | BitAndInt64
4255 | BitAndUInt16
4256 | BitAndUInt32
4257 | BitAndUInt64
4258 | BitOrInt16
4259 | BitOrInt32
4260 | BitOrInt64
4261 | BitOrUInt16
4262 | BitOrUInt32
4263 | BitOrUInt64
4264 | BitXorInt16
4265 | BitXorInt32
4266 | BitXorInt64
4267 | BitXorUInt16
4268 | BitXorUInt32
4269 | BitXorUInt64
4270 | BitShiftLeftInt16
4271 | BitShiftLeftInt32
4272 | BitShiftLeftInt64
4273 | BitShiftLeftUInt16
4274 | BitShiftLeftUInt32
4275 | BitShiftLeftUInt64
4276 | BitShiftRightInt16
4277 | BitShiftRightInt32
4278 | BitShiftRightInt64
4279 | BitShiftRightUInt16
4280 | BitShiftRightUInt32
4281 | BitShiftRightUInt64
4282 | SubInterval
4283 | MulInterval
4284 | DivInterval
4285 | AddNumeric
4286 | SubInt16
4287 | SubInt32
4288 | SubInt64
4289 | SubUInt16
4290 | SubUInt32
4291 | SubUInt64
4292 | SubFloat32
4293 | SubFloat64
4294 | SubTimestamp
4295 | SubTimestampTz
4296 | SubTimestampInterval
4297 | SubTimestampTzInterval
4298 | SubDate
4299 | SubDateInterval
4300 | SubTime
4301 | SubTimeInterval
4302 | SubNumeric
4303 | MulInt16
4304 | MulInt32
4305 | MulInt64
4306 | MulUInt16
4307 | MulUInt32
4308 | MulUInt64
4309 | MulFloat32
4310 | MulFloat64
4311 | MulNumeric
4312 | DivInt16
4313 | DivInt32
4314 | DivInt64
4315 | DivUInt16
4316 | DivUInt32
4317 | DivUInt64
4318 | DivFloat32
4319 | DivFloat64
4320 | DivNumeric
4321 | ModInt16
4322 | ModInt32
4323 | ModInt64
4324 | ModUInt16
4325 | ModUInt32
4326 | ModUInt64
4327 | ModFloat32
4328 | ModFloat64
4329 | ModNumeric
4330 | Eq
4331 | NotEq
4332 | Lt
4333 | Lte
4334 | Gt
4335 | Gte
4336 | JsonbConcat
4337 | JsonbContainsJsonb
4338 | JsonbGetInt64
4339 | JsonbGetInt64Stringify
4340 | JsonbGetString
4341 | JsonbGetStringStringify
4342 | JsonbGetPath
4343 | JsonbGetPathStringify
4344 | JsonbContainsString
4345 | JsonbDeleteInt64
4346 | JsonbDeleteString
4347 | MapContainsKey
4348 | MapGetValue
4349 | MapContainsAllKeys
4350 | MapContainsAnyKeys
4351 | MapContainsMap
4352 | TextConcat
4353 | IsLikeMatch { .. }
4354 | IsRegexpMatch { .. }
4355 | ArrayContains
4356 | ArrayContainsArray { .. }
4357 | ArrayLength
4358 | ArrayLower
4359 | ArrayUpper
4360 | ArrayArrayConcat
4361 | ListListConcat
4362 | ListElementConcat
4363 | ElementListConcat
4364 | ListContainsList { .. }
4365 | RangeContainsElem { .. }
4366 | RangeContainsRange { .. }
4367 | RangeOverlaps
4368 | RangeAfter
4369 | RangeBefore
4370 | RangeOverleft
4371 | RangeOverright
4372 | RangeAdjacent
4373 | RangeUnion
4374 | RangeIntersection
4375 | RangeDifference => true,
4376 ToCharTimestamp
4377 | ToCharTimestampTz
4378 | AgeTimestamp
4379 | AgeTimestampTz
4380 | DateBinTimestamp
4381 | DateBinTimestampTz
4382 | ExtractInterval
4383 | ExtractTime
4384 | ExtractTimestamp
4385 | ExtractTimestampTz
4386 | ExtractDate
4387 | DatePartInterval
4388 | DatePartTime
4389 | DatePartTimestamp
4390 | DatePartTimestampTz
4391 | DateTruncInterval
4392 | DateTruncTimestamp
4393 | DateTruncTimestampTz
4394 | TimezoneTimestamp
4395 | TimezoneTimestampTz
4396 | TimezoneIntervalTimestamp
4397 | TimezoneIntervalTimestampTz
4398 | TimezoneIntervalTime
4399 | TimezoneOffset
4400 | RoundNumeric
4401 | ConvertFrom
4402 | Left
4403 | Position
4404 | Right
4405 | Trim
4406 | TrimLeading
4407 | TrimTrailing
4408 | EncodedBytesCharLength
4409 | ListLengthMax { .. }
4410 | DigestString
4411 | DigestBytes
4412 | MzRenderTypmod
4413 | Encode
4414 | Decode
4415 | LogNumeric
4416 | Power
4417 | PowerNumeric
4418 | RepeatString
4419 | ArrayRemove
4420 | ListRemove
4421 | LikeEscape
4422 | UuidGenerateV5
4423 | GetBit
4424 | GetByte
4425 | MzAclItemContainsPrivilege
4426 | ConstantTimeEqBytes
4427 | ConstantTimeEqString
4428 | ParseIdent
4429 | PrettySql
4430 | RegexpReplace { .. }
4431 | StartsWith => false,
4432 }
4433 }
4434
4435 pub fn negate(&self) -> Option<Self> {
4437 match self {
4438 BinaryFunc::Eq => Some(BinaryFunc::NotEq),
4439 BinaryFunc::NotEq => Some(BinaryFunc::Eq),
4440 BinaryFunc::Lt => Some(BinaryFunc::Gte),
4441 BinaryFunc::Gte => Some(BinaryFunc::Lt),
4442 BinaryFunc::Gt => Some(BinaryFunc::Lte),
4443 BinaryFunc::Lte => Some(BinaryFunc::Gt),
4444 _ => None,
4445 }
4446 }
4447
4448 pub fn could_error(&self) -> bool {
4450 match self {
4451 BinaryFunc::Eq
4452 | BinaryFunc::NotEq
4453 | BinaryFunc::Lt
4454 | BinaryFunc::Gte
4455 | BinaryFunc::Gt
4456 | BinaryFunc::Lte => false,
4457 BinaryFunc::BitAndInt16
4458 | BinaryFunc::BitAndInt32
4459 | BinaryFunc::BitAndInt64
4460 | BinaryFunc::BitAndUInt16
4461 | BinaryFunc::BitAndUInt32
4462 | BinaryFunc::BitAndUInt64
4463 | BinaryFunc::BitOrInt16
4464 | BinaryFunc::BitOrInt32
4465 | BinaryFunc::BitOrInt64
4466 | BinaryFunc::BitOrUInt16
4467 | BinaryFunc::BitOrUInt32
4468 | BinaryFunc::BitOrUInt64
4469 | BinaryFunc::BitXorInt16
4470 | BinaryFunc::BitXorInt32
4471 | BinaryFunc::BitXorInt64
4472 | BinaryFunc::BitXorUInt16
4473 | BinaryFunc::BitXorUInt32
4474 | BinaryFunc::BitXorUInt64
4475 | BinaryFunc::BitShiftLeftInt16
4476 | BinaryFunc::BitShiftLeftInt32
4477 | BinaryFunc::BitShiftLeftInt64
4478 | BinaryFunc::BitShiftLeftUInt16
4479 | BinaryFunc::BitShiftLeftUInt32
4480 | BinaryFunc::BitShiftLeftUInt64
4481 | BinaryFunc::BitShiftRightInt16
4482 | BinaryFunc::BitShiftRightInt32
4483 | BinaryFunc::BitShiftRightInt64
4484 | BinaryFunc::BitShiftRightUInt16
4485 | BinaryFunc::BitShiftRightUInt32
4486 | BinaryFunc::BitShiftRightUInt64 => false,
4487 BinaryFunc::JsonbGetInt64
4488 | BinaryFunc::JsonbGetInt64Stringify
4489 | BinaryFunc::JsonbGetString
4490 | BinaryFunc::JsonbGetStringStringify
4491 | BinaryFunc::JsonbGetPath
4492 | BinaryFunc::JsonbGetPathStringify
4493 | BinaryFunc::JsonbContainsString
4494 | BinaryFunc::JsonbConcat
4495 | BinaryFunc::JsonbContainsJsonb
4496 | BinaryFunc::JsonbDeleteInt64
4497 | BinaryFunc::JsonbDeleteString => false,
4498 BinaryFunc::MapContainsKey
4499 | BinaryFunc::MapGetValue
4500 | BinaryFunc::MapContainsAllKeys
4501 | BinaryFunc::MapContainsAnyKeys
4502 | BinaryFunc::MapContainsMap => false,
4503 BinaryFunc::AddTimeInterval
4504 | BinaryFunc::SubTimestamp
4505 | BinaryFunc::SubTimestampTz
4506 | BinaryFunc::SubDate
4507 | BinaryFunc::SubTime
4508 | BinaryFunc::SubTimeInterval
4509 | BinaryFunc::UuidGenerateV5
4510 | BinaryFunc::RangeContainsRange { .. }
4511 | BinaryFunc::RangeContainsElem { .. }
4512 | BinaryFunc::RangeOverlaps
4513 | BinaryFunc::RangeAfter
4514 | BinaryFunc::RangeBefore
4515 | BinaryFunc::RangeOverleft
4516 | BinaryFunc::RangeOverright
4517 | BinaryFunc::RangeAdjacent
4518 | BinaryFunc::ArrayLower
4519 | BinaryFunc::ArrayContains
4520 | BinaryFunc::ArrayContainsArray { rev: _ }
4521 | BinaryFunc::ListListConcat
4522 | BinaryFunc::ListElementConcat
4523 | BinaryFunc::ElementListConcat
4524 | BinaryFunc::ListRemove
4525 | BinaryFunc::ToCharTimestamp
4526 | BinaryFunc::ToCharTimestampTz
4527 | BinaryFunc::ListContainsList { rev: _ }
4528 | BinaryFunc::Trim
4529 | BinaryFunc::TrimLeading
4530 | BinaryFunc::TrimTrailing
4531 | BinaryFunc::TextConcat
4532 | BinaryFunc::StartsWith => false,
4533
4534 _ => true,
4535 }
4536 }
4537
4538 pub fn is_monotone(&self) -> (bool, bool) {
4551 match self {
4552 BinaryFunc::AddInt16
4553 | BinaryFunc::AddInt32
4554 | BinaryFunc::AddInt64
4555 | BinaryFunc::AddUInt16
4556 | BinaryFunc::AddUInt32
4557 | BinaryFunc::AddUInt64
4558 | BinaryFunc::AddFloat32
4559 | BinaryFunc::AddFloat64
4560 | BinaryFunc::AddInterval
4561 | BinaryFunc::AddTimestampInterval
4562 | BinaryFunc::AddTimestampTzInterval
4563 | BinaryFunc::AddDateInterval
4564 | BinaryFunc::AddDateTime
4565 | BinaryFunc::AddTimeInterval
4566 | BinaryFunc::AddNumeric => (true, true),
4567 BinaryFunc::BitAndInt16
4568 | BinaryFunc::BitAndInt32
4569 | BinaryFunc::BitAndInt64
4570 | BinaryFunc::BitAndUInt16
4571 | BinaryFunc::BitAndUInt32
4572 | BinaryFunc::BitAndUInt64
4573 | BinaryFunc::BitOrInt16
4574 | BinaryFunc::BitOrInt32
4575 | BinaryFunc::BitOrInt64
4576 | BinaryFunc::BitOrUInt16
4577 | BinaryFunc::BitOrUInt32
4578 | BinaryFunc::BitOrUInt64
4579 | BinaryFunc::BitXorInt16
4580 | BinaryFunc::BitXorInt32
4581 | BinaryFunc::BitXorInt64
4582 | BinaryFunc::BitXorUInt16
4583 | BinaryFunc::BitXorUInt32
4584 | BinaryFunc::BitXorUInt64 => (false, false),
4585 BinaryFunc::BitShiftLeftInt16
4587 | BinaryFunc::BitShiftLeftInt32
4588 | BinaryFunc::BitShiftLeftInt64
4589 | BinaryFunc::BitShiftLeftUInt16
4590 | BinaryFunc::BitShiftLeftUInt32
4591 | BinaryFunc::BitShiftLeftUInt64
4592 | BinaryFunc::BitShiftRightInt16
4593 | BinaryFunc::BitShiftRightInt32
4594 | BinaryFunc::BitShiftRightInt64
4595 | BinaryFunc::BitShiftRightUInt16
4596 | BinaryFunc::BitShiftRightUInt32
4597 | BinaryFunc::BitShiftRightUInt64 => (false, false),
4598 BinaryFunc::SubInt16
4599 | BinaryFunc::SubInt32
4600 | BinaryFunc::SubInt64
4601 | BinaryFunc::SubUInt16
4602 | BinaryFunc::SubUInt32
4603 | BinaryFunc::SubUInt64
4604 | BinaryFunc::SubFloat32
4605 | BinaryFunc::SubFloat64
4606 | BinaryFunc::SubInterval
4607 | BinaryFunc::SubTimestamp
4608 | BinaryFunc::SubTimestampTz
4609 | BinaryFunc::SubTimestampInterval
4610 | BinaryFunc::SubTimestampTzInterval
4611 | BinaryFunc::SubDate
4612 | BinaryFunc::SubDateInterval
4613 | BinaryFunc::SubTime
4614 | BinaryFunc::SubTimeInterval
4615 | BinaryFunc::SubNumeric => (true, true),
4616 BinaryFunc::MulInt16
4617 | BinaryFunc::MulInt32
4618 | BinaryFunc::MulInt64
4619 | BinaryFunc::MulUInt16
4620 | BinaryFunc::MulUInt32
4621 | BinaryFunc::MulUInt64
4622 | BinaryFunc::MulFloat32
4623 | BinaryFunc::MulFloat64
4624 | BinaryFunc::MulNumeric
4625 | BinaryFunc::MulInterval => (true, true),
4626 BinaryFunc::DivInt16
4627 | BinaryFunc::DivInt32
4628 | BinaryFunc::DivInt64
4629 | BinaryFunc::DivUInt16
4630 | BinaryFunc::DivUInt32
4631 | BinaryFunc::DivUInt64
4632 | BinaryFunc::DivFloat32
4633 | BinaryFunc::DivFloat64
4634 | BinaryFunc::DivNumeric
4635 | BinaryFunc::DivInterval => (true, false),
4636 BinaryFunc::ModInt16
4637 | BinaryFunc::ModInt32
4638 | BinaryFunc::ModInt64
4639 | BinaryFunc::ModUInt16
4640 | BinaryFunc::ModUInt32
4641 | BinaryFunc::ModUInt64
4642 | BinaryFunc::ModFloat32
4643 | BinaryFunc::ModFloat64
4644 | BinaryFunc::ModNumeric => (false, false),
4645 BinaryFunc::RoundNumeric => (true, false),
4646 BinaryFunc::Eq | BinaryFunc::NotEq => (false, false),
4647 BinaryFunc::Lt | BinaryFunc::Lte | BinaryFunc::Gt | BinaryFunc::Gte => (true, true),
4648 BinaryFunc::LikeEscape
4649 | BinaryFunc::IsLikeMatch { .. }
4650 | BinaryFunc::IsRegexpMatch { .. } => (false, false),
4651 BinaryFunc::ToCharTimestamp | BinaryFunc::ToCharTimestampTz => (false, false),
4652 BinaryFunc::DateBinTimestamp | BinaryFunc::DateBinTimestampTz => (true, true),
4653 BinaryFunc::AgeTimestamp | BinaryFunc::AgeTimestampTz => (true, true),
4654 BinaryFunc::TextConcat => (false, true),
4661 BinaryFunc::Left => (false, false),
4664 BinaryFunc::ExtractInterval
4667 | BinaryFunc::ExtractTime
4668 | BinaryFunc::ExtractTimestamp
4669 | BinaryFunc::ExtractTimestampTz
4670 | BinaryFunc::ExtractDate => (false, false),
4671 BinaryFunc::DatePartInterval
4672 | BinaryFunc::DatePartTime
4673 | BinaryFunc::DatePartTimestamp
4674 | BinaryFunc::DatePartTimestampTz => (false, false),
4675 BinaryFunc::DateTruncTimestamp
4676 | BinaryFunc::DateTruncTimestampTz
4677 | BinaryFunc::DateTruncInterval => (false, false),
4678 BinaryFunc::TimezoneTimestamp
4679 | BinaryFunc::TimezoneTimestampTz
4680 | BinaryFunc::TimezoneIntervalTimestamp
4681 | BinaryFunc::TimezoneIntervalTimestampTz
4682 | BinaryFunc::TimezoneIntervalTime
4683 | BinaryFunc::TimezoneOffset => (false, false),
4684 BinaryFunc::JsonbGetInt64
4685 | BinaryFunc::JsonbGetInt64Stringify
4686 | BinaryFunc::JsonbGetString
4687 | BinaryFunc::JsonbGetStringStringify
4688 | BinaryFunc::JsonbGetPath
4689 | BinaryFunc::JsonbGetPathStringify
4690 | BinaryFunc::JsonbContainsString
4691 | BinaryFunc::JsonbConcat
4692 | BinaryFunc::JsonbContainsJsonb
4693 | BinaryFunc::JsonbDeleteInt64
4694 | BinaryFunc::JsonbDeleteString
4695 | BinaryFunc::MapContainsKey
4696 | BinaryFunc::MapGetValue
4697 | BinaryFunc::MapContainsAllKeys
4698 | BinaryFunc::MapContainsAnyKeys
4699 | BinaryFunc::MapContainsMap => (false, false),
4700 BinaryFunc::ConvertFrom
4701 | BinaryFunc::Position
4702 | BinaryFunc::Right
4703 | BinaryFunc::RepeatString
4704 | BinaryFunc::Trim
4705 | BinaryFunc::TrimLeading
4706 | BinaryFunc::TrimTrailing
4707 | BinaryFunc::EncodedBytesCharLength
4708 | BinaryFunc::ListLengthMax { .. }
4709 | BinaryFunc::ArrayContains
4710 | BinaryFunc::ArrayContainsArray { .. }
4711 | BinaryFunc::ArrayLength
4712 | BinaryFunc::ArrayLower
4713 | BinaryFunc::ArrayRemove
4714 | BinaryFunc::ArrayUpper
4715 | BinaryFunc::ArrayArrayConcat
4716 | BinaryFunc::ListListConcat
4717 | BinaryFunc::ListElementConcat
4718 | BinaryFunc::ElementListConcat
4719 | BinaryFunc::ListContainsList { .. }
4720 | BinaryFunc::ListRemove
4721 | BinaryFunc::DigestString
4722 | BinaryFunc::DigestBytes
4723 | BinaryFunc::MzRenderTypmod
4724 | BinaryFunc::Encode
4725 | BinaryFunc::Decode => (false, false),
4726 BinaryFunc::LogNumeric | BinaryFunc::Power | BinaryFunc::PowerNumeric => (false, false),
4728 BinaryFunc::GetBit
4729 | BinaryFunc::GetByte
4730 | BinaryFunc::RangeContainsElem { .. }
4731 | BinaryFunc::RangeContainsRange { .. }
4732 | BinaryFunc::RangeOverlaps
4733 | BinaryFunc::RangeAfter
4734 | BinaryFunc::RangeBefore
4735 | BinaryFunc::RangeOverleft
4736 | BinaryFunc::RangeOverright
4737 | BinaryFunc::RangeAdjacent
4738 | BinaryFunc::RangeUnion
4739 | BinaryFunc::RangeIntersection
4740 | BinaryFunc::RangeDifference => (false, false),
4741 BinaryFunc::UuidGenerateV5 => (false, false),
4742 BinaryFunc::MzAclItemContainsPrivilege => (false, false),
4743 BinaryFunc::ParseIdent => (false, false),
4744 BinaryFunc::ConstantTimeEqBytes | BinaryFunc::ConstantTimeEqString => (false, false),
4745 BinaryFunc::PrettySql => (false, false),
4746 BinaryFunc::RegexpReplace { .. } => (false, false),
4747 BinaryFunc::StartsWith => (false, false),
4748 }
4749 }
4750}
4751
4752impl fmt::Display for BinaryFunc {
4753 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4754 match self {
4755 BinaryFunc::AddInt16 => f.write_str("+"),
4756 BinaryFunc::AddInt32 => f.write_str("+"),
4757 BinaryFunc::AddInt64 => f.write_str("+"),
4758 BinaryFunc::AddUInt16 => f.write_str("+"),
4759 BinaryFunc::AddUInt32 => f.write_str("+"),
4760 BinaryFunc::AddUInt64 => f.write_str("+"),
4761 BinaryFunc::AddFloat32 => f.write_str("+"),
4762 BinaryFunc::AddFloat64 => f.write_str("+"),
4763 BinaryFunc::AddNumeric => f.write_str("+"),
4764 BinaryFunc::AddInterval => f.write_str("+"),
4765 BinaryFunc::AddTimestampInterval => f.write_str("+"),
4766 BinaryFunc::AddTimestampTzInterval => f.write_str("+"),
4767 BinaryFunc::AddDateTime => f.write_str("+"),
4768 BinaryFunc::AddDateInterval => f.write_str("+"),
4769 BinaryFunc::AddTimeInterval => f.write_str("+"),
4770 BinaryFunc::AgeTimestamp => f.write_str("age"),
4771 BinaryFunc::AgeTimestampTz => f.write_str("age"),
4772 BinaryFunc::BitAndInt16 => f.write_str("&"),
4773 BinaryFunc::BitAndInt32 => f.write_str("&"),
4774 BinaryFunc::BitAndInt64 => f.write_str("&"),
4775 BinaryFunc::BitAndUInt16 => f.write_str("&"),
4776 BinaryFunc::BitAndUInt32 => f.write_str("&"),
4777 BinaryFunc::BitAndUInt64 => f.write_str("&"),
4778 BinaryFunc::BitOrInt16 => f.write_str("|"),
4779 BinaryFunc::BitOrInt32 => f.write_str("|"),
4780 BinaryFunc::BitOrInt64 => f.write_str("|"),
4781 BinaryFunc::BitOrUInt16 => f.write_str("|"),
4782 BinaryFunc::BitOrUInt32 => f.write_str("|"),
4783 BinaryFunc::BitOrUInt64 => f.write_str("|"),
4784 BinaryFunc::BitXorInt16 => f.write_str("#"),
4785 BinaryFunc::BitXorInt32 => f.write_str("#"),
4786 BinaryFunc::BitXorInt64 => f.write_str("#"),
4787 BinaryFunc::BitXorUInt16 => f.write_str("#"),
4788 BinaryFunc::BitXorUInt32 => f.write_str("#"),
4789 BinaryFunc::BitXorUInt64 => f.write_str("#"),
4790 BinaryFunc::BitShiftLeftInt16 => f.write_str("<<"),
4791 BinaryFunc::BitShiftLeftInt32 => f.write_str("<<"),
4792 BinaryFunc::BitShiftLeftInt64 => f.write_str("<<"),
4793 BinaryFunc::BitShiftLeftUInt16 => f.write_str("<<"),
4794 BinaryFunc::BitShiftLeftUInt32 => f.write_str("<<"),
4795 BinaryFunc::BitShiftLeftUInt64 => f.write_str("<<"),
4796 BinaryFunc::BitShiftRightInt16 => f.write_str(">>"),
4797 BinaryFunc::BitShiftRightInt32 => f.write_str(">>"),
4798 BinaryFunc::BitShiftRightInt64 => f.write_str(">>"),
4799 BinaryFunc::BitShiftRightUInt16 => f.write_str(">>"),
4800 BinaryFunc::BitShiftRightUInt32 => f.write_str(">>"),
4801 BinaryFunc::BitShiftRightUInt64 => f.write_str(">>"),
4802 BinaryFunc::SubInt16 => f.write_str("-"),
4803 BinaryFunc::SubInt32 => f.write_str("-"),
4804 BinaryFunc::SubInt64 => f.write_str("-"),
4805 BinaryFunc::SubUInt16 => f.write_str("-"),
4806 BinaryFunc::SubUInt32 => f.write_str("-"),
4807 BinaryFunc::SubUInt64 => f.write_str("-"),
4808 BinaryFunc::SubFloat32 => f.write_str("-"),
4809 BinaryFunc::SubFloat64 => f.write_str("-"),
4810 BinaryFunc::SubNumeric => f.write_str("-"),
4811 BinaryFunc::SubInterval => f.write_str("-"),
4812 BinaryFunc::SubTimestamp => f.write_str("-"),
4813 BinaryFunc::SubTimestampTz => f.write_str("-"),
4814 BinaryFunc::SubTimestampInterval => f.write_str("-"),
4815 BinaryFunc::SubTimestampTzInterval => f.write_str("-"),
4816 BinaryFunc::SubDate => f.write_str("-"),
4817 BinaryFunc::SubDateInterval => f.write_str("-"),
4818 BinaryFunc::SubTime => f.write_str("-"),
4819 BinaryFunc::SubTimeInterval => f.write_str("-"),
4820 BinaryFunc::MulInt16 => f.write_str("*"),
4821 BinaryFunc::MulInt32 => f.write_str("*"),
4822 BinaryFunc::MulInt64 => f.write_str("*"),
4823 BinaryFunc::MulUInt16 => f.write_str("*"),
4824 BinaryFunc::MulUInt32 => f.write_str("*"),
4825 BinaryFunc::MulUInt64 => f.write_str("*"),
4826 BinaryFunc::MulFloat32 => f.write_str("*"),
4827 BinaryFunc::MulFloat64 => f.write_str("*"),
4828 BinaryFunc::MulNumeric => f.write_str("*"),
4829 BinaryFunc::MulInterval => f.write_str("*"),
4830 BinaryFunc::DivInt16 => f.write_str("/"),
4831 BinaryFunc::DivInt32 => f.write_str("/"),
4832 BinaryFunc::DivInt64 => f.write_str("/"),
4833 BinaryFunc::DivUInt16 => f.write_str("/"),
4834 BinaryFunc::DivUInt32 => f.write_str("/"),
4835 BinaryFunc::DivUInt64 => f.write_str("/"),
4836 BinaryFunc::DivFloat32 => f.write_str("/"),
4837 BinaryFunc::DivFloat64 => f.write_str("/"),
4838 BinaryFunc::DivNumeric => f.write_str("/"),
4839 BinaryFunc::DivInterval => f.write_str("/"),
4840 BinaryFunc::ModInt16 => f.write_str("%"),
4841 BinaryFunc::ModInt32 => f.write_str("%"),
4842 BinaryFunc::ModInt64 => f.write_str("%"),
4843 BinaryFunc::ModUInt16 => f.write_str("%"),
4844 BinaryFunc::ModUInt32 => f.write_str("%"),
4845 BinaryFunc::ModUInt64 => f.write_str("%"),
4846 BinaryFunc::ModFloat32 => f.write_str("%"),
4847 BinaryFunc::ModFloat64 => f.write_str("%"),
4848 BinaryFunc::ModNumeric => f.write_str("%"),
4849 BinaryFunc::Eq => f.write_str("="),
4850 BinaryFunc::NotEq => f.write_str("!="),
4851 BinaryFunc::Lt => f.write_str("<"),
4852 BinaryFunc::Lte => f.write_str("<="),
4853 BinaryFunc::Gt => f.write_str(">"),
4854 BinaryFunc::Gte => f.write_str(">="),
4855 BinaryFunc::LikeEscape => f.write_str("like_escape"),
4856 BinaryFunc::IsLikeMatch {
4857 case_insensitive: false,
4858 } => f.write_str("like"),
4859 BinaryFunc::IsLikeMatch {
4860 case_insensitive: true,
4861 } => f.write_str("ilike"),
4862 BinaryFunc::IsRegexpMatch {
4863 case_insensitive: false,
4864 } => f.write_str("~"),
4865 BinaryFunc::IsRegexpMatch {
4866 case_insensitive: true,
4867 } => f.write_str("~*"),
4868 BinaryFunc::ToCharTimestamp => f.write_str("tocharts"),
4869 BinaryFunc::ToCharTimestampTz => f.write_str("tochartstz"),
4870 BinaryFunc::DateBinTimestamp => f.write_str("bin_unix_epoch_timestamp"),
4871 BinaryFunc::DateBinTimestampTz => f.write_str("bin_unix_epoch_timestamptz"),
4872 BinaryFunc::ExtractInterval => f.write_str("extractiv"),
4873 BinaryFunc::ExtractTime => f.write_str("extractt"),
4874 BinaryFunc::ExtractTimestamp => f.write_str("extractts"),
4875 BinaryFunc::ExtractTimestampTz => f.write_str("extracttstz"),
4876 BinaryFunc::ExtractDate => f.write_str("extractd"),
4877 BinaryFunc::DatePartInterval => f.write_str("date_partiv"),
4878 BinaryFunc::DatePartTime => f.write_str("date_partt"),
4879 BinaryFunc::DatePartTimestamp => f.write_str("date_partts"),
4880 BinaryFunc::DatePartTimestampTz => f.write_str("date_parttstz"),
4881 BinaryFunc::DateTruncTimestamp => f.write_str("date_truncts"),
4882 BinaryFunc::DateTruncInterval => f.write_str("date_trunciv"),
4883 BinaryFunc::DateTruncTimestampTz => f.write_str("date_trunctstz"),
4884 BinaryFunc::TimezoneTimestamp => f.write_str("timezonets"),
4885 BinaryFunc::TimezoneTimestampTz => f.write_str("timezonetstz"),
4886 BinaryFunc::TimezoneIntervalTimestamp => f.write_str("timezoneits"),
4887 BinaryFunc::TimezoneIntervalTimestampTz => f.write_str("timezoneitstz"),
4888 BinaryFunc::TimezoneIntervalTime => f.write_str("timezoneit"),
4889 BinaryFunc::TimezoneOffset => f.write_str("timezone_offset"),
4890 BinaryFunc::TextConcat => f.write_str("||"),
4891 BinaryFunc::JsonbGetInt64 => f.write_str("->"),
4892 BinaryFunc::JsonbGetInt64Stringify => f.write_str("->>"),
4893 BinaryFunc::JsonbGetString => f.write_str("->"),
4894 BinaryFunc::JsonbGetStringStringify => f.write_str("->>"),
4895 BinaryFunc::JsonbGetPath => f.write_str("#>"),
4896 BinaryFunc::JsonbGetPathStringify => f.write_str("#>>"),
4897 BinaryFunc::JsonbContainsString | BinaryFunc::MapContainsKey => f.write_str("?"),
4898 BinaryFunc::JsonbConcat => f.write_str("||"),
4899 BinaryFunc::JsonbContainsJsonb | BinaryFunc::MapContainsMap => f.write_str("@>"),
4900 BinaryFunc::JsonbDeleteInt64 => f.write_str("-"),
4901 BinaryFunc::JsonbDeleteString => f.write_str("-"),
4902 BinaryFunc::MapGetValue => f.write_str("->"),
4903 BinaryFunc::MapContainsAllKeys => f.write_str("?&"),
4904 BinaryFunc::MapContainsAnyKeys => f.write_str("?|"),
4905 BinaryFunc::RoundNumeric => f.write_str("round"),
4906 BinaryFunc::ConvertFrom => f.write_str("convert_from"),
4907 BinaryFunc::Left => f.write_str("left"),
4908 BinaryFunc::Position => f.write_str("position"),
4909 BinaryFunc::Right => f.write_str("right"),
4910 BinaryFunc::Trim => f.write_str("btrim"),
4911 BinaryFunc::TrimLeading => f.write_str("ltrim"),
4912 BinaryFunc::TrimTrailing => f.write_str("rtrim"),
4913 BinaryFunc::EncodedBytesCharLength => f.write_str("length"),
4914 BinaryFunc::ListLengthMax { .. } => f.write_str("list_length_max"),
4915 BinaryFunc::ArrayContains => f.write_str("array_contains"),
4916 BinaryFunc::ArrayContainsArray { rev } => f.write_str(if *rev { "<@" } else { "@>" }),
4917 BinaryFunc::ArrayLength => f.write_str("array_length"),
4918 BinaryFunc::ArrayLower => f.write_str("array_lower"),
4919 BinaryFunc::ArrayRemove => f.write_str("array_remove"),
4920 BinaryFunc::ArrayUpper => f.write_str("array_upper"),
4921 BinaryFunc::ArrayArrayConcat => f.write_str("||"),
4922 BinaryFunc::ListListConcat => f.write_str("||"),
4923 BinaryFunc::ListElementConcat => f.write_str("||"),
4924 BinaryFunc::ElementListConcat => f.write_str("||"),
4925 BinaryFunc::ListRemove => f.write_str("list_remove"),
4926 BinaryFunc::ListContainsList { rev } => f.write_str(if *rev { "<@" } else { "@>" }),
4927 BinaryFunc::DigestString | BinaryFunc::DigestBytes => f.write_str("digest"),
4928 BinaryFunc::MzRenderTypmod => f.write_str("mz_render_typmod"),
4929 BinaryFunc::Encode => f.write_str("encode"),
4930 BinaryFunc::Decode => f.write_str("decode"),
4931 BinaryFunc::LogNumeric => f.write_str("log"),
4932 BinaryFunc::Power => f.write_str("power"),
4933 BinaryFunc::PowerNumeric => f.write_str("power_numeric"),
4934 BinaryFunc::RepeatString => f.write_str("repeat"),
4935 BinaryFunc::GetBit => f.write_str("get_bit"),
4936 BinaryFunc::GetByte => f.write_str("get_byte"),
4937 BinaryFunc::ConstantTimeEqBytes => f.write_str("constant_time_compare_bytes"),
4938 BinaryFunc::ConstantTimeEqString => f.write_str("constant_time_compare_strings"),
4939 BinaryFunc::RangeContainsElem { rev, .. } => {
4940 f.write_str(if *rev { "<@" } else { "@>" })
4941 }
4942 BinaryFunc::RangeContainsRange { rev, .. } => {
4943 f.write_str(if *rev { "<@" } else { "@>" })
4944 }
4945 BinaryFunc::RangeOverlaps => f.write_str("&&"),
4946 BinaryFunc::RangeAfter => f.write_str(">>"),
4947 BinaryFunc::RangeBefore => f.write_str("<<"),
4948 BinaryFunc::RangeOverleft => f.write_str("&<"),
4949 BinaryFunc::RangeOverright => f.write_str("&>"),
4950 BinaryFunc::RangeAdjacent => f.write_str("-|-"),
4951 BinaryFunc::RangeUnion => f.write_str("+"),
4952 BinaryFunc::RangeIntersection => f.write_str("*"),
4953 BinaryFunc::RangeDifference => f.write_str("-"),
4954 BinaryFunc::UuidGenerateV5 => f.write_str("uuid_generate_v5"),
4955 BinaryFunc::MzAclItemContainsPrivilege => f.write_str("mz_aclitem_contains_privilege"),
4956 BinaryFunc::ParseIdent => f.write_str("parse_ident"),
4957 BinaryFunc::PrettySql => f.write_str("pretty_sql"),
4958 BinaryFunc::RegexpReplace { regex, limit } => write!(
4959 f,
4960 "regexp_replace[{}, case_insensitive={}, limit={}]",
4961 regex.pattern().escaped(),
4962 regex.case_insensitive,
4963 limit
4964 ),
4965 BinaryFunc::StartsWith => f.write_str("starts_with"),
4966 }
4967 }
4968}
4969
4970impl Arbitrary for BinaryFunc {
4977 type Parameters = ();
4978
4979 type Strategy = Union<BoxedStrategy<Self>>;
4980
4981 fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
4982 Union::new(vec![
4983 Just(BinaryFunc::AddInt16).boxed(),
4984 Just(BinaryFunc::AddInt32).boxed(),
4985 Just(BinaryFunc::AddInt64).boxed(),
4986 Just(BinaryFunc::AddUInt16).boxed(),
4987 Just(BinaryFunc::AddUInt32).boxed(),
4988 Just(BinaryFunc::AddUInt64).boxed(),
4989 Just(BinaryFunc::AddFloat32).boxed(),
4990 Just(BinaryFunc::AddFloat64).boxed(),
4991 Just(BinaryFunc::AddInterval).boxed(),
4992 Just(BinaryFunc::AddTimestampInterval).boxed(),
4993 Just(BinaryFunc::AddTimestampTzInterval).boxed(),
4994 Just(BinaryFunc::AddDateInterval).boxed(),
4995 Just(BinaryFunc::AddDateTime).boxed(),
4996 Just(BinaryFunc::AddTimeInterval).boxed(),
4997 Just(BinaryFunc::AddNumeric).boxed(),
4998 Just(BinaryFunc::AgeTimestamp).boxed(),
4999 Just(BinaryFunc::AgeTimestampTz).boxed(),
5000 Just(BinaryFunc::BitAndInt16).boxed(),
5001 Just(BinaryFunc::BitAndInt32).boxed(),
5002 Just(BinaryFunc::BitAndInt64).boxed(),
5003 Just(BinaryFunc::BitAndUInt16).boxed(),
5004 Just(BinaryFunc::BitAndUInt32).boxed(),
5005 Just(BinaryFunc::BitAndUInt64).boxed(),
5006 Just(BinaryFunc::BitOrInt16).boxed(),
5007 Just(BinaryFunc::BitOrInt32).boxed(),
5008 Just(BinaryFunc::BitOrInt64).boxed(),
5009 Just(BinaryFunc::BitOrUInt16).boxed(),
5010 Just(BinaryFunc::BitOrUInt32).boxed(),
5011 Just(BinaryFunc::BitOrUInt64).boxed(),
5012 Just(BinaryFunc::BitXorInt16).boxed(),
5013 Just(BinaryFunc::BitXorInt32).boxed(),
5014 Just(BinaryFunc::BitXorInt64).boxed(),
5015 Just(BinaryFunc::BitXorUInt16).boxed(),
5016 Just(BinaryFunc::BitXorUInt32).boxed(),
5017 Just(BinaryFunc::BitXorUInt64).boxed(),
5018 Just(BinaryFunc::BitShiftLeftInt16).boxed(),
5019 Just(BinaryFunc::BitShiftLeftInt32).boxed(),
5020 Just(BinaryFunc::BitShiftLeftInt64).boxed(),
5021 Just(BinaryFunc::BitShiftLeftUInt16).boxed(),
5022 Just(BinaryFunc::BitShiftLeftUInt32).boxed(),
5023 Just(BinaryFunc::BitShiftLeftUInt64).boxed(),
5024 Just(BinaryFunc::BitShiftRightInt16).boxed(),
5025 Just(BinaryFunc::BitShiftRightInt32).boxed(),
5026 Just(BinaryFunc::BitShiftRightInt64).boxed(),
5027 Just(BinaryFunc::BitShiftRightUInt16).boxed(),
5028 Just(BinaryFunc::BitShiftRightUInt32).boxed(),
5029 Just(BinaryFunc::BitShiftRightUInt64).boxed(),
5030 Just(BinaryFunc::SubInt16).boxed(),
5031 Just(BinaryFunc::SubInt32).boxed(),
5032 Just(BinaryFunc::SubInt64).boxed(),
5033 Just(BinaryFunc::SubUInt16).boxed(),
5034 Just(BinaryFunc::SubUInt32).boxed(),
5035 Just(BinaryFunc::SubUInt64).boxed(),
5036 Just(BinaryFunc::SubFloat32).boxed(),
5037 Just(BinaryFunc::SubFloat64).boxed(),
5038 Just(BinaryFunc::SubInterval).boxed(),
5039 Just(BinaryFunc::SubTimestamp).boxed(),
5040 Just(BinaryFunc::SubTimestampTz).boxed(),
5041 Just(BinaryFunc::SubTimestampInterval).boxed(),
5042 Just(BinaryFunc::SubTimestampTzInterval).boxed(),
5043 Just(BinaryFunc::SubDate).boxed(),
5044 Just(BinaryFunc::SubDateInterval).boxed(),
5045 Just(BinaryFunc::SubTime).boxed(),
5046 Just(BinaryFunc::SubTimeInterval).boxed(),
5047 Just(BinaryFunc::SubNumeric).boxed(),
5048 Just(BinaryFunc::MulInt16).boxed(),
5049 Just(BinaryFunc::MulInt32).boxed(),
5050 Just(BinaryFunc::MulInt64).boxed(),
5051 Just(BinaryFunc::MulUInt16).boxed(),
5052 Just(BinaryFunc::MulUInt32).boxed(),
5053 Just(BinaryFunc::MulUInt64).boxed(),
5054 Just(BinaryFunc::MulFloat32).boxed(),
5055 Just(BinaryFunc::MulFloat64).boxed(),
5056 Just(BinaryFunc::MulNumeric).boxed(),
5057 Just(BinaryFunc::MulInterval).boxed(),
5058 Just(BinaryFunc::DivInt16).boxed(),
5059 Just(BinaryFunc::DivInt32).boxed(),
5060 Just(BinaryFunc::DivInt64).boxed(),
5061 Just(BinaryFunc::DivUInt16).boxed(),
5062 Just(BinaryFunc::DivUInt32).boxed(),
5063 Just(BinaryFunc::DivUInt64).boxed(),
5064 Just(BinaryFunc::DivFloat32).boxed(),
5065 Just(BinaryFunc::DivFloat64).boxed(),
5066 Just(BinaryFunc::DivNumeric).boxed(),
5067 Just(BinaryFunc::DivInterval).boxed(),
5068 Just(BinaryFunc::ModInt16).boxed(),
5069 Just(BinaryFunc::ModInt32).boxed(),
5070 Just(BinaryFunc::ModInt64).boxed(),
5071 Just(BinaryFunc::ModUInt16).boxed(),
5072 Just(BinaryFunc::ModUInt32).boxed(),
5073 Just(BinaryFunc::ModUInt64).boxed(),
5074 Just(BinaryFunc::ModFloat32).boxed(),
5075 Just(BinaryFunc::ModFloat64).boxed(),
5076 Just(BinaryFunc::ModNumeric).boxed(),
5077 Just(BinaryFunc::RoundNumeric).boxed(),
5078 Just(BinaryFunc::Eq).boxed(),
5079 Just(BinaryFunc::NotEq).boxed(),
5080 Just(BinaryFunc::Lt).boxed(),
5081 Just(BinaryFunc::Lte).boxed(),
5082 Just(BinaryFunc::Gt).boxed(),
5083 Just(BinaryFunc::Gte).boxed(),
5084 Just(BinaryFunc::LikeEscape).boxed(),
5085 bool::arbitrary()
5086 .prop_map(|case_insensitive| BinaryFunc::IsLikeMatch { case_insensitive })
5087 .boxed(),
5088 bool::arbitrary()
5089 .prop_map(|case_insensitive| BinaryFunc::IsRegexpMatch { case_insensitive })
5090 .boxed(),
5091 Just(BinaryFunc::ToCharTimestamp).boxed(),
5092 Just(BinaryFunc::ToCharTimestampTz).boxed(),
5093 Just(BinaryFunc::DateBinTimestamp).boxed(),
5094 Just(BinaryFunc::DateBinTimestampTz).boxed(),
5095 Just(BinaryFunc::ExtractInterval).boxed(),
5096 Just(BinaryFunc::ExtractTime).boxed(),
5097 Just(BinaryFunc::ExtractTimestamp).boxed(),
5098 Just(BinaryFunc::ExtractTimestampTz).boxed(),
5099 Just(BinaryFunc::ExtractDate).boxed(),
5100 Just(BinaryFunc::DatePartInterval).boxed(),
5101 Just(BinaryFunc::DatePartTime).boxed(),
5102 Just(BinaryFunc::DatePartTimestamp).boxed(),
5103 Just(BinaryFunc::DatePartTimestampTz).boxed(),
5104 Just(BinaryFunc::DateTruncTimestamp).boxed(),
5105 Just(BinaryFunc::DateTruncTimestampTz).boxed(),
5106 Just(BinaryFunc::DateTruncInterval).boxed(),
5107 Just(BinaryFunc::TimezoneTimestamp).boxed(),
5108 Just(BinaryFunc::TimezoneTimestampTz).boxed(),
5109 Just(BinaryFunc::TimezoneIntervalTimestamp).boxed(),
5110 Just(BinaryFunc::TimezoneIntervalTimestampTz).boxed(),
5111 Just(BinaryFunc::TimezoneIntervalTime).boxed(),
5112 Just(BinaryFunc::TimezoneOffset).boxed(),
5113 Just(BinaryFunc::TextConcat).boxed(),
5114 Just(BinaryFunc::JsonbGetInt64).boxed(),
5115 Just(BinaryFunc::JsonbGetInt64Stringify).boxed(),
5116 Just(BinaryFunc::JsonbGetString).boxed(),
5117 Just(BinaryFunc::JsonbGetStringStringify).boxed(),
5118 Just(BinaryFunc::JsonbGetPath).boxed(),
5119 Just(BinaryFunc::JsonbGetPathStringify).boxed(),
5120 Just(BinaryFunc::JsonbContainsString).boxed(),
5121 Just(BinaryFunc::JsonbConcat).boxed(),
5122 Just(BinaryFunc::JsonbContainsJsonb).boxed(),
5123 Just(BinaryFunc::JsonbDeleteInt64).boxed(),
5124 Just(BinaryFunc::JsonbDeleteString).boxed(),
5125 Just(BinaryFunc::MapContainsKey).boxed(),
5126 Just(BinaryFunc::MapGetValue).boxed(),
5127 Just(BinaryFunc::MapContainsAllKeys).boxed(),
5128 Just(BinaryFunc::MapContainsAnyKeys).boxed(),
5129 Just(BinaryFunc::MapContainsMap).boxed(),
5130 Just(BinaryFunc::ConvertFrom).boxed(),
5131 Just(BinaryFunc::Left).boxed(),
5132 Just(BinaryFunc::Position).boxed(),
5133 Just(BinaryFunc::Right).boxed(),
5134 Just(BinaryFunc::RepeatString).boxed(),
5135 Just(BinaryFunc::Trim).boxed(),
5136 Just(BinaryFunc::TrimLeading).boxed(),
5137 Just(BinaryFunc::TrimTrailing).boxed(),
5138 Just(BinaryFunc::EncodedBytesCharLength).boxed(),
5139 usize::arbitrary()
5140 .prop_map(|max_layer| BinaryFunc::ListLengthMax { max_layer })
5141 .boxed(),
5142 Just(BinaryFunc::ArrayContains).boxed(),
5143 Just(BinaryFunc::ArrayLength).boxed(),
5144 Just(BinaryFunc::ArrayLower).boxed(),
5145 Just(BinaryFunc::ArrayRemove).boxed(),
5146 Just(BinaryFunc::ArrayUpper).boxed(),
5147 Just(BinaryFunc::ArrayArrayConcat).boxed(),
5148 Just(BinaryFunc::ListListConcat).boxed(),
5149 Just(BinaryFunc::ListElementConcat).boxed(),
5150 Just(BinaryFunc::ElementListConcat).boxed(),
5151 Just(BinaryFunc::ListRemove).boxed(),
5152 Just(BinaryFunc::DigestString).boxed(),
5153 Just(BinaryFunc::DigestBytes).boxed(),
5154 Just(BinaryFunc::MzRenderTypmod).boxed(),
5155 Just(BinaryFunc::Encode).boxed(),
5156 Just(BinaryFunc::Decode).boxed(),
5157 Just(BinaryFunc::LogNumeric).boxed(),
5158 Just(BinaryFunc::Power).boxed(),
5159 Just(BinaryFunc::PowerNumeric).boxed(),
5160 (bool::arbitrary(), mz_repr::arb_range_type())
5161 .prop_map(|(rev, elem_type)| BinaryFunc::RangeContainsElem { elem_type, rev })
5162 .boxed(),
5163 bool::arbitrary()
5164 .prop_map(|rev| BinaryFunc::RangeContainsRange { rev })
5165 .boxed(),
5166 Just(BinaryFunc::RangeOverlaps).boxed(),
5167 Just(BinaryFunc::RangeAfter).boxed(),
5168 Just(BinaryFunc::RangeBefore).boxed(),
5169 Just(BinaryFunc::RangeOverleft).boxed(),
5170 Just(BinaryFunc::RangeOverright).boxed(),
5171 Just(BinaryFunc::RangeAdjacent).boxed(),
5172 Just(BinaryFunc::RangeUnion).boxed(),
5173 Just(BinaryFunc::RangeIntersection).boxed(),
5174 Just(BinaryFunc::RangeDifference).boxed(),
5175 Just(BinaryFunc::ParseIdent).boxed(),
5176 ])
5177 }
5178}
5179
5180impl RustType<ProtoBinaryFunc> for BinaryFunc {
5181 fn into_proto(&self) -> ProtoBinaryFunc {
5182 use crate::scalar::proto_binary_func::Kind::*;
5183 let kind = match self {
5184 BinaryFunc::AddInt16 => AddInt16(()),
5185 BinaryFunc::AddInt32 => AddInt32(()),
5186 BinaryFunc::AddInt64 => AddInt64(()),
5187 BinaryFunc::AddUInt16 => AddUint16(()),
5188 BinaryFunc::AddUInt32 => AddUint32(()),
5189 BinaryFunc::AddUInt64 => AddUint64(()),
5190 BinaryFunc::AddFloat32 => AddFloat32(()),
5191 BinaryFunc::AddFloat64 => AddFloat64(()),
5192 BinaryFunc::AddInterval => AddInterval(()),
5193 BinaryFunc::AddTimestampInterval => AddTimestampInterval(()),
5194 BinaryFunc::AddTimestampTzInterval => AddTimestampTzInterval(()),
5195 BinaryFunc::AddDateInterval => AddDateInterval(()),
5196 BinaryFunc::AddDateTime => AddDateTime(()),
5197 BinaryFunc::AddTimeInterval => AddTimeInterval(()),
5198 BinaryFunc::AddNumeric => AddNumeric(()),
5199 BinaryFunc::AgeTimestamp => AgeTimestamp(()),
5200 BinaryFunc::AgeTimestampTz => AgeTimestampTz(()),
5201 BinaryFunc::BitAndInt16 => BitAndInt16(()),
5202 BinaryFunc::BitAndInt32 => BitAndInt32(()),
5203 BinaryFunc::BitAndInt64 => BitAndInt64(()),
5204 BinaryFunc::BitAndUInt16 => BitAndUint16(()),
5205 BinaryFunc::BitAndUInt32 => BitAndUint32(()),
5206 BinaryFunc::BitAndUInt64 => BitAndUint64(()),
5207 BinaryFunc::BitOrInt16 => BitOrInt16(()),
5208 BinaryFunc::BitOrInt32 => BitOrInt32(()),
5209 BinaryFunc::BitOrInt64 => BitOrInt64(()),
5210 BinaryFunc::BitOrUInt16 => BitOrUint16(()),
5211 BinaryFunc::BitOrUInt32 => BitOrUint32(()),
5212 BinaryFunc::BitOrUInt64 => BitOrUint64(()),
5213 BinaryFunc::BitXorInt16 => BitXorInt16(()),
5214 BinaryFunc::BitXorInt32 => BitXorInt32(()),
5215 BinaryFunc::BitXorInt64 => BitXorInt64(()),
5216 BinaryFunc::BitXorUInt16 => BitXorUint16(()),
5217 BinaryFunc::BitXorUInt32 => BitXorUint32(()),
5218 BinaryFunc::BitXorUInt64 => BitXorUint64(()),
5219 BinaryFunc::BitShiftLeftInt16 => BitShiftLeftInt16(()),
5220 BinaryFunc::BitShiftLeftInt32 => BitShiftLeftInt32(()),
5221 BinaryFunc::BitShiftLeftInt64 => BitShiftLeftInt64(()),
5222 BinaryFunc::BitShiftLeftUInt16 => BitShiftLeftUint16(()),
5223 BinaryFunc::BitShiftLeftUInt32 => BitShiftLeftUint32(()),
5224 BinaryFunc::BitShiftLeftUInt64 => BitShiftLeftUint64(()),
5225 BinaryFunc::BitShiftRightInt16 => BitShiftRightInt16(()),
5226 BinaryFunc::BitShiftRightInt32 => BitShiftRightInt32(()),
5227 BinaryFunc::BitShiftRightInt64 => BitShiftRightInt64(()),
5228 BinaryFunc::BitShiftRightUInt16 => BitShiftRightUint16(()),
5229 BinaryFunc::BitShiftRightUInt32 => BitShiftRightUint32(()),
5230 BinaryFunc::BitShiftRightUInt64 => BitShiftRightUint64(()),
5231 BinaryFunc::SubInt16 => SubInt16(()),
5232 BinaryFunc::SubInt32 => SubInt32(()),
5233 BinaryFunc::SubInt64 => SubInt64(()),
5234 BinaryFunc::SubUInt16 => SubUint16(()),
5235 BinaryFunc::SubUInt32 => SubUint32(()),
5236 BinaryFunc::SubUInt64 => SubUint64(()),
5237 BinaryFunc::SubFloat32 => SubFloat32(()),
5238 BinaryFunc::SubFloat64 => SubFloat64(()),
5239 BinaryFunc::SubInterval => SubInterval(()),
5240 BinaryFunc::SubTimestamp => SubTimestamp(()),
5241 BinaryFunc::SubTimestampTz => SubTimestampTz(()),
5242 BinaryFunc::SubTimestampInterval => SubTimestampInterval(()),
5243 BinaryFunc::SubTimestampTzInterval => SubTimestampTzInterval(()),
5244 BinaryFunc::SubDate => SubDate(()),
5245 BinaryFunc::SubDateInterval => SubDateInterval(()),
5246 BinaryFunc::SubTime => SubTime(()),
5247 BinaryFunc::SubTimeInterval => SubTimeInterval(()),
5248 BinaryFunc::SubNumeric => SubNumeric(()),
5249 BinaryFunc::MulInt16 => MulInt16(()),
5250 BinaryFunc::MulInt32 => MulInt32(()),
5251 BinaryFunc::MulInt64 => MulInt64(()),
5252 BinaryFunc::MulUInt16 => MulUint16(()),
5253 BinaryFunc::MulUInt32 => MulUint32(()),
5254 BinaryFunc::MulUInt64 => MulUint64(()),
5255 BinaryFunc::MulFloat32 => MulFloat32(()),
5256 BinaryFunc::MulFloat64 => MulFloat64(()),
5257 BinaryFunc::MulNumeric => MulNumeric(()),
5258 BinaryFunc::MulInterval => MulInterval(()),
5259 BinaryFunc::DivInt16 => DivInt16(()),
5260 BinaryFunc::DivInt32 => DivInt32(()),
5261 BinaryFunc::DivInt64 => DivInt64(()),
5262 BinaryFunc::DivUInt16 => DivUint16(()),
5263 BinaryFunc::DivUInt32 => DivUint32(()),
5264 BinaryFunc::DivUInt64 => DivUint64(()),
5265 BinaryFunc::DivFloat32 => DivFloat32(()),
5266 BinaryFunc::DivFloat64 => DivFloat64(()),
5267 BinaryFunc::DivNumeric => DivNumeric(()),
5268 BinaryFunc::DivInterval => DivInterval(()),
5269 BinaryFunc::ModInt16 => ModInt16(()),
5270 BinaryFunc::ModInt32 => ModInt32(()),
5271 BinaryFunc::ModInt64 => ModInt64(()),
5272 BinaryFunc::ModUInt16 => ModUint16(()),
5273 BinaryFunc::ModUInt32 => ModUint32(()),
5274 BinaryFunc::ModUInt64 => ModUint64(()),
5275 BinaryFunc::ModFloat32 => ModFloat32(()),
5276 BinaryFunc::ModFloat64 => ModFloat64(()),
5277 BinaryFunc::ModNumeric => ModNumeric(()),
5278 BinaryFunc::RoundNumeric => RoundNumeric(()),
5279 BinaryFunc::Eq => Eq(()),
5280 BinaryFunc::NotEq => NotEq(()),
5281 BinaryFunc::Lt => Lt(()),
5282 BinaryFunc::Lte => Lte(()),
5283 BinaryFunc::Gt => Gt(()),
5284 BinaryFunc::Gte => Gte(()),
5285 BinaryFunc::LikeEscape => LikeEscape(()),
5286 BinaryFunc::IsLikeMatch { case_insensitive } => IsLikeMatch(*case_insensitive),
5287 BinaryFunc::IsRegexpMatch { case_insensitive } => IsRegexpMatch(*case_insensitive),
5288 BinaryFunc::ToCharTimestamp => ToCharTimestamp(()),
5289 BinaryFunc::ToCharTimestampTz => ToCharTimestampTz(()),
5290 BinaryFunc::DateBinTimestamp => DateBinTimestamp(()),
5291 BinaryFunc::DateBinTimestampTz => DateBinTimestampTz(()),
5292 BinaryFunc::ExtractInterval => ExtractInterval(()),
5293 BinaryFunc::ExtractTime => ExtractTime(()),
5294 BinaryFunc::ExtractTimestamp => ExtractTimestamp(()),
5295 BinaryFunc::ExtractTimestampTz => ExtractTimestampTz(()),
5296 BinaryFunc::ExtractDate => ExtractDate(()),
5297 BinaryFunc::DatePartInterval => DatePartInterval(()),
5298 BinaryFunc::DatePartTime => DatePartTime(()),
5299 BinaryFunc::DatePartTimestamp => DatePartTimestamp(()),
5300 BinaryFunc::DatePartTimestampTz => DatePartTimestampTz(()),
5301 BinaryFunc::DateTruncTimestamp => DateTruncTimestamp(()),
5302 BinaryFunc::DateTruncTimestampTz => DateTruncTimestampTz(()),
5303 BinaryFunc::DateTruncInterval => DateTruncInterval(()),
5304 BinaryFunc::TimezoneTimestamp => TimezoneTimestamp(()),
5305 BinaryFunc::TimezoneTimestampTz => TimezoneTimestampTz(()),
5306 BinaryFunc::TimezoneIntervalTimestamp => TimezoneIntervalTimestamp(()),
5307 BinaryFunc::TimezoneIntervalTimestampTz => TimezoneIntervalTimestampTz(()),
5308 BinaryFunc::TimezoneIntervalTime => TimezoneIntervalTime(()),
5309 BinaryFunc::TimezoneOffset => TimezoneOffset(()),
5310 BinaryFunc::TextConcat => TextConcat(()),
5311 BinaryFunc::JsonbGetInt64 => JsonbGetInt64(()),
5312 BinaryFunc::JsonbGetInt64Stringify => JsonbGetInt64Stringify(()),
5313 BinaryFunc::JsonbGetString => JsonbGetString(()),
5314 BinaryFunc::JsonbGetStringStringify => JsonbGetStringStringify(()),
5315 BinaryFunc::JsonbGetPath => JsonbGetPath(()),
5316 BinaryFunc::JsonbGetPathStringify => JsonbGetPathStringify(()),
5317 BinaryFunc::JsonbContainsString => JsonbContainsString(()),
5318 BinaryFunc::JsonbConcat => JsonbConcat(()),
5319 BinaryFunc::JsonbContainsJsonb => JsonbContainsJsonb(()),
5320 BinaryFunc::JsonbDeleteInt64 => JsonbDeleteInt64(()),
5321 BinaryFunc::JsonbDeleteString => JsonbDeleteString(()),
5322 BinaryFunc::MapContainsKey => MapContainsKey(()),
5323 BinaryFunc::MapGetValue => MapGetValue(()),
5324 BinaryFunc::MapContainsAllKeys => MapContainsAllKeys(()),
5325 BinaryFunc::MapContainsAnyKeys => MapContainsAnyKeys(()),
5326 BinaryFunc::MapContainsMap => MapContainsMap(()),
5327 BinaryFunc::ConvertFrom => ConvertFrom(()),
5328 BinaryFunc::Left => Left(()),
5329 BinaryFunc::Position => Position(()),
5330 BinaryFunc::Right => Right(()),
5331 BinaryFunc::RepeatString => RepeatString(()),
5332 BinaryFunc::Trim => Trim(()),
5333 BinaryFunc::TrimLeading => TrimLeading(()),
5334 BinaryFunc::TrimTrailing => TrimTrailing(()),
5335 BinaryFunc::EncodedBytesCharLength => EncodedBytesCharLength(()),
5336 BinaryFunc::ListLengthMax { max_layer } => ListLengthMax(max_layer.into_proto()),
5337 BinaryFunc::ArrayContains => ArrayContains(()),
5338 BinaryFunc::ArrayContainsArray { rev } => ArrayContainsArray(*rev),
5339 BinaryFunc::ArrayLength => ArrayLength(()),
5340 BinaryFunc::ArrayLower => ArrayLower(()),
5341 BinaryFunc::ArrayRemove => ArrayRemove(()),
5342 BinaryFunc::ArrayUpper => ArrayUpper(()),
5343 BinaryFunc::ArrayArrayConcat => ArrayArrayConcat(()),
5344 BinaryFunc::ListListConcat => ListListConcat(()),
5345 BinaryFunc::ListElementConcat => ListElementConcat(()),
5346 BinaryFunc::ElementListConcat => ElementListConcat(()),
5347 BinaryFunc::ListRemove => ListRemove(()),
5348 BinaryFunc::ListContainsList { rev } => ListContainsList(*rev),
5349 BinaryFunc::DigestString => DigestString(()),
5350 BinaryFunc::DigestBytes => DigestBytes(()),
5351 BinaryFunc::MzRenderTypmod => MzRenderTypmod(()),
5352 BinaryFunc::Encode => Encode(()),
5353 BinaryFunc::Decode => Decode(()),
5354 BinaryFunc::LogNumeric => LogNumeric(()),
5355 BinaryFunc::Power => Power(()),
5356 BinaryFunc::PowerNumeric => PowerNumeric(()),
5357 BinaryFunc::GetBit => GetBit(()),
5358 BinaryFunc::GetByte => GetByte(()),
5359 BinaryFunc::RangeContainsElem { elem_type, rev } => {
5360 RangeContainsElem(crate::scalar::proto_binary_func::ProtoRangeContainsInner {
5361 elem_type: Some(elem_type.into_proto()),
5362 rev: *rev,
5363 })
5364 }
5365 BinaryFunc::RangeContainsRange { rev } => RangeContainsRange(*rev),
5366 BinaryFunc::RangeOverlaps => RangeOverlaps(()),
5367 BinaryFunc::RangeAfter => RangeAfter(()),
5368 BinaryFunc::RangeBefore => RangeBefore(()),
5369 BinaryFunc::RangeOverleft => RangeOverleft(()),
5370 BinaryFunc::RangeOverright => RangeOverright(()),
5371 BinaryFunc::RangeAdjacent => RangeAdjacent(()),
5372 BinaryFunc::RangeUnion => RangeUnion(()),
5373 BinaryFunc::RangeIntersection => RangeIntersection(()),
5374 BinaryFunc::RangeDifference => RangeDifference(()),
5375 BinaryFunc::UuidGenerateV5 => UuidGenerateV5(()),
5376 BinaryFunc::MzAclItemContainsPrivilege => MzAclItemContainsPrivilege(()),
5377 BinaryFunc::ParseIdent => ParseIdent(()),
5378 BinaryFunc::ConstantTimeEqBytes => ConstantTimeEqBytes(()),
5379 BinaryFunc::ConstantTimeEqString => ConstantTimeEqString(()),
5380 BinaryFunc::PrettySql => PrettySql(()),
5381 BinaryFunc::RegexpReplace { regex, limit } => {
5382 use crate::scalar::proto_binary_func::*;
5383 RegexpReplace(ProtoRegexpReplace {
5384 regex: Some(regex.into_proto()),
5385 limit: limit.into_proto(),
5386 })
5387 }
5388 BinaryFunc::StartsWith => StartsWith(()),
5389 };
5390 ProtoBinaryFunc { kind: Some(kind) }
5391 }
5392
5393 fn from_proto(proto: ProtoBinaryFunc) -> Result<Self, TryFromProtoError> {
5394 use crate::scalar::proto_binary_func::Kind::*;
5395 if let Some(kind) = proto.kind {
5396 match kind {
5397 AddInt16(()) => Ok(BinaryFunc::AddInt16),
5398 AddInt32(()) => Ok(BinaryFunc::AddInt32),
5399 AddInt64(()) => Ok(BinaryFunc::AddInt64),
5400 AddUint16(()) => Ok(BinaryFunc::AddUInt16),
5401 AddUint32(()) => Ok(BinaryFunc::AddUInt32),
5402 AddUint64(()) => Ok(BinaryFunc::AddUInt64),
5403 AddFloat32(()) => Ok(BinaryFunc::AddFloat32),
5404 AddFloat64(()) => Ok(BinaryFunc::AddFloat64),
5405 AddInterval(()) => Ok(BinaryFunc::AddInterval),
5406 AddTimestampInterval(()) => Ok(BinaryFunc::AddTimestampInterval),
5407 AddTimestampTzInterval(()) => Ok(BinaryFunc::AddTimestampTzInterval),
5408 AddDateInterval(()) => Ok(BinaryFunc::AddDateInterval),
5409 AddDateTime(()) => Ok(BinaryFunc::AddDateTime),
5410 AddTimeInterval(()) => Ok(BinaryFunc::AddTimeInterval),
5411 AddNumeric(()) => Ok(BinaryFunc::AddNumeric),
5412 AgeTimestamp(()) => Ok(BinaryFunc::AgeTimestamp),
5413 AgeTimestampTz(()) => Ok(BinaryFunc::AgeTimestampTz),
5414 BitAndInt16(()) => Ok(BinaryFunc::BitAndInt16),
5415 BitAndInt32(()) => Ok(BinaryFunc::BitAndInt32),
5416 BitAndInt64(()) => Ok(BinaryFunc::BitAndInt64),
5417 BitAndUint16(()) => Ok(BinaryFunc::BitAndUInt16),
5418 BitAndUint32(()) => Ok(BinaryFunc::BitAndUInt32),
5419 BitAndUint64(()) => Ok(BinaryFunc::BitAndUInt64),
5420 BitOrInt16(()) => Ok(BinaryFunc::BitOrInt16),
5421 BitOrInt32(()) => Ok(BinaryFunc::BitOrInt32),
5422 BitOrInt64(()) => Ok(BinaryFunc::BitOrInt64),
5423 BitOrUint16(()) => Ok(BinaryFunc::BitOrUInt16),
5424 BitOrUint32(()) => Ok(BinaryFunc::BitOrUInt32),
5425 BitOrUint64(()) => Ok(BinaryFunc::BitOrUInt64),
5426 BitXorInt16(()) => Ok(BinaryFunc::BitXorInt16),
5427 BitXorInt32(()) => Ok(BinaryFunc::BitXorInt32),
5428 BitXorInt64(()) => Ok(BinaryFunc::BitXorInt64),
5429 BitXorUint16(()) => Ok(BinaryFunc::BitXorUInt16),
5430 BitXorUint32(()) => Ok(BinaryFunc::BitXorUInt32),
5431 BitXorUint64(()) => Ok(BinaryFunc::BitXorUInt64),
5432 BitShiftLeftInt16(()) => Ok(BinaryFunc::BitShiftLeftInt16),
5433 BitShiftLeftInt32(()) => Ok(BinaryFunc::BitShiftLeftInt32),
5434 BitShiftLeftInt64(()) => Ok(BinaryFunc::BitShiftLeftInt64),
5435 BitShiftLeftUint16(()) => Ok(BinaryFunc::BitShiftLeftUInt16),
5436 BitShiftLeftUint32(()) => Ok(BinaryFunc::BitShiftLeftUInt32),
5437 BitShiftLeftUint64(()) => Ok(BinaryFunc::BitShiftLeftUInt64),
5438 BitShiftRightInt16(()) => Ok(BinaryFunc::BitShiftRightInt16),
5439 BitShiftRightInt32(()) => Ok(BinaryFunc::BitShiftRightInt32),
5440 BitShiftRightInt64(()) => Ok(BinaryFunc::BitShiftRightInt64),
5441 BitShiftRightUint16(()) => Ok(BinaryFunc::BitShiftRightUInt16),
5442 BitShiftRightUint32(()) => Ok(BinaryFunc::BitShiftRightUInt32),
5443 BitShiftRightUint64(()) => Ok(BinaryFunc::BitShiftRightUInt64),
5444 SubInt16(()) => Ok(BinaryFunc::SubInt16),
5445 SubInt32(()) => Ok(BinaryFunc::SubInt32),
5446 SubInt64(()) => Ok(BinaryFunc::SubInt64),
5447 SubUint16(()) => Ok(BinaryFunc::SubUInt16),
5448 SubUint32(()) => Ok(BinaryFunc::SubUInt32),
5449 SubUint64(()) => Ok(BinaryFunc::SubUInt64),
5450 SubFloat32(()) => Ok(BinaryFunc::SubFloat32),
5451 SubFloat64(()) => Ok(BinaryFunc::SubFloat64),
5452 SubInterval(()) => Ok(BinaryFunc::SubInterval),
5453 SubTimestamp(()) => Ok(BinaryFunc::SubTimestamp),
5454 SubTimestampTz(()) => Ok(BinaryFunc::SubTimestampTz),
5455 SubTimestampInterval(()) => Ok(BinaryFunc::SubTimestampInterval),
5456 SubTimestampTzInterval(()) => Ok(BinaryFunc::SubTimestampTzInterval),
5457 SubDate(()) => Ok(BinaryFunc::SubDate),
5458 SubDateInterval(()) => Ok(BinaryFunc::SubDateInterval),
5459 SubTime(()) => Ok(BinaryFunc::SubTime),
5460 SubTimeInterval(()) => Ok(BinaryFunc::SubTimeInterval),
5461 SubNumeric(()) => Ok(BinaryFunc::SubNumeric),
5462 MulInt16(()) => Ok(BinaryFunc::MulInt16),
5463 MulInt32(()) => Ok(BinaryFunc::MulInt32),
5464 MulInt64(()) => Ok(BinaryFunc::MulInt64),
5465 MulUint16(()) => Ok(BinaryFunc::MulUInt16),
5466 MulUint32(()) => Ok(BinaryFunc::MulUInt32),
5467 MulUint64(()) => Ok(BinaryFunc::MulUInt64),
5468 MulFloat32(()) => Ok(BinaryFunc::MulFloat32),
5469 MulFloat64(()) => Ok(BinaryFunc::MulFloat64),
5470 MulNumeric(()) => Ok(BinaryFunc::MulNumeric),
5471 MulInterval(()) => Ok(BinaryFunc::MulInterval),
5472 DivInt16(()) => Ok(BinaryFunc::DivInt16),
5473 DivInt32(()) => Ok(BinaryFunc::DivInt32),
5474 DivInt64(()) => Ok(BinaryFunc::DivInt64),
5475 DivUint16(()) => Ok(BinaryFunc::DivUInt16),
5476 DivUint32(()) => Ok(BinaryFunc::DivUInt32),
5477 DivUint64(()) => Ok(BinaryFunc::DivUInt64),
5478 DivFloat32(()) => Ok(BinaryFunc::DivFloat32),
5479 DivFloat64(()) => Ok(BinaryFunc::DivFloat64),
5480 DivNumeric(()) => Ok(BinaryFunc::DivNumeric),
5481 DivInterval(()) => Ok(BinaryFunc::DivInterval),
5482 ModInt16(()) => Ok(BinaryFunc::ModInt16),
5483 ModInt32(()) => Ok(BinaryFunc::ModInt32),
5484 ModInt64(()) => Ok(BinaryFunc::ModInt64),
5485 ModUint16(()) => Ok(BinaryFunc::ModUInt16),
5486 ModUint32(()) => Ok(BinaryFunc::ModUInt32),
5487 ModUint64(()) => Ok(BinaryFunc::ModUInt64),
5488 ModFloat32(()) => Ok(BinaryFunc::ModFloat32),
5489 ModFloat64(()) => Ok(BinaryFunc::ModFloat64),
5490 ModNumeric(()) => Ok(BinaryFunc::ModNumeric),
5491 RoundNumeric(()) => Ok(BinaryFunc::RoundNumeric),
5492 Eq(()) => Ok(BinaryFunc::Eq),
5493 NotEq(()) => Ok(BinaryFunc::NotEq),
5494 Lt(()) => Ok(BinaryFunc::Lt),
5495 Lte(()) => Ok(BinaryFunc::Lte),
5496 Gt(()) => Ok(BinaryFunc::Gt),
5497 Gte(()) => Ok(BinaryFunc::Gte),
5498 LikeEscape(()) => Ok(BinaryFunc::LikeEscape),
5499 IsLikeMatch(case_insensitive) => Ok(BinaryFunc::IsLikeMatch { case_insensitive }),
5500 IsRegexpMatch(case_insensitive) => {
5501 Ok(BinaryFunc::IsRegexpMatch { case_insensitive })
5502 }
5503 ToCharTimestamp(()) => Ok(BinaryFunc::ToCharTimestamp),
5504 ToCharTimestampTz(()) => Ok(BinaryFunc::ToCharTimestampTz),
5505 DateBinTimestamp(()) => Ok(BinaryFunc::DateBinTimestamp),
5506 DateBinTimestampTz(()) => Ok(BinaryFunc::DateBinTimestampTz),
5507 ExtractInterval(()) => Ok(BinaryFunc::ExtractInterval),
5508 ExtractTime(()) => Ok(BinaryFunc::ExtractTime),
5509 ExtractTimestamp(()) => Ok(BinaryFunc::ExtractTimestamp),
5510 ExtractTimestampTz(()) => Ok(BinaryFunc::ExtractTimestampTz),
5511 ExtractDate(()) => Ok(BinaryFunc::ExtractDate),
5512 DatePartInterval(()) => Ok(BinaryFunc::DatePartInterval),
5513 DatePartTime(()) => Ok(BinaryFunc::DatePartTime),
5514 DatePartTimestamp(()) => Ok(BinaryFunc::DatePartTimestamp),
5515 DatePartTimestampTz(()) => Ok(BinaryFunc::DatePartTimestampTz),
5516 DateTruncTimestamp(()) => Ok(BinaryFunc::DateTruncTimestamp),
5517 DateTruncTimestampTz(()) => Ok(BinaryFunc::DateTruncTimestampTz),
5518 DateTruncInterval(()) => Ok(BinaryFunc::DateTruncInterval),
5519 TimezoneTimestamp(()) => Ok(BinaryFunc::TimezoneTimestamp),
5520 TimezoneTimestampTz(()) => Ok(BinaryFunc::TimezoneTimestampTz),
5521 TimezoneIntervalTimestamp(()) => Ok(BinaryFunc::TimezoneIntervalTimestamp),
5522 TimezoneIntervalTimestampTz(()) => Ok(BinaryFunc::TimezoneIntervalTimestampTz),
5523 TimezoneIntervalTime(()) => Ok(BinaryFunc::TimezoneIntervalTime),
5524 TimezoneOffset(()) => Ok(BinaryFunc::TimezoneOffset),
5525 TextConcat(()) => Ok(BinaryFunc::TextConcat),
5526 JsonbGetInt64(()) => Ok(BinaryFunc::JsonbGetInt64),
5527 JsonbGetInt64Stringify(()) => Ok(BinaryFunc::JsonbGetInt64Stringify),
5528 JsonbGetString(()) => Ok(BinaryFunc::JsonbGetString),
5529 JsonbGetStringStringify(()) => Ok(BinaryFunc::JsonbGetStringStringify),
5530 JsonbGetPath(()) => Ok(BinaryFunc::JsonbGetPath),
5531 JsonbGetPathStringify(()) => Ok(BinaryFunc::JsonbGetPathStringify),
5532 JsonbContainsString(()) => Ok(BinaryFunc::JsonbContainsString),
5533 JsonbConcat(()) => Ok(BinaryFunc::JsonbConcat),
5534 JsonbContainsJsonb(()) => Ok(BinaryFunc::JsonbContainsJsonb),
5535 JsonbDeleteInt64(()) => Ok(BinaryFunc::JsonbDeleteInt64),
5536 JsonbDeleteString(()) => Ok(BinaryFunc::JsonbDeleteString),
5537 MapContainsKey(()) => Ok(BinaryFunc::MapContainsKey),
5538 MapGetValue(()) => Ok(BinaryFunc::MapGetValue),
5539 MapContainsAllKeys(()) => Ok(BinaryFunc::MapContainsAllKeys),
5540 MapContainsAnyKeys(()) => Ok(BinaryFunc::MapContainsAnyKeys),
5541 MapContainsMap(()) => Ok(BinaryFunc::MapContainsMap),
5542 ConvertFrom(()) => Ok(BinaryFunc::ConvertFrom),
5543 Left(()) => Ok(BinaryFunc::Left),
5544 Position(()) => Ok(BinaryFunc::Position),
5545 Right(()) => Ok(BinaryFunc::Right),
5546 RepeatString(()) => Ok(BinaryFunc::RepeatString),
5547 Trim(()) => Ok(BinaryFunc::Trim),
5548 TrimLeading(()) => Ok(BinaryFunc::TrimLeading),
5549 TrimTrailing(()) => Ok(BinaryFunc::TrimTrailing),
5550 EncodedBytesCharLength(()) => Ok(BinaryFunc::EncodedBytesCharLength),
5551 ListLengthMax(max_layer) => Ok(BinaryFunc::ListLengthMax {
5552 max_layer: max_layer.into_rust()?,
5553 }),
5554 ArrayContains(()) => Ok(BinaryFunc::ArrayContains),
5555 ArrayContainsArray(rev) => Ok(BinaryFunc::ArrayContainsArray { rev }),
5556 ArrayLength(()) => Ok(BinaryFunc::ArrayLength),
5557 ArrayLower(()) => Ok(BinaryFunc::ArrayLower),
5558 ArrayRemove(()) => Ok(BinaryFunc::ArrayRemove),
5559 ArrayUpper(()) => Ok(BinaryFunc::ArrayUpper),
5560 ArrayArrayConcat(()) => Ok(BinaryFunc::ArrayArrayConcat),
5561 ListListConcat(()) => Ok(BinaryFunc::ListListConcat),
5562 ListElementConcat(()) => Ok(BinaryFunc::ListElementConcat),
5563 ElementListConcat(()) => Ok(BinaryFunc::ElementListConcat),
5564 ListRemove(()) => Ok(BinaryFunc::ListRemove),
5565 ListContainsList(rev) => Ok(BinaryFunc::ListContainsList { rev }),
5566 DigestString(()) => Ok(BinaryFunc::DigestString),
5567 DigestBytes(()) => Ok(BinaryFunc::DigestBytes),
5568 MzRenderTypmod(()) => Ok(BinaryFunc::MzRenderTypmod),
5569 Encode(()) => Ok(BinaryFunc::Encode),
5570 Decode(()) => Ok(BinaryFunc::Decode),
5571 LogNumeric(()) => Ok(BinaryFunc::LogNumeric),
5572 Power(()) => Ok(BinaryFunc::Power),
5573 PowerNumeric(()) => Ok(BinaryFunc::PowerNumeric),
5574 GetBit(()) => Ok(BinaryFunc::GetBit),
5575 GetByte(()) => Ok(BinaryFunc::GetByte),
5576 RangeContainsElem(inner) => Ok(BinaryFunc::RangeContainsElem {
5577 elem_type: inner
5578 .elem_type
5579 .into_rust_if_some("ProtoRangeContainsInner::elem_type")?,
5580 rev: inner.rev,
5581 }),
5582 RangeContainsRange(rev) => Ok(BinaryFunc::RangeContainsRange { rev }),
5583 RangeOverlaps(()) => Ok(BinaryFunc::RangeOverlaps),
5584 RangeAfter(()) => Ok(BinaryFunc::RangeAfter),
5585 RangeBefore(()) => Ok(BinaryFunc::RangeBefore),
5586 RangeOverleft(()) => Ok(BinaryFunc::RangeOverleft),
5587 RangeOverright(()) => Ok(BinaryFunc::RangeOverright),
5588 RangeAdjacent(()) => Ok(BinaryFunc::RangeAdjacent),
5589 RangeUnion(()) => Ok(BinaryFunc::RangeUnion),
5590 RangeIntersection(()) => Ok(BinaryFunc::RangeIntersection),
5591 RangeDifference(()) => Ok(BinaryFunc::RangeDifference),
5592 UuidGenerateV5(()) => Ok(BinaryFunc::UuidGenerateV5),
5593 MzAclItemContainsPrivilege(()) => Ok(BinaryFunc::MzAclItemContainsPrivilege),
5594 ParseIdent(()) => Ok(BinaryFunc::ParseIdent),
5595 ConstantTimeEqBytes(()) => Ok(BinaryFunc::ConstantTimeEqBytes),
5596 ConstantTimeEqString(()) => Ok(BinaryFunc::ConstantTimeEqString),
5597 PrettySql(()) => Ok(BinaryFunc::PrettySql),
5598 RegexpReplace(inner) => Ok(BinaryFunc::RegexpReplace {
5599 regex: inner.regex.into_rust_if_some("ProtoRegexReplace::regex")?,
5600 limit: inner.limit.into_rust()?,
5601 }),
5602 StartsWith(()) => Ok(BinaryFunc::StartsWith),
5603 }
5604 } else {
5605 Err(TryFromProtoError::missing_field("ProtoBinaryFunc::kind"))
5606 }
5607 }
5608}
5609
5610trait LazyUnaryFunc {
5613 fn eval<'a>(
5614 &'a self,
5615 datums: &[Datum<'a>],
5616 temp_storage: &'a RowArena,
5617 a: &'a MirScalarExpr,
5618 ) -> Result<Datum<'a>, EvalError>;
5619
5620 fn output_type(&self, input_type: ColumnType) -> ColumnType;
5622
5623 fn propagates_nulls(&self) -> bool;
5625
5626 fn introduces_nulls(&self) -> bool;
5628
5629 fn could_error(&self) -> bool {
5631 true
5633 }
5634
5635 fn preserves_uniqueness(&self) -> bool;
5648
5649 fn inverse(&self) -> Option<crate::UnaryFunc>;
5677
5678 fn is_monotone(&self) -> bool;
5685}
5686
5687trait EagerUnaryFunc<'a> {
5689 type Input: DatumType<'a, EvalError>;
5690 type Output: DatumType<'a, EvalError>;
5691
5692 fn call(&self, input: Self::Input) -> Self::Output;
5693
5694 fn output_type(&self, input_type: ColumnType) -> ColumnType;
5696
5697 fn propagates_nulls(&self) -> bool {
5699 !Self::Input::nullable()
5701 }
5702
5703 fn introduces_nulls(&self) -> bool {
5705 Self::Output::nullable()
5707 }
5708
5709 fn could_error(&self) -> bool {
5711 Self::Output::fallible()
5712 }
5713
5714 fn preserves_uniqueness(&self) -> bool {
5716 false
5717 }
5718
5719 fn inverse(&self) -> Option<crate::UnaryFunc> {
5720 None
5721 }
5722
5723 fn is_monotone(&self) -> bool {
5724 false
5725 }
5726}
5727
5728impl<T: for<'a> EagerUnaryFunc<'a>> LazyUnaryFunc for T {
5729 fn eval<'a>(
5730 &'a self,
5731 datums: &[Datum<'a>],
5732 temp_storage: &'a RowArena,
5733 a: &'a MirScalarExpr,
5734 ) -> Result<Datum<'a>, EvalError> {
5735 match T::Input::try_from_result(a.eval(datums, temp_storage)) {
5736 Ok(input) => self.call(input).into_result(temp_storage),
5738 Err(Ok(datum)) if !datum.is_null() => {
5740 Err(EvalError::Internal("invalid input type".into()))
5741 }
5742 Err(res) => res,
5744 }
5745 }
5746
5747 fn output_type(&self, input_type: ColumnType) -> ColumnType {
5748 self.output_type(input_type)
5749 }
5750
5751 fn propagates_nulls(&self) -> bool {
5752 self.propagates_nulls()
5753 }
5754
5755 fn introduces_nulls(&self) -> bool {
5756 self.introduces_nulls()
5757 }
5758
5759 fn could_error(&self) -> bool {
5760 self.could_error()
5761 }
5762
5763 fn preserves_uniqueness(&self) -> bool {
5764 self.preserves_uniqueness()
5765 }
5766
5767 fn inverse(&self) -> Option<crate::UnaryFunc> {
5768 self.inverse()
5769 }
5770
5771 fn is_monotone(&self) -> bool {
5772 self.is_monotone()
5773 }
5774}
5775
5776derive_unary!(
5777 Not,
5778 IsNull,
5779 IsTrue,
5780 IsFalse,
5781 BitNotInt16,
5782 BitNotInt32,
5783 BitNotInt64,
5784 BitNotUint16,
5785 BitNotUint32,
5786 BitNotUint64,
5787 NegInt16,
5788 NegInt32,
5789 NegInt64,
5790 NegFloat32,
5791 NegFloat64,
5792 NegNumeric,
5793 NegInterval,
5794 SqrtFloat64,
5795 SqrtNumeric,
5796 CbrtFloat64,
5797 AbsInt16,
5798 AbsInt32,
5799 AbsInt64,
5800 AbsFloat32,
5801 AbsFloat64,
5802 AbsNumeric,
5803 CastBoolToString,
5804 CastBoolToStringNonstandard,
5805 CastBoolToInt32,
5806 CastBoolToInt64,
5807 CastInt16ToFloat32,
5808 CastInt16ToFloat64,
5809 CastInt16ToInt32,
5810 CastInt16ToInt64,
5811 CastInt16ToUint16,
5812 CastInt16ToUint32,
5813 CastInt16ToUint64,
5814 CastInt16ToString,
5815 CastInt2VectorToArray,
5816 CastInt32ToBool,
5817 CastInt32ToFloat32,
5818 CastInt32ToFloat64,
5819 CastInt32ToOid,
5820 CastInt32ToPgLegacyChar,
5821 CastInt32ToInt16,
5822 CastInt32ToInt64,
5823 CastInt32ToUint16,
5824 CastInt32ToUint32,
5825 CastInt32ToUint64,
5826 CastInt32ToString,
5827 CastOidToInt32,
5828 CastOidToInt64,
5829 CastOidToString,
5830 CastOidToRegClass,
5831 CastRegClassToOid,
5832 CastOidToRegProc,
5833 CastRegProcToOid,
5834 CastOidToRegType,
5835 CastRegTypeToOid,
5836 CastInt64ToInt16,
5837 CastInt64ToInt32,
5838 CastInt64ToUint16,
5839 CastInt64ToUint32,
5840 CastInt64ToUint64,
5841 CastInt16ToNumeric,
5842 CastInt32ToNumeric,
5843 CastInt64ToBool,
5844 CastInt64ToNumeric,
5845 CastInt64ToFloat32,
5846 CastInt64ToFloat64,
5847 CastInt64ToOid,
5848 CastInt64ToString,
5849 CastUint16ToUint32,
5850 CastUint16ToUint64,
5851 CastUint16ToInt16,
5852 CastUint16ToInt32,
5853 CastUint16ToInt64,
5854 CastUint16ToNumeric,
5855 CastUint16ToFloat32,
5856 CastUint16ToFloat64,
5857 CastUint16ToString,
5858 CastUint32ToUint16,
5859 CastUint32ToUint64,
5860 CastUint32ToInt16,
5861 CastUint32ToInt32,
5862 CastUint32ToInt64,
5863 CastUint32ToNumeric,
5864 CastUint32ToFloat32,
5865 CastUint32ToFloat64,
5866 CastUint32ToString,
5867 CastUint64ToUint16,
5868 CastUint64ToUint32,
5869 CastUint64ToInt16,
5870 CastUint64ToInt32,
5871 CastUint64ToInt64,
5872 CastUint64ToNumeric,
5873 CastUint64ToFloat32,
5874 CastUint64ToFloat64,
5875 CastUint64ToString,
5876 CastFloat32ToInt16,
5877 CastFloat32ToInt32,
5878 CastFloat32ToInt64,
5879 CastFloat32ToUint16,
5880 CastFloat32ToUint32,
5881 CastFloat32ToUint64,
5882 CastFloat32ToFloat64,
5883 CastFloat32ToString,
5884 CastFloat32ToNumeric,
5885 CastFloat64ToNumeric,
5886 CastFloat64ToInt16,
5887 CastFloat64ToInt32,
5888 CastFloat64ToInt64,
5889 CastFloat64ToUint16,
5890 CastFloat64ToUint32,
5891 CastFloat64ToUint64,
5892 CastFloat64ToFloat32,
5893 CastFloat64ToString,
5894 CastNumericToFloat32,
5895 CastNumericToFloat64,
5896 CastNumericToInt16,
5897 CastNumericToInt32,
5898 CastNumericToInt64,
5899 CastNumericToUint16,
5900 CastNumericToUint32,
5901 CastNumericToUint64,
5902 CastNumericToString,
5903 CastMzTimestampToString,
5904 CastMzTimestampToTimestamp,
5905 CastMzTimestampToTimestampTz,
5906 CastStringToMzTimestamp,
5907 CastUint64ToMzTimestamp,
5908 CastUint32ToMzTimestamp,
5909 CastInt64ToMzTimestamp,
5910 CastInt32ToMzTimestamp,
5911 CastNumericToMzTimestamp,
5912 CastTimestampToMzTimestamp,
5913 CastTimestampTzToMzTimestamp,
5914 CastDateToMzTimestamp,
5915 CastStringToBool,
5916 CastStringToPgLegacyChar,
5917 CastStringToPgLegacyName,
5918 CastStringToBytes,
5919 CastStringToInt16,
5920 CastStringToInt32,
5921 CastStringToInt64,
5922 CastStringToUint16,
5923 CastStringToUint32,
5924 CastStringToUint64,
5925 CastStringToInt2Vector,
5926 CastStringToOid,
5927 CastStringToFloat32,
5928 CastStringToFloat64,
5929 CastStringToDate,
5930 CastStringToArray,
5931 CastStringToList,
5932 CastStringToMap,
5933 CastStringToRange,
5934 CastStringToTime,
5935 CastStringToTimestamp,
5936 CastStringToTimestampTz,
5937 CastStringToInterval,
5938 CastStringToNumeric,
5939 CastStringToUuid,
5940 CastStringToChar,
5941 PadChar,
5942 CastStringToVarChar,
5943 CastCharToString,
5944 CastVarCharToString,
5945 CastDateToTimestamp,
5946 CastDateToTimestampTz,
5947 CastDateToString,
5948 CastTimeToInterval,
5949 CastTimeToString,
5950 CastIntervalToString,
5951 CastIntervalToTime,
5952 CastTimestampToDate,
5953 AdjustTimestampPrecision,
5954 CastTimestampToTimestampTz,
5955 CastTimestampToString,
5956 CastTimestampToTime,
5957 CastTimestampTzToDate,
5958 CastTimestampTzToTimestamp,
5959 AdjustTimestampTzPrecision,
5960 CastTimestampTzToString,
5961 CastTimestampTzToTime,
5962 CastPgLegacyCharToString,
5963 CastPgLegacyCharToChar,
5964 CastPgLegacyCharToVarChar,
5965 CastPgLegacyCharToInt32,
5966 CastBytesToString,
5967 CastStringToJsonb,
5968 CastJsonbToString,
5969 CastJsonbableToJsonb,
5970 CastJsonbToInt16,
5971 CastJsonbToInt32,
5972 CastJsonbToInt64,
5973 CastJsonbToFloat32,
5974 CastJsonbToFloat64,
5975 CastJsonbToNumeric,
5976 CastJsonbToBool,
5977 CastUuidToString,
5978 CastRecordToString,
5979 CastRecord1ToRecord2,
5980 CastArrayToArray,
5981 CastArrayToJsonb,
5982 CastArrayToString,
5983 CastListToString,
5984 CastListToJsonb,
5985 CastList1ToList2,
5986 CastArrayToListOneDim,
5987 CastMapToString,
5988 CastInt2VectorToString,
5989 CastRangeToString,
5990 CeilFloat32,
5991 CeilFloat64,
5992 CeilNumeric,
5993 FloorFloat32,
5994 FloorFloat64,
5995 FloorNumeric,
5996 Ascii,
5997 BitCountBytes,
5998 BitLengthBytes,
5999 BitLengthString,
6000 ByteLengthBytes,
6001 ByteLengthString,
6002 CharLength,
6003 Chr,
6004 IsLikeMatch,
6005 IsRegexpMatch,
6006 RegexpMatch,
6007 ExtractInterval,
6008 ExtractTime,
6009 ExtractTimestamp,
6010 ExtractTimestampTz,
6011 ExtractDate,
6012 DatePartInterval,
6013 DatePartTime,
6014 DatePartTimestamp,
6015 DatePartTimestampTz,
6016 DateTruncTimestamp,
6017 DateTruncTimestampTz,
6018 TimezoneTimestamp,
6019 TimezoneTimestampTz,
6020 TimezoneTime,
6021 ToTimestamp,
6022 ToCharTimestamp,
6023 ToCharTimestampTz,
6024 JustifyDays,
6025 JustifyHours,
6026 JustifyInterval,
6027 JsonbArrayLength,
6028 JsonbTypeof,
6029 JsonbStripNulls,
6030 JsonbPretty,
6031 RoundFloat32,
6032 RoundFloat64,
6033 RoundNumeric,
6034 TruncFloat32,
6035 TruncFloat64,
6036 TruncNumeric,
6037 TrimWhitespace,
6038 TrimLeadingWhitespace,
6039 TrimTrailingWhitespace,
6040 Initcap,
6041 RecordGet,
6042 ListLength,
6043 MapLength,
6044 MapBuildFromRecordList,
6045 Upper,
6046 Lower,
6047 Cos,
6048 Acos,
6049 Cosh,
6050 Acosh,
6051 Sin,
6052 Asin,
6053 Sinh,
6054 Asinh,
6055 Tan,
6056 Atan,
6057 Tanh,
6058 Atanh,
6059 Cot,
6060 Degrees,
6061 Radians,
6062 Log10,
6063 Log10Numeric,
6064 Ln,
6065 LnNumeric,
6066 Exp,
6067 ExpNumeric,
6068 Sleep,
6069 Panic,
6070 AdjustNumericScale,
6071 PgColumnSize,
6072 MzRowSize,
6073 MzTypeName,
6074 StepMzTimestamp,
6075 RangeLower,
6076 RangeUpper,
6077 RangeEmpty,
6078 RangeLowerInc,
6079 RangeUpperInc,
6080 RangeLowerInf,
6081 RangeUpperInf,
6082 MzAclItemGrantor,
6083 MzAclItemGrantee,
6084 MzAclItemPrivileges,
6085 MzFormatPrivileges,
6086 MzValidatePrivileges,
6087 MzValidateRolePrivilege,
6088 AclItemGrantor,
6089 AclItemGrantee,
6090 AclItemPrivileges,
6091 QuoteIdent,
6092 TryParseMonotonicIso8601Timestamp,
6093 RegexpSplitToArray,
6094 PgSizePretty,
6095 Crc32Bytes,
6096 Crc32String,
6097 KafkaMurmur2Bytes,
6098 KafkaMurmur2String,
6099 SeahashBytes,
6100 SeahashString,
6101 Reverse
6102);
6103
6104impl UnaryFunc {
6105 pub fn is(&self) -> Option<&'static str> {
6109 match self {
6110 UnaryFunc::IsNull(_) => Some("NULL"),
6111 UnaryFunc::IsTrue(_) => Some("TRUE"),
6112 UnaryFunc::IsFalse(_) => Some("FALSE"),
6113 _ => None,
6114 }
6115 }
6116}
6117
6118impl Arbitrary for UnaryFunc {
6125 type Parameters = ();
6126
6127 type Strategy = Union<BoxedStrategy<Self>>;
6128
6129 fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
6130 Union::new(vec![
6131 Not::arbitrary().prop_map_into().boxed(),
6132 IsNull::arbitrary().prop_map_into().boxed(),
6133 IsTrue::arbitrary().prop_map_into().boxed(),
6134 IsFalse::arbitrary().prop_map_into().boxed(),
6135 BitNotInt16::arbitrary().prop_map_into().boxed(),
6136 BitNotInt32::arbitrary().prop_map_into().boxed(),
6137 BitNotInt64::arbitrary().prop_map_into().boxed(),
6138 BitNotUint16::arbitrary().prop_map_into().boxed(),
6139 BitNotUint32::arbitrary().prop_map_into().boxed(),
6140 BitNotUint64::arbitrary().prop_map_into().boxed(),
6141 NegInt16::arbitrary().prop_map_into().boxed(),
6142 NegInt32::arbitrary().prop_map_into().boxed(),
6143 NegInt64::arbitrary().prop_map_into().boxed(),
6144 NegFloat32::arbitrary().prop_map_into().boxed(),
6145 NegFloat64::arbitrary().prop_map_into().boxed(),
6146 NegNumeric::arbitrary().prop_map_into().boxed(),
6147 NegInterval::arbitrary().prop_map_into().boxed(),
6148 SqrtFloat64::arbitrary().prop_map_into().boxed(),
6149 SqrtNumeric::arbitrary().prop_map_into().boxed(),
6150 CbrtFloat64::arbitrary().prop_map_into().boxed(),
6151 AbsInt16::arbitrary().prop_map_into().boxed(),
6152 AbsInt32::arbitrary().prop_map_into().boxed(),
6153 AbsInt64::arbitrary().prop_map_into().boxed(),
6154 AbsFloat32::arbitrary().prop_map_into().boxed(),
6155 AbsFloat64::arbitrary().prop_map_into().boxed(),
6156 AbsNumeric::arbitrary().prop_map_into().boxed(),
6157 CastBoolToString::arbitrary().prop_map_into().boxed(),
6158 CastBoolToStringNonstandard::arbitrary()
6159 .prop_map_into()
6160 .boxed(),
6161 CastBoolToInt32::arbitrary().prop_map_into().boxed(),
6162 CastBoolToInt64::arbitrary().prop_map_into().boxed(),
6163 CastInt16ToFloat32::arbitrary().prop_map_into().boxed(),
6164 CastInt16ToFloat64::arbitrary().prop_map_into().boxed(),
6165 CastInt16ToInt32::arbitrary().prop_map_into().boxed(),
6166 CastInt16ToInt64::arbitrary().prop_map_into().boxed(),
6167 CastInt16ToUint16::arbitrary().prop_map_into().boxed(),
6168 CastInt16ToUint32::arbitrary().prop_map_into().boxed(),
6169 CastInt16ToUint64::arbitrary().prop_map_into().boxed(),
6170 CastInt16ToString::arbitrary().prop_map_into().boxed(),
6171 CastInt2VectorToArray::arbitrary().prop_map_into().boxed(),
6172 CastInt32ToBool::arbitrary().prop_map_into().boxed(),
6173 CastInt32ToFloat32::arbitrary().prop_map_into().boxed(),
6174 CastInt32ToFloat64::arbitrary().prop_map_into().boxed(),
6175 CastInt32ToOid::arbitrary().prop_map_into().boxed(),
6176 CastInt32ToPgLegacyChar::arbitrary().prop_map_into().boxed(),
6177 CastInt32ToInt16::arbitrary().prop_map_into().boxed(),
6178 CastInt32ToInt64::arbitrary().prop_map_into().boxed(),
6179 CastInt32ToUint16::arbitrary().prop_map_into().boxed(),
6180 CastInt32ToUint32::arbitrary().prop_map_into().boxed(),
6181 CastInt32ToUint64::arbitrary().prop_map_into().boxed(),
6182 CastInt32ToString::arbitrary().prop_map_into().boxed(),
6183 CastOidToInt32::arbitrary().prop_map_into().boxed(),
6184 CastOidToInt64::arbitrary().prop_map_into().boxed(),
6185 CastOidToString::arbitrary().prop_map_into().boxed(),
6186 CastOidToRegClass::arbitrary().prop_map_into().boxed(),
6187 CastRegClassToOid::arbitrary().prop_map_into().boxed(),
6188 CastOidToRegProc::arbitrary().prop_map_into().boxed(),
6189 CastRegProcToOid::arbitrary().prop_map_into().boxed(),
6190 CastOidToRegType::arbitrary().prop_map_into().boxed(),
6191 CastRegTypeToOid::arbitrary().prop_map_into().boxed(),
6192 CastInt64ToInt16::arbitrary().prop_map_into().boxed(),
6193 CastInt64ToInt32::arbitrary().prop_map_into().boxed(),
6194 CastInt64ToUint16::arbitrary().prop_map_into().boxed(),
6195 CastInt64ToUint32::arbitrary().prop_map_into().boxed(),
6196 CastInt64ToUint64::arbitrary().prop_map_into().boxed(),
6197 any::<Option<NumericMaxScale>>()
6198 .prop_map(|i| UnaryFunc::CastInt16ToNumeric(CastInt16ToNumeric(i)))
6199 .boxed(),
6200 any::<Option<NumericMaxScale>>()
6201 .prop_map(|i| UnaryFunc::CastInt32ToNumeric(CastInt32ToNumeric(i)))
6202 .boxed(),
6203 CastInt64ToBool::arbitrary().prop_map_into().boxed(),
6204 any::<Option<NumericMaxScale>>()
6205 .prop_map(|i| UnaryFunc::CastInt64ToNumeric(CastInt64ToNumeric(i)))
6206 .boxed(),
6207 CastInt64ToFloat32::arbitrary().prop_map_into().boxed(),
6208 CastInt64ToFloat64::arbitrary().prop_map_into().boxed(),
6209 CastInt64ToOid::arbitrary().prop_map_into().boxed(),
6210 CastInt64ToString::arbitrary().prop_map_into().boxed(),
6211 CastUint16ToUint32::arbitrary().prop_map_into().boxed(),
6212 CastUint16ToUint64::arbitrary().prop_map_into().boxed(),
6213 CastUint16ToInt16::arbitrary().prop_map_into().boxed(),
6214 CastUint16ToInt32::arbitrary().prop_map_into().boxed(),
6215 CastUint16ToInt64::arbitrary().prop_map_into().boxed(),
6216 any::<Option<NumericMaxScale>>()
6217 .prop_map(|i| UnaryFunc::CastUint16ToNumeric(CastUint16ToNumeric(i)))
6218 .boxed(),
6219 CastUint16ToFloat32::arbitrary().prop_map_into().boxed(),
6220 CastUint16ToFloat64::arbitrary().prop_map_into().boxed(),
6221 CastUint16ToString::arbitrary().prop_map_into().boxed(),
6222 CastUint32ToUint16::arbitrary().prop_map_into().boxed(),
6223 CastUint32ToUint64::arbitrary().prop_map_into().boxed(),
6224 CastUint32ToInt32::arbitrary().prop_map_into().boxed(),
6225 CastUint32ToInt64::arbitrary().prop_map_into().boxed(),
6226 any::<Option<NumericMaxScale>>()
6227 .prop_map(|i| UnaryFunc::CastUint32ToNumeric(CastUint32ToNumeric(i)))
6228 .boxed(),
6229 CastUint32ToFloat32::arbitrary().prop_map_into().boxed(),
6230 CastUint32ToFloat64::arbitrary().prop_map_into().boxed(),
6231 CastUint32ToString::arbitrary().prop_map_into().boxed(),
6232 CastUint64ToUint16::arbitrary().prop_map_into().boxed(),
6233 CastUint64ToUint32::arbitrary().prop_map_into().boxed(),
6234 CastUint64ToInt32::arbitrary().prop_map_into().boxed(),
6235 CastUint64ToInt64::arbitrary().prop_map_into().boxed(),
6236 any::<Option<NumericMaxScale>>()
6237 .prop_map(|i| UnaryFunc::CastUint64ToNumeric(CastUint64ToNumeric(i)))
6238 .boxed(),
6239 CastUint64ToFloat32::arbitrary().prop_map_into().boxed(),
6240 CastUint64ToFloat64::arbitrary().prop_map_into().boxed(),
6241 CastUint64ToString::arbitrary().prop_map_into().boxed(),
6242 CastFloat32ToInt16::arbitrary().prop_map_into().boxed(),
6243 CastFloat32ToInt32::arbitrary().prop_map_into().boxed(),
6244 CastFloat32ToInt64::arbitrary().prop_map_into().boxed(),
6245 CastFloat32ToUint16::arbitrary().prop_map_into().boxed(),
6246 CastFloat32ToUint32::arbitrary().prop_map_into().boxed(),
6247 CastFloat32ToUint64::arbitrary().prop_map_into().boxed(),
6248 CastFloat32ToFloat64::arbitrary().prop_map_into().boxed(),
6249 CastFloat32ToString::arbitrary().prop_map_into().boxed(),
6250 any::<Option<NumericMaxScale>>()
6251 .prop_map(|i| UnaryFunc::CastFloat32ToNumeric(CastFloat32ToNumeric(i)))
6252 .boxed(),
6253 any::<Option<NumericMaxScale>>()
6254 .prop_map(|i| UnaryFunc::CastFloat64ToNumeric(CastFloat64ToNumeric(i)))
6255 .boxed(),
6256 CastFloat64ToInt16::arbitrary().prop_map_into().boxed(),
6257 CastFloat64ToInt32::arbitrary().prop_map_into().boxed(),
6258 CastFloat64ToInt64::arbitrary().prop_map_into().boxed(),
6259 CastFloat64ToUint16::arbitrary().prop_map_into().boxed(),
6260 CastFloat64ToUint32::arbitrary().prop_map_into().boxed(),
6261 CastFloat64ToUint64::arbitrary().prop_map_into().boxed(),
6262 CastFloat64ToFloat32::arbitrary().prop_map_into().boxed(),
6263 CastFloat64ToString::arbitrary().prop_map_into().boxed(),
6264 CastNumericToFloat32::arbitrary().prop_map_into().boxed(),
6265 CastNumericToFloat64::arbitrary().prop_map_into().boxed(),
6266 CastNumericToInt16::arbitrary().prop_map_into().boxed(),
6267 CastNumericToInt32::arbitrary().prop_map_into().boxed(),
6268 CastNumericToInt64::arbitrary().prop_map_into().boxed(),
6269 CastNumericToUint16::arbitrary().prop_map_into().boxed(),
6270 CastNumericToUint32::arbitrary().prop_map_into().boxed(),
6271 CastNumericToUint64::arbitrary().prop_map_into().boxed(),
6272 CastNumericToString::arbitrary().prop_map_into().boxed(),
6273 CastStringToBool::arbitrary().prop_map_into().boxed(),
6274 CastStringToPgLegacyChar::arbitrary()
6275 .prop_map_into()
6276 .boxed(),
6277 CastStringToPgLegacyName::arbitrary()
6278 .prop_map_into()
6279 .boxed(),
6280 CastStringToBytes::arbitrary().prop_map_into().boxed(),
6281 CastStringToInt16::arbitrary().prop_map_into().boxed(),
6282 CastStringToInt32::arbitrary().prop_map_into().boxed(),
6283 CastStringToInt64::arbitrary().prop_map_into().boxed(),
6284 CastStringToUint16::arbitrary().prop_map_into().boxed(),
6285 CastStringToUint32::arbitrary().prop_map_into().boxed(),
6286 CastStringToUint64::arbitrary().prop_map_into().boxed(),
6287 CastStringToInt2Vector::arbitrary().prop_map_into().boxed(),
6288 CastStringToOid::arbitrary().prop_map_into().boxed(),
6289 CastStringToFloat32::arbitrary().prop_map_into().boxed(),
6290 CastStringToFloat64::arbitrary().prop_map_into().boxed(),
6291 CastStringToDate::arbitrary().prop_map_into().boxed(),
6292 (any::<ScalarType>(), any::<MirScalarExpr>())
6293 .prop_map(|(return_ty, expr)| {
6294 UnaryFunc::CastStringToArray(CastStringToArray {
6295 return_ty,
6296 cast_expr: Box::new(expr),
6297 })
6298 })
6299 .boxed(),
6300 (any::<ScalarType>(), any::<MirScalarExpr>())
6301 .prop_map(|(return_ty, expr)| {
6302 UnaryFunc::CastStringToList(CastStringToList {
6303 return_ty,
6304 cast_expr: Box::new(expr),
6305 })
6306 })
6307 .boxed(),
6308 (any::<ScalarType>(), any::<MirScalarExpr>())
6309 .prop_map(|(return_ty, expr)| {
6310 UnaryFunc::CastStringToMap(CastStringToMap {
6311 return_ty,
6312 cast_expr: Box::new(expr),
6313 })
6314 })
6315 .boxed(),
6316 (any::<ScalarType>(), any::<MirScalarExpr>())
6317 .prop_map(|(return_ty, expr)| {
6318 UnaryFunc::CastStringToRange(CastStringToRange {
6319 return_ty,
6320 cast_expr: Box::new(expr),
6321 })
6322 })
6323 .boxed(),
6324 CastStringToTime::arbitrary().prop_map_into().boxed(),
6325 CastStringToTimestamp::arbitrary().prop_map_into().boxed(),
6326 CastStringToTimestampTz::arbitrary().prop_map_into().boxed(),
6327 CastStringToInterval::arbitrary().prop_map_into().boxed(),
6328 CastStringToNumeric::arbitrary().prop_map_into().boxed(),
6329 CastStringToUuid::arbitrary().prop_map_into().boxed(),
6330 CastStringToChar::arbitrary().prop_map_into().boxed(),
6331 PadChar::arbitrary().prop_map_into().boxed(),
6332 CastStringToVarChar::arbitrary().prop_map_into().boxed(),
6333 CastCharToString::arbitrary().prop_map_into().boxed(),
6334 CastVarCharToString::arbitrary().prop_map_into().boxed(),
6335 CastDateToTimestamp::arbitrary().prop_map_into().boxed(),
6336 CastDateToTimestampTz::arbitrary().prop_map_into().boxed(),
6337 CastDateToString::arbitrary().prop_map_into().boxed(),
6338 CastTimeToInterval::arbitrary().prop_map_into().boxed(),
6339 CastTimeToString::arbitrary().prop_map_into().boxed(),
6340 CastIntervalToString::arbitrary().prop_map_into().boxed(),
6341 CastIntervalToTime::arbitrary().prop_map_into().boxed(),
6342 CastTimestampToDate::arbitrary().prop_map_into().boxed(),
6343 CastTimestampToTimestampTz::arbitrary()
6344 .prop_map_into()
6345 .boxed(),
6346 CastTimestampToString::arbitrary().prop_map_into().boxed(),
6347 CastTimestampToTime::arbitrary().prop_map_into().boxed(),
6348 CastTimestampTzToDate::arbitrary().prop_map_into().boxed(),
6349 CastTimestampTzToTimestamp::arbitrary()
6350 .prop_map_into()
6351 .boxed(),
6352 CastTimestampTzToString::arbitrary().prop_map_into().boxed(),
6353 CastTimestampTzToTime::arbitrary().prop_map_into().boxed(),
6354 CastPgLegacyCharToString::arbitrary()
6355 .prop_map_into()
6356 .boxed(),
6357 CastPgLegacyCharToChar::arbitrary().prop_map_into().boxed(),
6358 CastPgLegacyCharToVarChar::arbitrary()
6359 .prop_map_into()
6360 .boxed(),
6361 CastPgLegacyCharToInt32::arbitrary().prop_map_into().boxed(),
6362 CastBytesToString::arbitrary().prop_map_into().boxed(),
6363 CastStringToJsonb::arbitrary().prop_map_into().boxed(),
6364 CastJsonbToString::arbitrary().prop_map_into().boxed(),
6365 CastJsonbableToJsonb::arbitrary().prop_map_into().boxed(),
6366 CastJsonbToInt16::arbitrary().prop_map_into().boxed(),
6367 CastJsonbToInt32::arbitrary().prop_map_into().boxed(),
6368 CastJsonbToInt64::arbitrary().prop_map_into().boxed(),
6369 CastJsonbToFloat32::arbitrary().prop_map_into().boxed(),
6370 CastJsonbToFloat64::arbitrary().prop_map_into().boxed(),
6371 CastJsonbToNumeric::arbitrary().prop_map_into().boxed(),
6372 CastJsonbToBool::arbitrary().prop_map_into().boxed(),
6373 CastUuidToString::arbitrary().prop_map_into().boxed(),
6374 CastRecordToString::arbitrary().prop_map_into().boxed(),
6375 (
6376 any::<ScalarType>(),
6377 proptest::collection::vec(any::<MirScalarExpr>(), 1..5),
6378 )
6379 .prop_map(|(return_ty, cast_exprs)| {
6380 UnaryFunc::CastRecord1ToRecord2(CastRecord1ToRecord2 {
6381 return_ty,
6382 cast_exprs: cast_exprs.into(),
6383 })
6384 })
6385 .boxed(),
6386 CastArrayToJsonb::arbitrary().prop_map_into().boxed(),
6387 CastArrayToString::arbitrary().prop_map_into().boxed(),
6388 CastListToString::arbitrary().prop_map_into().boxed(),
6389 CastListToJsonb::arbitrary().prop_map_into().boxed(),
6390 (any::<ScalarType>(), any::<MirScalarExpr>())
6391 .prop_map(|(return_ty, expr)| {
6392 UnaryFunc::CastList1ToList2(CastList1ToList2 {
6393 return_ty,
6394 cast_expr: Box::new(expr),
6395 })
6396 })
6397 .boxed(),
6398 CastArrayToListOneDim::arbitrary().prop_map_into().boxed(),
6399 CastMapToString::arbitrary().prop_map_into().boxed(),
6400 CastInt2VectorToString::arbitrary().prop_map_into().boxed(),
6401 CastRangeToString::arbitrary().prop_map_into().boxed(),
6402 CeilFloat32::arbitrary().prop_map_into().boxed(),
6403 CeilFloat64::arbitrary().prop_map_into().boxed(),
6404 CeilNumeric::arbitrary().prop_map_into().boxed(),
6405 FloorFloat32::arbitrary().prop_map_into().boxed(),
6406 FloorFloat64::arbitrary().prop_map_into().boxed(),
6407 FloorNumeric::arbitrary().prop_map_into().boxed(),
6408 Ascii::arbitrary().prop_map_into().boxed(),
6409 BitCountBytes::arbitrary().prop_map_into().boxed(),
6410 BitLengthBytes::arbitrary().prop_map_into().boxed(),
6411 BitLengthString::arbitrary().prop_map_into().boxed(),
6412 ByteLengthBytes::arbitrary().prop_map_into().boxed(),
6413 ByteLengthString::arbitrary().prop_map_into().boxed(),
6414 CharLength::arbitrary().prop_map_into().boxed(),
6415 Chr::arbitrary().prop_map_into().boxed(),
6416 like_pattern::any_matcher()
6417 .prop_map(|matcher| UnaryFunc::IsLikeMatch(IsLikeMatch(matcher)))
6418 .boxed(),
6419 any_regex()
6420 .prop_map(|regex| UnaryFunc::IsRegexpMatch(IsRegexpMatch(regex)))
6421 .boxed(),
6422 any_regex()
6423 .prop_map(|regex| UnaryFunc::RegexpMatch(RegexpMatch(regex)))
6424 .boxed(),
6425 any_regex()
6426 .prop_map(|regex| UnaryFunc::RegexpSplitToArray(RegexpSplitToArray(regex)))
6427 .boxed(),
6428 ExtractInterval::arbitrary().prop_map_into().boxed(),
6429 ExtractTime::arbitrary().prop_map_into().boxed(),
6430 ExtractTimestamp::arbitrary().prop_map_into().boxed(),
6431 ExtractTimestampTz::arbitrary().prop_map_into().boxed(),
6432 ExtractDate::arbitrary().prop_map_into().boxed(),
6433 DatePartInterval::arbitrary().prop_map_into().boxed(),
6434 DatePartTime::arbitrary().prop_map_into().boxed(),
6435 DatePartTimestamp::arbitrary().prop_map_into().boxed(),
6436 DatePartTimestampTz::arbitrary().prop_map_into().boxed(),
6437 DateTruncTimestamp::arbitrary().prop_map_into().boxed(),
6438 DateTruncTimestampTz::arbitrary().prop_map_into().boxed(),
6439 TimezoneTimestamp::arbitrary().prop_map_into().boxed(),
6440 TimezoneTimestampTz::arbitrary().prop_map_into().boxed(),
6441 TimezoneTime::arbitrary().prop_map_into().boxed(),
6442 ToTimestamp::arbitrary().prop_map_into().boxed(),
6443 JustifyDays::arbitrary().prop_map_into().boxed(),
6444 JustifyHours::arbitrary().prop_map_into().boxed(),
6445 JustifyInterval::arbitrary().prop_map_into().boxed(),
6446 JsonbArrayLength::arbitrary().prop_map_into().boxed(),
6447 JsonbTypeof::arbitrary().prop_map_into().boxed(),
6448 JsonbStripNulls::arbitrary().prop_map_into().boxed(),
6449 JsonbPretty::arbitrary().prop_map_into().boxed(),
6450 RoundFloat32::arbitrary().prop_map_into().boxed(),
6451 RoundFloat64::arbitrary().prop_map_into().boxed(),
6452 RoundNumeric::arbitrary().prop_map_into().boxed(),
6453 TruncFloat32::arbitrary().prop_map_into().boxed(),
6454 TruncFloat64::arbitrary().prop_map_into().boxed(),
6455 TruncNumeric::arbitrary().prop_map_into().boxed(),
6456 TrimWhitespace::arbitrary().prop_map_into().boxed(),
6457 TrimLeadingWhitespace::arbitrary().prop_map_into().boxed(),
6458 TrimTrailingWhitespace::arbitrary().prop_map_into().boxed(),
6459 RecordGet::arbitrary().prop_map_into().boxed(),
6460 ListLength::arbitrary().prop_map_into().boxed(),
6461 (any::<ScalarType>())
6462 .prop_map(|value_type| {
6463 UnaryFunc::MapBuildFromRecordList(MapBuildFromRecordList { value_type })
6464 })
6465 .boxed(),
6466 MapLength::arbitrary().prop_map_into().boxed(),
6467 Upper::arbitrary().prop_map_into().boxed(),
6468 Lower::arbitrary().prop_map_into().boxed(),
6469 Cos::arbitrary().prop_map_into().boxed(),
6470 Acos::arbitrary().prop_map_into().boxed(),
6471 Cosh::arbitrary().prop_map_into().boxed(),
6472 Acosh::arbitrary().prop_map_into().boxed(),
6473 Sin::arbitrary().prop_map_into().boxed(),
6474 Asin::arbitrary().prop_map_into().boxed(),
6475 Sinh::arbitrary().prop_map_into().boxed(),
6476 Asinh::arbitrary().prop_map_into().boxed(),
6477 Tan::arbitrary().prop_map_into().boxed(),
6478 Atan::arbitrary().prop_map_into().boxed(),
6479 Tanh::arbitrary().prop_map_into().boxed(),
6480 Atanh::arbitrary().prop_map_into().boxed(),
6481 Cot::arbitrary().prop_map_into().boxed(),
6482 Degrees::arbitrary().prop_map_into().boxed(),
6483 Radians::arbitrary().prop_map_into().boxed(),
6484 Log10::arbitrary().prop_map_into().boxed(),
6485 Log10Numeric::arbitrary().prop_map_into().boxed(),
6486 Ln::arbitrary().prop_map_into().boxed(),
6487 LnNumeric::arbitrary().prop_map_into().boxed(),
6488 Exp::arbitrary().prop_map_into().boxed(),
6489 ExpNumeric::arbitrary().prop_map_into().boxed(),
6490 Sleep::arbitrary().prop_map_into().boxed(),
6491 Panic::arbitrary().prop_map_into().boxed(),
6492 AdjustNumericScale::arbitrary().prop_map_into().boxed(),
6493 PgColumnSize::arbitrary().prop_map_into().boxed(),
6494 PgSizePretty::arbitrary().prop_map_into().boxed(),
6495 MzRowSize::arbitrary().prop_map_into().boxed(),
6496 MzTypeName::arbitrary().prop_map_into().boxed(),
6497 RangeLower::arbitrary().prop_map_into().boxed(),
6498 RangeUpper::arbitrary().prop_map_into().boxed(),
6499 RangeEmpty::arbitrary().prop_map_into().boxed(),
6500 RangeLowerInc::arbitrary().prop_map_into().boxed(),
6501 RangeUpperInc::arbitrary().prop_map_into().boxed(),
6502 RangeLowerInf::arbitrary().prop_map_into().boxed(),
6503 RangeUpperInf::arbitrary().prop_map_into().boxed(),
6504 MzAclItemGrantor::arbitrary().prop_map_into().boxed(),
6505 MzAclItemGrantee::arbitrary().prop_map_into().boxed(),
6506 MzAclItemPrivileges::arbitrary().prop_map_into().boxed(),
6507 MzFormatPrivileges::arbitrary().prop_map_into().boxed(),
6508 MzValidatePrivileges::arbitrary().prop_map_into().boxed(),
6509 MzValidateRolePrivilege::arbitrary().prop_map_into().boxed(),
6510 AclItemGrantor::arbitrary().prop_map_into().boxed(),
6511 AclItemGrantee::arbitrary().prop_map_into().boxed(),
6512 AclItemPrivileges::arbitrary().prop_map_into().boxed(),
6513 QuoteIdent::arbitrary().prop_map_into().boxed(),
6514 ])
6515 }
6516}
6517
6518impl RustType<ProtoUnaryFunc> for UnaryFunc {
6519 fn into_proto(&self) -> ProtoUnaryFunc {
6520 use crate::scalar::proto_unary_func::Kind::*;
6521 use crate::scalar::proto_unary_func::*;
6522 let kind = match self {
6523 UnaryFunc::Not(_) => Not(()),
6524 UnaryFunc::IsNull(_) => IsNull(()),
6525 UnaryFunc::IsTrue(_) => IsTrue(()),
6526 UnaryFunc::IsFalse(_) => IsFalse(()),
6527 UnaryFunc::BitNotInt16(_) => BitNotInt16(()),
6528 UnaryFunc::BitNotInt32(_) => BitNotInt32(()),
6529 UnaryFunc::BitNotInt64(_) => BitNotInt64(()),
6530 UnaryFunc::BitNotUint16(_) => BitNotUint16(()),
6531 UnaryFunc::BitNotUint32(_) => BitNotUint32(()),
6532 UnaryFunc::BitNotUint64(_) => BitNotUint64(()),
6533 UnaryFunc::NegInt16(_) => NegInt16(()),
6534 UnaryFunc::NegInt32(_) => NegInt32(()),
6535 UnaryFunc::NegInt64(_) => NegInt64(()),
6536 UnaryFunc::NegFloat32(_) => NegFloat32(()),
6537 UnaryFunc::NegFloat64(_) => NegFloat64(()),
6538 UnaryFunc::NegNumeric(_) => NegNumeric(()),
6539 UnaryFunc::NegInterval(_) => NegInterval(()),
6540 UnaryFunc::SqrtFloat64(_) => SqrtFloat64(()),
6541 UnaryFunc::SqrtNumeric(_) => SqrtNumeric(()),
6542 UnaryFunc::CbrtFloat64(_) => CbrtFloat64(()),
6543 UnaryFunc::AbsInt16(_) => AbsInt16(()),
6544 UnaryFunc::AbsInt32(_) => AbsInt32(()),
6545 UnaryFunc::AbsInt64(_) => AbsInt64(()),
6546 UnaryFunc::AbsFloat32(_) => AbsFloat32(()),
6547 UnaryFunc::AbsFloat64(_) => AbsFloat64(()),
6548 UnaryFunc::AbsNumeric(_) => AbsNumeric(()),
6549 UnaryFunc::CastBoolToString(_) => CastBoolToString(()),
6550 UnaryFunc::CastBoolToStringNonstandard(_) => CastBoolToStringNonstandard(()),
6551 UnaryFunc::CastBoolToInt32(_) => CastBoolToInt32(()),
6552 UnaryFunc::CastBoolToInt64(_) => CastBoolToInt64(()),
6553 UnaryFunc::CastInt16ToFloat32(_) => CastInt16ToFloat32(()),
6554 UnaryFunc::CastInt16ToFloat64(_) => CastInt16ToFloat64(()),
6555 UnaryFunc::CastInt16ToInt32(_) => CastInt16ToInt32(()),
6556 UnaryFunc::CastInt16ToInt64(_) => CastInt16ToInt64(()),
6557 UnaryFunc::CastInt16ToUint16(_) => CastInt16ToUint16(()),
6558 UnaryFunc::CastInt16ToUint32(_) => CastInt16ToUint32(()),
6559 UnaryFunc::CastInt16ToUint64(_) => CastInt16ToUint64(()),
6560 UnaryFunc::CastInt16ToString(_) => CastInt16ToString(()),
6561 UnaryFunc::CastInt2VectorToArray(_) => CastInt2VectorToArray(()),
6562 UnaryFunc::CastInt32ToBool(_) => CastInt32ToBool(()),
6563 UnaryFunc::CastInt32ToFloat32(_) => CastInt32ToFloat32(()),
6564 UnaryFunc::CastInt32ToFloat64(_) => CastInt32ToFloat64(()),
6565 UnaryFunc::CastInt32ToOid(_) => CastInt32ToOid(()),
6566 UnaryFunc::CastInt32ToPgLegacyChar(_) => CastInt32ToPgLegacyChar(()),
6567 UnaryFunc::CastInt32ToInt16(_) => CastInt32ToInt16(()),
6568 UnaryFunc::CastInt32ToInt64(_) => CastInt32ToInt64(()),
6569 UnaryFunc::CastInt32ToUint16(_) => CastInt32ToUint16(()),
6570 UnaryFunc::CastInt32ToUint32(_) => CastInt32ToUint32(()),
6571 UnaryFunc::CastInt32ToUint64(_) => CastInt32ToUint64(()),
6572 UnaryFunc::CastInt32ToString(_) => CastInt32ToString(()),
6573 UnaryFunc::CastOidToInt32(_) => CastOidToInt32(()),
6574 UnaryFunc::CastOidToInt64(_) => CastOidToInt64(()),
6575 UnaryFunc::CastOidToString(_) => CastOidToString(()),
6576 UnaryFunc::CastOidToRegClass(_) => CastOidToRegClass(()),
6577 UnaryFunc::CastRegClassToOid(_) => CastRegClassToOid(()),
6578 UnaryFunc::CastOidToRegProc(_) => CastOidToRegProc(()),
6579 UnaryFunc::CastRegProcToOid(_) => CastRegProcToOid(()),
6580 UnaryFunc::CastOidToRegType(_) => CastOidToRegType(()),
6581 UnaryFunc::CastRegTypeToOid(_) => CastRegTypeToOid(()),
6582 UnaryFunc::CastInt64ToInt16(_) => CastInt64ToInt16(()),
6583 UnaryFunc::CastInt64ToInt32(_) => CastInt64ToInt32(()),
6584 UnaryFunc::CastInt64ToUint16(_) => CastInt64ToUint16(()),
6585 UnaryFunc::CastInt64ToUint32(_) => CastInt64ToUint32(()),
6586 UnaryFunc::CastInt64ToUint64(_) => CastInt64ToUint64(()),
6587 UnaryFunc::CastInt16ToNumeric(func) => CastInt16ToNumeric(func.0.into_proto()),
6588 UnaryFunc::CastInt32ToNumeric(func) => CastInt32ToNumeric(func.0.into_proto()),
6589 UnaryFunc::CastInt64ToBool(_) => CastInt64ToBool(()),
6590 UnaryFunc::CastInt64ToNumeric(func) => CastInt64ToNumeric(func.0.into_proto()),
6591 UnaryFunc::CastInt64ToFloat32(_) => CastInt64ToFloat32(()),
6592 UnaryFunc::CastInt64ToFloat64(_) => CastInt64ToFloat64(()),
6593 UnaryFunc::CastInt64ToOid(_) => CastInt64ToOid(()),
6594 UnaryFunc::CastInt64ToString(_) => CastInt64ToString(()),
6595 UnaryFunc::CastUint16ToUint32(_) => CastUint16ToUint32(()),
6596 UnaryFunc::CastUint16ToUint64(_) => CastUint16ToUint64(()),
6597 UnaryFunc::CastUint16ToInt16(_) => CastUint16ToInt16(()),
6598 UnaryFunc::CastUint16ToInt32(_) => CastUint16ToInt32(()),
6599 UnaryFunc::CastUint16ToInt64(_) => CastUint16ToInt64(()),
6600 UnaryFunc::CastUint16ToNumeric(func) => CastUint16ToNumeric(func.0.into_proto()),
6601 UnaryFunc::CastUint16ToFloat32(_) => CastUint16ToFloat32(()),
6602 UnaryFunc::CastUint16ToFloat64(_) => CastUint16ToFloat64(()),
6603 UnaryFunc::CastUint16ToString(_) => CastUint16ToString(()),
6604 UnaryFunc::CastUint32ToUint16(_) => CastUint32ToUint16(()),
6605 UnaryFunc::CastUint32ToUint64(_) => CastUint32ToUint64(()),
6606 UnaryFunc::CastUint32ToInt16(_) => CastUint32ToInt16(()),
6607 UnaryFunc::CastUint32ToInt32(_) => CastUint32ToInt32(()),
6608 UnaryFunc::CastUint32ToInt64(_) => CastUint32ToInt64(()),
6609 UnaryFunc::CastUint32ToNumeric(func) => CastUint32ToNumeric(func.0.into_proto()),
6610 UnaryFunc::CastUint32ToFloat32(_) => CastUint32ToFloat32(()),
6611 UnaryFunc::CastUint32ToFloat64(_) => CastUint32ToFloat64(()),
6612 UnaryFunc::CastUint32ToString(_) => CastUint32ToString(()),
6613 UnaryFunc::CastUint64ToUint16(_) => CastUint64ToUint16(()),
6614 UnaryFunc::CastUint64ToUint32(_) => CastUint64ToUint32(()),
6615 UnaryFunc::CastUint64ToInt16(_) => CastUint64ToInt16(()),
6616 UnaryFunc::CastUint64ToInt32(_) => CastUint64ToInt32(()),
6617 UnaryFunc::CastUint64ToInt64(_) => CastUint64ToInt64(()),
6618 UnaryFunc::CastUint64ToNumeric(func) => CastUint64ToNumeric(func.0.into_proto()),
6619 UnaryFunc::CastUint64ToFloat32(_) => CastUint64ToFloat32(()),
6620 UnaryFunc::CastUint64ToFloat64(_) => CastUint64ToFloat64(()),
6621 UnaryFunc::CastUint64ToString(_) => CastUint64ToString(()),
6622 UnaryFunc::CastFloat32ToInt16(_) => CastFloat32ToInt16(()),
6623 UnaryFunc::CastFloat32ToInt32(_) => CastFloat32ToInt32(()),
6624 UnaryFunc::CastFloat32ToInt64(_) => CastFloat32ToInt64(()),
6625 UnaryFunc::CastFloat32ToUint16(_) => CastFloat32ToUint16(()),
6626 UnaryFunc::CastFloat32ToUint32(_) => CastFloat32ToUint32(()),
6627 UnaryFunc::CastFloat32ToUint64(_) => CastFloat32ToUint64(()),
6628 UnaryFunc::CastFloat32ToFloat64(_) => CastFloat32ToFloat64(()),
6629 UnaryFunc::CastFloat32ToString(_) => CastFloat32ToString(()),
6630 UnaryFunc::CastFloat32ToNumeric(func) => CastFloat32ToNumeric(func.0.into_proto()),
6631 UnaryFunc::CastFloat64ToNumeric(func) => CastFloat64ToNumeric(func.0.into_proto()),
6632 UnaryFunc::CastFloat64ToInt16(_) => CastFloat64ToInt16(()),
6633 UnaryFunc::CastFloat64ToInt32(_) => CastFloat64ToInt32(()),
6634 UnaryFunc::CastFloat64ToInt64(_) => CastFloat64ToInt64(()),
6635 UnaryFunc::CastFloat64ToUint16(_) => CastFloat64ToUint16(()),
6636 UnaryFunc::CastFloat64ToUint32(_) => CastFloat64ToUint32(()),
6637 UnaryFunc::CastFloat64ToUint64(_) => CastFloat64ToUint64(()),
6638 UnaryFunc::CastFloat64ToFloat32(_) => CastFloat64ToFloat32(()),
6639 UnaryFunc::CastFloat64ToString(_) => CastFloat64ToString(()),
6640 UnaryFunc::CastNumericToFloat32(_) => CastNumericToFloat32(()),
6641 UnaryFunc::CastNumericToFloat64(_) => CastNumericToFloat64(()),
6642 UnaryFunc::CastNumericToInt16(_) => CastNumericToInt16(()),
6643 UnaryFunc::CastNumericToInt32(_) => CastNumericToInt32(()),
6644 UnaryFunc::CastNumericToInt64(_) => CastNumericToInt64(()),
6645 UnaryFunc::CastNumericToUint16(_) => CastNumericToUint16(()),
6646 UnaryFunc::CastNumericToUint32(_) => CastNumericToUint32(()),
6647 UnaryFunc::CastNumericToUint64(_) => CastNumericToUint64(()),
6648 UnaryFunc::CastNumericToString(_) => CastNumericToString(()),
6649 UnaryFunc::CastStringToBool(_) => CastStringToBool(()),
6650 UnaryFunc::CastStringToPgLegacyChar(_) => CastStringToPgLegacyChar(()),
6651 UnaryFunc::CastStringToPgLegacyName(_) => CastStringToPgLegacyName(()),
6652 UnaryFunc::CastStringToBytes(_) => CastStringToBytes(()),
6653 UnaryFunc::CastStringToInt16(_) => CastStringToInt16(()),
6654 UnaryFunc::CastStringToInt32(_) => CastStringToInt32(()),
6655 UnaryFunc::CastStringToInt64(_) => CastStringToInt64(()),
6656 UnaryFunc::CastStringToUint16(_) => CastStringToUint16(()),
6657 UnaryFunc::CastStringToUint32(_) => CastStringToUint32(()),
6658 UnaryFunc::CastStringToUint64(_) => CastStringToUint64(()),
6659 UnaryFunc::CastStringToInt2Vector(_) => CastStringToInt2Vector(()),
6660 UnaryFunc::CastStringToOid(_) => CastStringToOid(()),
6661 UnaryFunc::CastStringToFloat32(_) => CastStringToFloat32(()),
6662 UnaryFunc::CastStringToFloat64(_) => CastStringToFloat64(()),
6663 UnaryFunc::CastStringToDate(_) => CastStringToDate(()),
6664 UnaryFunc::CastStringToArray(inner) => {
6665 CastStringToArray(Box::new(ProtoCastToVariableType {
6666 return_ty: Some(inner.return_ty.into_proto()),
6667 cast_expr: Some(inner.cast_expr.into_proto()),
6668 }))
6669 }
6670 UnaryFunc::CastStringToList(inner) => {
6671 CastStringToList(Box::new(ProtoCastToVariableType {
6672 return_ty: Some(inner.return_ty.into_proto()),
6673 cast_expr: Some(inner.cast_expr.into_proto()),
6674 }))
6675 }
6676 UnaryFunc::CastStringToMap(inner) => {
6677 CastStringToMap(Box::new(ProtoCastToVariableType {
6678 return_ty: Some(inner.return_ty.into_proto()),
6679 cast_expr: Some(inner.cast_expr.into_proto()),
6680 }))
6681 }
6682 UnaryFunc::CastStringToRange(inner) => {
6683 CastStringToRange(Box::new(ProtoCastToVariableType {
6684 return_ty: Some(inner.return_ty.into_proto()),
6685 cast_expr: Some(inner.cast_expr.into_proto()),
6686 }))
6687 }
6688 UnaryFunc::CastStringToTime(_) => CastStringToTime(()),
6689 UnaryFunc::CastStringToTimestamp(precision) => {
6690 CastStringToTimestamp(precision.0.into_proto())
6691 }
6692 UnaryFunc::CastStringToTimestampTz(precision) => {
6693 CastStringToTimestampTz(precision.0.into_proto())
6694 }
6695 UnaryFunc::CastStringToInterval(_) => CastStringToInterval(()),
6696 UnaryFunc::CastStringToNumeric(func) => CastStringToNumeric(func.0.into_proto()),
6697 UnaryFunc::CastStringToUuid(_) => CastStringToUuid(()),
6698 UnaryFunc::CastStringToChar(func) => CastStringToChar(ProtoCastStringToChar {
6699 length: func.length.into_proto(),
6700 fail_on_len: func.fail_on_len,
6701 }),
6702 UnaryFunc::PadChar(func) => PadChar(ProtoPadChar {
6703 length: func.length.into_proto(),
6704 }),
6705 UnaryFunc::CastStringToVarChar(func) => CastStringToVarChar(ProtoCastStringToVarChar {
6706 length: func.length.into_proto(),
6707 fail_on_len: func.fail_on_len,
6708 }),
6709 UnaryFunc::CastCharToString(_) => CastCharToString(()),
6710 UnaryFunc::CastVarCharToString(_) => CastVarCharToString(()),
6711 UnaryFunc::CastDateToTimestamp(func) => CastDateToTimestamp(func.0.into_proto()),
6712 UnaryFunc::CastDateToTimestampTz(func) => CastDateToTimestampTz(func.0.into_proto()),
6713 UnaryFunc::CastDateToString(_) => CastDateToString(()),
6714 UnaryFunc::CastTimeToInterval(_) => CastTimeToInterval(()),
6715 UnaryFunc::CastTimeToString(_) => CastTimeToString(()),
6716 UnaryFunc::CastIntervalToString(_) => CastIntervalToString(()),
6717 UnaryFunc::CastIntervalToTime(_) => CastIntervalToTime(()),
6718 UnaryFunc::CastTimestampToDate(_) => CastTimestampToDate(()),
6719 UnaryFunc::AdjustTimestampPrecision(func) => Kind::AdjustTimestampPrecision(
6720 mz_repr::adt::timestamp::ProtoFromToTimestampPrecisions {
6721 from: func.from.map(|p| p.into_proto()),
6722 to: func.to.map(|p| p.into_proto()),
6723 },
6724 ),
6725 UnaryFunc::CastTimestampToTimestampTz(func) => CastTimestampToTimestampTz(
6726 mz_repr::adt::timestamp::ProtoFromToTimestampPrecisions {
6727 from: func.from.map(|p| p.into_proto()),
6728 to: func.to.map(|p| p.into_proto()),
6729 },
6730 ),
6731 UnaryFunc::CastTimestampToString(_) => CastTimestampToString(()),
6732 UnaryFunc::CastTimestampToTime(_) => CastTimestampToTime(()),
6733 UnaryFunc::CastTimestampTzToDate(_) => CastTimestampTzToDate(()),
6734 UnaryFunc::AdjustTimestampTzPrecision(func) => Kind::AdjustTimestampTzPrecision(
6735 mz_repr::adt::timestamp::ProtoFromToTimestampPrecisions {
6736 from: func.from.map(|p| p.into_proto()),
6737 to: func.to.map(|p| p.into_proto()),
6738 },
6739 ),
6740 UnaryFunc::CastTimestampTzToTimestamp(func) => CastTimestampTzToTimestamp(
6741 mz_repr::adt::timestamp::ProtoFromToTimestampPrecisions {
6742 from: func.from.map(|p| p.into_proto()),
6743 to: func.to.map(|p| p.into_proto()),
6744 },
6745 ),
6746 UnaryFunc::CastTimestampTzToString(_) => CastTimestampTzToString(()),
6747 UnaryFunc::CastTimestampTzToTime(_) => CastTimestampTzToTime(()),
6748 UnaryFunc::CastPgLegacyCharToString(_) => CastPgLegacyCharToString(()),
6749 UnaryFunc::CastPgLegacyCharToChar(_) => CastPgLegacyCharToChar(()),
6750 UnaryFunc::CastPgLegacyCharToVarChar(_) => CastPgLegacyCharToVarChar(()),
6751 UnaryFunc::CastPgLegacyCharToInt32(_) => CastPgLegacyCharToInt32(()),
6752 UnaryFunc::CastBytesToString(_) => CastBytesToString(()),
6753 UnaryFunc::CastStringToJsonb(_) => CastStringToJsonb(()),
6754 UnaryFunc::CastJsonbToString(_) => CastJsonbToString(()),
6755 UnaryFunc::CastJsonbableToJsonb(_) => CastJsonbableToJsonb(()),
6756 UnaryFunc::CastJsonbToInt16(_) => CastJsonbToInt16(()),
6757 UnaryFunc::CastJsonbToInt32(_) => CastJsonbToInt32(()),
6758 UnaryFunc::CastJsonbToInt64(_) => CastJsonbToInt64(()),
6759 UnaryFunc::CastJsonbToFloat32(_) => CastJsonbToFloat32(()),
6760 UnaryFunc::CastJsonbToFloat64(_) => CastJsonbToFloat64(()),
6761 UnaryFunc::CastJsonbToNumeric(func) => CastJsonbToNumeric(func.0.into_proto()),
6762 UnaryFunc::CastJsonbToBool(_) => CastJsonbToBool(()),
6763 UnaryFunc::CastUuidToString(_) => CastUuidToString(()),
6764 UnaryFunc::CastRecordToString(func) => CastRecordToString(func.ty.into_proto()),
6765 UnaryFunc::CastRecord1ToRecord2(inner) => {
6766 CastRecord1ToRecord2(ProtoCastRecord1ToRecord2 {
6767 return_ty: Some(inner.return_ty.into_proto()),
6768 cast_exprs: inner.cast_exprs.into_proto(),
6769 })
6770 }
6771 UnaryFunc::CastArrayToArray(inner) => {
6772 CastArrayToArray(Box::new(ProtoCastToVariableType {
6773 return_ty: Some(inner.return_ty.into_proto()),
6774 cast_expr: Some(inner.cast_expr.into_proto()),
6775 }))
6776 }
6777 UnaryFunc::CastArrayToJsonb(inner) => CastArrayToJsonb(inner.cast_element.into_proto()),
6778 UnaryFunc::CastArrayToString(func) => CastArrayToString(func.ty.into_proto()),
6779 UnaryFunc::CastListToJsonb(inner) => CastListToJsonb(inner.cast_element.into_proto()),
6780 UnaryFunc::CastListToString(func) => CastListToString(func.ty.into_proto()),
6781 UnaryFunc::CastList1ToList2(inner) => {
6782 CastList1ToList2(Box::new(ProtoCastToVariableType {
6783 return_ty: Some(inner.return_ty.into_proto()),
6784 cast_expr: Some(inner.cast_expr.into_proto()),
6785 }))
6786 }
6787 UnaryFunc::CastArrayToListOneDim(_) => CastArrayToListOneDim(()),
6788 UnaryFunc::CastMapToString(func) => CastMapToString(func.ty.into_proto()),
6789 UnaryFunc::CastInt2VectorToString(_) => CastInt2VectorToString(()),
6790 UnaryFunc::CastRangeToString(func) => CastRangeToString(func.ty.into_proto()),
6791 UnaryFunc::CeilFloat32(_) => CeilFloat32(()),
6792 UnaryFunc::CeilFloat64(_) => CeilFloat64(()),
6793 UnaryFunc::CeilNumeric(_) => CeilNumeric(()),
6794 UnaryFunc::FloorFloat32(_) => FloorFloat32(()),
6795 UnaryFunc::FloorFloat64(_) => FloorFloat64(()),
6796 UnaryFunc::FloorNumeric(_) => FloorNumeric(()),
6797 UnaryFunc::Ascii(_) => Ascii(()),
6798 UnaryFunc::BitCountBytes(_) => BitCountBytes(()),
6799 UnaryFunc::BitLengthBytes(_) => BitLengthBytes(()),
6800 UnaryFunc::BitLengthString(_) => BitLengthString(()),
6801 UnaryFunc::ByteLengthBytes(_) => ByteLengthBytes(()),
6802 UnaryFunc::ByteLengthString(_) => ByteLengthString(()),
6803 UnaryFunc::CharLength(_) => CharLength(()),
6804 UnaryFunc::Chr(_) => Chr(()),
6805 UnaryFunc::IsLikeMatch(pattern) => IsLikeMatch(pattern.0.into_proto()),
6806 UnaryFunc::IsRegexpMatch(regex) => IsRegexpMatch(regex.0.into_proto()),
6807 UnaryFunc::RegexpMatch(regex) => RegexpMatch(regex.0.into_proto()),
6808 UnaryFunc::RegexpSplitToArray(regex) => RegexpSplitToArray(regex.0.into_proto()),
6809 UnaryFunc::ExtractInterval(func) => ExtractInterval(func.0.into_proto()),
6810 UnaryFunc::ExtractTime(func) => ExtractTime(func.0.into_proto()),
6811 UnaryFunc::ExtractTimestamp(func) => ExtractTimestamp(func.0.into_proto()),
6812 UnaryFunc::ExtractTimestampTz(func) => ExtractTimestampTz(func.0.into_proto()),
6813 UnaryFunc::ExtractDate(func) => ExtractDate(func.0.into_proto()),
6814 UnaryFunc::DatePartInterval(func) => DatePartInterval(func.0.into_proto()),
6815 UnaryFunc::DatePartTime(func) => DatePartTime(func.0.into_proto()),
6816 UnaryFunc::DatePartTimestamp(func) => DatePartTimestamp(func.0.into_proto()),
6817 UnaryFunc::DatePartTimestampTz(func) => DatePartTimestampTz(func.0.into_proto()),
6818 UnaryFunc::DateTruncTimestamp(func) => DateTruncTimestamp(func.0.into_proto()),
6819 UnaryFunc::DateTruncTimestampTz(func) => DateTruncTimestampTz(func.0.into_proto()),
6820 UnaryFunc::TimezoneTimestamp(func) => TimezoneTimestamp(func.0.into_proto()),
6821 UnaryFunc::TimezoneTimestampTz(func) => TimezoneTimestampTz(func.0.into_proto()),
6822 UnaryFunc::TimezoneTime(func) => TimezoneTime(ProtoTimezoneTime {
6823 tz: Some(func.tz.into_proto()),
6824 wall_time: Some(func.wall_time.into_proto()),
6825 }),
6826 UnaryFunc::ToTimestamp(_) => ToTimestamp(()),
6827 UnaryFunc::ToCharTimestamp(func) => ToCharTimestamp(ProtoToCharTimestamp {
6828 format_string: func.format_string.into_proto(),
6829 format: Some(func.format.into_proto()),
6830 }),
6831 UnaryFunc::ToCharTimestampTz(func) => ToCharTimestampTz(ProtoToCharTimestamp {
6832 format_string: func.format_string.into_proto(),
6833 format: Some(func.format.into_proto()),
6834 }),
6835 UnaryFunc::JustifyDays(_) => JustifyDays(()),
6836 UnaryFunc::JustifyHours(_) => JustifyHours(()),
6837 UnaryFunc::JustifyInterval(_) => JustifyInterval(()),
6838 UnaryFunc::JsonbArrayLength(_) => JsonbArrayLength(()),
6839 UnaryFunc::JsonbTypeof(_) => JsonbTypeof(()),
6840 UnaryFunc::JsonbStripNulls(_) => JsonbStripNulls(()),
6841 UnaryFunc::JsonbPretty(_) => JsonbPretty(()),
6842 UnaryFunc::RoundFloat32(_) => RoundFloat32(()),
6843 UnaryFunc::RoundFloat64(_) => RoundFloat64(()),
6844 UnaryFunc::RoundNumeric(_) => RoundNumeric(()),
6845 UnaryFunc::TruncFloat32(_) => TruncFloat32(()),
6846 UnaryFunc::TruncFloat64(_) => TruncFloat64(()),
6847 UnaryFunc::TruncNumeric(_) => TruncNumeric(()),
6848 UnaryFunc::TrimWhitespace(_) => TrimWhitespace(()),
6849 UnaryFunc::TrimLeadingWhitespace(_) => TrimLeadingWhitespace(()),
6850 UnaryFunc::TrimTrailingWhitespace(_) => TrimTrailingWhitespace(()),
6851 UnaryFunc::Initcap(_) => Initcap(()),
6852 UnaryFunc::RecordGet(func) => RecordGet(func.0.into_proto()),
6853 UnaryFunc::ListLength(_) => ListLength(()),
6854 UnaryFunc::MapBuildFromRecordList(inner) => {
6855 MapBuildFromRecordList(inner.value_type.into_proto())
6856 }
6857 UnaryFunc::MapLength(_) => MapLength(()),
6858 UnaryFunc::Upper(_) => Upper(()),
6859 UnaryFunc::Lower(_) => Lower(()),
6860 UnaryFunc::Cos(_) => Cos(()),
6861 UnaryFunc::Acos(_) => Acos(()),
6862 UnaryFunc::Cosh(_) => Cosh(()),
6863 UnaryFunc::Acosh(_) => Acosh(()),
6864 UnaryFunc::Sin(_) => Sin(()),
6865 UnaryFunc::Asin(_) => Asin(()),
6866 UnaryFunc::Sinh(_) => Sinh(()),
6867 UnaryFunc::Asinh(_) => Asinh(()),
6868 UnaryFunc::Tan(_) => Tan(()),
6869 UnaryFunc::Atan(_) => Atan(()),
6870 UnaryFunc::Tanh(_) => Tanh(()),
6871 UnaryFunc::Atanh(_) => Atanh(()),
6872 UnaryFunc::Cot(_) => Cot(()),
6873 UnaryFunc::Degrees(_) => Degrees(()),
6874 UnaryFunc::Radians(_) => Radians(()),
6875 UnaryFunc::Log10(_) => Log10(()),
6876 UnaryFunc::Log10Numeric(_) => Log10Numeric(()),
6877 UnaryFunc::Ln(_) => Ln(()),
6878 UnaryFunc::LnNumeric(_) => LnNumeric(()),
6879 UnaryFunc::Exp(_) => Exp(()),
6880 UnaryFunc::ExpNumeric(_) => ExpNumeric(()),
6881 UnaryFunc::Sleep(_) => Sleep(()),
6882 UnaryFunc::Panic(_) => Panic(()),
6883 UnaryFunc::AdjustNumericScale(func) => AdjustNumericScale(func.0.into_proto()),
6884 UnaryFunc::PgColumnSize(_) => PgColumnSize(()),
6885 UnaryFunc::PgSizePretty(_) => PgSizePretty(()),
6886 UnaryFunc::MzRowSize(_) => MzRowSize(()),
6887 UnaryFunc::MzTypeName(_) => MzTypeName(()),
6888 UnaryFunc::CastMzTimestampToString(_) => CastMzTimestampToString(()),
6889 UnaryFunc::CastMzTimestampToTimestamp(_) => CastMzTimestampToTimestamp(()),
6890 UnaryFunc::CastMzTimestampToTimestampTz(_) => CastMzTimestampToTimestampTz(()),
6891 UnaryFunc::CastStringToMzTimestamp(_) => CastStringToMzTimestamp(()),
6892 UnaryFunc::CastUint64ToMzTimestamp(_) => CastUint64ToMzTimestamp(()),
6893 UnaryFunc::CastUint32ToMzTimestamp(_) => CastUint32ToMzTimestamp(()),
6894 UnaryFunc::CastInt64ToMzTimestamp(_) => CastInt64ToMzTimestamp(()),
6895 UnaryFunc::CastInt32ToMzTimestamp(_) => CastInt32ToMzTimestamp(()),
6896 UnaryFunc::CastNumericToMzTimestamp(_) => CastNumericToMzTimestamp(()),
6897 UnaryFunc::CastTimestampToMzTimestamp(_) => CastTimestampToMzTimestamp(()),
6898 UnaryFunc::CastTimestampTzToMzTimestamp(_) => CastTimestampTzToMzTimestamp(()),
6899 UnaryFunc::CastDateToMzTimestamp(_) => CastDateToMzTimestamp(()),
6900 UnaryFunc::StepMzTimestamp(_) => StepMzTimestamp(()),
6901 UnaryFunc::RangeLower(_) => RangeLower(()),
6902 UnaryFunc::RangeUpper(_) => RangeUpper(()),
6903 UnaryFunc::RangeEmpty(_) => RangeEmpty(()),
6904 UnaryFunc::RangeLowerInc(_) => RangeLowerInc(()),
6905 UnaryFunc::RangeUpperInc(_) => RangeUpperInc(()),
6906 UnaryFunc::RangeLowerInf(_) => RangeLowerInf(()),
6907 UnaryFunc::RangeUpperInf(_) => RangeUpperInf(()),
6908 UnaryFunc::MzAclItemGrantor(_) => MzAclItemGrantor(()),
6909 UnaryFunc::MzAclItemGrantee(_) => MzAclItemGrantee(()),
6910 UnaryFunc::MzAclItemPrivileges(_) => MzAclItemPrivileges(()),
6911 UnaryFunc::MzFormatPrivileges(_) => MzFormatPrivileges(()),
6912 UnaryFunc::MzValidatePrivileges(_) => MzValidatePrivileges(()),
6913 UnaryFunc::MzValidateRolePrivilege(_) => MzValidateRolePrivilege(()),
6914 UnaryFunc::AclItemGrantor(_) => AclItemGrantor(()),
6915 UnaryFunc::AclItemGrantee(_) => AclItemGrantee(()),
6916 UnaryFunc::AclItemPrivileges(_) => AclItemPrivileges(()),
6917 UnaryFunc::QuoteIdent(_) => QuoteIdent(()),
6918 UnaryFunc::TryParseMonotonicIso8601Timestamp(_) => {
6919 TryParseMonotonicIso8601Timestamp(())
6920 }
6921 UnaryFunc::Crc32Bytes(_) => Crc32Bytes(()),
6922 UnaryFunc::Crc32String(_) => Crc32String(()),
6923 UnaryFunc::KafkaMurmur2Bytes(_) => KafkaMurmur2Bytes(()),
6924 UnaryFunc::KafkaMurmur2String(_) => KafkaMurmur2String(()),
6925 UnaryFunc::SeahashBytes(_) => SeahashBytes(()),
6926 UnaryFunc::SeahashString(_) => SeahashString(()),
6927 UnaryFunc::Reverse(_) => Reverse(()),
6928 };
6929 ProtoUnaryFunc { kind: Some(kind) }
6930 }
6931
6932 fn from_proto(proto: ProtoUnaryFunc) -> Result<Self, TryFromProtoError> {
6933 use crate::scalar::proto_unary_func::Kind::*;
6934 if let Some(kind) = proto.kind {
6935 match kind {
6936 Not(()) => Ok(impls::Not.into()),
6937 IsNull(()) => Ok(impls::IsNull.into()),
6938 IsTrue(()) => Ok(impls::IsTrue.into()),
6939 IsFalse(()) => Ok(impls::IsFalse.into()),
6940 BitNotInt16(()) => Ok(impls::BitNotInt16.into()),
6941 BitNotInt32(()) => Ok(impls::BitNotInt32.into()),
6942 BitNotInt64(()) => Ok(impls::BitNotInt64.into()),
6943 BitNotUint16(()) => Ok(impls::BitNotUint16.into()),
6944 BitNotUint32(()) => Ok(impls::BitNotUint32.into()),
6945 BitNotUint64(()) => Ok(impls::BitNotUint64.into()),
6946 NegInt16(()) => Ok(impls::NegInt16.into()),
6947 NegInt32(()) => Ok(impls::NegInt32.into()),
6948 NegInt64(()) => Ok(impls::NegInt64.into()),
6949 NegFloat32(()) => Ok(impls::NegFloat32.into()),
6950 NegFloat64(()) => Ok(impls::NegFloat64.into()),
6951 NegNumeric(()) => Ok(impls::NegNumeric.into()),
6952 NegInterval(()) => Ok(impls::NegInterval.into()),
6953 SqrtFloat64(()) => Ok(impls::SqrtFloat64.into()),
6954 SqrtNumeric(()) => Ok(impls::SqrtNumeric.into()),
6955 CbrtFloat64(()) => Ok(impls::CbrtFloat64.into()),
6956 AbsInt16(()) => Ok(impls::AbsInt16.into()),
6957 AbsInt32(()) => Ok(impls::AbsInt32.into()),
6958 AbsInt64(()) => Ok(impls::AbsInt64.into()),
6959 AbsFloat32(()) => Ok(impls::AbsFloat32.into()),
6960 AbsFloat64(()) => Ok(impls::AbsFloat64.into()),
6961 AbsNumeric(()) => Ok(impls::AbsNumeric.into()),
6962 CastBoolToString(()) => Ok(impls::CastBoolToString.into()),
6963 CastBoolToStringNonstandard(()) => Ok(impls::CastBoolToStringNonstandard.into()),
6964 CastBoolToInt32(()) => Ok(impls::CastBoolToInt32.into()),
6965 CastBoolToInt64(()) => Ok(impls::CastBoolToInt64.into()),
6966 CastInt16ToFloat32(()) => Ok(impls::CastInt16ToFloat32.into()),
6967 CastInt16ToFloat64(()) => Ok(impls::CastInt16ToFloat64.into()),
6968 CastInt16ToInt32(()) => Ok(impls::CastInt16ToInt32.into()),
6969 CastInt16ToInt64(()) => Ok(impls::CastInt16ToInt64.into()),
6970 CastInt16ToUint16(()) => Ok(impls::CastInt16ToUint16.into()),
6971 CastInt16ToUint32(()) => Ok(impls::CastInt16ToUint32.into()),
6972 CastInt16ToUint64(()) => Ok(impls::CastInt16ToUint64.into()),
6973 CastInt16ToString(()) => Ok(impls::CastInt16ToString.into()),
6974 CastInt2VectorToArray(()) => Ok(impls::CastInt2VectorToArray.into()),
6975 CastInt32ToBool(()) => Ok(impls::CastInt32ToBool.into()),
6976 CastInt32ToFloat32(()) => Ok(impls::CastInt32ToFloat32.into()),
6977 CastInt32ToFloat64(()) => Ok(impls::CastInt32ToFloat64.into()),
6978 CastInt32ToOid(()) => Ok(impls::CastInt32ToOid.into()),
6979 CastInt32ToPgLegacyChar(()) => Ok(impls::CastInt32ToPgLegacyChar.into()),
6980 CastInt32ToInt16(()) => Ok(impls::CastInt32ToInt16.into()),
6981 CastInt32ToInt64(()) => Ok(impls::CastInt32ToInt64.into()),
6982 CastInt32ToUint16(()) => Ok(impls::CastInt32ToUint16.into()),
6983 CastInt32ToUint32(()) => Ok(impls::CastInt32ToUint32.into()),
6984 CastInt32ToUint64(()) => Ok(impls::CastInt32ToUint64.into()),
6985 CastInt32ToString(()) => Ok(impls::CastInt32ToString.into()),
6986 CastOidToInt32(()) => Ok(impls::CastOidToInt32.into()),
6987 CastOidToInt64(()) => Ok(impls::CastOidToInt64.into()),
6988 CastOidToString(()) => Ok(impls::CastOidToString.into()),
6989 CastOidToRegClass(()) => Ok(impls::CastOidToRegClass.into()),
6990 CastRegClassToOid(()) => Ok(impls::CastRegClassToOid.into()),
6991 CastOidToRegProc(()) => Ok(impls::CastOidToRegProc.into()),
6992 CastRegProcToOid(()) => Ok(impls::CastRegProcToOid.into()),
6993 CastOidToRegType(()) => Ok(impls::CastOidToRegType.into()),
6994 CastRegTypeToOid(()) => Ok(impls::CastRegTypeToOid.into()),
6995 CastInt64ToInt16(()) => Ok(impls::CastInt64ToInt16.into()),
6996 CastInt64ToInt32(()) => Ok(impls::CastInt64ToInt32.into()),
6997 CastInt64ToUint16(()) => Ok(impls::CastInt64ToUint16.into()),
6998 CastInt64ToUint32(()) => Ok(impls::CastInt64ToUint32.into()),
6999 CastInt64ToUint64(()) => Ok(impls::CastInt64ToUint64.into()),
7000 CastInt16ToNumeric(max_scale) => {
7001 Ok(impls::CastInt16ToNumeric(max_scale.into_rust()?).into())
7002 }
7003 CastInt32ToNumeric(max_scale) => {
7004 Ok(impls::CastInt32ToNumeric(max_scale.into_rust()?).into())
7005 }
7006 CastInt64ToBool(()) => Ok(impls::CastInt64ToBool.into()),
7007 CastInt64ToNumeric(max_scale) => {
7008 Ok(impls::CastInt64ToNumeric(max_scale.into_rust()?).into())
7009 }
7010 CastInt64ToFloat32(()) => Ok(impls::CastInt64ToFloat32.into()),
7011 CastInt64ToFloat64(()) => Ok(impls::CastInt64ToFloat64.into()),
7012 CastInt64ToOid(()) => Ok(impls::CastInt64ToOid.into()),
7013 CastInt64ToString(()) => Ok(impls::CastInt64ToString.into()),
7014 CastUint16ToUint32(()) => Ok(impls::CastUint16ToUint32.into()),
7015 CastUint16ToUint64(()) => Ok(impls::CastUint16ToUint64.into()),
7016 CastUint16ToInt16(()) => Ok(impls::CastUint16ToInt16.into()),
7017 CastUint16ToInt32(()) => Ok(impls::CastUint16ToInt32.into()),
7018 CastUint16ToInt64(()) => Ok(impls::CastUint16ToInt64.into()),
7019 CastUint16ToNumeric(max_scale) => {
7020 Ok(impls::CastUint16ToNumeric(max_scale.into_rust()?).into())
7021 }
7022 CastUint16ToFloat32(()) => Ok(impls::CastUint16ToFloat32.into()),
7023 CastUint16ToFloat64(()) => Ok(impls::CastUint16ToFloat64.into()),
7024 CastUint16ToString(()) => Ok(impls::CastUint16ToString.into()),
7025 CastUint32ToUint16(()) => Ok(impls::CastUint32ToUint16.into()),
7026 CastUint32ToUint64(()) => Ok(impls::CastUint32ToUint64.into()),
7027 CastUint32ToInt16(()) => Ok(impls::CastUint32ToInt16.into()),
7028 CastUint32ToInt32(()) => Ok(impls::CastUint32ToInt32.into()),
7029 CastUint32ToInt64(()) => Ok(impls::CastUint32ToInt64.into()),
7030 CastUint32ToNumeric(max_scale) => {
7031 Ok(impls::CastUint32ToNumeric(max_scale.into_rust()?).into())
7032 }
7033 CastUint32ToFloat32(()) => Ok(impls::CastUint32ToFloat32.into()),
7034 CastUint32ToFloat64(()) => Ok(impls::CastUint32ToFloat64.into()),
7035 CastUint32ToString(()) => Ok(impls::CastUint32ToString.into()),
7036 CastUint64ToUint16(()) => Ok(impls::CastUint64ToUint16.into()),
7037 CastUint64ToUint32(()) => Ok(impls::CastUint64ToUint32.into()),
7038 CastUint64ToInt16(()) => Ok(impls::CastUint64ToInt16.into()),
7039 CastUint64ToInt32(()) => Ok(impls::CastUint64ToInt32.into()),
7040 CastUint64ToInt64(()) => Ok(impls::CastUint64ToInt64.into()),
7041 CastUint64ToNumeric(max_scale) => {
7042 Ok(impls::CastUint64ToNumeric(max_scale.into_rust()?).into())
7043 }
7044 CastUint64ToFloat32(()) => Ok(impls::CastUint64ToFloat32.into()),
7045 CastUint64ToFloat64(()) => Ok(impls::CastUint64ToFloat64.into()),
7046 CastUint64ToString(()) => Ok(impls::CastUint64ToString.into()),
7047 CastFloat32ToInt16(()) => Ok(impls::CastFloat32ToInt16.into()),
7048 CastFloat32ToInt32(()) => Ok(impls::CastFloat32ToInt32.into()),
7049 CastFloat32ToInt64(()) => Ok(impls::CastFloat32ToInt64.into()),
7050 CastFloat32ToUint16(()) => Ok(impls::CastFloat32ToUint16.into()),
7051 CastFloat32ToUint32(()) => Ok(impls::CastFloat32ToUint32.into()),
7052 CastFloat32ToUint64(()) => Ok(impls::CastFloat32ToUint64.into()),
7053 CastFloat32ToFloat64(()) => Ok(impls::CastFloat32ToFloat64.into()),
7054 CastFloat32ToString(()) => Ok(impls::CastFloat32ToString.into()),
7055 CastFloat32ToNumeric(max_scale) => {
7056 Ok(impls::CastFloat32ToNumeric(max_scale.into_rust()?).into())
7057 }
7058 CastFloat64ToNumeric(max_scale) => {
7059 Ok(impls::CastFloat64ToNumeric(max_scale.into_rust()?).into())
7060 }
7061 CastFloat64ToInt16(()) => Ok(impls::CastFloat64ToInt16.into()),
7062 CastFloat64ToInt32(()) => Ok(impls::CastFloat64ToInt32.into()),
7063 CastFloat64ToInt64(()) => Ok(impls::CastFloat64ToInt64.into()),
7064 CastFloat64ToUint16(()) => Ok(impls::CastFloat64ToUint16.into()),
7065 CastFloat64ToUint32(()) => Ok(impls::CastFloat64ToUint32.into()),
7066 CastFloat64ToUint64(()) => Ok(impls::CastFloat64ToUint64.into()),
7067 CastFloat64ToFloat32(()) => Ok(impls::CastFloat64ToFloat32.into()),
7068 CastFloat64ToString(()) => Ok(impls::CastFloat64ToString.into()),
7069 CastNumericToFloat32(()) => Ok(impls::CastNumericToFloat32.into()),
7070 CastNumericToFloat64(()) => Ok(impls::CastNumericToFloat64.into()),
7071 CastNumericToInt16(()) => Ok(impls::CastNumericToInt16.into()),
7072 CastNumericToInt32(()) => Ok(impls::CastNumericToInt32.into()),
7073 CastNumericToInt64(()) => Ok(impls::CastNumericToInt64.into()),
7074 CastNumericToUint16(()) => Ok(impls::CastNumericToUint16.into()),
7075 CastNumericToUint32(()) => Ok(impls::CastNumericToUint32.into()),
7076 CastNumericToUint64(()) => Ok(impls::CastNumericToUint64.into()),
7077 CastNumericToString(()) => Ok(impls::CastNumericToString.into()),
7078 CastStringToBool(()) => Ok(impls::CastStringToBool.into()),
7079 CastStringToPgLegacyChar(()) => Ok(impls::CastStringToPgLegacyChar.into()),
7080 CastStringToPgLegacyName(()) => Ok(impls::CastStringToPgLegacyName.into()),
7081 CastStringToBytes(()) => Ok(impls::CastStringToBytes.into()),
7082 CastStringToInt16(()) => Ok(impls::CastStringToInt16.into()),
7083 CastStringToInt32(()) => Ok(impls::CastStringToInt32.into()),
7084 CastStringToInt64(()) => Ok(impls::CastStringToInt64.into()),
7085 CastStringToUint16(()) => Ok(impls::CastStringToUint16.into()),
7086 CastStringToUint32(()) => Ok(impls::CastStringToUint32.into()),
7087 CastStringToUint64(()) => Ok(impls::CastStringToUint64.into()),
7088 CastStringToInt2Vector(()) => Ok(impls::CastStringToInt2Vector.into()),
7089 CastStringToOid(()) => Ok(impls::CastStringToOid.into()),
7090 CastStringToFloat32(()) => Ok(impls::CastStringToFloat32.into()),
7091 CastStringToFloat64(()) => Ok(impls::CastStringToFloat64.into()),
7092 CastStringToDate(()) => Ok(impls::CastStringToDate.into()),
7093 CastStringToArray(inner) => Ok(impls::CastStringToArray {
7094 return_ty: inner
7095 .return_ty
7096 .into_rust_if_some("ProtoCastStringToArray::return_ty")?,
7097 cast_expr: inner
7098 .cast_expr
7099 .into_rust_if_some("ProtoCastStringToArray::cast_expr")?,
7100 }
7101 .into()),
7102 CastStringToList(inner) => Ok(impls::CastStringToList {
7103 return_ty: inner
7104 .return_ty
7105 .into_rust_if_some("ProtoCastStringToList::return_ty")?,
7106 cast_expr: inner
7107 .cast_expr
7108 .into_rust_if_some("ProtoCastStringToList::cast_expr")?,
7109 }
7110 .into()),
7111 CastStringToRange(inner) => Ok(impls::CastStringToRange {
7112 return_ty: inner
7113 .return_ty
7114 .into_rust_if_some("ProtoCastStringToRange::return_ty")?,
7115 cast_expr: inner
7116 .cast_expr
7117 .into_rust_if_some("ProtoCastStringToRange::cast_expr")?,
7118 }
7119 .into()),
7120 CastStringToMap(inner) => Ok(impls::CastStringToMap {
7121 return_ty: inner
7122 .return_ty
7123 .into_rust_if_some("ProtoCastStringToMap::return_ty")?,
7124 cast_expr: inner
7125 .cast_expr
7126 .into_rust_if_some("ProtoCastStringToMap::cast_expr")?,
7127 }
7128 .into()),
7129 CastStringToTime(()) => Ok(impls::CastStringToTime.into()),
7130 CastStringToTimestamp(precision) => {
7131 Ok(impls::CastStringToTimestamp(precision.into_rust()?).into())
7132 }
7133 CastStringToTimestampTz(precision) => {
7134 Ok(impls::CastStringToTimestampTz(precision.into_rust()?).into())
7135 }
7136 CastStringToInterval(()) => Ok(impls::CastStringToInterval.into()),
7137 CastStringToNumeric(max_scale) => {
7138 Ok(impls::CastStringToNumeric(max_scale.into_rust()?).into())
7139 }
7140 CastStringToUuid(()) => Ok(impls::CastStringToUuid.into()),
7141 CastStringToChar(func) => Ok(impls::CastStringToChar {
7142 length: func.length.into_rust()?,
7143 fail_on_len: func.fail_on_len,
7144 }
7145 .into()),
7146 PadChar(func) => Ok(impls::PadChar {
7147 length: func.length.into_rust()?,
7148 }
7149 .into()),
7150 CastStringToVarChar(func) => Ok(impls::CastStringToVarChar {
7151 length: func.length.into_rust()?,
7152 fail_on_len: func.fail_on_len,
7153 }
7154 .into()),
7155 CastCharToString(()) => Ok(impls::CastCharToString.into()),
7156 CastVarCharToString(()) => Ok(impls::CastVarCharToString.into()),
7157 CastDateToTimestamp(precision) => {
7158 Ok(impls::CastDateToTimestamp(precision.into_rust()?).into())
7159 }
7160 CastDateToTimestampTz(precision) => {
7161 Ok(impls::CastDateToTimestampTz(precision.into_rust()?).into())
7162 }
7163 CastDateToString(()) => Ok(impls::CastDateToString.into()),
7164 CastTimeToInterval(()) => Ok(impls::CastTimeToInterval.into()),
7165 CastTimeToString(()) => Ok(impls::CastTimeToString.into()),
7166 CastIntervalToString(()) => Ok(impls::CastIntervalToString.into()),
7167 CastIntervalToTime(()) => Ok(impls::CastIntervalToTime.into()),
7168 CastTimestampToDate(()) => Ok(impls::CastTimestampToDate.into()),
7169 AdjustTimestampPrecision(precisions) => Ok(impls::AdjustTimestampPrecision {
7170 from: precisions.from.into_rust()?,
7171 to: precisions.to.into_rust()?,
7172 }
7173 .into()),
7174 CastTimestampToTimestampTz(precisions) => Ok(impls::CastTimestampToTimestampTz {
7175 from: precisions.from.into_rust()?,
7176 to: precisions.to.into_rust()?,
7177 }
7178 .into()),
7179 CastTimestampToString(()) => Ok(impls::CastTimestampToString.into()),
7180 CastTimestampToTime(()) => Ok(impls::CastTimestampToTime.into()),
7181 CastTimestampTzToDate(()) => Ok(impls::CastTimestampTzToDate.into()),
7182 CastTimestampTzToTimestamp(precisions) => Ok(impls::CastTimestampTzToTimestamp {
7183 from: precisions.from.into_rust()?,
7184 to: precisions.to.into_rust()?,
7185 }
7186 .into()),
7187 AdjustTimestampTzPrecision(precisions) => Ok(impls::AdjustTimestampTzPrecision {
7188 from: precisions.from.into_rust()?,
7189 to: precisions.to.into_rust()?,
7190 }
7191 .into()),
7192 CastTimestampTzToString(()) => Ok(impls::CastTimestampTzToString.into()),
7193 CastTimestampTzToTime(()) => Ok(impls::CastTimestampTzToTime.into()),
7194 CastPgLegacyCharToString(()) => Ok(impls::CastPgLegacyCharToString.into()),
7195 CastPgLegacyCharToChar(()) => Ok(impls::CastPgLegacyCharToChar.into()),
7196 CastPgLegacyCharToVarChar(()) => Ok(impls::CastPgLegacyCharToVarChar.into()),
7197 CastPgLegacyCharToInt32(()) => Ok(impls::CastPgLegacyCharToInt32.into()),
7198 CastBytesToString(()) => Ok(impls::CastBytesToString.into()),
7199 CastStringToJsonb(()) => Ok(impls::CastStringToJsonb.into()),
7200 CastJsonbToString(()) => Ok(impls::CastJsonbToString.into()),
7201 CastJsonbableToJsonb(()) => Ok(impls::CastJsonbableToJsonb.into()),
7202 CastJsonbToInt16(()) => Ok(impls::CastJsonbToInt16.into()),
7203 CastJsonbToInt32(()) => Ok(impls::CastJsonbToInt32.into()),
7204 CastJsonbToInt64(()) => Ok(impls::CastJsonbToInt64.into()),
7205 CastJsonbToFloat32(()) => Ok(impls::CastJsonbToFloat32.into()),
7206 CastJsonbToFloat64(()) => Ok(impls::CastJsonbToFloat64.into()),
7207 CastJsonbToNumeric(max_scale) => {
7208 Ok(impls::CastJsonbToNumeric(max_scale.into_rust()?).into())
7209 }
7210 CastJsonbToBool(()) => Ok(impls::CastJsonbToBool.into()),
7211 CastUuidToString(()) => Ok(impls::CastUuidToString.into()),
7212 CastRecordToString(ty) => Ok(impls::CastRecordToString {
7213 ty: ty.into_rust()?,
7214 }
7215 .into()),
7216 CastRecord1ToRecord2(inner) => Ok(impls::CastRecord1ToRecord2 {
7217 return_ty: inner
7218 .return_ty
7219 .into_rust_if_some("ProtoCastRecord1ToRecord2::return_ty")?,
7220 cast_exprs: inner.cast_exprs.into_rust()?,
7221 }
7222 .into()),
7223 CastArrayToArray(inner) => Ok(impls::CastArrayToArray {
7224 return_ty: inner
7225 .return_ty
7226 .into_rust_if_some("ProtoCastArrayToArray::return_ty")?,
7227 cast_expr: inner
7228 .cast_expr
7229 .into_rust_if_some("ProtoCastArrayToArray::cast_expr")?,
7230 }
7231 .into()),
7232 CastArrayToJsonb(cast_element) => Ok(impls::CastArrayToJsonb {
7233 cast_element: cast_element.into_rust()?,
7234 }
7235 .into()),
7236 CastArrayToString(ty) => Ok(impls::CastArrayToString {
7237 ty: ty.into_rust()?,
7238 }
7239 .into()),
7240 CastListToJsonb(cast_element) => Ok(impls::CastListToJsonb {
7241 cast_element: cast_element.into_rust()?,
7242 }
7243 .into()),
7244 CastListToString(ty) => Ok(impls::CastListToString {
7245 ty: ty.into_rust()?,
7246 }
7247 .into()),
7248 CastList1ToList2(inner) => Ok(impls::CastList1ToList2 {
7249 return_ty: inner
7250 .return_ty
7251 .into_rust_if_some("ProtoCastList1ToList2::return_ty")?,
7252 cast_expr: inner
7253 .cast_expr
7254 .into_rust_if_some("ProtoCastList1ToList2::cast_expr")?,
7255 }
7256 .into()),
7257 CastArrayToListOneDim(()) => Ok(impls::CastArrayToListOneDim.into()),
7258 CastMapToString(ty) => Ok(impls::CastMapToString {
7259 ty: ty.into_rust()?,
7260 }
7261 .into()),
7262 CastInt2VectorToString(_) => Ok(impls::CastInt2VectorToString.into()),
7263 CastRangeToString(ty) => Ok(impls::CastRangeToString {
7264 ty: ty.into_rust()?,
7265 }
7266 .into()),
7267 CeilFloat32(_) => Ok(impls::CeilFloat32.into()),
7268 CeilFloat64(_) => Ok(impls::CeilFloat64.into()),
7269 CeilNumeric(_) => Ok(impls::CeilNumeric.into()),
7270 FloorFloat32(_) => Ok(impls::FloorFloat32.into()),
7271 FloorFloat64(_) => Ok(impls::FloorFloat64.into()),
7272 FloorNumeric(_) => Ok(impls::FloorNumeric.into()),
7273 Ascii(_) => Ok(impls::Ascii.into()),
7274 BitCountBytes(_) => Ok(impls::BitCountBytes.into()),
7275 BitLengthBytes(_) => Ok(impls::BitLengthBytes.into()),
7276 BitLengthString(_) => Ok(impls::BitLengthString.into()),
7277 ByteLengthBytes(_) => Ok(impls::ByteLengthBytes.into()),
7278 ByteLengthString(_) => Ok(impls::ByteLengthString.into()),
7279 CharLength(_) => Ok(impls::CharLength.into()),
7280 Chr(_) => Ok(impls::Chr.into()),
7281 IsLikeMatch(pattern) => Ok(impls::IsLikeMatch(pattern.into_rust()?).into()),
7282 IsRegexpMatch(regex) => Ok(impls::IsRegexpMatch(regex.into_rust()?).into()),
7283 RegexpMatch(regex) => Ok(impls::RegexpMatch(regex.into_rust()?).into()),
7284 RegexpSplitToArray(regex) => {
7285 Ok(impls::RegexpSplitToArray(regex.into_rust()?).into())
7286 }
7287 ExtractInterval(units) => Ok(impls::ExtractInterval(units.into_rust()?).into()),
7288 ExtractTime(units) => Ok(impls::ExtractTime(units.into_rust()?).into()),
7289 ExtractTimestamp(units) => Ok(impls::ExtractTimestamp(units.into_rust()?).into()),
7290 ExtractTimestampTz(units) => {
7291 Ok(impls::ExtractTimestampTz(units.into_rust()?).into())
7292 }
7293 ExtractDate(units) => Ok(impls::ExtractDate(units.into_rust()?).into()),
7294 DatePartInterval(units) => Ok(impls::DatePartInterval(units.into_rust()?).into()),
7295 DatePartTime(units) => Ok(impls::DatePartTime(units.into_rust()?).into()),
7296 DatePartTimestamp(units) => Ok(impls::DatePartTimestamp(units.into_rust()?).into()),
7297 DatePartTimestampTz(units) => {
7298 Ok(impls::DatePartTimestampTz(units.into_rust()?).into())
7299 }
7300 DateTruncTimestamp(units) => {
7301 Ok(impls::DateTruncTimestamp(units.into_rust()?).into())
7302 }
7303 DateTruncTimestampTz(units) => {
7304 Ok(impls::DateTruncTimestampTz(units.into_rust()?).into())
7305 }
7306 TimezoneTimestamp(tz) => Ok(impls::TimezoneTimestamp(tz.into_rust()?).into()),
7307 TimezoneTimestampTz(tz) => Ok(impls::TimezoneTimestampTz(tz.into_rust()?).into()),
7308 TimezoneTime(func) => Ok(impls::TimezoneTime {
7309 tz: func.tz.into_rust_if_some("ProtoTimezoneTime::tz")?,
7310 wall_time: func
7311 .wall_time
7312 .into_rust_if_some("ProtoTimezoneTime::wall_time")?,
7313 }
7314 .into()),
7315 ToTimestamp(()) => Ok(impls::ToTimestamp.into()),
7316 ToCharTimestamp(func) => Ok(impls::ToCharTimestamp {
7317 format_string: func.format_string,
7318 format: func
7319 .format
7320 .into_rust_if_some("ProtoToCharTimestamp::format")?,
7321 }
7322 .into()),
7323 ToCharTimestampTz(func) => Ok(impls::ToCharTimestampTz {
7324 format_string: func.format_string,
7325 format: func
7326 .format
7327 .into_rust_if_some("ProtoToCharTimestamp::format")?,
7328 }
7329 .into()),
7330 JustifyDays(()) => Ok(impls::JustifyDays.into()),
7331 JustifyHours(()) => Ok(impls::JustifyHours.into()),
7332 JustifyInterval(()) => Ok(impls::JustifyInterval.into()),
7333 JsonbArrayLength(()) => Ok(impls::JsonbArrayLength.into()),
7334 JsonbTypeof(()) => Ok(impls::JsonbTypeof.into()),
7335 JsonbStripNulls(()) => Ok(impls::JsonbStripNulls.into()),
7336 JsonbPretty(()) => Ok(impls::JsonbPretty.into()),
7337 RoundFloat32(()) => Ok(impls::RoundFloat32.into()),
7338 RoundFloat64(()) => Ok(impls::RoundFloat64.into()),
7339 RoundNumeric(()) => Ok(impls::RoundNumeric.into()),
7340 TruncFloat32(()) => Ok(impls::TruncFloat32.into()),
7341 TruncFloat64(()) => Ok(impls::TruncFloat64.into()),
7342 TruncNumeric(()) => Ok(impls::TruncNumeric.into()),
7343 TrimWhitespace(()) => Ok(impls::TrimWhitespace.into()),
7344 TrimLeadingWhitespace(()) => Ok(impls::TrimLeadingWhitespace.into()),
7345 TrimTrailingWhitespace(()) => Ok(impls::TrimTrailingWhitespace.into()),
7346 Initcap(()) => Ok(impls::Initcap.into()),
7347 RecordGet(field) => Ok(impls::RecordGet(field.into_rust()?).into()),
7348 ListLength(()) => Ok(impls::ListLength.into()),
7349 MapBuildFromRecordList(value_type) => Ok(impls::MapBuildFromRecordList {
7350 value_type: value_type.into_rust()?,
7351 }
7352 .into()),
7353 MapLength(()) => Ok(impls::MapLength.into()),
7354 Upper(()) => Ok(impls::Upper.into()),
7355 Lower(()) => Ok(impls::Lower.into()),
7356 Cos(()) => Ok(impls::Cos.into()),
7357 Acos(()) => Ok(impls::Acos.into()),
7358 Cosh(()) => Ok(impls::Cosh.into()),
7359 Acosh(()) => Ok(impls::Acosh.into()),
7360 Sin(()) => Ok(impls::Sin.into()),
7361 Asin(()) => Ok(impls::Asin.into()),
7362 Sinh(()) => Ok(impls::Sinh.into()),
7363 Asinh(()) => Ok(impls::Asinh.into()),
7364 Tan(()) => Ok(impls::Tan.into()),
7365 Atan(()) => Ok(impls::Atan.into()),
7366 Tanh(()) => Ok(impls::Tanh.into()),
7367 Atanh(()) => Ok(impls::Atanh.into()),
7368 Cot(()) => Ok(impls::Cot.into()),
7369 Degrees(()) => Ok(impls::Degrees.into()),
7370 Radians(()) => Ok(impls::Radians.into()),
7371 Log10(()) => Ok(impls::Log10.into()),
7372 Log10Numeric(()) => Ok(impls::Log10Numeric.into()),
7373 Ln(()) => Ok(impls::Ln.into()),
7374 LnNumeric(()) => Ok(impls::LnNumeric.into()),
7375 Exp(()) => Ok(impls::Exp.into()),
7376 ExpNumeric(()) => Ok(impls::ExpNumeric.into()),
7377 Sleep(()) => Ok(impls::Sleep.into()),
7378 Panic(()) => Ok(impls::Panic.into()),
7379 AdjustNumericScale(max_scale) => {
7380 Ok(impls::AdjustNumericScale(max_scale.into_rust()?).into())
7381 }
7382 PgColumnSize(()) => Ok(impls::PgColumnSize.into()),
7383 PgSizePretty(()) => Ok(impls::PgSizePretty.into()),
7384 MzRowSize(()) => Ok(impls::MzRowSize.into()),
7385 MzTypeName(()) => Ok(impls::MzTypeName.into()),
7386
7387 CastMzTimestampToString(()) => Ok(impls::CastMzTimestampToString.into()),
7388 CastMzTimestampToTimestamp(()) => Ok(impls::CastMzTimestampToTimestamp.into()),
7389 CastMzTimestampToTimestampTz(()) => Ok(impls::CastMzTimestampToTimestampTz.into()),
7390 CastStringToMzTimestamp(()) => Ok(impls::CastStringToMzTimestamp.into()),
7391 CastUint64ToMzTimestamp(()) => Ok(impls::CastUint64ToMzTimestamp.into()),
7392 CastUint32ToMzTimestamp(()) => Ok(impls::CastUint32ToMzTimestamp.into()),
7393 CastInt64ToMzTimestamp(()) => Ok(impls::CastInt64ToMzTimestamp.into()),
7394 CastInt32ToMzTimestamp(()) => Ok(impls::CastInt32ToMzTimestamp.into()),
7395 CastNumericToMzTimestamp(()) => Ok(impls::CastNumericToMzTimestamp.into()),
7396 CastTimestampToMzTimestamp(()) => Ok(impls::CastTimestampToMzTimestamp.into()),
7397 CastTimestampTzToMzTimestamp(()) => Ok(impls::CastTimestampTzToMzTimestamp.into()),
7398 CastDateToMzTimestamp(()) => Ok(impls::CastDateToMzTimestamp.into()),
7399 StepMzTimestamp(()) => Ok(impls::StepMzTimestamp.into()),
7400 RangeLower(()) => Ok(impls::RangeLower.into()),
7401 RangeUpper(()) => Ok(impls::RangeUpper.into()),
7402 RangeEmpty(()) => Ok(impls::RangeEmpty.into()),
7403 RangeLowerInc(_) => Ok(impls::RangeLowerInc.into()),
7404 RangeUpperInc(_) => Ok(impls::RangeUpperInc.into()),
7405 RangeLowerInf(_) => Ok(impls::RangeLowerInf.into()),
7406 RangeUpperInf(_) => Ok(impls::RangeUpperInf.into()),
7407 MzAclItemGrantor(_) => Ok(impls::MzAclItemGrantor.into()),
7408 MzAclItemGrantee(_) => Ok(impls::MzAclItemGrantee.into()),
7409 MzAclItemPrivileges(_) => Ok(impls::MzAclItemPrivileges.into()),
7410 MzFormatPrivileges(_) => Ok(impls::MzFormatPrivileges.into()),
7411 MzValidatePrivileges(_) => Ok(impls::MzValidatePrivileges.into()),
7412 MzValidateRolePrivilege(_) => Ok(impls::MzValidateRolePrivilege.into()),
7413 AclItemGrantor(_) => Ok(impls::AclItemGrantor.into()),
7414 AclItemGrantee(_) => Ok(impls::AclItemGrantee.into()),
7415 AclItemPrivileges(_) => Ok(impls::AclItemPrivileges.into()),
7416 QuoteIdent(_) => Ok(impls::QuoteIdent.into()),
7417 TryParseMonotonicIso8601Timestamp(_) => {
7418 Ok(impls::TryParseMonotonicIso8601Timestamp.into())
7419 }
7420 Crc32Bytes(()) => Ok(impls::Crc32Bytes.into()),
7421 Crc32String(()) => Ok(impls::Crc32String.into()),
7422 KafkaMurmur2Bytes(()) => Ok(impls::KafkaMurmur2Bytes.into()),
7423 KafkaMurmur2String(()) => Ok(impls::KafkaMurmur2String.into()),
7424 SeahashBytes(()) => Ok(impls::SeahashBytes.into()),
7425 SeahashString(()) => Ok(impls::SeahashString.into()),
7426 Reverse(()) => Ok(impls::Reverse.into()),
7427 }
7428 } else {
7429 Err(TryFromProtoError::missing_field("ProtoUnaryFunc::kind"))
7430 }
7431 }
7432}
7433
7434impl IntoRustIfSome<UnaryFunc> for Option<Box<ProtoUnaryFunc>> {
7435 fn into_rust_if_some<S: ToString>(self, field: S) -> Result<UnaryFunc, TryFromProtoError> {
7436 let value = self.ok_or_else(|| TryFromProtoError::missing_field(field))?;
7437 (*value).into_rust()
7438 }
7439}
7440
7441fn coalesce<'a>(
7442 datums: &[Datum<'a>],
7443 temp_storage: &'a RowArena,
7444 exprs: &'a [MirScalarExpr],
7445) -> Result<Datum<'a>, EvalError> {
7446 for e in exprs {
7447 let d = e.eval(datums, temp_storage)?;
7448 if !d.is_null() {
7449 return Ok(d);
7450 }
7451 }
7452 Ok(Datum::Null)
7453}
7454
7455fn greatest<'a>(
7456 datums: &[Datum<'a>],
7457 temp_storage: &'a RowArena,
7458 exprs: &'a [MirScalarExpr],
7459) -> Result<Datum<'a>, EvalError> {
7460 let datums = fallible_iterator::convert(exprs.iter().map(|e| e.eval(datums, temp_storage)));
7461 Ok(datums
7462 .filter(|d| Ok(!d.is_null()))
7463 .max()?
7464 .unwrap_or(Datum::Null))
7465}
7466
7467fn least<'a>(
7468 datums: &[Datum<'a>],
7469 temp_storage: &'a RowArena,
7470 exprs: &'a [MirScalarExpr],
7471) -> Result<Datum<'a>, EvalError> {
7472 let datums = fallible_iterator::convert(exprs.iter().map(|e| e.eval(datums, temp_storage)));
7473 Ok(datums
7474 .filter(|d| Ok(!d.is_null()))
7475 .min()?
7476 .unwrap_or(Datum::Null))
7477}
7478
7479fn error_if_null<'a>(
7480 datums: &[Datum<'a>],
7481 temp_storage: &'a RowArena,
7482 exprs: &'a [MirScalarExpr],
7483) -> Result<Datum<'a>, EvalError> {
7484 let first = exprs[0].eval(datums, temp_storage)?;
7485 match first {
7486 Datum::Null => {
7487 let err_msg = match exprs[1].eval(datums, temp_storage)? {
7488 Datum::Null => {
7489 return Err(EvalError::Internal(
7490 "unexpected NULL in error side of error_if_null".into(),
7491 ));
7492 }
7493 o => o.unwrap_str(),
7494 };
7495 Err(EvalError::IfNullError(err_msg.into()))
7496 }
7497 _ => Ok(first),
7498 }
7499}
7500
7501#[sqlfunc(
7502 sqlname = "||",
7503 is_infix_op = true,
7504 output_type = "String",
7505 propagates_nulls = true,
7506 is_monotone = (false, true),
7507)]
7508fn text_concat_binary<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
7509 let mut buf = String::new();
7510 buf.push_str(a.unwrap_str());
7511 buf.push_str(b.unwrap_str());
7512 Datum::String(temp_storage.push_string(buf))
7513}
7514
7515fn text_concat_variadic<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7516 let mut buf = String::new();
7517 for d in datums {
7518 if !d.is_null() {
7519 buf.push_str(d.unwrap_str());
7520 }
7521 }
7522 Datum::String(temp_storage.push_string(buf))
7523}
7524
7525fn text_concat_ws<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7526 let ws = match datums[0] {
7527 Datum::Null => return Datum::Null,
7528 d => d.unwrap_str(),
7529 };
7530
7531 let buf = Itertools::join(
7532 &mut datums[1..].iter().filter_map(|d| match d {
7533 Datum::Null => None,
7534 d => Some(d.unwrap_str()),
7535 }),
7536 ws,
7537 );
7538
7539 Datum::String(temp_storage.push_string(buf))
7540}
7541
7542fn pad_leading<'a>(
7543 datums: &[Datum<'a>],
7544 temp_storage: &'a RowArena,
7545) -> Result<Datum<'a>, EvalError> {
7546 let string = datums[0].unwrap_str();
7547
7548 let len = match usize::try_from(datums[1].unwrap_int32()) {
7549 Ok(len) => len,
7550 Err(_) => {
7551 return Err(EvalError::InvalidParameterValue(
7552 "length must be nonnegative".into(),
7553 ));
7554 }
7555 };
7556 if len > MAX_STRING_BYTES {
7557 return Err(EvalError::LengthTooLarge);
7558 }
7559
7560 let pad_string = if datums.len() == 3 {
7561 datums[2].unwrap_str()
7562 } else {
7563 " "
7564 };
7565
7566 let (end_char, end_char_byte_offset) = string
7567 .chars()
7568 .take(len)
7569 .fold((0, 0), |acc, char| (acc.0 + 1, acc.1 + char.len_utf8()));
7570
7571 let mut buf = String::with_capacity(len);
7572 if len == end_char {
7573 buf.push_str(&string[0..end_char_byte_offset]);
7574 } else {
7575 buf.extend(pad_string.chars().cycle().take(len - end_char));
7576 buf.push_str(string);
7577 }
7578
7579 Ok(Datum::String(temp_storage.push_string(buf)))
7580}
7581
7582fn substr<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
7583 let s: &'a str = datums[0].unwrap_str();
7584
7585 let raw_start_idx = i64::from(datums[1].unwrap_int32()) - 1;
7586 let start_idx = match usize::try_from(cmp::max(raw_start_idx, 0)) {
7587 Ok(i) => i,
7588 Err(_) => {
7589 return Err(EvalError::InvalidParameterValue(
7590 format!(
7591 "substring starting index ({}) exceeds min/max position",
7592 raw_start_idx
7593 )
7594 .into(),
7595 ));
7596 }
7597 };
7598
7599 let mut char_indices = s.char_indices();
7600 let get_str_index = |(index, _char)| index;
7601
7602 let str_len = s.len();
7603 let start_char_idx = char_indices.nth(start_idx).map_or(str_len, get_str_index);
7604
7605 if datums.len() == 3 {
7606 let end_idx = match i64::from(datums[2].unwrap_int32()) {
7607 e if e < 0 => {
7608 return Err(EvalError::InvalidParameterValue(
7609 "negative substring length not allowed".into(),
7610 ));
7611 }
7612 e if e == 0 || e + raw_start_idx < 1 => return Ok(Datum::String("")),
7613 e => {
7614 let e = cmp::min(raw_start_idx + e - 1, e - 1);
7615 match usize::try_from(e) {
7616 Ok(i) => i,
7617 Err(_) => {
7618 return Err(EvalError::InvalidParameterValue(
7619 format!("substring length ({}) exceeds max position", e).into(),
7620 ));
7621 }
7622 }
7623 }
7624 };
7625
7626 let end_char_idx = char_indices.nth(end_idx).map_or(str_len, get_str_index);
7627
7628 Ok(Datum::String(&s[start_char_idx..end_char_idx]))
7629 } else {
7630 Ok(Datum::String(&s[start_char_idx..]))
7631 }
7632}
7633
7634fn split_part<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
7635 let string = datums[0].unwrap_str();
7636 let delimiter = datums[1].unwrap_str();
7637
7638 let index = match usize::try_from(i64::from(datums[2].unwrap_int32()) - 1) {
7640 Ok(index) => index,
7641 Err(_) => {
7642 return Err(EvalError::InvalidParameterValue(
7643 "field position must be greater than zero".into(),
7644 ));
7645 }
7646 };
7647
7648 if delimiter.is_empty() {
7652 if index == 0 {
7653 return Ok(datums[0]);
7654 } else {
7655 return Ok(Datum::String(""));
7656 }
7657 }
7658
7659 Ok(Datum::String(
7662 string.split(delimiter).nth(index).unwrap_or(""),
7663 ))
7664}
7665
7666#[sqlfunc(
7667 output_type = "String",
7668 propagates_nulls = true,
7669 introduces_nulls = false
7670)]
7671fn like_escape<'a>(
7672 a: Datum<'a>,
7673 b: Datum<'a>,
7674 temp_storage: &'a RowArena,
7675) -> Result<Datum<'a>, EvalError> {
7676 let pattern = a.unwrap_str();
7677 let escape = like_pattern::EscapeBehavior::from_str(b.unwrap_str())?;
7678 let normalized = like_pattern::normalize_pattern(pattern, escape)?;
7679 Ok(Datum::String(temp_storage.push_string(normalized)))
7680}
7681
7682fn is_like_match_dynamic<'a>(
7683 a: Datum<'a>,
7684 b: Datum<'a>,
7685 case_insensitive: bool,
7686) -> Result<Datum<'a>, EvalError> {
7687 let haystack = a.unwrap_str();
7688 let needle = like_pattern::compile(b.unwrap_str(), case_insensitive)?;
7689 Ok(Datum::from(needle.is_match(haystack.as_ref())))
7690}
7691
7692fn is_regexp_match_dynamic<'a>(
7693 a: Datum<'a>,
7694 b: Datum<'a>,
7695 case_insensitive: bool,
7696) -> Result<Datum<'a>, EvalError> {
7697 let haystack = a.unwrap_str();
7698 let needle = build_regex(b.unwrap_str(), if case_insensitive { "i" } else { "" })?;
7699 Ok(Datum::from(needle.is_match(haystack)))
7700}
7701
7702fn regexp_match_dynamic<'a>(
7703 datums: &[Datum<'a>],
7704 temp_storage: &'a RowArena,
7705) -> Result<Datum<'a>, EvalError> {
7706 let haystack = datums[0];
7707 let needle = datums[1].unwrap_str();
7708 let flags = match datums.get(2) {
7709 Some(d) => d.unwrap_str(),
7710 None => "",
7711 };
7712 let needle = build_regex(needle, flags)?;
7713 regexp_match_static(haystack, temp_storage, &needle)
7714}
7715
7716fn regexp_match_static<'a>(
7717 haystack: Datum<'a>,
7718 temp_storage: &'a RowArena,
7719 needle: ®ex::Regex,
7720) -> Result<Datum<'a>, EvalError> {
7721 let mut row = Row::default();
7722 let mut packer = row.packer();
7723 if needle.captures_len() > 1 {
7724 match needle.captures(haystack.unwrap_str()) {
7729 None => packer.push(Datum::Null),
7730 Some(captures) => packer.try_push_array(
7731 &[ArrayDimension {
7732 lower_bound: 1,
7733 length: captures.len() - 1,
7734 }],
7735 captures.iter().skip(1).map(|mtch| match mtch {
7737 None => Datum::Null,
7738 Some(mtch) => Datum::String(mtch.as_str()),
7739 }),
7740 )?,
7741 }
7742 } else {
7743 match needle.find(haystack.unwrap_str()) {
7746 None => packer.push(Datum::Null),
7747 Some(mtch) => packer.try_push_array(
7748 &[ArrayDimension {
7749 lower_bound: 1,
7750 length: 1,
7751 }],
7752 iter::once(Datum::String(mtch.as_str())),
7753 )?,
7754 };
7755 };
7756 Ok(temp_storage.push_unary_row(row))
7757}
7758
7759fn regexp_replace_dynamic<'a>(
7760 datums: &[Datum<'a>],
7761 temp_storage: &'a RowArena,
7762) -> Result<Datum<'a>, EvalError> {
7763 let source = datums[0];
7764 let pattern = datums[1];
7765 let replacement = datums[2];
7766 let flags = match datums.get(3) {
7767 Some(d) => d.unwrap_str(),
7768 None => "",
7769 };
7770 let (limit, flags) = regexp_replace_parse_flags(flags);
7771 let regexp = build_regex(pattern.unwrap_str(), &flags)?;
7772 regexp_replace_static(source, replacement, ®exp, limit, temp_storage)
7773}
7774
7775pub(crate) fn regexp_replace_parse_flags(flags: &str) -> (usize, Cow<'_, str>) {
7778 let (limit, flags) = if flags.contains('g') {
7781 let flags = flags.replace('g', "");
7782 (0, Cow::Owned(flags))
7783 } else {
7784 (1, Cow::Borrowed(flags))
7785 };
7786 (limit, flags)
7787}
7788
7789fn regexp_replace_static<'a>(
7790 source: Datum<'a>,
7791 replacement: Datum<'a>,
7792 regexp: ®ex::Regex,
7793 limit: usize,
7794 temp_storage: &'a RowArena,
7795) -> Result<Datum<'a>, EvalError> {
7796 let replaced = match regexp.replacen(source.unwrap_str(), limit, replacement.unwrap_str()) {
7797 Cow::Borrowed(s) => s,
7798 Cow::Owned(s) => temp_storage.push_string(s),
7799 };
7800 Ok(Datum::String(replaced))
7801}
7802
7803pub fn build_regex(needle: &str, flags: &str) -> Result<Regex, EvalError> {
7804 let mut case_insensitive = false;
7805 for f in flags.chars() {
7807 match f {
7808 'i' => {
7809 case_insensitive = true;
7810 }
7811 'c' => {
7812 case_insensitive = false;
7813 }
7814 _ => return Err(EvalError::InvalidRegexFlag(f)),
7815 }
7816 }
7817 Ok(Regex::new(needle, case_insensitive)?)
7818}
7819
7820pub fn hmac_string<'a>(
7821 datums: &[Datum<'a>],
7822 temp_storage: &'a RowArena,
7823) -> Result<Datum<'a>, EvalError> {
7824 let to_digest = datums[0].unwrap_str().as_bytes();
7825 let key = datums[1].unwrap_str().as_bytes();
7826 let typ = datums[2].unwrap_str();
7827 hmac_inner(to_digest, key, typ, temp_storage)
7828}
7829
7830pub fn hmac_bytes<'a>(
7831 datums: &[Datum<'a>],
7832 temp_storage: &'a RowArena,
7833) -> Result<Datum<'a>, EvalError> {
7834 let to_digest = datums[0].unwrap_bytes();
7835 let key = datums[1].unwrap_bytes();
7836 let typ = datums[2].unwrap_str();
7837 hmac_inner(to_digest, key, typ, temp_storage)
7838}
7839
7840pub fn hmac_inner<'a>(
7841 to_digest: &[u8],
7842 key: &[u8],
7843 typ: &str,
7844 temp_storage: &'a RowArena,
7845) -> Result<Datum<'a>, EvalError> {
7846 let bytes = match typ {
7847 "md5" => {
7848 let mut mac = Hmac::<Md5>::new_from_slice(key).expect("HMAC accepts any key size");
7849 mac.update(to_digest);
7850 mac.finalize().into_bytes().to_vec()
7851 }
7852 "sha1" => {
7853 let mut mac = Hmac::<Sha1>::new_from_slice(key).expect("HMAC accepts any key size");
7854 mac.update(to_digest);
7855 mac.finalize().into_bytes().to_vec()
7856 }
7857 "sha224" => {
7858 let mut mac = Hmac::<Sha224>::new_from_slice(key).expect("HMAC accepts any key size");
7859 mac.update(to_digest);
7860 mac.finalize().into_bytes().to_vec()
7861 }
7862 "sha256" => {
7863 let mut mac = Hmac::<Sha256>::new_from_slice(key).expect("HMAC accepts any key size");
7864 mac.update(to_digest);
7865 mac.finalize().into_bytes().to_vec()
7866 }
7867 "sha384" => {
7868 let mut mac = Hmac::<Sha384>::new_from_slice(key).expect("HMAC accepts any key size");
7869 mac.update(to_digest);
7870 mac.finalize().into_bytes().to_vec()
7871 }
7872 "sha512" => {
7873 let mut mac = Hmac::<Sha512>::new_from_slice(key).expect("HMAC accepts any key size");
7874 mac.update(to_digest);
7875 mac.finalize().into_bytes().to_vec()
7876 }
7877 other => return Err(EvalError::InvalidHashAlgorithm(other.into())),
7878 };
7879 Ok(Datum::Bytes(temp_storage.push_bytes(bytes)))
7880}
7881
7882fn repeat_string<'a>(
7883 string: Datum<'a>,
7884 count: Datum<'a>,
7885 temp_storage: &'a RowArena,
7886) -> Result<Datum<'a>, EvalError> {
7887 let len = usize::try_from(count.unwrap_int32()).unwrap_or(0);
7888 let string = string.unwrap_str();
7889 if (len * string.len()) > MAX_STRING_BYTES {
7890 return Err(EvalError::LengthTooLarge);
7891 }
7892 Ok(Datum::String(temp_storage.push_string(string.repeat(len))))
7893}
7894
7895fn replace<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7896 Datum::String(
7897 temp_storage.push_string(
7898 datums[0]
7899 .unwrap_str()
7900 .replace(datums[1].unwrap_str(), datums[2].unwrap_str()),
7901 ),
7902 )
7903}
7904
7905fn translate<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7906 let string = datums[0].unwrap_str();
7907 let from = datums[1].unwrap_str().chars().collect::<Vec<_>>();
7908 let to = datums[2].unwrap_str().chars().collect::<Vec<_>>();
7909
7910 Datum::String(
7911 temp_storage.push_string(
7912 string
7913 .chars()
7914 .filter_map(|c| match from.iter().position(|f| f == &c) {
7915 Some(idx) => to.get(idx).copied(),
7916 None => Some(c),
7917 })
7918 .collect(),
7919 ),
7920 )
7921}
7922
7923fn jsonb_build_array<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7924 temp_storage.make_datum(|packer| {
7925 packer.push_list(datums.into_iter().map(|d| match d {
7926 Datum::Null => Datum::JsonNull,
7927 d => *d,
7928 }))
7929 })
7930}
7931
7932fn jsonb_build_object<'a>(
7933 datums: &[Datum<'a>],
7934 temp_storage: &'a RowArena,
7935) -> Result<Datum<'a>, EvalError> {
7936 let mut kvs = datums.chunks(2).collect::<Vec<_>>();
7937 kvs.sort_by(|kv1, kv2| kv1[0].cmp(&kv2[0]));
7938 kvs.dedup_by(|kv1, kv2| kv1[0] == kv2[0]);
7939 temp_storage.try_make_datum(|packer| {
7940 packer.push_dict_with(|packer| {
7941 for kv in kvs {
7942 let k = kv[0];
7943 if k.is_null() {
7944 return Err(EvalError::KeyCannotBeNull);
7945 };
7946 let v = match kv[1] {
7947 Datum::Null => Datum::JsonNull,
7948 d => d,
7949 };
7950 packer.push(k);
7951 packer.push(v);
7952 }
7953 Ok(())
7954 })
7955 })
7956}
7957
7958fn map_build<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
7959 let map: std::collections::BTreeMap<&str, _> = datums
7961 .into_iter()
7962 .tuples()
7963 .filter_map(|(k, v)| {
7964 if k.is_null() {
7965 None
7966 } else {
7967 Some((k.unwrap_str(), v))
7968 }
7969 })
7970 .collect();
7971
7972 temp_storage.make_datum(|packer| packer.push_dict(map))
7973}
7974
7975fn array_create_multidim<'a>(
7989 datums: &[Datum<'a>],
7990 temp_storage: &'a RowArena,
7991) -> Result<Datum<'a>, EvalError> {
7992 if datums.iter().all(|d| d.unwrap_array().dims().is_empty()) {
7995 let dims = &[];
7996 let datums = &[];
7997 let datum = temp_storage.try_make_datum(|packer| packer.try_push_array(dims, datums))?;
7998 return Ok(datum);
7999 }
8000
8001 let mut dims = vec![ArrayDimension {
8002 lower_bound: 1,
8003 length: datums.len(),
8004 }];
8005 if let Some(d) = datums.first() {
8006 dims.extend(d.unwrap_array().dims());
8007 };
8008 let elements = datums
8009 .iter()
8010 .flat_map(|d| d.unwrap_array().elements().iter());
8011 let datum =
8012 temp_storage.try_make_datum(move |packer| packer.try_push_array(&dims, elements))?;
8013 Ok(datum)
8014}
8015
8016fn array_create_scalar<'a>(
8023 datums: &[Datum<'a>],
8024 temp_storage: &'a RowArena,
8025) -> Result<Datum<'a>, EvalError> {
8026 let mut dims = &[ArrayDimension {
8027 lower_bound: 1,
8028 length: datums.len(),
8029 }][..];
8030 if datums.is_empty() {
8031 dims = &[];
8035 }
8036 let datum = temp_storage.try_make_datum(|packer| packer.try_push_array(dims, datums))?;
8037 Ok(datum)
8038}
8039
8040fn array_to_string<'a>(
8041 datums: &[Datum<'a>],
8042 elem_type: &ScalarType,
8043 temp_storage: &'a RowArena,
8044) -> Result<Datum<'a>, EvalError> {
8045 if datums[0].is_null() || datums[1].is_null() {
8046 return Ok(Datum::Null);
8047 }
8048 let array = datums[0].unwrap_array();
8049 let delimiter = datums[1].unwrap_str();
8050 let null_str = match datums.get(2) {
8051 None | Some(Datum::Null) => None,
8052 Some(d) => Some(d.unwrap_str()),
8053 };
8054
8055 let mut out = String::new();
8056 for elem in array.elements().iter() {
8057 if elem.is_null() {
8058 if let Some(null_str) = null_str {
8059 out.push_str(null_str);
8060 out.push_str(delimiter);
8061 }
8062 } else {
8063 stringify_datum(&mut out, elem, elem_type)?;
8064 out.push_str(delimiter);
8065 }
8066 }
8067 if out.len() > 0 {
8068 out.truncate(out.len() - delimiter.len());
8070 }
8071 Ok(Datum::String(temp_storage.push_string(out)))
8072}
8073
8074fn list_create<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
8075 temp_storage.make_datum(|packer| packer.push_list(datums))
8076}
8077
8078fn stringify_datum<'a, B>(
8079 buf: &mut B,
8080 d: Datum<'a>,
8081 ty: &ScalarType,
8082) -> Result<strconv::Nestable, EvalError>
8083where
8084 B: FormatBuffer,
8085{
8086 use ScalarType::*;
8087 match &ty {
8088 AclItem => Ok(strconv::format_acl_item(buf, d.unwrap_acl_item())),
8089 Bool => Ok(strconv::format_bool(buf, d.unwrap_bool())),
8090 Int16 => Ok(strconv::format_int16(buf, d.unwrap_int16())),
8091 Int32 => Ok(strconv::format_int32(buf, d.unwrap_int32())),
8092 Int64 => Ok(strconv::format_int64(buf, d.unwrap_int64())),
8093 UInt16 => Ok(strconv::format_uint16(buf, d.unwrap_uint16())),
8094 UInt32 | Oid | RegClass | RegProc | RegType => {
8095 Ok(strconv::format_uint32(buf, d.unwrap_uint32()))
8096 }
8097 UInt64 => Ok(strconv::format_uint64(buf, d.unwrap_uint64())),
8098 Float32 => Ok(strconv::format_float32(buf, d.unwrap_float32())),
8099 Float64 => Ok(strconv::format_float64(buf, d.unwrap_float64())),
8100 Numeric { .. } => Ok(strconv::format_numeric(buf, &d.unwrap_numeric())),
8101 Date => Ok(strconv::format_date(buf, d.unwrap_date())),
8102 Time => Ok(strconv::format_time(buf, d.unwrap_time())),
8103 Timestamp { .. } => Ok(strconv::format_timestamp(buf, &d.unwrap_timestamp())),
8104 TimestampTz { .. } => Ok(strconv::format_timestamptz(buf, &d.unwrap_timestamptz())),
8105 Interval => Ok(strconv::format_interval(buf, d.unwrap_interval())),
8106 Bytes => Ok(strconv::format_bytes(buf, d.unwrap_bytes())),
8107 String | VarChar { .. } | PgLegacyName => Ok(strconv::format_string(buf, d.unwrap_str())),
8108 Char { length } => Ok(strconv::format_string(
8109 buf,
8110 &mz_repr::adt::char::format_str_pad(d.unwrap_str(), *length),
8111 )),
8112 PgLegacyChar => {
8113 format_pg_legacy_char(buf, d.unwrap_uint8())?;
8114 Ok(strconv::Nestable::MayNeedEscaping)
8115 }
8116 Jsonb => Ok(strconv::format_jsonb(buf, JsonbRef::from_datum(d))),
8117 Uuid => Ok(strconv::format_uuid(buf, d.unwrap_uuid())),
8118 Record { fields, .. } => {
8119 let mut fields = fields.iter();
8120 strconv::format_record(buf, &d.unwrap_list(), |buf, d| {
8121 let (_name, ty) = fields.next().unwrap();
8122 if d.is_null() {
8123 Ok(buf.write_null())
8124 } else {
8125 stringify_datum(buf.nonnull_buffer(), d, &ty.scalar_type)
8126 }
8127 })
8128 }
8129 Array(elem_type) => strconv::format_array(
8130 buf,
8131 &d.unwrap_array().dims().into_iter().collect::<Vec<_>>(),
8132 &d.unwrap_array().elements(),
8133 |buf, d| {
8134 if d.is_null() {
8135 Ok(buf.write_null())
8136 } else {
8137 stringify_datum(buf.nonnull_buffer(), d, elem_type)
8138 }
8139 },
8140 ),
8141 List { element_type, .. } => strconv::format_list(buf, &d.unwrap_list(), |buf, d| {
8142 if d.is_null() {
8143 Ok(buf.write_null())
8144 } else {
8145 stringify_datum(buf.nonnull_buffer(), d, element_type)
8146 }
8147 }),
8148 Map { value_type, .. } => strconv::format_map(buf, &d.unwrap_map(), |buf, d| {
8149 if d.is_null() {
8150 Ok(buf.write_null())
8151 } else {
8152 stringify_datum(buf.nonnull_buffer(), d, value_type)
8153 }
8154 }),
8155 Int2Vector => strconv::format_legacy_vector(buf, &d.unwrap_array().elements(), |buf, d| {
8156 stringify_datum(buf.nonnull_buffer(), d, &ScalarType::Int16)
8157 }),
8158 MzTimestamp { .. } => Ok(strconv::format_mz_timestamp(buf, d.unwrap_mz_timestamp())),
8159 Range { element_type } => strconv::format_range(buf, &d.unwrap_range(), |buf, d| match d {
8160 Some(d) => stringify_datum(buf.nonnull_buffer(), *d, element_type),
8161 None => Ok::<_, EvalError>(buf.write_null()),
8162 }),
8163 MzAclItem => Ok(strconv::format_mz_acl_item(buf, d.unwrap_mz_acl_item())),
8164 }
8165}
8166
8167fn array_index<'a>(datums: &[Datum<'a>], offset: i64) -> Datum<'a> {
8168 mz_ore::soft_assert_no_log!(offset == 0 || offset == 1, "offset must be either 0 or 1");
8169
8170 let array = datums[0].unwrap_array();
8171 let dims = array.dims();
8172 if dims.len() != datums.len() - 1 {
8173 return Datum::Null;
8175 }
8176
8177 let mut final_idx = 0;
8178
8179 for (d, idx) in dims.into_iter().zip_eq(datums[1..].iter()) {
8180 let idx = isize::cast_from(idx.unwrap_int64() + offset);
8182
8183 let (lower, upper) = d.dimension_bounds();
8184
8185 if !(lower..upper + 1).contains(&idx) {
8188 return Datum::Null;
8189 }
8190
8191 final_idx *= d.length;
8193
8194 final_idx += usize::try_from(idx - d.lower_bound)
8198 .expect("previous bounds check ensures phsical index is at least 0");
8199 }
8200
8201 array
8202 .elements()
8203 .iter()
8204 .nth(final_idx)
8205 .unwrap_or(Datum::Null)
8206}
8207
8208#[allow(clippy::as_conversions)]
8210fn list_index<'a>(datums: &[Datum<'a>]) -> Datum<'a> {
8211 let mut buf = datums[0];
8212
8213 for i in datums[1..].iter() {
8214 if buf.is_null() {
8215 break;
8216 }
8217
8218 let i = i.unwrap_int64();
8219 if i < 1 {
8220 return Datum::Null;
8221 }
8222
8223 buf = buf
8224 .unwrap_list()
8225 .iter()
8226 .nth(i as usize - 1)
8227 .unwrap_or(Datum::Null);
8228 }
8229 buf
8230}
8231
8232#[allow(clippy::as_conversions)]
8234fn list_slice_linear<'a>(datums: &[Datum<'a>], temp_storage: &'a RowArena) -> Datum<'a> {
8235 assert_eq!(
8236 datums.len() % 2,
8237 1,
8238 "expr::scalar::func::list_slice expects an odd number of arguments; 1 for list + 2 \
8239 for each start-end pair"
8240 );
8241 assert!(
8242 datums.len() > 2,
8243 "expr::scalar::func::list_slice expects at least 3 arguments; 1 for list + at least \
8244 one start-end pair"
8245 );
8246
8247 let mut start_idx = 0;
8248 let mut total_length = usize::MAX;
8249
8250 for (start, end) in datums[1..].iter().tuples::<(_, _)>() {
8251 let start = std::cmp::max(start.unwrap_int64(), 1);
8252 let end = end.unwrap_int64();
8253
8254 if start > end {
8256 start_idx = 0;
8257 total_length = 0;
8258 break;
8259 }
8260
8261 let start_inner = start as usize - 1;
8262 start_idx += start_inner;
8264
8265 let length_inner = (end - start) as usize + 1;
8267 total_length = std::cmp::min(length_inner, total_length - start_inner);
8268 }
8269
8270 let iter = datums[0]
8271 .unwrap_list()
8272 .iter()
8273 .skip(start_idx)
8274 .take(total_length);
8275
8276 temp_storage.make_datum(|row| {
8277 row.push_list_with(|row| {
8278 for d in iter {
8280 row.push(d);
8281 }
8282 });
8283 })
8284}
8285
8286fn create_range<'a>(
8287 datums: &[Datum<'a>],
8288 temp_storage: &'a RowArena,
8289) -> Result<Datum<'a>, EvalError> {
8290 let flags = match datums[2] {
8291 Datum::Null => {
8292 return Err(EvalError::InvalidRange(
8293 range::InvalidRangeError::NullRangeBoundFlags,
8294 ));
8295 }
8296 o => o.unwrap_str(),
8297 };
8298
8299 let (lower_inclusive, upper_inclusive) = range::parse_range_bound_flags(flags)?;
8300
8301 let mut range = Range::new(Some((
8302 RangeBound::new(datums[0], lower_inclusive),
8303 RangeBound::new(datums[1], upper_inclusive),
8304 )));
8305
8306 range.canonicalize()?;
8307
8308 Ok(temp_storage.make_datum(|row| {
8309 row.push_range(range).expect("errors already handled");
8310 }))
8311}
8312
8313fn array_position<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
8314 let array = match datums[0] {
8315 Datum::Null => return Ok(Datum::Null),
8316 o => o.unwrap_array(),
8317 };
8318
8319 if array.dims().len() > 1 {
8320 return Err(EvalError::MultiDimensionalArraySearch);
8321 }
8322
8323 let search = datums[1];
8324 if search == Datum::Null {
8325 return Ok(Datum::Null);
8326 }
8327
8328 let skip: usize = match datums.get(2) {
8329 Some(Datum::Null) => return Err(EvalError::MustNotBeNull("initial position".into())),
8330 None => 0,
8331 Some(o) => usize::try_from(o.unwrap_int32())
8332 .unwrap_or(0)
8333 .saturating_sub(1),
8334 };
8335
8336 let r = array.elements().iter().skip(skip).position(|d| d == search);
8337
8338 Ok(Datum::from(r.map(|p| {
8339 i32::try_from(p + skip + 1).expect("fewer than i32::MAX elements in array")
8341 })))
8342}
8343
8344#[allow(clippy::as_conversions)]
8346fn make_timestamp<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
8347 let year: i32 = match datums[0].unwrap_int64().try_into() {
8348 Ok(year) => year,
8349 Err(_) => return Ok(Datum::Null),
8350 };
8351 let month: u32 = match datums[1].unwrap_int64().try_into() {
8352 Ok(month) => month,
8353 Err(_) => return Ok(Datum::Null),
8354 };
8355 let day: u32 = match datums[2].unwrap_int64().try_into() {
8356 Ok(day) => day,
8357 Err(_) => return Ok(Datum::Null),
8358 };
8359 let hour: u32 = match datums[3].unwrap_int64().try_into() {
8360 Ok(day) => day,
8361 Err(_) => return Ok(Datum::Null),
8362 };
8363 let minute: u32 = match datums[4].unwrap_int64().try_into() {
8364 Ok(day) => day,
8365 Err(_) => return Ok(Datum::Null),
8366 };
8367 let second_float = datums[5].unwrap_float64();
8368 let second = second_float as u32;
8369 let micros = ((second_float - second as f64) * 1_000_000.0) as u32;
8370 let date = match NaiveDate::from_ymd_opt(year, month, day) {
8371 Some(date) => date,
8372 None => return Ok(Datum::Null),
8373 };
8374 let timestamp = match date.and_hms_micro_opt(hour, minute, second, micros) {
8375 Some(timestamp) => timestamp,
8376 None => return Ok(Datum::Null),
8377 };
8378 Ok(timestamp.try_into()?)
8379}
8380
8381#[sqlfunc(output_type = "i32", propagates_nulls = true)]
8382fn position<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
8383 let substring: &'a str = a.unwrap_str();
8384 let string = b.unwrap_str();
8385 let char_index = string.find(substring);
8386
8387 if let Some(char_index) = char_index {
8388 let string_prefix = &string[0..char_index];
8390
8391 let num_prefix_chars = string_prefix.chars().count();
8392 let num_prefix_chars = i32::try_from(num_prefix_chars)
8393 .map_err(|_| EvalError::Int32OutOfRange(num_prefix_chars.to_string().into()))?;
8394
8395 Ok(Datum::Int32(num_prefix_chars + 1))
8396 } else {
8397 Ok(Datum::Int32(0))
8398 }
8399}
8400
8401#[sqlfunc(output_type = "String", propagates_nulls = true)]
8402fn left<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
8403 let string: &'a str = a.unwrap_str();
8404 let n = i64::from(b.unwrap_int32());
8405
8406 let mut byte_indices = string.char_indices().map(|(i, _)| i);
8407
8408 let end_in_bytes = match n.cmp(&0) {
8409 Ordering::Equal => 0,
8410 Ordering::Greater => {
8411 let n = usize::try_from(n).map_err(|_| {
8412 EvalError::InvalidParameterValue(format!("invalid parameter n: {:?}", n).into())
8413 })?;
8414 byte_indices.nth(n).unwrap_or(string.len())
8416 }
8417 Ordering::Less => {
8418 let n = usize::try_from(n.abs() - 1).map_err(|_| {
8419 EvalError::InvalidParameterValue(format!("invalid parameter n: {:?}", n).into())
8420 })?;
8421 byte_indices.rev().nth(n).unwrap_or(0)
8422 }
8423 };
8424
8425 Ok(Datum::String(&string[..end_in_bytes]))
8426}
8427
8428#[sqlfunc(output_type = "String", propagates_nulls = true)]
8429fn right<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
8430 let string: &'a str = a.unwrap_str();
8431 let n = b.unwrap_int32();
8432
8433 let mut byte_indices = string.char_indices().map(|(i, _)| i);
8434
8435 let start_in_bytes = if n == 0 {
8436 string.len()
8437 } else if n > 0 {
8438 let n = usize::try_from(n - 1).map_err(|_| {
8439 EvalError::InvalidParameterValue(format!("invalid parameter n: {:?}", n).into())
8440 })?;
8441 byte_indices.rev().nth(n).unwrap_or(0)
8443 } else if n == i32::MIN {
8444 0
8446 } else {
8447 let n = n.abs();
8448 let n = usize::try_from(n).map_err(|_| {
8449 EvalError::InvalidParameterValue(format!("invalid parameter n: {:?}", n).into())
8450 })?;
8451 byte_indices.nth(n).unwrap_or(string.len())
8452 };
8453
8454 Ok(Datum::String(&string[start_in_bytes..]))
8455}
8456
8457#[sqlfunc(sqlname = "btrim", output_type = "String", propagates_nulls = true)]
8458fn trim<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8459 let trim_chars = b.unwrap_str();
8460
8461 Datum::from(a.unwrap_str().trim_matches(|c| trim_chars.contains(c)))
8462}
8463
8464#[sqlfunc(sqlname = "ltrim", output_type = "String", propagates_nulls = true)]
8465fn trim_leading<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8466 let trim_chars = b.unwrap_str();
8467
8468 Datum::from(
8469 a.unwrap_str()
8470 .trim_start_matches(|c| trim_chars.contains(c)),
8471 )
8472}
8473
8474#[sqlfunc(sqlname = "rtrim", output_type = "String", propagates_nulls = true)]
8475fn trim_trailing<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8476 let trim_chars = b.unwrap_str();
8477
8478 Datum::from(a.unwrap_str().trim_end_matches(|c| trim_chars.contains(c)))
8479}
8480
8481#[sqlfunc(
8482 output_type = "Option<i32>",
8483 is_infix_op = true,
8484 sqlname = "array_length",
8485 propagates_nulls = true,
8486 introduces_nulls = true
8487)]
8488fn array_length<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
8489 let i = match usize::try_from(b.unwrap_int64()) {
8490 Ok(0) | Err(_) => return Ok(Datum::Null),
8491 Ok(n) => n - 1,
8492 };
8493 Ok(match a.unwrap_array().dims().into_iter().nth(i) {
8494 None => Datum::Null,
8495 Some(dim) => Datum::Int32(
8496 dim.length
8497 .try_into()
8498 .map_err(|_| EvalError::Int32OutOfRange(dim.length.to_string().into()))?,
8499 ),
8500 })
8501}
8502
8503#[sqlfunc(
8504 output_type = "Option<i32>",
8505 is_infix_op = true,
8506 sqlname = "array_lower",
8507 propagates_nulls = true,
8508 introduces_nulls = true
8509)]
8510#[allow(clippy::as_conversions)]
8512fn array_lower<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8513 let i = b.unwrap_int64();
8514 if i < 1 {
8515 return Datum::Null;
8516 }
8517 match a.unwrap_array().dims().into_iter().nth(i as usize - 1) {
8518 Some(_) => Datum::Int32(1),
8519 None => Datum::Null,
8520 }
8521}
8522
8523#[sqlfunc(
8524 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8525 sqlname = "array_remove",
8526 propagates_nulls = false,
8527 introduces_nulls = false
8528)]
8529fn array_remove<'a>(
8530 a: Datum<'a>,
8531 b: Datum<'a>,
8532 temp_storage: &'a RowArena,
8533) -> Result<Datum<'a>, EvalError> {
8534 if a.is_null() {
8535 return Ok(a);
8536 }
8537
8538 let arr = a.unwrap_array();
8539
8540 if arr.dims().len() == 0 {
8542 return Ok(a);
8543 }
8544
8545 if arr.dims().len() > 1 {
8547 return Err(EvalError::MultidimensionalArrayRemovalNotSupported);
8548 }
8549
8550 let elems: Vec<_> = arr.elements().iter().filter(|v| v != &b).collect();
8551 let mut dims = arr.dims().into_iter().collect::<Vec<_>>();
8552 dims[0] = ArrayDimension {
8554 lower_bound: 1,
8555 length: elems.len(),
8556 };
8557
8558 Ok(temp_storage.try_make_datum(|packer| packer.try_push_array(&dims, elems))?)
8559}
8560
8561#[sqlfunc(
8562 output_type = "Option<i32>",
8563 is_infix_op = true,
8564 sqlname = "array_upper",
8565 propagates_nulls = true,
8566 introduces_nulls = true
8567)]
8568#[allow(clippy::as_conversions)]
8570fn array_upper<'a>(a: Datum<'a>, b: Datum<'a>) -> Result<Datum<'a>, EvalError> {
8571 let i = b.unwrap_int64();
8572 if i < 1 {
8573 return Ok(Datum::Null);
8574 }
8575 Ok(
8576 match a.unwrap_array().dims().into_iter().nth(i as usize - 1) {
8577 Some(dim) => Datum::Int32(
8578 dim.length
8579 .try_into()
8580 .map_err(|_| EvalError::Int32OutOfRange(dim.length.to_string().into()))?,
8581 ),
8582 None => Datum::Null,
8583 },
8584 )
8585}
8586
8587#[allow(clippy::as_conversions)]
8589fn list_length_max<'a>(
8590 a: Datum<'a>,
8591 b: Datum<'a>,
8592 max_layer: usize,
8593) -> Result<Datum<'a>, EvalError> {
8594 fn max_len_on_layer<'a>(d: Datum<'a>, on_layer: i64) -> Option<usize> {
8595 match d {
8596 Datum::List(i) => {
8597 let mut i = i.iter();
8598 if on_layer > 1 {
8599 let mut max_len = None;
8600 while let Some(Datum::List(i)) = i.next() {
8601 max_len =
8602 std::cmp::max(max_len_on_layer(Datum::List(i), on_layer - 1), max_len);
8603 }
8604 max_len
8605 } else {
8606 Some(i.count())
8607 }
8608 }
8609 Datum::Null => None,
8610 _ => unreachable!(),
8611 }
8612 }
8613
8614 let b = b.unwrap_int64();
8615
8616 if b as usize > max_layer || b < 1 {
8617 Err(EvalError::InvalidLayer { max_layer, val: b })
8618 } else {
8619 match max_len_on_layer(a, b) {
8620 Some(l) => match l.try_into() {
8621 Ok(c) => Ok(Datum::Int32(c)),
8622 Err(_) => Err(EvalError::Int32OutOfRange(l.to_string().into())),
8623 },
8624 None => Ok(Datum::Null),
8625 }
8626 }
8627}
8628
8629#[sqlfunc(
8630 output_type = "bool",
8631 is_infix_op = true,
8632 sqlname = "array_contains",
8633 propagates_nulls = true,
8634 introduces_nulls = false
8635)]
8636fn array_contains<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8637 let array = Datum::unwrap_array(&b);
8638 Datum::from(array.elements().iter().any(|e| e == a))
8639}
8640
8641#[sqlfunc(
8642 output_type = "bool",
8643 is_infix_op = true,
8644 sqlname = "@>",
8645 propagates_nulls = true,
8646 introduces_nulls = false
8647)]
8648fn array_contains_array<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8649 let a = a.unwrap_array().elements();
8650 let b = b.unwrap_array().elements();
8651
8652 if b.iter().contains(&Datum::Null) {
8654 Datum::False
8655 } else {
8656 b.iter()
8657 .all(|item_b| a.iter().any(|item_a| item_a == item_b))
8658 .into()
8659 }
8660}
8661
8662#[sqlfunc(
8663 output_type = "bool",
8664 is_infix_op = true,
8665 sqlname = "<@",
8666 propagates_nulls = true,
8667 introduces_nulls = false
8668)]
8669#[allow(dead_code)]
8670fn array_contains_array_rev<'a>(a: Datum<'a>, b: Datum<'a>) -> Datum<'a> {
8671 array_contains_array(a, b)
8672}
8673
8674#[sqlfunc(
8675 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8676 is_infix_op = true,
8677 sqlname = "||",
8678 propagates_nulls = false,
8679 introduces_nulls = false
8680)]
8681fn array_array_concat<'a>(
8682 a: Datum<'a>,
8683 b: Datum<'a>,
8684 temp_storage: &'a RowArena,
8685) -> Result<Datum<'a>, EvalError> {
8686 if a.is_null() {
8687 return Ok(b);
8688 } else if b.is_null() {
8689 return Ok(a);
8690 }
8691
8692 let a_array = a.unwrap_array();
8693 let b_array = b.unwrap_array();
8694
8695 let a_dims: Vec<ArrayDimension> = a_array.dims().into_iter().collect();
8696 let b_dims: Vec<ArrayDimension> = b_array.dims().into_iter().collect();
8697
8698 let a_ndims = a_dims.len();
8699 let b_ndims = b_dims.len();
8700
8701 if a_ndims == 0 {
8704 return Ok(b);
8705 } else if b_ndims == 0 {
8706 return Ok(a);
8707 }
8708
8709 #[allow(clippy::as_conversions)]
8720 if (a_ndims as isize - b_ndims as isize).abs() > 1 {
8721 return Err(EvalError::IncompatibleArrayDimensions {
8722 dims: Some((a_ndims, b_ndims)),
8723 });
8724 }
8725
8726 let mut dims;
8727
8728 match a_ndims.cmp(&b_ndims) {
8733 Ordering::Equal => {
8737 if &a_dims[1..] != &b_dims[1..] {
8738 return Err(EvalError::IncompatibleArrayDimensions { dims: None });
8739 }
8740 dims = vec![ArrayDimension {
8741 lower_bound: a_dims[0].lower_bound,
8742 length: a_dims[0].length + b_dims[0].length,
8743 }];
8744 dims.extend(&a_dims[1..]);
8745 }
8746 Ordering::Less => {
8750 if &a_dims[..] != &b_dims[1..] {
8751 return Err(EvalError::IncompatibleArrayDimensions { dims: None });
8752 }
8753 dims = vec![ArrayDimension {
8754 lower_bound: b_dims[0].lower_bound,
8755 length: b_dims[0].length + 1,
8759 }];
8760 dims.extend(a_dims);
8761 }
8762 Ordering::Greater => {
8766 if &a_dims[1..] != &b_dims[..] {
8767 return Err(EvalError::IncompatibleArrayDimensions { dims: None });
8768 }
8769 dims = vec![ArrayDimension {
8770 lower_bound: a_dims[0].lower_bound,
8771 length: a_dims[0].length + 1,
8775 }];
8776 dims.extend(b_dims);
8777 }
8778 }
8779
8780 let elems = a_array.elements().iter().chain(b_array.elements().iter());
8781
8782 Ok(temp_storage.try_make_datum(|packer| packer.try_push_array(&dims, elems))?)
8783}
8784
8785#[sqlfunc(
8786 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8787 is_infix_op = true,
8788 sqlname = "||",
8789 propagates_nulls = false,
8790 introduces_nulls = false
8791)]
8792fn list_list_concat<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
8793 if a.is_null() {
8794 return b;
8795 } else if b.is_null() {
8796 return a;
8797 }
8798
8799 let a = a.unwrap_list().iter();
8800 let b = b.unwrap_list().iter();
8801
8802 temp_storage.make_datum(|packer| packer.push_list(a.chain(b)))
8803}
8804
8805#[sqlfunc(
8806 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8807 is_infix_op = true,
8808 sqlname = "||",
8809 propagates_nulls = false,
8810 introduces_nulls = false
8811)]
8812fn list_element_concat<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
8813 temp_storage.make_datum(|packer| {
8814 packer.push_list_with(|packer| {
8815 if !a.is_null() {
8816 for elem in a.unwrap_list().iter() {
8817 packer.push(elem);
8818 }
8819 }
8820 packer.push(b);
8821 })
8822 })
8823}
8824
8825#[sqlfunc(
8826 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8827 is_infix_op = true,
8828 sqlname = "||",
8829 propagates_nulls = false,
8830 introduces_nulls = false
8831)]
8832fn element_list_concat<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
8833 temp_storage.make_datum(|packer| {
8834 packer.push_list_with(|packer| {
8835 packer.push(a);
8836 if !b.is_null() {
8837 for elem in b.unwrap_list().iter() {
8838 packer.push(elem);
8839 }
8840 }
8841 })
8842 })
8843}
8844
8845#[sqlfunc(
8846 output_type_expr = "input_type_a.scalar_type.without_modifiers().nullable(true)",
8847 sqlname = "list_remove",
8848 propagates_nulls = false,
8849 introduces_nulls = false
8850)]
8851fn list_remove<'a>(a: Datum<'a>, b: Datum<'a>, temp_storage: &'a RowArena) -> Datum<'a> {
8852 if a.is_null() {
8853 return a;
8854 }
8855
8856 temp_storage.make_datum(|packer| {
8857 packer.push_list_with(|packer| {
8858 for elem in a.unwrap_list().iter() {
8859 if elem != b {
8860 packer.push(elem);
8861 }
8862 }
8863 })
8864 })
8865}
8866
8867#[sqlfunc(
8868 output_type = "Vec<u8>",
8869 sqlname = "digest",
8870 propagates_nulls = true,
8871 introduces_nulls = false
8872)]
8873fn digest_string<'a>(
8874 a: Datum<'a>,
8875 b: Datum<'a>,
8876 temp_storage: &'a RowArena,
8877) -> Result<Datum<'a>, EvalError> {
8878 let to_digest = a.unwrap_str().as_bytes();
8879 digest_inner(to_digest, b, temp_storage)
8880}
8881
8882#[sqlfunc(
8883 output_type = "Vec<u8>",
8884 sqlname = "digest",
8885 propagates_nulls = true,
8886 introduces_nulls = false
8887)]
8888fn digest_bytes<'a>(
8889 a: Datum<'a>,
8890 b: Datum<'a>,
8891 temp_storage: &'a RowArena,
8892) -> Result<Datum<'a>, EvalError> {
8893 let to_digest = a.unwrap_bytes();
8894 digest_inner(to_digest, b, temp_storage)
8895}
8896
8897fn digest_inner<'a>(
8898 bytes: &[u8],
8899 digest_fn: Datum<'a>,
8900 temp_storage: &'a RowArena,
8901) -> Result<Datum<'a>, EvalError> {
8902 let bytes = match digest_fn.unwrap_str() {
8903 "md5" => Md5::digest(bytes).to_vec(),
8904 "sha1" => Sha1::digest(bytes).to_vec(),
8905 "sha224" => Sha224::digest(bytes).to_vec(),
8906 "sha256" => Sha256::digest(bytes).to_vec(),
8907 "sha384" => Sha384::digest(bytes).to_vec(),
8908 "sha512" => Sha512::digest(bytes).to_vec(),
8909 other => return Err(EvalError::InvalidHashAlgorithm(other.into())),
8910 };
8911 Ok(Datum::Bytes(temp_storage.push_bytes(bytes)))
8912}
8913
8914#[sqlfunc(
8915 output_type = "String",
8916 sqlname = "mz_render_typmod",
8917 propagates_nulls = true,
8918 introduces_nulls = false
8919)]
8920fn mz_render_typmod<'a>(
8921 oid: Datum<'a>,
8922 typmod: Datum<'a>,
8923 temp_storage: &'a RowArena,
8924) -> Result<Datum<'a>, EvalError> {
8925 let oid = oid.unwrap_uint32();
8926 let typmod = typmod.unwrap_int32();
8927 let s = match Type::from_oid_and_typmod(oid, typmod) {
8928 Ok(typ) => typ.constraint().display_or("").to_string(),
8929 Err(_) if typmod >= 0 => format!("({typmod})"),
8932 Err(_) => "".into(),
8933 };
8934 Ok(Datum::String(temp_storage.push_string(s)))
8935}
8936
8937fn make_acl_item<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
8938 let grantee = Oid(datums[0].unwrap_uint32());
8939 let grantor = Oid(datums[1].unwrap_uint32());
8940 let privileges = datums[2].unwrap_str();
8941 let acl_mode = AclMode::parse_multiple_privileges(privileges)
8942 .map_err(|e: anyhow::Error| EvalError::InvalidPrivileges(e.to_string().into()))?;
8943 let is_grantable = datums[3].unwrap_bool();
8944 if is_grantable {
8945 return Err(EvalError::Unsupported {
8946 feature: "GRANT OPTION".into(),
8947 discussion_no: None,
8948 });
8949 }
8950
8951 Ok(Datum::AclItem(AclItem {
8952 grantee,
8953 grantor,
8954 acl_mode,
8955 }))
8956}
8957
8958fn make_mz_acl_item<'a>(datums: &[Datum<'a>]) -> Result<Datum<'a>, EvalError> {
8959 let grantee: RoleId = datums[0]
8960 .unwrap_str()
8961 .parse()
8962 .map_err(|e: anyhow::Error| EvalError::InvalidRoleId(e.to_string().into()))?;
8963 let grantor: RoleId = datums[1]
8964 .unwrap_str()
8965 .parse()
8966 .map_err(|e: anyhow::Error| EvalError::InvalidRoleId(e.to_string().into()))?;
8967 if grantor == RoleId::Public {
8968 return Err(EvalError::InvalidRoleId(
8969 "mz_aclitem grantor cannot be PUBLIC role".into(),
8970 ));
8971 }
8972 let privileges = datums[2].unwrap_str();
8973 let acl_mode = AclMode::parse_multiple_privileges(privileges)
8974 .map_err(|e: anyhow::Error| EvalError::InvalidPrivileges(e.to_string().into()))?;
8975
8976 Ok(Datum::MzAclItem(MzAclItem {
8977 grantee,
8978 grantor,
8979 acl_mode,
8980 }))
8981}
8982
8983fn array_fill<'a>(
8984 datums: &[Datum<'a>],
8985 temp_storage: &'a RowArena,
8986) -> Result<Datum<'a>, EvalError> {
8987 const MAX_SIZE: usize = 1 << 28 - 1;
8988 const NULL_ARR_ERR: &str = "dimension array or low bound array";
8989 const NULL_ELEM_ERR: &str = "dimension values";
8990
8991 let fill = datums[0];
8992 if matches!(fill, Datum::Array(_)) {
8993 return Err(EvalError::Unsupported {
8994 feature: "array_fill with arrays".into(),
8995 discussion_no: None,
8996 });
8997 }
8998
8999 let arr = match datums[1] {
9000 Datum::Null => return Err(EvalError::MustNotBeNull(NULL_ARR_ERR.into())),
9001 o => o.unwrap_array(),
9002 };
9003
9004 let dimensions = arr
9005 .elements()
9006 .iter()
9007 .map(|d| match d {
9008 Datum::Null => Err(EvalError::MustNotBeNull(NULL_ELEM_ERR.into())),
9009 d => Ok(usize::cast_from(u32::reinterpret_cast(d.unwrap_int32()))),
9010 })
9011 .collect::<Result<Vec<_>, _>>()?;
9012
9013 let lower_bounds = match datums.get(2) {
9014 Some(d) => {
9015 let arr = match d {
9016 Datum::Null => return Err(EvalError::MustNotBeNull(NULL_ARR_ERR.into())),
9017 o => o.unwrap_array(),
9018 };
9019
9020 arr.elements()
9021 .iter()
9022 .map(|l| match l {
9023 Datum::Null => Err(EvalError::MustNotBeNull(NULL_ELEM_ERR.into())),
9024 l => Ok(isize::cast_from(l.unwrap_int32())),
9025 })
9026 .collect::<Result<Vec<_>, _>>()?
9027 }
9028 None => {
9029 vec![1isize; dimensions.len()]
9030 }
9031 };
9032
9033 if lower_bounds.len() != dimensions.len() {
9034 return Err(EvalError::ArrayFillWrongArraySubscripts);
9035 }
9036
9037 let fill_count: usize = dimensions
9038 .iter()
9039 .cloned()
9040 .map(Some)
9041 .reduce(|a, b| match (a, b) {
9042 (Some(a), Some(b)) => a.checked_mul(b),
9043 _ => None,
9044 })
9045 .flatten()
9046 .ok_or(EvalError::MaxArraySizeExceeded(MAX_SIZE))?;
9047
9048 if matches!(
9049 mz_repr::datum_size(&fill).checked_mul(fill_count),
9050 None | Some(MAX_SIZE..)
9051 ) {
9052 return Err(EvalError::MaxArraySizeExceeded(MAX_SIZE));
9053 }
9054
9055 let array_dimensions = if fill_count == 0 {
9056 vec![ArrayDimension {
9057 lower_bound: 1,
9058 length: 0,
9059 }]
9060 } else {
9061 dimensions
9062 .into_iter()
9063 .zip_eq(lower_bounds)
9064 .map(|(length, lower_bound)| ArrayDimension {
9065 lower_bound,
9066 length,
9067 })
9068 .collect()
9069 };
9070
9071 Ok(temp_storage.try_make_datum(|packer| {
9072 packer.try_push_array(&array_dimensions, vec![fill; fill_count])
9073 })?)
9074}
9075
9076#[derive(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
9077pub enum VariadicFunc {
9078 Coalesce,
9079 Greatest,
9080 Least,
9081 Concat,
9082 ConcatWs,
9083 MakeTimestamp,
9084 PadLeading,
9085 Substr,
9086 Replace,
9087 JsonbBuildArray,
9088 JsonbBuildObject,
9089 MapBuild {
9090 value_type: ScalarType,
9091 },
9092 ArrayCreate {
9093 elem_type: ScalarType,
9095 },
9096 ArrayToString {
9097 elem_type: ScalarType,
9098 },
9099 ArrayIndex {
9100 offset: i64,
9103 },
9104 ListCreate {
9105 elem_type: ScalarType,
9107 },
9108 RecordCreate {
9109 field_names: Vec<ColumnName>,
9110 },
9111 ListIndex,
9112 ListSliceLinear,
9113 SplitPart,
9114 RegexpMatch,
9115 HmacString,
9116 HmacBytes,
9117 ErrorIfNull,
9118 DateBinTimestamp,
9119 DateBinTimestampTz,
9120 DateDiffTimestamp,
9121 DateDiffTimestampTz,
9122 DateDiffDate,
9123 DateDiffTime,
9124 And,
9125 Or,
9126 RangeCreate {
9127 elem_type: ScalarType,
9128 },
9129 MakeAclItem,
9130 MakeMzAclItem,
9131 Translate,
9132 ArrayPosition,
9133 ArrayFill {
9134 elem_type: ScalarType,
9135 },
9136 StringToArray,
9137 TimezoneTime,
9138 RegexpSplitToArray,
9139 RegexpReplace,
9140}
9141
9142impl VariadicFunc {
9143 pub fn eval<'a>(
9144 &'a self,
9145 datums: &[Datum<'a>],
9146 temp_storage: &'a RowArena,
9147 exprs: &'a [MirScalarExpr],
9148 ) -> Result<Datum<'a>, EvalError> {
9149 match self {
9151 VariadicFunc::Coalesce => return coalesce(datums, temp_storage, exprs),
9152 VariadicFunc::Greatest => return greatest(datums, temp_storage, exprs),
9153 VariadicFunc::And => return and(datums, temp_storage, exprs),
9154 VariadicFunc::Or => return or(datums, temp_storage, exprs),
9155 VariadicFunc::ErrorIfNull => return error_if_null(datums, temp_storage, exprs),
9156 VariadicFunc::Least => return least(datums, temp_storage, exprs),
9157 _ => {}
9158 };
9159
9160 let ds = exprs
9162 .iter()
9163 .map(|e| e.eval(datums, temp_storage))
9164 .collect::<Result<Vec<_>, _>>()?;
9165 if self.propagates_nulls() && ds.iter().any(|d| d.is_null()) {
9167 return Ok(Datum::Null);
9168 }
9169
9170 match self {
9172 VariadicFunc::Coalesce
9173 | VariadicFunc::Greatest
9174 | VariadicFunc::And
9175 | VariadicFunc::Or
9176 | VariadicFunc::ErrorIfNull
9177 | VariadicFunc::Least => unreachable!(),
9178 VariadicFunc::Concat => Ok(text_concat_variadic(&ds, temp_storage)),
9179 VariadicFunc::ConcatWs => Ok(text_concat_ws(&ds, temp_storage)),
9180 VariadicFunc::MakeTimestamp => make_timestamp(&ds),
9181 VariadicFunc::PadLeading => pad_leading(&ds, temp_storage),
9182 VariadicFunc::Substr => substr(&ds),
9183 VariadicFunc::Replace => Ok(replace(&ds, temp_storage)),
9184 VariadicFunc::Translate => Ok(translate(&ds, temp_storage)),
9185 VariadicFunc::JsonbBuildArray => Ok(jsonb_build_array(&ds, temp_storage)),
9186 VariadicFunc::JsonbBuildObject => jsonb_build_object(&ds, temp_storage),
9187 VariadicFunc::MapBuild { .. } => Ok(map_build(&ds, temp_storage)),
9188 VariadicFunc::ArrayCreate {
9189 elem_type: ScalarType::Array(_),
9190 } => array_create_multidim(&ds, temp_storage),
9191 VariadicFunc::ArrayCreate { .. } => array_create_scalar(&ds, temp_storage),
9192 VariadicFunc::ArrayToString { elem_type } => {
9193 array_to_string(&ds, elem_type, temp_storage)
9194 }
9195 VariadicFunc::ArrayIndex { offset } => Ok(array_index(&ds, *offset)),
9196
9197 VariadicFunc::ListCreate { .. } | VariadicFunc::RecordCreate { .. } => {
9198 Ok(list_create(&ds, temp_storage))
9199 }
9200 VariadicFunc::ListIndex => Ok(list_index(&ds)),
9201 VariadicFunc::ListSliceLinear => Ok(list_slice_linear(&ds, temp_storage)),
9202 VariadicFunc::SplitPart => split_part(&ds),
9203 VariadicFunc::RegexpMatch => regexp_match_dynamic(&ds, temp_storage),
9204 VariadicFunc::HmacString => hmac_string(&ds, temp_storage),
9205 VariadicFunc::HmacBytes => hmac_bytes(&ds, temp_storage),
9206 VariadicFunc::DateBinTimestamp => date_bin(
9207 ds[0].unwrap_interval(),
9208 ds[1].unwrap_timestamp(),
9209 ds[2].unwrap_timestamp(),
9210 ),
9211 VariadicFunc::DateBinTimestampTz => date_bin(
9212 ds[0].unwrap_interval(),
9213 ds[1].unwrap_timestamptz(),
9214 ds[2].unwrap_timestamptz(),
9215 ),
9216 VariadicFunc::DateDiffTimestamp => date_diff_timestamp(ds[0], ds[1], ds[2]),
9217 VariadicFunc::DateDiffTimestampTz => date_diff_timestamptz(ds[0], ds[1], ds[2]),
9218 VariadicFunc::DateDiffDate => date_diff_date(ds[0], ds[1], ds[2]),
9219 VariadicFunc::DateDiffTime => date_diff_time(ds[0], ds[1], ds[2]),
9220 VariadicFunc::RangeCreate { .. } => create_range(&ds, temp_storage),
9221 VariadicFunc::MakeAclItem => make_acl_item(&ds),
9222 VariadicFunc::MakeMzAclItem => make_mz_acl_item(&ds),
9223 VariadicFunc::ArrayPosition => array_position(&ds),
9224 VariadicFunc::ArrayFill { .. } => array_fill(&ds, temp_storage),
9225 VariadicFunc::TimezoneTime => parse_timezone(ds[0].unwrap_str(), TimezoneSpec::Posix)
9226 .map(|tz| {
9227 timezone_time(
9228 tz,
9229 ds[1].unwrap_time(),
9230 &ds[2].unwrap_timestamptz().naive_utc(),
9231 )
9232 .into()
9233 }),
9234 VariadicFunc::RegexpSplitToArray => {
9235 let flags = if ds.len() == 2 {
9236 Datum::String("")
9237 } else {
9238 ds[2]
9239 };
9240 regexp_split_to_array(ds[0], ds[1], flags, temp_storage)
9241 }
9242 VariadicFunc::RegexpReplace => regexp_replace_dynamic(&ds, temp_storage),
9243 VariadicFunc::StringToArray => {
9244 let null_string = if ds.len() == 2 { Datum::Null } else { ds[2] };
9245
9246 string_to_array(ds[0], ds[1], null_string, temp_storage)
9247 }
9248 }
9249 }
9250
9251 pub fn is_associative(&self) -> bool {
9252 match self {
9253 VariadicFunc::Coalesce
9254 | VariadicFunc::Greatest
9255 | VariadicFunc::Least
9256 | VariadicFunc::Concat
9257 | VariadicFunc::And
9258 | VariadicFunc::Or => true,
9259
9260 VariadicFunc::MakeTimestamp
9261 | VariadicFunc::PadLeading
9262 | VariadicFunc::ConcatWs
9263 | VariadicFunc::Substr
9264 | VariadicFunc::Replace
9265 | VariadicFunc::Translate
9266 | VariadicFunc::JsonbBuildArray
9267 | VariadicFunc::JsonbBuildObject
9268 | VariadicFunc::MapBuild { value_type: _ }
9269 | VariadicFunc::ArrayCreate { elem_type: _ }
9270 | VariadicFunc::ArrayToString { elem_type: _ }
9271 | VariadicFunc::ArrayIndex { offset: _ }
9272 | VariadicFunc::ListCreate { elem_type: _ }
9273 | VariadicFunc::RecordCreate { field_names: _ }
9274 | VariadicFunc::ListIndex
9275 | VariadicFunc::ListSliceLinear
9276 | VariadicFunc::SplitPart
9277 | VariadicFunc::RegexpMatch
9278 | VariadicFunc::HmacString
9279 | VariadicFunc::HmacBytes
9280 | VariadicFunc::ErrorIfNull
9281 | VariadicFunc::DateBinTimestamp
9282 | VariadicFunc::DateBinTimestampTz
9283 | VariadicFunc::DateDiffTimestamp
9284 | VariadicFunc::DateDiffTimestampTz
9285 | VariadicFunc::DateDiffDate
9286 | VariadicFunc::DateDiffTime
9287 | VariadicFunc::RangeCreate { .. }
9288 | VariadicFunc::MakeAclItem
9289 | VariadicFunc::MakeMzAclItem
9290 | VariadicFunc::ArrayPosition
9291 | VariadicFunc::ArrayFill { .. }
9292 | VariadicFunc::TimezoneTime
9293 | VariadicFunc::RegexpSplitToArray
9294 | VariadicFunc::StringToArray
9295 | VariadicFunc::RegexpReplace => false,
9296 }
9297 }
9298
9299 pub fn output_type(&self, input_types: Vec<ColumnType>) -> ColumnType {
9300 use VariadicFunc::*;
9301 let in_nullable = input_types.iter().any(|t| t.nullable);
9302 match self {
9303 Greatest | Least => input_types
9304 .into_iter()
9305 .reduce(|l, r| l.union(&r).unwrap())
9306 .unwrap(),
9307 Coalesce => {
9308 let nullable = input_types.iter().all(|typ| typ.nullable);
9312 input_types
9313 .into_iter()
9314 .reduce(|l, r| l.union(&r).unwrap())
9315 .unwrap()
9316 .nullable(nullable)
9317 }
9318 Concat | ConcatWs => ScalarType::String.nullable(in_nullable),
9319 MakeTimestamp => ScalarType::Timestamp { precision: None }.nullable(true),
9320 PadLeading => ScalarType::String.nullable(in_nullable),
9321 Substr => ScalarType::String.nullable(in_nullable),
9322 Replace => ScalarType::String.nullable(in_nullable),
9323 Translate => ScalarType::String.nullable(in_nullable),
9324 JsonbBuildArray | JsonbBuildObject => ScalarType::Jsonb.nullable(true),
9325 MapBuild { value_type } => ScalarType::Map {
9326 value_type: Box::new(value_type.clone()),
9327 custom_id: None,
9328 }
9329 .nullable(true),
9330 ArrayCreate { elem_type } => {
9331 debug_assert!(
9332 input_types.iter().all(|t| t.scalar_type.base_eq(elem_type)),
9333 "Args to ArrayCreate should have types that are compatible with the elem_type"
9334 );
9335 match elem_type {
9336 ScalarType::Array(_) => elem_type.clone().nullable(false),
9337 _ => ScalarType::Array(Box::new(elem_type.clone())).nullable(false),
9338 }
9339 }
9340 ArrayToString { .. } => ScalarType::String.nullable(in_nullable),
9341 ArrayIndex { .. } => input_types[0]
9342 .scalar_type
9343 .unwrap_array_element_type()
9344 .clone()
9345 .nullable(true),
9346 ListCreate { elem_type } => {
9347 ScalarType::List {
9354 element_type: Box::new(elem_type.clone()),
9355 custom_id: None,
9356 }
9357 .nullable(false)
9358 }
9359 ListIndex => input_types[0]
9360 .scalar_type
9361 .unwrap_list_nth_layer_type(input_types.len() - 1)
9362 .clone()
9363 .nullable(true),
9364 ListSliceLinear { .. } => input_types[0].scalar_type.clone().nullable(in_nullable),
9365 RecordCreate { field_names } => ScalarType::Record {
9366 fields: field_names
9367 .clone()
9368 .into_iter()
9369 .zip_eq(input_types)
9370 .collect(),
9371 custom_id: None,
9372 }
9373 .nullable(false),
9374 SplitPart => ScalarType::String.nullable(in_nullable),
9375 RegexpMatch => ScalarType::Array(Box::new(ScalarType::String)).nullable(true),
9376 HmacString | HmacBytes => ScalarType::Bytes.nullable(in_nullable),
9377 ErrorIfNull => input_types[0].scalar_type.clone().nullable(false),
9378 DateBinTimestamp => ScalarType::Timestamp { precision: None }.nullable(in_nullable),
9379 DateBinTimestampTz => ScalarType::TimestampTz { precision: None }.nullable(in_nullable),
9380 DateDiffTimestamp => ScalarType::Int64.nullable(in_nullable),
9381 DateDiffTimestampTz => ScalarType::Int64.nullable(in_nullable),
9382 DateDiffDate => ScalarType::Int64.nullable(in_nullable),
9383 DateDiffTime => ScalarType::Int64.nullable(in_nullable),
9384 And | Or => ScalarType::Bool.nullable(in_nullable),
9385 RangeCreate { elem_type } => ScalarType::Range {
9386 element_type: Box::new(elem_type.clone()),
9387 }
9388 .nullable(false),
9389 MakeAclItem => ScalarType::AclItem.nullable(true),
9390 MakeMzAclItem => ScalarType::MzAclItem.nullable(true),
9391 ArrayPosition => ScalarType::Int32.nullable(true),
9392 ArrayFill { elem_type } => {
9393 ScalarType::Array(Box::new(elem_type.clone())).nullable(false)
9394 }
9395 TimezoneTime => ScalarType::Time.nullable(in_nullable),
9396 RegexpSplitToArray => {
9397 ScalarType::Array(Box::new(ScalarType::String)).nullable(in_nullable)
9398 }
9399 RegexpReplace => ScalarType::String.nullable(in_nullable),
9400 StringToArray => ScalarType::Array(Box::new(ScalarType::String)).nullable(true),
9401 }
9402 }
9403
9404 pub fn propagates_nulls(&self) -> bool {
9409 !matches!(
9412 self,
9413 VariadicFunc::And
9414 | VariadicFunc::Or
9415 | VariadicFunc::Coalesce
9416 | VariadicFunc::Greatest
9417 | VariadicFunc::Least
9418 | VariadicFunc::Concat
9419 | VariadicFunc::ConcatWs
9420 | VariadicFunc::JsonbBuildArray
9421 | VariadicFunc::JsonbBuildObject
9422 | VariadicFunc::MapBuild { .. }
9423 | VariadicFunc::ListCreate { .. }
9424 | VariadicFunc::RecordCreate { .. }
9425 | VariadicFunc::ArrayCreate { .. }
9426 | VariadicFunc::ArrayToString { .. }
9427 | VariadicFunc::ErrorIfNull
9428 | VariadicFunc::RangeCreate { .. }
9429 | VariadicFunc::ArrayPosition
9430 | VariadicFunc::ArrayFill { .. }
9431 | VariadicFunc::StringToArray
9432 )
9433 }
9434
9435 pub fn introduces_nulls(&self) -> bool {
9441 use VariadicFunc::*;
9442 match self {
9443 Concat
9444 | ConcatWs
9445 | PadLeading
9446 | Substr
9447 | Replace
9448 | Translate
9449 | JsonbBuildArray
9450 | JsonbBuildObject
9451 | MapBuild { .. }
9452 | ArrayCreate { .. }
9453 | ArrayToString { .. }
9454 | ListCreate { .. }
9455 | RecordCreate { .. }
9456 | ListSliceLinear
9457 | SplitPart
9458 | HmacString
9459 | HmacBytes
9460 | ErrorIfNull
9461 | DateBinTimestamp
9462 | DateBinTimestampTz
9463 | DateDiffTimestamp
9464 | DateDiffTimestampTz
9465 | DateDiffDate
9466 | DateDiffTime
9467 | RangeCreate { .. }
9468 | And
9469 | Or
9470 | MakeAclItem
9471 | MakeMzAclItem
9472 | ArrayPosition
9473 | ArrayFill { .. }
9474 | TimezoneTime
9475 | RegexpSplitToArray
9476 | RegexpReplace => false,
9477 Coalesce
9478 | Greatest
9479 | Least
9480 | MakeTimestamp
9481 | ArrayIndex { .. }
9482 | StringToArray
9483 | ListIndex
9484 | RegexpMatch => true,
9485 }
9486 }
9487
9488 pub fn switch_and_or(&self) -> Self {
9489 match self {
9490 VariadicFunc::And => VariadicFunc::Or,
9491 VariadicFunc::Or => VariadicFunc::And,
9492 _ => unreachable!(),
9493 }
9494 }
9495
9496 pub fn is_infix_op(&self) -> bool {
9497 use VariadicFunc::*;
9498 matches!(self, And | Or)
9499 }
9500
9501 pub fn unit_of_and_or(&self) -> MirScalarExpr {
9504 match self {
9505 VariadicFunc::And => MirScalarExpr::literal_true(),
9506 VariadicFunc::Or => MirScalarExpr::literal_false(),
9507 _ => unreachable!(),
9508 }
9509 }
9510
9511 pub fn zero_of_and_or(&self) -> MirScalarExpr {
9513 match self {
9514 VariadicFunc::And => MirScalarExpr::literal_false(),
9515 VariadicFunc::Or => MirScalarExpr::literal_true(),
9516 _ => unreachable!(),
9517 }
9518 }
9519
9520 pub fn could_error(&self) -> bool {
9522 match self {
9523 VariadicFunc::And | VariadicFunc::Or => false,
9524 VariadicFunc::Coalesce => false,
9525 VariadicFunc::Greatest | VariadicFunc::Least => false,
9526 VariadicFunc::Concat | VariadicFunc::ConcatWs => false,
9527 VariadicFunc::Replace => false,
9528 VariadicFunc::Translate => false,
9529 VariadicFunc::ArrayIndex { .. } => false,
9530 VariadicFunc::ListCreate { .. } | VariadicFunc::RecordCreate { .. } => false,
9531 _ => true,
9533 }
9534 }
9535
9536 pub fn is_monotone(&self) -> bool {
9549 match self {
9550 VariadicFunc::Coalesce
9551 | VariadicFunc::Greatest
9552 | VariadicFunc::Least
9553 | VariadicFunc::And
9554 | VariadicFunc::Or => true,
9555 VariadicFunc::Concat
9556 | VariadicFunc::ConcatWs
9557 | VariadicFunc::MakeTimestamp
9558 | VariadicFunc::PadLeading
9559 | VariadicFunc::Substr
9560 | VariadicFunc::Replace
9561 | VariadicFunc::JsonbBuildArray
9562 | VariadicFunc::JsonbBuildObject
9563 | VariadicFunc::MapBuild { .. }
9564 | VariadicFunc::ArrayCreate { .. }
9565 | VariadicFunc::ArrayToString { .. }
9566 | VariadicFunc::ArrayIndex { .. }
9567 | VariadicFunc::ListCreate { .. }
9568 | VariadicFunc::RecordCreate { .. }
9569 | VariadicFunc::ListIndex
9570 | VariadicFunc::ListSliceLinear
9571 | VariadicFunc::SplitPart
9572 | VariadicFunc::RegexpMatch
9573 | VariadicFunc::HmacString
9574 | VariadicFunc::HmacBytes
9575 | VariadicFunc::ErrorIfNull
9576 | VariadicFunc::DateBinTimestamp
9577 | VariadicFunc::DateBinTimestampTz
9578 | VariadicFunc::RangeCreate { .. }
9579 | VariadicFunc::MakeAclItem
9580 | VariadicFunc::MakeMzAclItem
9581 | VariadicFunc::Translate
9582 | VariadicFunc::ArrayPosition
9583 | VariadicFunc::ArrayFill { .. }
9584 | VariadicFunc::DateDiffTimestamp
9585 | VariadicFunc::DateDiffTimestampTz
9586 | VariadicFunc::DateDiffDate
9587 | VariadicFunc::DateDiffTime
9588 | VariadicFunc::TimezoneTime
9589 | VariadicFunc::RegexpSplitToArray
9590 | VariadicFunc::StringToArray
9591 | VariadicFunc::RegexpReplace => false,
9592 }
9593 }
9594}
9595
9596impl fmt::Display for VariadicFunc {
9597 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9598 match self {
9599 VariadicFunc::Coalesce => f.write_str("coalesce"),
9600 VariadicFunc::Greatest => f.write_str("greatest"),
9601 VariadicFunc::Least => f.write_str("least"),
9602 VariadicFunc::Concat => f.write_str("concat"),
9603 VariadicFunc::ConcatWs => f.write_str("concat_ws"),
9604 VariadicFunc::MakeTimestamp => f.write_str("makets"),
9605 VariadicFunc::PadLeading => f.write_str("lpad"),
9606 VariadicFunc::Substr => f.write_str("substr"),
9607 VariadicFunc::Replace => f.write_str("replace"),
9608 VariadicFunc::Translate => f.write_str("translate"),
9609 VariadicFunc::JsonbBuildArray => f.write_str("jsonb_build_array"),
9610 VariadicFunc::JsonbBuildObject => f.write_str("jsonb_build_object"),
9611 VariadicFunc::MapBuild { .. } => f.write_str("map_build"),
9612 VariadicFunc::ArrayCreate { .. } => f.write_str("array_create"),
9613 VariadicFunc::ArrayToString { .. } => f.write_str("array_to_string"),
9614 VariadicFunc::ArrayIndex { .. } => f.write_str("array_index"),
9615 VariadicFunc::ListCreate { .. } => f.write_str("list_create"),
9616 VariadicFunc::RecordCreate { .. } => f.write_str("record_create"),
9617 VariadicFunc::ListIndex => f.write_str("list_index"),
9618 VariadicFunc::ListSliceLinear => f.write_str("list_slice_linear"),
9619 VariadicFunc::SplitPart => f.write_str("split_string"),
9620 VariadicFunc::RegexpMatch => f.write_str("regexp_match"),
9621 VariadicFunc::HmacString | VariadicFunc::HmacBytes => f.write_str("hmac"),
9622 VariadicFunc::ErrorIfNull => f.write_str("error_if_null"),
9623 VariadicFunc::DateBinTimestamp => f.write_str("timestamp_bin"),
9624 VariadicFunc::DateBinTimestampTz => f.write_str("timestamptz_bin"),
9625 VariadicFunc::DateDiffTimestamp
9626 | VariadicFunc::DateDiffTimestampTz
9627 | VariadicFunc::DateDiffDate
9628 | VariadicFunc::DateDiffTime => f.write_str("datediff"),
9629 VariadicFunc::And => f.write_str("AND"),
9630 VariadicFunc::Or => f.write_str("OR"),
9631 VariadicFunc::RangeCreate {
9632 elem_type: element_type,
9633 } => f.write_str(match element_type {
9634 ScalarType::Int32 => "int4range",
9635 ScalarType::Int64 => "int8range",
9636 ScalarType::Date => "daterange",
9637 ScalarType::Numeric { .. } => "numrange",
9638 ScalarType::Timestamp { .. } => "tsrange",
9639 ScalarType::TimestampTz { .. } => "tstzrange",
9640 _ => unreachable!(),
9641 }),
9642 VariadicFunc::MakeAclItem => f.write_str("makeaclitem"),
9643 VariadicFunc::MakeMzAclItem => f.write_str("make_mz_aclitem"),
9644 VariadicFunc::ArrayPosition => f.write_str("array_position"),
9645 VariadicFunc::ArrayFill { .. } => f.write_str("array_fill"),
9646 VariadicFunc::TimezoneTime => f.write_str("timezonet"),
9647 VariadicFunc::RegexpSplitToArray => f.write_str("regexp_split_to_array"),
9648 VariadicFunc::RegexpReplace => f.write_str("regexp_replace"),
9649 VariadicFunc::StringToArray => f.write_str("string_to_array"),
9650 }
9651 }
9652}
9653
9654impl Arbitrary for VariadicFunc {
9661 type Parameters = ();
9662
9663 type Strategy = Union<BoxedStrategy<Self>>;
9664
9665 fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
9666 Union::new(vec![
9667 Just(VariadicFunc::Coalesce).boxed(),
9668 Just(VariadicFunc::Greatest).boxed(),
9669 Just(VariadicFunc::Least).boxed(),
9670 Just(VariadicFunc::Concat).boxed(),
9671 Just(VariadicFunc::ConcatWs).boxed(),
9672 Just(VariadicFunc::MakeTimestamp).boxed(),
9673 Just(VariadicFunc::PadLeading).boxed(),
9674 Just(VariadicFunc::Substr).boxed(),
9675 Just(VariadicFunc::Replace).boxed(),
9676 Just(VariadicFunc::JsonbBuildArray).boxed(),
9677 Just(VariadicFunc::JsonbBuildObject).boxed(),
9678 ScalarType::arbitrary()
9679 .prop_map(|value_type| VariadicFunc::MapBuild { value_type })
9680 .boxed(),
9681 Just(VariadicFunc::MakeAclItem).boxed(),
9682 Just(VariadicFunc::MakeMzAclItem).boxed(),
9683 ScalarType::arbitrary()
9684 .prop_map(|elem_type| VariadicFunc::ArrayCreate { elem_type })
9685 .boxed(),
9686 ScalarType::arbitrary()
9687 .prop_map(|elem_type| VariadicFunc::ArrayToString { elem_type })
9688 .boxed(),
9689 i64::arbitrary()
9690 .prop_map(|offset| VariadicFunc::ArrayIndex { offset })
9691 .boxed(),
9692 ScalarType::arbitrary()
9693 .prop_map(|elem_type| VariadicFunc::ListCreate { elem_type })
9694 .boxed(),
9695 Vec::<ColumnName>::arbitrary()
9696 .prop_map(|field_names| VariadicFunc::RecordCreate { field_names })
9697 .boxed(),
9698 Just(VariadicFunc::ListIndex).boxed(),
9699 Just(VariadicFunc::ListSliceLinear).boxed(),
9700 Just(VariadicFunc::SplitPart).boxed(),
9701 Just(VariadicFunc::RegexpMatch).boxed(),
9702 Just(VariadicFunc::HmacString).boxed(),
9703 Just(VariadicFunc::HmacBytes).boxed(),
9704 Just(VariadicFunc::ErrorIfNull).boxed(),
9705 Just(VariadicFunc::DateBinTimestamp).boxed(),
9706 Just(VariadicFunc::DateBinTimestampTz).boxed(),
9707 Just(VariadicFunc::DateDiffTimestamp).boxed(),
9708 Just(VariadicFunc::DateDiffTimestampTz).boxed(),
9709 Just(VariadicFunc::DateDiffDate).boxed(),
9710 Just(VariadicFunc::DateDiffTime).boxed(),
9711 Just(VariadicFunc::And).boxed(),
9712 Just(VariadicFunc::Or).boxed(),
9713 mz_repr::arb_range_type()
9714 .prop_map(|elem_type| VariadicFunc::RangeCreate { elem_type })
9715 .boxed(),
9716 Just(VariadicFunc::ArrayPosition).boxed(),
9717 ScalarType::arbitrary()
9718 .prop_map(|elem_type| VariadicFunc::ArrayFill { elem_type })
9719 .boxed(),
9720 ])
9721 }
9722}
9723
9724impl RustType<ProtoVariadicFunc> for VariadicFunc {
9725 fn into_proto(&self) -> ProtoVariadicFunc {
9726 use crate::scalar::proto_variadic_func::Kind::*;
9727 use crate::scalar::proto_variadic_func::ProtoRecordCreate;
9728 let kind = match self {
9729 VariadicFunc::Coalesce => Coalesce(()),
9730 VariadicFunc::Greatest => Greatest(()),
9731 VariadicFunc::Least => Least(()),
9732 VariadicFunc::Concat => Concat(()),
9733 VariadicFunc::ConcatWs => ConcatWs(()),
9734 VariadicFunc::MakeTimestamp => MakeTimestamp(()),
9735 VariadicFunc::PadLeading => PadLeading(()),
9736 VariadicFunc::Substr => Substr(()),
9737 VariadicFunc::Replace => Replace(()),
9738 VariadicFunc::Translate => Translate(()),
9739 VariadicFunc::JsonbBuildArray => JsonbBuildArray(()),
9740 VariadicFunc::JsonbBuildObject => JsonbBuildObject(()),
9741 VariadicFunc::MapBuild { value_type } => MapBuild(value_type.into_proto()),
9742 VariadicFunc::ArrayCreate { elem_type } => ArrayCreate(elem_type.into_proto()),
9743 VariadicFunc::ArrayToString { elem_type } => ArrayToString(elem_type.into_proto()),
9744 VariadicFunc::ArrayIndex { offset } => ArrayIndex(offset.into_proto()),
9745 VariadicFunc::ListCreate { elem_type } => ListCreate(elem_type.into_proto()),
9746 VariadicFunc::RecordCreate { field_names } => RecordCreate(ProtoRecordCreate {
9747 field_names: field_names.into_proto(),
9748 }),
9749 VariadicFunc::ListIndex => ListIndex(()),
9750 VariadicFunc::ListSliceLinear => ListSliceLinear(()),
9751 VariadicFunc::SplitPart => SplitPart(()),
9752 VariadicFunc::RegexpMatch => RegexpMatch(()),
9753 VariadicFunc::HmacString => HmacString(()),
9754 VariadicFunc::HmacBytes => HmacBytes(()),
9755 VariadicFunc::ErrorIfNull => ErrorIfNull(()),
9756 VariadicFunc::DateBinTimestamp => DateBinTimestamp(()),
9757 VariadicFunc::DateBinTimestampTz => DateBinTimestampTz(()),
9758 VariadicFunc::DateDiffTimestamp => DateDiffTimestamp(()),
9759 VariadicFunc::DateDiffTimestampTz => DateDiffTimestampTz(()),
9760 VariadicFunc::DateDiffDate => DateDiffDate(()),
9761 VariadicFunc::DateDiffTime => DateDiffTime(()),
9762 VariadicFunc::And => And(()),
9763 VariadicFunc::Or => Or(()),
9764 VariadicFunc::RangeCreate { elem_type } => RangeCreate(elem_type.into_proto()),
9765 VariadicFunc::MakeAclItem => MakeAclItem(()),
9766 VariadicFunc::MakeMzAclItem => MakeMzAclItem(()),
9767 VariadicFunc::ArrayPosition => ArrayPosition(()),
9768 VariadicFunc::ArrayFill { elem_type } => ArrayFill(elem_type.into_proto()),
9769 VariadicFunc::TimezoneTime => TimezoneTime(()),
9770 VariadicFunc::RegexpSplitToArray => RegexpSplitToArray(()),
9771 VariadicFunc::RegexpReplace => RegexpReplace(()),
9772 VariadicFunc::StringToArray => StringToArray(()),
9773 };
9774 ProtoVariadicFunc { kind: Some(kind) }
9775 }
9776
9777 fn from_proto(proto: ProtoVariadicFunc) -> Result<Self, TryFromProtoError> {
9778 use crate::scalar::proto_variadic_func::Kind::*;
9779 use crate::scalar::proto_variadic_func::ProtoRecordCreate;
9780 if let Some(kind) = proto.kind {
9781 match kind {
9782 Coalesce(()) => Ok(VariadicFunc::Coalesce),
9783 Greatest(()) => Ok(VariadicFunc::Greatest),
9784 Least(()) => Ok(VariadicFunc::Least),
9785 Concat(()) => Ok(VariadicFunc::Concat),
9786 ConcatWs(()) => Ok(VariadicFunc::ConcatWs),
9787 MakeTimestamp(()) => Ok(VariadicFunc::MakeTimestamp),
9788 PadLeading(()) => Ok(VariadicFunc::PadLeading),
9789 Substr(()) => Ok(VariadicFunc::Substr),
9790 Replace(()) => Ok(VariadicFunc::Replace),
9791 Translate(()) => Ok(VariadicFunc::Translate),
9792 JsonbBuildArray(()) => Ok(VariadicFunc::JsonbBuildArray),
9793 JsonbBuildObject(()) => Ok(VariadicFunc::JsonbBuildObject),
9794 MapBuild(value_type) => Ok(VariadicFunc::MapBuild {
9795 value_type: value_type.into_rust()?,
9796 }),
9797 ArrayCreate(elem_type) => Ok(VariadicFunc::ArrayCreate {
9798 elem_type: elem_type.into_rust()?,
9799 }),
9800 ArrayToString(elem_type) => Ok(VariadicFunc::ArrayToString {
9801 elem_type: elem_type.into_rust()?,
9802 }),
9803 ArrayIndex(offset) => Ok(VariadicFunc::ArrayIndex {
9804 offset: offset.into_rust()?,
9805 }),
9806 ListCreate(elem_type) => Ok(VariadicFunc::ListCreate {
9807 elem_type: elem_type.into_rust()?,
9808 }),
9809 RecordCreate(ProtoRecordCreate { field_names }) => Ok(VariadicFunc::RecordCreate {
9810 field_names: field_names.into_rust()?,
9811 }),
9812 ListIndex(()) => Ok(VariadicFunc::ListIndex),
9813 ListSliceLinear(()) => Ok(VariadicFunc::ListSliceLinear),
9814 SplitPart(()) => Ok(VariadicFunc::SplitPart),
9815 RegexpMatch(()) => Ok(VariadicFunc::RegexpMatch),
9816 HmacString(()) => Ok(VariadicFunc::HmacString),
9817 HmacBytes(()) => Ok(VariadicFunc::HmacBytes),
9818 ErrorIfNull(()) => Ok(VariadicFunc::ErrorIfNull),
9819 DateBinTimestamp(()) => Ok(VariadicFunc::DateBinTimestamp),
9820 DateBinTimestampTz(()) => Ok(VariadicFunc::DateBinTimestampTz),
9821 DateDiffTimestamp(()) => Ok(VariadicFunc::DateDiffTimestamp),
9822 DateDiffTimestampTz(()) => Ok(VariadicFunc::DateDiffTimestampTz),
9823 DateDiffDate(()) => Ok(VariadicFunc::DateDiffDate),
9824 DateDiffTime(()) => Ok(VariadicFunc::DateDiffTime),
9825 And(()) => Ok(VariadicFunc::And),
9826 Or(()) => Ok(VariadicFunc::Or),
9827 RangeCreate(elem_type) => Ok(VariadicFunc::RangeCreate {
9828 elem_type: elem_type.into_rust()?,
9829 }),
9830 MakeAclItem(()) => Ok(VariadicFunc::MakeAclItem),
9831 MakeMzAclItem(()) => Ok(VariadicFunc::MakeMzAclItem),
9832 ArrayPosition(()) => Ok(VariadicFunc::ArrayPosition),
9833 ArrayFill(elem_type) => Ok(VariadicFunc::ArrayFill {
9834 elem_type: elem_type.into_rust()?,
9835 }),
9836 TimezoneTime(()) => Ok(VariadicFunc::TimezoneTime),
9837 RegexpSplitToArray(()) => Ok(VariadicFunc::RegexpSplitToArray),
9838 RegexpReplace(()) => Ok(VariadicFunc::RegexpReplace),
9839 StringToArray(()) => Ok(VariadicFunc::StringToArray),
9840 }
9841 } else {
9842 Err(TryFromProtoError::missing_field(
9843 "`ProtoVariadicFunc::kind`",
9844 ))
9845 }
9846 }
9847}
9848
9849#[cfg(test)]
9850mod test {
9851 use chrono::prelude::*;
9852 use mz_ore::assert_ok;
9853 use mz_proto::protobuf_roundtrip;
9854 use mz_repr::PropDatum;
9855 use proptest::prelude::*;
9856
9857 use super::*;
9858
9859 #[mz_ore::test]
9860 fn add_interval_months() {
9861 let dt = ym(2000, 1);
9862
9863 assert_eq!(add_timestamp_months(&*dt, 0).unwrap(), dt);
9864 assert_eq!(add_timestamp_months(&*dt, 1).unwrap(), ym(2000, 2));
9865 assert_eq!(add_timestamp_months(&*dt, 12).unwrap(), ym(2001, 1));
9866 assert_eq!(add_timestamp_months(&*dt, 13).unwrap(), ym(2001, 2));
9867 assert_eq!(add_timestamp_months(&*dt, 24).unwrap(), ym(2002, 1));
9868 assert_eq!(add_timestamp_months(&*dt, 30).unwrap(), ym(2002, 7));
9869
9870 assert_eq!(add_timestamp_months(&*dt, -1).unwrap(), ym(1999, 12));
9872 assert_eq!(add_timestamp_months(&*dt, -12).unwrap(), ym(1999, 1));
9873 assert_eq!(add_timestamp_months(&*dt, -13).unwrap(), ym(1998, 12));
9874 assert_eq!(add_timestamp_months(&*dt, -24).unwrap(), ym(1998, 1));
9875 assert_eq!(add_timestamp_months(&*dt, -30).unwrap(), ym(1997, 7));
9876
9877 let dt = ym(1999, 12);
9879 assert_eq!(add_timestamp_months(&*dt, 1).unwrap(), ym(2000, 1));
9880 let end_of_month_dt = NaiveDate::from_ymd_opt(1999, 12, 31)
9881 .unwrap()
9882 .and_hms_opt(9, 9, 9)
9883 .unwrap();
9884 assert_eq!(
9885 add_timestamp_months(&end_of_month_dt, 2).unwrap(),
9887 NaiveDate::from_ymd_opt(2000, 2, 29)
9888 .unwrap()
9889 .and_hms_opt(9, 9, 9)
9890 .unwrap()
9891 .try_into()
9892 .unwrap(),
9893 );
9894 assert_eq!(
9895 add_timestamp_months(&end_of_month_dt, 14).unwrap(),
9897 NaiveDate::from_ymd_opt(2001, 2, 28)
9898 .unwrap()
9899 .and_hms_opt(9, 9, 9)
9900 .unwrap()
9901 .try_into()
9902 .unwrap(),
9903 );
9904 }
9905
9906 fn ym(year: i32, month: u32) -> CheckedTimestamp<NaiveDateTime> {
9907 NaiveDate::from_ymd_opt(year, month, 1)
9908 .unwrap()
9909 .and_hms_opt(9, 9, 9)
9910 .unwrap()
9911 .try_into()
9912 .unwrap()
9913 }
9914
9915 proptest! {
9916 #![proptest_config(ProptestConfig::with_cases(4096))]
9917
9918 #[mz_ore::test]
9919 #[cfg_attr(miri, ignore)] fn unmaterializable_func_protobuf_roundtrip(expect in any::<UnmaterializableFunc>()) {
9921 let actual = protobuf_roundtrip::<_, ProtoUnmaterializableFunc>(&expect);
9922 assert_ok!(actual);
9923 assert_eq!(actual.unwrap(), expect);
9924 }
9925
9926 #[mz_ore::test]
9927 #[cfg_attr(miri, ignore)] fn unary_func_protobuf_roundtrip(expect in any::<UnaryFunc>()) {
9929 let actual = protobuf_roundtrip::<_, ProtoUnaryFunc>(&expect);
9930 assert_ok!(actual);
9931 assert_eq!(actual.unwrap(), expect);
9932 }
9933
9934 #[mz_ore::test]
9935 #[cfg_attr(miri, ignore)] fn binary_func_protobuf_roundtrip(expect in any::<BinaryFunc>()) {
9937 let actual = protobuf_roundtrip::<_, ProtoBinaryFunc>(&expect);
9938 assert_ok!(actual);
9939 assert_eq!(actual.unwrap(), expect);
9940 }
9941
9942 #[mz_ore::test]
9943 #[cfg_attr(miri, ignore)] fn variadic_func_protobuf_roundtrip(expect in any::<VariadicFunc>()) {
9945 let actual = protobuf_roundtrip::<_, ProtoVariadicFunc>(&expect);
9946 assert_ok!(actual);
9947 assert_eq!(actual.unwrap(), expect);
9948 }
9949 }
9950
9951 #[mz_ore::test]
9952 fn test_could_error() {
9953 for func in [
9954 UnaryFunc::IsNull(IsNull),
9955 UnaryFunc::CastVarCharToString(CastVarCharToString),
9956 UnaryFunc::Not(Not),
9957 UnaryFunc::IsLikeMatch(IsLikeMatch(like_pattern::compile("%hi%", false).unwrap())),
9958 ] {
9959 assert!(!func.could_error())
9960 }
9961 }
9962
9963 #[mz_ore::test]
9964 #[cfg_attr(miri, ignore)] fn test_is_monotone() {
9966 use proptest::prelude::*;
9967
9968 fn assert_monotone<'a, const N: usize>(
9971 expr: &MirScalarExpr,
9972 arena: &'a RowArena,
9973 datums: &[[Datum<'a>; N]],
9974 ) {
9975 let Ok(results) = datums
9977 .iter()
9978 .map(|args| expr.eval(args.as_slice(), arena))
9979 .collect::<Result<Vec<_>, _>>()
9980 else {
9981 return;
9982 };
9983
9984 let forward = results.iter().tuple_windows().all(|(a, b)| a <= b);
9985 let reverse = results.iter().tuple_windows().all(|(a, b)| a >= b);
9986 assert!(
9987 forward || reverse,
9988 "expected {expr} to be monotone, but passing {datums:?} returned {results:?}"
9989 );
9990 }
9991
9992 fn proptest_unary<'a>(
9993 func: UnaryFunc,
9994 arena: &'a RowArena,
9995 arg: impl Strategy<Value = PropDatum>,
9996 ) {
9997 let is_monotone = func.is_monotone();
9998 let expr = MirScalarExpr::CallUnary {
9999 func,
10000 expr: Box::new(MirScalarExpr::column(0)),
10001 };
10002 if is_monotone {
10003 proptest!(|(
10004 mut arg in proptest::array::uniform3(arg),
10005 )| {
10006 arg.sort();
10007 let args: Vec<_> = arg.iter().map(|a| [Datum::from(a)]).collect();
10008 assert_monotone(&expr, arena, &args);
10009 });
10010 }
10011 }
10012
10013 fn proptest_binary<'a>(
10014 func: BinaryFunc,
10015 arena: &'a RowArena,
10016 left: impl Strategy<Value = PropDatum>,
10017 right: impl Strategy<Value = PropDatum>,
10018 ) {
10019 let (left_monotone, right_monotone) = func.is_monotone();
10020 let expr = MirScalarExpr::CallBinary {
10021 func,
10022 expr1: Box::new(MirScalarExpr::column(0)),
10023 expr2: Box::new(MirScalarExpr::column(1)),
10024 };
10025 proptest!(|(
10026 mut left in proptest::array::uniform3(left),
10027 mut right in proptest::array::uniform3(right),
10028 )| {
10029 left.sort();
10030 right.sort();
10031 if left_monotone {
10032 for r in &right {
10033 let args: Vec<[_; 2]> = left
10034 .iter()
10035 .map(|l| [Datum::from(l), Datum::from(r)])
10036 .collect();
10037 assert_monotone(&expr, arena, &args);
10038 }
10039 }
10040 if right_monotone {
10041 for l in &left {
10042 let args: Vec<[_; 2]> = right
10043 .iter()
10044 .map(|r| [Datum::from(l), Datum::from(r)])
10045 .collect();
10046 assert_monotone(&expr, arena, &args);
10047 }
10048 }
10049 });
10050 }
10051
10052 let interesting_strs: Vec<_> = ScalarType::String.interesting_datums().collect();
10053 let str_datums = proptest::strategy::Union::new([
10054 proptest::string::string_regex("[A-Z]{0,10}")
10055 .expect("valid regex")
10056 .prop_map(|s| PropDatum::String(s.to_string()))
10057 .boxed(),
10058 (0..interesting_strs.len())
10059 .prop_map(move |i| {
10060 let Datum::String(val) = interesting_strs[i] else {
10061 unreachable!("interesting strings has non-strings")
10062 };
10063 PropDatum::String(val.to_string())
10064 })
10065 .boxed(),
10066 ]);
10067
10068 let interesting_i32s: Vec<Datum<'static>> =
10069 ScalarType::Int32.interesting_datums().collect();
10070 let i32_datums = proptest::strategy::Union::new([
10071 any::<i32>().prop_map(PropDatum::Int32).boxed(),
10072 (0..interesting_i32s.len())
10073 .prop_map(move |i| {
10074 let Datum::Int32(val) = interesting_i32s[i] else {
10075 unreachable!("interesting int32 has non-i32s")
10076 };
10077 PropDatum::Int32(val)
10078 })
10079 .boxed(),
10080 (-10i32..10).prop_map(PropDatum::Int32).boxed(),
10081 ]);
10082
10083 let arena = RowArena::new();
10084
10085 proptest_unary(
10089 UnaryFunc::CastInt32ToNumeric(CastInt32ToNumeric(None)),
10090 &arena,
10091 &i32_datums,
10092 );
10093 proptest_unary(
10094 UnaryFunc::CastInt32ToUint16(CastInt32ToUint16),
10095 &arena,
10096 &i32_datums,
10097 );
10098 proptest_unary(
10099 UnaryFunc::CastInt32ToString(CastInt32ToString),
10100 &arena,
10101 &i32_datums,
10102 );
10103 proptest_binary(BinaryFunc::AddInt32, &arena, &i32_datums, &i32_datums);
10104 proptest_binary(BinaryFunc::SubInt32, &arena, &i32_datums, &i32_datums);
10105 proptest_binary(BinaryFunc::MulInt32, &arena, &i32_datums, &i32_datums);
10106 proptest_binary(BinaryFunc::DivInt32, &arena, &i32_datums, &i32_datums);
10107 proptest_binary(BinaryFunc::TextConcat, &arena, &str_datums, &str_datums);
10108 proptest_binary(BinaryFunc::Left, &arena, &str_datums, &i32_datums);
10109 }
10110}