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