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