1use std::collections::{BTreeMap, BTreeSet};
15use std::fmt::{Display, Formatter};
16use std::sync::Arc;
17use std::{fmt, mem};
18
19use itertools::Itertools;
20use mz_expr::virtual_syntax::{AlgExcept, Except, IR};
21use mz_expr::visit::{Visit, VisitChildren};
22use mz_expr::{CollectionPlan, Id, LetRecLimit, RowSetFinishing, func};
23use mz_expr::AggregateFunc::{FusedWindowAggregate, WindowAggregate};
25use mz_expr::func::variadic::{And, Or};
26pub use mz_expr::{
27 BinaryFunc, ColumnOrder, TableFunc, UnaryFunc, UnmaterializableFunc, VariadicFunc, WindowFrame,
28};
29use mz_ore::collections::CollectionExt;
30use mz_ore::error::ErrorExt;
31use mz_ore::str::separated;
32use mz_ore::treat_as_equal::TreatAsEqual;
33use mz_ore::{soft_assert_or_log, stack};
34use mz_repr::adt::array::ArrayDimension;
35use mz_repr::adt::numeric::NumericMaxScale;
36use mz_repr::*;
37use serde::{Deserialize, Serialize};
38
39use crate::plan::error::PlanError;
40use crate::plan::query::{
41 EXECUTE_CAST_CONTEXT, ExprContext, execute_expr_context, offset_into_value,
42};
43use crate::plan::typeconv::{self, CastContext, plan_cast};
44use crate::plan::{Params, QueryContext, QueryLifetime, StatementContext};
45
46use super::plan_utils::GroupSizeHints;
47
48#[allow(missing_debug_implementations)]
49pub struct Hir;
50
51impl IR for Hir {
52 type Relation = HirRelationExpr;
53 type Scalar = HirScalarExpr;
54}
55
56impl AlgExcept for Hir {
57 fn except(all: &bool, lhs: Self::Relation, rhs: Self::Relation) -> Self::Relation {
58 if *all {
59 let rhs = rhs.negate();
60 HirRelationExpr::union(lhs, rhs).threshold()
61 } else {
62 let lhs = lhs.distinct();
63 let rhs = rhs.distinct().negate();
64 HirRelationExpr::union(lhs, rhs).threshold()
65 }
66 }
67
68 fn un_except<'a>(expr: &'a Self::Relation) -> Option<Except<'a, Self>> {
69 let mut result = None;
70
71 use HirRelationExpr::*;
72 if let Threshold { input } = expr {
73 if let Union { base: lhs, inputs } = input.as_ref() {
74 if let [rhs] = &inputs[..] {
75 if let Negate { input: rhs } = rhs {
76 match (lhs.as_ref(), rhs.as_ref()) {
77 (Distinct { input: lhs }, Distinct { input: rhs }) => {
78 let all = false;
79 let lhs = lhs.as_ref();
80 let rhs = rhs.as_ref();
81 result = Some(Except { all, lhs, rhs })
82 }
83 (lhs, rhs) => {
84 let all = true;
85 result = Some(Except { all, lhs, rhs })
86 }
87 }
88 }
89 }
90 }
91 }
92
93 result
94 }
95}
96
97#[derive(
98 Debug,
99 Clone,
100 PartialEq,
101 Eq,
102 PartialOrd,
103 Ord,
104 Hash,
105 Serialize,
106 Deserialize
107)]
108pub enum HirRelationExpr {
110 Constant {
111 rows: Vec<Row>,
112 typ: SqlRelationType,
113 },
114 Get {
115 id: mz_expr::Id,
116 typ: SqlRelationType,
117 },
118 LetRec {
120 limit: Option<LetRecLimit>,
122 bindings: Vec<(String, mz_expr::LocalId, HirRelationExpr, SqlRelationType)>,
124 body: Box<HirRelationExpr>,
126 },
127 Let {
129 name: String,
130 id: mz_expr::LocalId,
132 value: Box<HirRelationExpr>,
134 body: Box<HirRelationExpr>,
136 },
137 Project {
138 input: Box<HirRelationExpr>,
139 outputs: Vec<usize>,
140 },
141 Map {
142 input: Box<HirRelationExpr>,
143 scalars: Vec<HirScalarExpr>,
144 },
145 CallTable {
146 func: TableFunc,
147 exprs: Vec<HirScalarExpr>,
148 },
149 Filter {
150 input: Box<HirRelationExpr>,
151 predicates: Vec<HirScalarExpr>,
152 },
153 Join {
156 left: Box<HirRelationExpr>,
157 right: Box<HirRelationExpr>,
158 on: HirScalarExpr,
159 kind: JoinKind,
160 },
161 Reduce {
165 input: Box<HirRelationExpr>,
166 group_key: Vec<usize>,
167 aggregates: Vec<AggregateExpr>,
168 expected_group_size: Option<u64>,
169 },
170 Distinct {
171 input: Box<HirRelationExpr>,
172 },
173 TopK {
175 input: Box<HirRelationExpr>,
177 group_key: Vec<usize>,
179 order_key: Vec<ColumnOrder>,
181 limit: Option<HirScalarExpr>,
190 offset: HirScalarExpr,
195 expected_group_size: Option<u64>,
197 },
198 Negate {
199 input: Box<HirRelationExpr>,
200 },
201 Threshold {
203 input: Box<HirRelationExpr>,
204 },
205 Union {
206 base: Box<HirRelationExpr>,
207 inputs: Vec<HirRelationExpr>,
208 },
209}
210
211pub type NameMetadata = TreatAsEqual<Option<Arc<str>>>;
213
214#[derive(
215 Debug,
216 Clone,
217 PartialEq,
218 Eq,
219 PartialOrd,
220 Ord,
221 Hash,
222 Serialize,
223 Deserialize
224)]
225pub enum HirScalarExpr {
227 Column(ColumnRef, NameMetadata),
231 Parameter(usize, NameMetadata),
232 Literal(Row, SqlColumnType, NameMetadata),
233 CallUnmaterializable(UnmaterializableFunc, NameMetadata),
234 CallUnary {
235 func: UnaryFunc,
236 expr: Box<HirScalarExpr>,
237 name: NameMetadata,
238 },
239 CallBinary {
240 func: BinaryFunc,
241 expr1: Box<HirScalarExpr>,
242 expr2: Box<HirScalarExpr>,
243 name: NameMetadata,
244 },
245 CallVariadic {
246 func: VariadicFunc,
247 exprs: Vec<HirScalarExpr>,
248 name: NameMetadata,
249 },
250 If {
251 cond: Box<HirScalarExpr>,
252 then: Box<HirScalarExpr>,
253 els: Box<HirScalarExpr>,
254 name: NameMetadata,
255 },
256 Exists(Box<HirRelationExpr>, NameMetadata),
258 Select(Box<HirRelationExpr>, NameMetadata),
263 Windowing(WindowExpr, NameMetadata),
264}
265
266#[derive(
267 Debug,
268 Clone,
269 PartialEq,
270 Eq,
271 PartialOrd,
272 Ord,
273 Hash,
274 Serialize,
275 Deserialize
276)]
277pub struct WindowExpr {
280 pub func: WindowExprType,
281 pub partition_by: Vec<HirScalarExpr>,
282 pub order_by: Vec<HirScalarExpr>,
293}
294
295impl WindowExpr {
296 pub fn visit_expressions<'a, F, E>(&'a self, f: &mut F) -> Result<(), E>
297 where
298 F: FnMut(&'a HirScalarExpr) -> Result<(), E>,
299 {
300 #[allow(deprecated)]
301 self.func.visit_expressions(f)?;
302 for expr in self.partition_by.iter() {
303 f(expr)?;
304 }
305 for expr in self.order_by.iter() {
306 f(expr)?;
307 }
308 Ok(())
309 }
310
311 pub fn visit_expressions_mut<'a, F, E>(&'a mut self, f: &mut F) -> Result<(), E>
312 where
313 F: FnMut(&'a mut HirScalarExpr) -> Result<(), E>,
314 {
315 #[allow(deprecated)]
316 self.func.visit_expressions_mut(f)?;
317 for expr in self.partition_by.iter_mut() {
318 f(expr)?;
319 }
320 for expr in self.order_by.iter_mut() {
321 f(expr)?;
322 }
323 Ok(())
324 }
325}
326
327impl VisitChildren<HirScalarExpr> for WindowExpr {
330 fn visit_children<F>(&self, mut f: F)
331 where
332 F: FnMut(&HirScalarExpr),
333 {
334 self.func.visit_children(&mut f);
335 for expr in self.partition_by.iter() {
336 f(expr);
337 }
338 for expr in self.order_by.iter() {
339 f(expr);
340 }
341 }
342
343 fn visit_mut_children<F>(&mut self, mut f: F)
344 where
345 F: FnMut(&mut HirScalarExpr),
346 {
347 self.func.visit_mut_children(&mut f);
348 for expr in self.partition_by.iter_mut() {
349 f(expr);
350 }
351 for expr in self.order_by.iter_mut() {
352 f(expr);
353 }
354 }
355
356 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
357 where
358 F: FnMut(&HirScalarExpr) -> Result<(), E>,
359 {
360 self.func.try_visit_children(&mut f)?;
361 for expr in self.partition_by.iter() {
362 f(expr)?;
363 }
364 for expr in self.order_by.iter() {
365 f(expr)?;
366 }
367 Ok(())
368 }
369
370 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
371 where
372 F: FnMut(&mut HirScalarExpr) -> Result<(), E>,
373 {
374 self.func.try_visit_mut_children(&mut f)?;
375 for expr in self.partition_by.iter_mut() {
376 f(expr)?;
377 }
378 for expr in self.order_by.iter_mut() {
379 f(expr)?;
380 }
381 Ok(())
382 }
383
384 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
385 where
386 HirScalarExpr: 'a,
387 {
388 self.func
389 .children()
390 .chain(self.partition_by.iter())
391 .chain(self.order_by.iter())
392 }
393
394 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
395 where
396 HirScalarExpr: 'a,
397 {
398 self.func
399 .children_mut()
400 .chain(self.partition_by.iter_mut())
401 .chain(self.order_by.iter_mut())
402 }
403}
404
405#[derive(
406 Debug,
407 Clone,
408 PartialEq,
409 Eq,
410 PartialOrd,
411 Ord,
412 Hash,
413 Serialize,
414 Deserialize
415)]
416pub enum WindowExprType {
433 Scalar(ScalarWindowExpr),
434 Value(ValueWindowExpr),
435 Aggregate(AggregateWindowExpr),
436}
437
438impl WindowExprType {
439 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_children` instead."]
440 pub fn visit_expressions<'a, F, E>(&'a self, f: &mut F) -> Result<(), E>
441 where
442 F: FnMut(&'a HirScalarExpr) -> Result<(), E>,
443 {
444 #[allow(deprecated)]
445 match self {
446 Self::Scalar(expr) => expr.visit_expressions(f),
447 Self::Value(expr) => expr.visit_expressions(f),
448 Self::Aggregate(expr) => expr.visit_expressions(f),
449 }
450 }
451
452 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_mut_children` instead."]
453 pub fn visit_expressions_mut<'a, F, E>(&'a mut self, f: &mut F) -> Result<(), E>
454 where
455 F: FnMut(&'a mut HirScalarExpr) -> Result<(), E>,
456 {
457 #[allow(deprecated)]
458 match self {
459 Self::Scalar(expr) => expr.visit_expressions_mut(f),
460 Self::Value(expr) => expr.visit_expressions_mut(f),
461 Self::Aggregate(expr) => expr.visit_expressions_mut(f),
462 }
463 }
464
465 fn typ(
466 &self,
467 outers: &[SqlRelationType],
468 inner: &SqlRelationType,
469 params: &BTreeMap<usize, SqlScalarType>,
470 ) -> SqlColumnType {
471 match self {
472 Self::Scalar(expr) => expr.typ(outers, inner, params),
473 Self::Value(expr) => expr.typ(outers, inner, params),
474 Self::Aggregate(expr) => expr.typ(outers, inner, params),
475 }
476 }
477}
478
479impl VisitChildren<HirScalarExpr> for WindowExprType {
482 fn visit_children<F>(&self, f: F)
483 where
484 F: FnMut(&HirScalarExpr),
485 {
486 match self {
487 Self::Scalar(_) => (),
488 Self::Value(expr) => expr.visit_children(f),
489 Self::Aggregate(expr) => expr.visit_children(f),
490 }
491 }
492
493 fn visit_mut_children<F>(&mut self, f: F)
494 where
495 F: FnMut(&mut HirScalarExpr),
496 {
497 match self {
498 Self::Scalar(_) => (),
499 Self::Value(expr) => expr.visit_mut_children(f),
500 Self::Aggregate(expr) => expr.visit_mut_children(f),
501 }
502 }
503
504 fn try_visit_children<F, E>(&self, f: F) -> Result<(), E>
505 where
506 F: FnMut(&HirScalarExpr) -> Result<(), E>,
507 {
508 match self {
509 Self::Scalar(_) => Ok(()),
510 Self::Value(expr) => expr.try_visit_children(f),
511 Self::Aggregate(expr) => expr.try_visit_children(f),
512 }
513 }
514
515 fn try_visit_mut_children<F, E>(&mut self, f: F) -> Result<(), E>
516 where
517 F: FnMut(&mut HirScalarExpr) -> Result<(), E>,
518 {
519 match self {
520 Self::Scalar(_) => Ok(()),
521 Self::Value(expr) => expr.try_visit_mut_children(f),
522 Self::Aggregate(expr) => expr.try_visit_mut_children(f),
523 }
524 }
525
526 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
527 where
528 HirScalarExpr: 'a,
529 {
530 match self {
531 Self::Scalar(_) => vec![],
532 Self::Value(expr) => expr.children().collect(),
533 Self::Aggregate(expr) => expr.children().collect(),
534 }
535 .into_iter()
536 }
537
538 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
539 where
540 HirScalarExpr: 'a,
541 {
542 match self {
543 Self::Scalar(_) => vec![],
544 Self::Value(expr) => expr.children_mut().collect(),
545 Self::Aggregate(expr) => expr.children_mut().collect(),
546 }
547 .into_iter()
548 }
549}
550
551#[derive(
552 Debug,
553 Clone,
554 PartialEq,
555 Eq,
556 PartialOrd,
557 Ord,
558 Hash,
559 Serialize,
560 Deserialize
561)]
562pub struct ScalarWindowExpr {
563 pub func: ScalarWindowFunc,
564 pub order_by: Vec<ColumnOrder>,
565}
566
567impl ScalarWindowExpr {
568 #[deprecated = "Implement `VisitChildren<HirScalarExpr>` if needed."]
569 pub fn visit_expressions<'a, F, E>(&'a self, _f: &mut F) -> Result<(), E>
570 where
571 F: FnMut(&'a HirScalarExpr) -> Result<(), E>,
572 {
573 match self.func {
574 ScalarWindowFunc::RowNumber => {}
575 ScalarWindowFunc::Rank => {}
576 ScalarWindowFunc::DenseRank => {}
577 }
578 Ok(())
579 }
580
581 #[deprecated = "Implement `VisitChildren<HirScalarExpr>` if needed."]
582 pub fn visit_expressions_mut<'a, F, E>(&'a self, _f: &mut F) -> Result<(), E>
583 where
584 F: FnMut(&'a mut HirScalarExpr) -> Result<(), E>,
585 {
586 match self.func {
587 ScalarWindowFunc::RowNumber => {}
588 ScalarWindowFunc::Rank => {}
589 ScalarWindowFunc::DenseRank => {}
590 }
591 Ok(())
592 }
593
594 fn typ(
595 &self,
596 _outers: &[SqlRelationType],
597 _inner: &SqlRelationType,
598 _params: &BTreeMap<usize, SqlScalarType>,
599 ) -> SqlColumnType {
600 self.func.output_sql_type()
601 }
602
603 pub fn into_expr(self) -> mz_expr::AggregateFunc {
604 match self.func {
605 ScalarWindowFunc::RowNumber => mz_expr::AggregateFunc::RowNumber {
606 order_by: self.order_by,
607 },
608 ScalarWindowFunc::Rank => mz_expr::AggregateFunc::Rank {
609 order_by: self.order_by,
610 },
611 ScalarWindowFunc::DenseRank => mz_expr::AggregateFunc::DenseRank {
612 order_by: self.order_by,
613 },
614 }
615 }
616}
617
618#[derive(
619 Debug,
620 Clone,
621 PartialEq,
622 Eq,
623 PartialOrd,
624 Ord,
625 Hash,
626 Serialize,
627 Deserialize
628)]
629pub enum ScalarWindowFunc {
631 RowNumber,
632 Rank,
633 DenseRank,
634}
635
636impl Display for ScalarWindowFunc {
637 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
638 match self {
639 ScalarWindowFunc::RowNumber => write!(f, "row_number"),
640 ScalarWindowFunc::Rank => write!(f, "rank"),
641 ScalarWindowFunc::DenseRank => write!(f, "dense_rank"),
642 }
643 }
644}
645
646impl ScalarWindowFunc {
647 pub fn output_sql_type(&self) -> SqlColumnType {
648 match self {
649 ScalarWindowFunc::RowNumber => SqlScalarType::Int64.nullable(false),
650 ScalarWindowFunc::Rank => SqlScalarType::Int64.nullable(false),
651 ScalarWindowFunc::DenseRank => SqlScalarType::Int64.nullable(false),
652 }
653 }
654}
655
656#[derive(
657 Debug,
658 Clone,
659 PartialEq,
660 Eq,
661 PartialOrd,
662 Ord,
663 Hash,
664 Serialize,
665 Deserialize
666)]
667pub struct ValueWindowExpr {
668 pub func: ValueWindowFunc,
669 pub args: Box<HirScalarExpr>,
675 pub order_by: Vec<ColumnOrder>,
677 pub window_frame: WindowFrame,
678 pub ignore_nulls: bool,
679}
680
681impl Display for ValueWindowFunc {
682 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
683 match self {
684 ValueWindowFunc::Lag => write!(f, "lag"),
685 ValueWindowFunc::Lead => write!(f, "lead"),
686 ValueWindowFunc::FirstValue => write!(f, "first_value"),
687 ValueWindowFunc::LastValue => write!(f, "last_value"),
688 ValueWindowFunc::Fused(funcs) => write!(f, "fused[{}]", separated(", ", funcs)),
689 }
690 }
691}
692
693impl ValueWindowExpr {
694 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_children` instead."]
695 pub fn visit_expressions<'a, F, E>(&'a self, f: &mut F) -> Result<(), E>
696 where
697 F: FnMut(&'a HirScalarExpr) -> Result<(), E>,
698 {
699 f(&self.args)
700 }
701
702 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_mut_children` instead."]
703 pub fn visit_expressions_mut<'a, F, E>(&'a mut self, f: &mut F) -> Result<(), E>
704 where
705 F: FnMut(&'a mut HirScalarExpr) -> Result<(), E>,
706 {
707 f(&mut self.args)
708 }
709
710 fn typ(
711 &self,
712 outers: &[SqlRelationType],
713 inner: &SqlRelationType,
714 params: &BTreeMap<usize, SqlScalarType>,
715 ) -> SqlColumnType {
716 self.func
717 .output_sql_type(self.args.typ(outers, inner, params))
718 }
719
720 pub fn into_expr(self) -> (Box<HirScalarExpr>, mz_expr::AggregateFunc) {
722 (
723 self.args,
724 self.func
725 .into_expr(self.order_by, self.window_frame, self.ignore_nulls),
726 )
727 }
728}
729
730impl VisitChildren<HirScalarExpr> for ValueWindowExpr {
733 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
738 where
739 HirScalarExpr: 'a,
740 {
741 std::iter::once(&*self.args)
745 }
746
747 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
748 where
749 HirScalarExpr: 'a,
750 {
751 std::iter::once(&mut *self.args)
752 }
753}
754
755#[derive(
756 Debug,
757 Clone,
758 PartialEq,
759 Eq,
760 PartialOrd,
761 Ord,
762 Hash,
763 Serialize,
764 Deserialize
765)]
766pub enum ValueWindowFunc {
768 Lag,
769 Lead,
770 FirstValue,
771 LastValue,
772 Fused(Vec<ValueWindowFunc>),
773}
774
775impl ValueWindowFunc {
776 pub fn output_sql_type(&self, input_type: SqlColumnType) -> SqlColumnType {
777 match self {
778 ValueWindowFunc::Lag | ValueWindowFunc::Lead => {
779 input_type.scalar_type.unwrap_record_element_type()[0]
781 .clone()
782 .nullable(true)
783 }
784 ValueWindowFunc::FirstValue | ValueWindowFunc::LastValue => {
785 input_type.scalar_type.nullable(true)
786 }
787 ValueWindowFunc::Fused(funcs) => {
788 let input_types = input_type.scalar_type.unwrap_record_element_column_type();
789 SqlScalarType::Record {
790 fields: funcs
791 .iter()
792 .zip_eq(input_types)
793 .map(|(f, t)| (ColumnName::from(""), f.output_sql_type(t.clone())))
794 .collect(),
795 custom_id: None,
796 }
797 .nullable(false)
798 }
799 }
800 }
801
802 pub fn into_expr(
803 self,
804 order_by: Vec<ColumnOrder>,
805 window_frame: WindowFrame,
806 ignore_nulls: bool,
807 ) -> mz_expr::AggregateFunc {
808 match self {
809 ValueWindowFunc::Lag => mz_expr::AggregateFunc::LagLead {
811 order_by,
812 lag_lead: mz_expr::LagLeadType::Lag,
813 ignore_nulls,
814 },
815 ValueWindowFunc::Lead => mz_expr::AggregateFunc::LagLead {
816 order_by,
817 lag_lead: mz_expr::LagLeadType::Lead,
818 ignore_nulls,
819 },
820 ValueWindowFunc::FirstValue => mz_expr::AggregateFunc::FirstValue {
821 order_by,
822 window_frame,
823 },
824 ValueWindowFunc::LastValue => mz_expr::AggregateFunc::LastValue {
825 order_by,
826 window_frame,
827 },
828 ValueWindowFunc::Fused(funcs) => mz_expr::AggregateFunc::FusedValueWindowFunc {
829 funcs: funcs
830 .into_iter()
831 .map(|func| {
832 func.into_expr(order_by.clone(), window_frame.clone(), ignore_nulls)
833 })
834 .collect(),
835 order_by,
836 },
837 }
838 }
839}
840
841#[derive(
842 Debug,
843 Clone,
844 PartialEq,
845 Eq,
846 PartialOrd,
847 Ord,
848 Hash,
849 Serialize,
850 Deserialize
851)]
852pub struct AggregateWindowExpr {
853 pub aggregate_expr: AggregateExpr,
854 pub order_by: Vec<ColumnOrder>,
855 pub window_frame: WindowFrame,
856}
857
858impl AggregateWindowExpr {
859 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_children` instead."]
860 pub fn visit_expressions<'a, F, E>(&'a self, f: &mut F) -> Result<(), E>
861 where
862 F: FnMut(&'a HirScalarExpr) -> Result<(), E>,
863 {
864 f(&self.aggregate_expr.expr)
865 }
866
867 #[deprecated = "Use `VisitChildren<HirScalarExpr>::visit_mut_children` instead."]
868 pub fn visit_expressions_mut<'a, F, E>(&'a mut self, f: &mut F) -> Result<(), E>
869 where
870 F: FnMut(&'a mut HirScalarExpr) -> Result<(), E>,
871 {
872 f(&mut self.aggregate_expr.expr)
873 }
874
875 fn typ(
876 &self,
877 outers: &[SqlRelationType],
878 inner: &SqlRelationType,
879 params: &BTreeMap<usize, SqlScalarType>,
880 ) -> SqlColumnType {
881 self.aggregate_expr
882 .func
883 .output_sql_type(self.aggregate_expr.expr.typ(outers, inner, params))
884 }
885
886 pub fn into_expr(self) -> (Box<HirScalarExpr>, mz_expr::AggregateFunc) {
887 if let AggregateFunc::FusedWindowAgg { funcs } = &self.aggregate_expr.func {
888 (
889 self.aggregate_expr.expr,
890 FusedWindowAggregate {
891 wrapped_aggregates: funcs.iter().map(|f| f.clone().into_expr()).collect(),
892 order_by: self.order_by,
893 window_frame: self.window_frame,
894 },
895 )
896 } else {
897 (
898 self.aggregate_expr.expr,
899 WindowAggregate {
900 wrapped_aggregate: Box::new(self.aggregate_expr.func.into_expr()),
901 order_by: self.order_by,
902 window_frame: self.window_frame,
903 },
904 )
905 }
906 }
907}
908
909impl VisitChildren<HirScalarExpr> for AggregateWindowExpr {
912 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
917 where
918 HirScalarExpr: 'a,
919 {
920 std::iter::once(&*self.aggregate_expr.expr)
924 }
925
926 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
927 where
928 HirScalarExpr: 'a,
929 {
930 std::iter::once(&mut *self.aggregate_expr.expr)
931 }
932}
933
934#[derive(Clone, Debug)]
959pub enum CoercibleScalarExpr {
960 Coerced(HirScalarExpr),
961 Parameter(usize),
962 LiteralNull,
963 LiteralString(String),
964 LiteralRecord(Vec<CoercibleScalarExpr>),
965}
966
967impl CoercibleScalarExpr {
968 pub fn type_as(
969 self,
970 ecx: &ExprContext,
971 ty: &SqlScalarType,
972 ) -> Result<HirScalarExpr, PlanError> {
973 let expr = typeconv::plan_coerce(ecx, self, ty)?;
974 let expr_ty = ecx.scalar_type(&expr);
975 if ty != &expr_ty {
976 sql_bail!(
977 "{} must have type {}, not type {}",
978 ecx.name,
979 ecx.humanize_sql_scalar_type(ty, false),
980 ecx.humanize_sql_scalar_type(&expr_ty, false),
981 );
982 }
983 Ok(expr)
984 }
985
986 pub fn type_as_any(self, ecx: &ExprContext) -> Result<HirScalarExpr, PlanError> {
987 typeconv::plan_coerce(ecx, self, &SqlScalarType::String)
988 }
989
990 pub fn cast_to(
991 self,
992 ecx: &ExprContext,
993 ccx: CastContext,
994 ty: &SqlScalarType,
995 ) -> Result<HirScalarExpr, PlanError> {
996 let expr = typeconv::plan_coerce(ecx, self, ty)?;
997 typeconv::plan_cast(ecx, ccx, expr, ty)
998 }
999}
1000
1001#[derive(Clone, Debug)]
1003pub enum CoercibleColumnType {
1004 Coerced(SqlColumnType),
1005 Record(Vec<CoercibleColumnType>),
1006 Uncoerced,
1007}
1008
1009impl CoercibleColumnType {
1010 pub fn nullable(&self) -> bool {
1012 match self {
1013 CoercibleColumnType::Coerced(ct) => ct.nullable,
1015
1016 CoercibleColumnType::Record(_) => false,
1018
1019 CoercibleColumnType::Uncoerced => true,
1022 }
1023 }
1024}
1025
1026#[derive(Clone, Debug)]
1028pub enum CoercibleScalarType {
1029 Coerced(SqlScalarType),
1030 Record(Vec<CoercibleColumnType>),
1031 Uncoerced,
1032}
1033
1034impl CoercibleScalarType {
1035 pub fn is_coerced(&self) -> bool {
1037 matches!(self, CoercibleScalarType::Coerced(_))
1038 }
1039
1040 pub fn as_coerced(&self) -> Option<&SqlScalarType> {
1042 match self {
1043 CoercibleScalarType::Coerced(t) => Some(t),
1044 _ => None,
1045 }
1046 }
1047
1048 pub fn map_coerced<F>(self, f: F) -> CoercibleScalarType
1051 where
1052 F: FnOnce(SqlScalarType) -> SqlScalarType,
1053 {
1054 match self {
1055 CoercibleScalarType::Coerced(t) => CoercibleScalarType::Coerced(f(t)),
1056 _ => self,
1057 }
1058 }
1059
1060 pub fn force_coerced_if_record(&mut self) {
1067 fn convert(uncoerced_fields: impl Iterator<Item = CoercibleColumnType>) -> SqlScalarType {
1068 let mut fields = vec![];
1069 for (i, uf) in uncoerced_fields.enumerate() {
1070 let name = ColumnName::from(format!("f{}", i + 1));
1071 let ty = match uf {
1072 CoercibleColumnType::Coerced(ty) => ty,
1073 CoercibleColumnType::Record(mut fields) => {
1074 convert(fields.drain(..)).nullable(false)
1075 }
1076 CoercibleColumnType::Uncoerced => SqlScalarType::String.nullable(true),
1077 };
1078 fields.push((name, ty))
1079 }
1080 SqlScalarType::Record {
1081 fields: fields.into(),
1082 custom_id: None,
1083 }
1084 }
1085
1086 if let CoercibleScalarType::Record(fields) = self {
1087 *self = CoercibleScalarType::Coerced(convert(fields.drain(..)));
1088 }
1089 }
1090}
1091
1092pub trait AbstractExpr {
1096 type Type: AbstractColumnType;
1097
1098 fn typ(
1100 &self,
1101 outers: &[SqlRelationType],
1102 inner: &SqlRelationType,
1103 params: &BTreeMap<usize, SqlScalarType>,
1104 ) -> Self::Type;
1105}
1106
1107impl AbstractExpr for CoercibleScalarExpr {
1108 type Type = CoercibleColumnType;
1109
1110 fn typ(
1111 &self,
1112 outers: &[SqlRelationType],
1113 inner: &SqlRelationType,
1114 params: &BTreeMap<usize, SqlScalarType>,
1115 ) -> Self::Type {
1116 match self {
1117 CoercibleScalarExpr::Coerced(expr) => {
1118 CoercibleColumnType::Coerced(expr.typ(outers, inner, params))
1119 }
1120 CoercibleScalarExpr::LiteralRecord(scalars) => {
1121 let fields = scalars
1122 .iter()
1123 .map(|s| s.typ(outers, inner, params))
1124 .collect();
1125 CoercibleColumnType::Record(fields)
1126 }
1127 _ => CoercibleColumnType::Uncoerced,
1128 }
1129 }
1130}
1131
1132pub trait AbstractColumnType {
1137 type AbstractScalarType;
1138
1139 fn scalar_type(self) -> Self::AbstractScalarType;
1142}
1143
1144impl AbstractColumnType for SqlColumnType {
1145 type AbstractScalarType = SqlScalarType;
1146
1147 fn scalar_type(self) -> Self::AbstractScalarType {
1148 self.scalar_type
1149 }
1150}
1151
1152impl AbstractColumnType for CoercibleColumnType {
1153 type AbstractScalarType = CoercibleScalarType;
1154
1155 fn scalar_type(self) -> Self::AbstractScalarType {
1156 match self {
1157 CoercibleColumnType::Coerced(t) => CoercibleScalarType::Coerced(t.scalar_type),
1158 CoercibleColumnType::Record(t) => CoercibleScalarType::Record(t),
1159 CoercibleColumnType::Uncoerced => CoercibleScalarType::Uncoerced,
1160 }
1161 }
1162}
1163
1164impl From<HirScalarExpr> for CoercibleScalarExpr {
1165 fn from(expr: HirScalarExpr) -> CoercibleScalarExpr {
1166 CoercibleScalarExpr::Coerced(expr)
1167 }
1168}
1169
1170#[derive(
1185 Debug,
1186 Clone,
1187 Copy,
1188 PartialEq,
1189 Eq,
1190 Hash,
1191 Ord,
1192 PartialOrd,
1193 Serialize,
1194 Deserialize
1195)]
1196pub struct ColumnRef {
1197 pub level: usize,
1199 pub column: usize,
1201}
1202
1203#[derive(
1204 Debug,
1205 Clone,
1206 PartialEq,
1207 Eq,
1208 PartialOrd,
1209 Ord,
1210 Hash,
1211 Serialize,
1212 Deserialize
1213)]
1214pub enum JoinKind {
1215 Inner,
1216 LeftOuter,
1217 RightOuter,
1218 FullOuter,
1219}
1220
1221impl fmt::Display for JoinKind {
1222 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1223 write!(
1224 f,
1225 "{}",
1226 match self {
1227 JoinKind::Inner => "Inner",
1228 JoinKind::LeftOuter => "LeftOuter",
1229 JoinKind::RightOuter => "RightOuter",
1230 JoinKind::FullOuter => "FullOuter",
1231 }
1232 )
1233 }
1234}
1235
1236impl JoinKind {
1237 pub fn can_be_correlated(&self) -> bool {
1238 match self {
1239 JoinKind::Inner | JoinKind::LeftOuter => true,
1240 JoinKind::RightOuter | JoinKind::FullOuter => false,
1241 }
1242 }
1243
1244 pub fn can_elide_identity_left_join(&self) -> bool {
1245 match self {
1246 JoinKind::Inner | JoinKind::RightOuter => true,
1247 JoinKind::LeftOuter | JoinKind::FullOuter => false,
1248 }
1249 }
1250
1251 pub fn can_elide_identity_right_join(&self) -> bool {
1252 match self {
1253 JoinKind::Inner | JoinKind::LeftOuter => true,
1254 JoinKind::RightOuter | JoinKind::FullOuter => false,
1255 }
1256 }
1257}
1258
1259#[derive(
1260 Debug,
1261 Clone,
1262 PartialEq,
1263 Eq,
1264 PartialOrd,
1265 Ord,
1266 Hash,
1267 Serialize,
1268 Deserialize
1269)]
1270pub struct AggregateExpr {
1271 pub func: AggregateFunc,
1272 pub expr: Box<HirScalarExpr>,
1273 pub distinct: bool,
1274}
1275
1276#[derive(
1284 Clone,
1285 Debug,
1286 Eq,
1287 PartialEq,
1288 PartialOrd,
1289 Ord,
1290 Hash,
1291 Serialize,
1292 Deserialize
1293)]
1294pub enum AggregateFunc {
1295 MaxNumeric,
1296 MaxInt16,
1297 MaxInt32,
1298 MaxInt64,
1299 MaxUInt16,
1300 MaxUInt32,
1301 MaxUInt64,
1302 MaxMzTimestamp,
1303 MaxFloat32,
1304 MaxFloat64,
1305 MaxBool,
1306 MaxString,
1307 MaxDate,
1308 MaxTimestamp,
1309 MaxTimestampTz,
1310 MaxInterval,
1311 MaxTime,
1312 MaxArray,
1313 MaxList,
1314 MinNumeric,
1315 MinInt16,
1316 MinInt32,
1317 MinInt64,
1318 MinUInt16,
1319 MinUInt32,
1320 MinUInt64,
1321 MinMzTimestamp,
1322 MinFloat32,
1323 MinFloat64,
1324 MinBool,
1325 MinString,
1326 MinDate,
1327 MinTimestamp,
1328 MinTimestampTz,
1329 MinInterval,
1330 MinTime,
1331 MinArray,
1332 MinList,
1333 SumInt16,
1334 SumInt32,
1335 SumInt64,
1336 SumUInt16,
1337 SumUInt32,
1338 SumUInt64,
1339 SumFloat32,
1340 SumFloat64,
1341 SumNumeric,
1342 SumInterval,
1343 Count,
1344 Any,
1345 All,
1346 JsonbAgg {
1353 order_by: Vec<ColumnOrder>,
1354 },
1355 JsonbObjectAgg {
1358 order_by: Vec<ColumnOrder>,
1359 },
1360 MapAgg {
1364 order_by: Vec<ColumnOrder>,
1365 value_type: SqlScalarType,
1366 },
1367 ArrayConcat {
1370 order_by: Vec<ColumnOrder>,
1371 },
1372 ListConcat {
1375 order_by: Vec<ColumnOrder>,
1376 },
1377 StringAgg {
1378 order_by: Vec<ColumnOrder>,
1379 },
1380 FusedWindowAgg {
1386 funcs: Vec<AggregateFunc>,
1387 },
1388 Dummy,
1393}
1394
1395impl AggregateFunc {
1396 pub fn into_expr(self) -> mz_expr::AggregateFunc {
1398 match self {
1399 AggregateFunc::MaxNumeric => mz_expr::AggregateFunc::MaxNumeric,
1400 AggregateFunc::MaxInt16 => mz_expr::AggregateFunc::MaxInt16,
1401 AggregateFunc::MaxInt32 => mz_expr::AggregateFunc::MaxInt32,
1402 AggregateFunc::MaxInt64 => mz_expr::AggregateFunc::MaxInt64,
1403 AggregateFunc::MaxUInt16 => mz_expr::AggregateFunc::MaxUInt16,
1404 AggregateFunc::MaxUInt32 => mz_expr::AggregateFunc::MaxUInt32,
1405 AggregateFunc::MaxUInt64 => mz_expr::AggregateFunc::MaxUInt64,
1406 AggregateFunc::MaxMzTimestamp => mz_expr::AggregateFunc::MaxMzTimestamp,
1407 AggregateFunc::MaxFloat32 => mz_expr::AggregateFunc::MaxFloat32,
1408 AggregateFunc::MaxFloat64 => mz_expr::AggregateFunc::MaxFloat64,
1409 AggregateFunc::MaxBool => mz_expr::AggregateFunc::MaxBool,
1410 AggregateFunc::MaxString => mz_expr::AggregateFunc::MaxString,
1411 AggregateFunc::MaxDate => mz_expr::AggregateFunc::MaxDate,
1412 AggregateFunc::MaxTimestamp => mz_expr::AggregateFunc::MaxTimestamp,
1413 AggregateFunc::MaxTimestampTz => mz_expr::AggregateFunc::MaxTimestampTz,
1414 AggregateFunc::MaxInterval => mz_expr::AggregateFunc::MaxInterval,
1415 AggregateFunc::MaxTime => mz_expr::AggregateFunc::MaxTime,
1416 AggregateFunc::MaxArray => mz_expr::AggregateFunc::MaxArray,
1417 AggregateFunc::MaxList => mz_expr::AggregateFunc::MaxList,
1418 AggregateFunc::MinNumeric => mz_expr::AggregateFunc::MinNumeric,
1419 AggregateFunc::MinInt16 => mz_expr::AggregateFunc::MinInt16,
1420 AggregateFunc::MinInt32 => mz_expr::AggregateFunc::MinInt32,
1421 AggregateFunc::MinInt64 => mz_expr::AggregateFunc::MinInt64,
1422 AggregateFunc::MinUInt16 => mz_expr::AggregateFunc::MinUInt16,
1423 AggregateFunc::MinUInt32 => mz_expr::AggregateFunc::MinUInt32,
1424 AggregateFunc::MinUInt64 => mz_expr::AggregateFunc::MinUInt64,
1425 AggregateFunc::MinMzTimestamp => mz_expr::AggregateFunc::MinMzTimestamp,
1426 AggregateFunc::MinFloat32 => mz_expr::AggregateFunc::MinFloat32,
1427 AggregateFunc::MinFloat64 => mz_expr::AggregateFunc::MinFloat64,
1428 AggregateFunc::MinBool => mz_expr::AggregateFunc::MinBool,
1429 AggregateFunc::MinString => mz_expr::AggregateFunc::MinString,
1430 AggregateFunc::MinDate => mz_expr::AggregateFunc::MinDate,
1431 AggregateFunc::MinTimestamp => mz_expr::AggregateFunc::MinTimestamp,
1432 AggregateFunc::MinTimestampTz => mz_expr::AggregateFunc::MinTimestampTz,
1433 AggregateFunc::MinInterval => mz_expr::AggregateFunc::MinInterval,
1434 AggregateFunc::MinTime => mz_expr::AggregateFunc::MinTime,
1435 AggregateFunc::MinArray => mz_expr::AggregateFunc::MinArray,
1436 AggregateFunc::MinList => mz_expr::AggregateFunc::MinList,
1437 AggregateFunc::SumInt16 => mz_expr::AggregateFunc::SumInt16,
1438 AggregateFunc::SumInt32 => mz_expr::AggregateFunc::SumInt32,
1439 AggregateFunc::SumInt64 => mz_expr::AggregateFunc::SumInt64,
1440 AggregateFunc::SumUInt16 => mz_expr::AggregateFunc::SumUInt16,
1441 AggregateFunc::SumUInt32 => mz_expr::AggregateFunc::SumUInt32,
1442 AggregateFunc::SumUInt64 => mz_expr::AggregateFunc::SumUInt64,
1443 AggregateFunc::SumFloat32 => mz_expr::AggregateFunc::SumFloat32,
1444 AggregateFunc::SumFloat64 => mz_expr::AggregateFunc::SumFloat64,
1445 AggregateFunc::SumNumeric => mz_expr::AggregateFunc::SumNumeric,
1446 AggregateFunc::SumInterval => mz_expr::AggregateFunc::SumInterval,
1447 AggregateFunc::Count => mz_expr::AggregateFunc::Count,
1448 AggregateFunc::Any => mz_expr::AggregateFunc::Any,
1449 AggregateFunc::All => mz_expr::AggregateFunc::All,
1450 AggregateFunc::JsonbAgg { order_by } => mz_expr::AggregateFunc::JsonbAgg { order_by },
1451 AggregateFunc::JsonbObjectAgg { order_by } => {
1452 mz_expr::AggregateFunc::JsonbObjectAgg { order_by }
1453 }
1454 AggregateFunc::MapAgg {
1455 order_by,
1456 value_type,
1457 } => mz_expr::AggregateFunc::MapAgg {
1458 order_by,
1459 value_type,
1460 },
1461 AggregateFunc::ArrayConcat { order_by } => {
1462 mz_expr::AggregateFunc::ArrayConcat { order_by }
1463 }
1464 AggregateFunc::ListConcat { order_by } => {
1465 mz_expr::AggregateFunc::ListConcat { order_by }
1466 }
1467 AggregateFunc::StringAgg { order_by } => mz_expr::AggregateFunc::StringAgg { order_by },
1468 AggregateFunc::FusedWindowAgg { funcs: _ } => {
1471 panic!("into_expr called on FusedWindowAgg")
1472 }
1473 AggregateFunc::Dummy => mz_expr::AggregateFunc::Dummy,
1474 }
1475 }
1476
1477 pub fn identity_datum(&self) -> Datum<'static> {
1484 match self {
1485 AggregateFunc::Any => Datum::False,
1486 AggregateFunc::All => Datum::True,
1487 AggregateFunc::Dummy => Datum::Dummy,
1488 AggregateFunc::ArrayConcat { .. } => Datum::empty_array(),
1489 AggregateFunc::ListConcat { .. } => Datum::empty_list(),
1490 AggregateFunc::MaxNumeric
1491 | AggregateFunc::MaxInt16
1492 | AggregateFunc::MaxInt32
1493 | AggregateFunc::MaxInt64
1494 | AggregateFunc::MaxUInt16
1495 | AggregateFunc::MaxUInt32
1496 | AggregateFunc::MaxUInt64
1497 | AggregateFunc::MaxMzTimestamp
1498 | AggregateFunc::MaxFloat32
1499 | AggregateFunc::MaxFloat64
1500 | AggregateFunc::MaxBool
1501 | AggregateFunc::MaxString
1502 | AggregateFunc::MaxDate
1503 | AggregateFunc::MaxTimestamp
1504 | AggregateFunc::MaxTimestampTz
1505 | AggregateFunc::MaxInterval
1506 | AggregateFunc::MaxTime
1507 | AggregateFunc::MaxArray
1508 | AggregateFunc::MaxList
1509 | AggregateFunc::MinNumeric
1510 | AggregateFunc::MinInt16
1511 | AggregateFunc::MinInt32
1512 | AggregateFunc::MinInt64
1513 | AggregateFunc::MinUInt16
1514 | AggregateFunc::MinUInt32
1515 | AggregateFunc::MinUInt64
1516 | AggregateFunc::MinMzTimestamp
1517 | AggregateFunc::MinFloat32
1518 | AggregateFunc::MinFloat64
1519 | AggregateFunc::MinBool
1520 | AggregateFunc::MinString
1521 | AggregateFunc::MinDate
1522 | AggregateFunc::MinTimestamp
1523 | AggregateFunc::MinTimestampTz
1524 | AggregateFunc::MinInterval
1525 | AggregateFunc::MinTime
1526 | AggregateFunc::MinArray
1527 | AggregateFunc::MinList
1528 | AggregateFunc::SumInt16
1529 | AggregateFunc::SumInt32
1530 | AggregateFunc::SumInt64
1531 | AggregateFunc::SumUInt16
1532 | AggregateFunc::SumUInt32
1533 | AggregateFunc::SumUInt64
1534 | AggregateFunc::SumFloat32
1535 | AggregateFunc::SumFloat64
1536 | AggregateFunc::SumNumeric
1537 | AggregateFunc::SumInterval
1538 | AggregateFunc::Count
1539 | AggregateFunc::JsonbAgg { .. }
1540 | AggregateFunc::JsonbObjectAgg { .. }
1541 | AggregateFunc::MapAgg { .. }
1542 | AggregateFunc::StringAgg { .. } => Datum::Null,
1543 AggregateFunc::FusedWindowAgg { funcs: _ } => {
1544 panic!("FusedWindowAgg doesn't have an identity_datum")
1554 }
1555 }
1556 }
1557
1558 pub fn output_sql_type(&self, input_type: SqlColumnType) -> SqlColumnType {
1564 let scalar_type = match self {
1565 AggregateFunc::Count => SqlScalarType::Int64,
1566 AggregateFunc::Any => SqlScalarType::Bool,
1567 AggregateFunc::All => SqlScalarType::Bool,
1568 AggregateFunc::JsonbAgg { .. } => SqlScalarType::Jsonb,
1569 AggregateFunc::JsonbObjectAgg { .. } => SqlScalarType::Jsonb,
1570 AggregateFunc::StringAgg { .. } => SqlScalarType::String,
1571 AggregateFunc::SumInt16 | AggregateFunc::SumInt32 => SqlScalarType::Int64,
1572 AggregateFunc::SumInt64 => SqlScalarType::Numeric {
1573 max_scale: Some(NumericMaxScale::ZERO),
1574 },
1575 AggregateFunc::SumUInt16 | AggregateFunc::SumUInt32 => SqlScalarType::UInt64,
1576 AggregateFunc::SumUInt64 => SqlScalarType::Numeric {
1577 max_scale: Some(NumericMaxScale::ZERO),
1578 },
1579 AggregateFunc::MapAgg { value_type, .. } => SqlScalarType::Map {
1580 value_type: Box::new(value_type.clone()),
1581 custom_id: None,
1582 },
1583 AggregateFunc::ArrayConcat { .. } | AggregateFunc::ListConcat { .. } => {
1584 match input_type.scalar_type {
1585 SqlScalarType::Record { fields, .. } => fields[0].1.scalar_type.clone(),
1587 _ => unreachable!(),
1588 }
1589 }
1590 AggregateFunc::MaxNumeric
1591 | AggregateFunc::MaxInt16
1592 | AggregateFunc::MaxInt32
1593 | AggregateFunc::MaxInt64
1594 | AggregateFunc::MaxUInt16
1595 | AggregateFunc::MaxUInt32
1596 | AggregateFunc::MaxUInt64
1597 | AggregateFunc::MaxMzTimestamp
1598 | AggregateFunc::MaxFloat32
1599 | AggregateFunc::MaxFloat64
1600 | AggregateFunc::MaxBool
1601 | AggregateFunc::MaxString
1602 | AggregateFunc::MaxDate
1603 | AggregateFunc::MaxTimestamp
1604 | AggregateFunc::MaxTimestampTz
1605 | AggregateFunc::MaxInterval
1606 | AggregateFunc::MaxTime
1607 | AggregateFunc::MaxArray
1608 | AggregateFunc::MaxList
1609 | AggregateFunc::MinNumeric
1610 | AggregateFunc::MinInt16
1611 | AggregateFunc::MinInt32
1612 | AggregateFunc::MinInt64
1613 | AggregateFunc::MinUInt16
1614 | AggregateFunc::MinUInt32
1615 | AggregateFunc::MinUInt64
1616 | AggregateFunc::MinMzTimestamp
1617 | AggregateFunc::MinFloat32
1618 | AggregateFunc::MinFloat64
1619 | AggregateFunc::MinBool
1620 | AggregateFunc::MinString
1621 | AggregateFunc::MinDate
1622 | AggregateFunc::MinTimestamp
1623 | AggregateFunc::MinTimestampTz
1624 | AggregateFunc::MinInterval
1625 | AggregateFunc::MinTime
1626 | AggregateFunc::MinArray
1627 | AggregateFunc::MinList
1628 | AggregateFunc::SumFloat32
1629 | AggregateFunc::SumFloat64
1630 | AggregateFunc::SumNumeric
1631 | AggregateFunc::SumInterval
1632 | AggregateFunc::Dummy => input_type.scalar_type,
1633 AggregateFunc::FusedWindowAgg { funcs } => {
1634 let input_types = input_type.scalar_type.unwrap_record_element_column_type();
1635 SqlScalarType::Record {
1636 fields: funcs
1637 .iter()
1638 .zip_eq(input_types)
1639 .map(|(f, t)| (ColumnName::from(""), f.output_sql_type(t.clone())))
1640 .collect(),
1641 custom_id: None,
1642 }
1643 }
1644 };
1645 let nullable = !matches!(self, AggregateFunc::Count);
1647 scalar_type.nullable(nullable)
1648 }
1649
1650 pub fn is_order_sensitive(&self) -> bool {
1651 use AggregateFunc::*;
1652 matches!(
1653 self,
1654 JsonbAgg { .. }
1655 | JsonbObjectAgg { .. }
1656 | MapAgg { .. }
1657 | ArrayConcat { .. }
1658 | ListConcat { .. }
1659 | StringAgg { .. }
1660 )
1661 }
1662}
1663
1664impl HirRelationExpr {
1665 pub fn top_level_typ(&self) -> SqlRelationType {
1667 self.typ(&[], &BTreeMap::new())
1668 }
1669
1670 pub fn typ(
1675 &self,
1676 outers: &[SqlRelationType],
1677 params: &BTreeMap<usize, SqlScalarType>,
1678 ) -> SqlRelationType {
1679 stack::maybe_grow(|| match self {
1680 HirRelationExpr::Constant { typ, .. } => typ.clone(),
1681 HirRelationExpr::Get { typ, .. } => typ.clone(),
1682 HirRelationExpr::Let { body, .. } => body.typ(outers, params),
1683 HirRelationExpr::LetRec { body, .. } => body.typ(outers, params),
1684 HirRelationExpr::Project { input, outputs } => {
1685 let input_typ = input.typ(outers, params);
1686 SqlRelationType::new(
1687 outputs
1688 .iter()
1689 .map(|&i| input_typ.column_types[i].clone())
1690 .collect(),
1691 )
1692 }
1693 HirRelationExpr::Map { input, scalars } => {
1694 let mut typ = input.typ(outers, params);
1695 for scalar in scalars {
1696 typ.column_types.push(scalar.typ(outers, &typ, params));
1697 }
1698 typ
1699 }
1700 HirRelationExpr::CallTable { func, exprs: _ } => func.output_sql_type(),
1701 HirRelationExpr::Filter { input, .. } | HirRelationExpr::TopK { input, .. } => {
1702 input.typ(outers, params)
1703 }
1704 HirRelationExpr::Join {
1705 left, right, kind, ..
1706 } => {
1707 let left_nullable = matches!(kind, JoinKind::RightOuter | JoinKind::FullOuter);
1708 let right_nullable =
1709 matches!(kind, JoinKind::LeftOuter { .. } | JoinKind::FullOuter);
1710 let lt = left.typ(outers, params).column_types.into_iter().map(|t| {
1711 let nullable = t.nullable || left_nullable;
1712 t.nullable(nullable)
1713 });
1714 let mut outers = outers.to_vec();
1715 outers.insert(0, SqlRelationType::new(lt.clone().collect()));
1716 let rt = right
1717 .typ(&outers, params)
1718 .column_types
1719 .into_iter()
1720 .map(|t| {
1721 let nullable = t.nullable || right_nullable;
1722 t.nullable(nullable)
1723 });
1724 SqlRelationType::new(lt.chain(rt).collect())
1725 }
1726 HirRelationExpr::Reduce {
1727 input,
1728 group_key,
1729 aggregates,
1730 expected_group_size: _,
1731 } => {
1732 let input_typ = input.typ(outers, params);
1733 let mut column_types = group_key
1734 .iter()
1735 .map(|&i| input_typ.column_types[i].clone())
1736 .collect::<Vec<_>>();
1737 for agg in aggregates {
1738 column_types.push(agg.typ(outers, &input_typ, params));
1739 }
1740 SqlRelationType::new(column_types)
1742 }
1743 HirRelationExpr::Distinct { input }
1745 | HirRelationExpr::Negate { input }
1746 | HirRelationExpr::Threshold { input } => input.typ(outers, params),
1747 HirRelationExpr::Union { base, inputs } => {
1748 let mut base_cols = base.typ(outers, params).column_types;
1749 for input in inputs {
1750 for (base_col, col) in base_cols
1751 .iter_mut()
1752 .zip_eq(input.typ(outers, params).column_types)
1753 {
1754 *base_col = base_col.sql_union(&col).unwrap(); }
1756 }
1757 SqlRelationType::new(base_cols)
1758 }
1759 })
1760 }
1761
1762 pub fn arity(&self) -> usize {
1763 match self {
1764 HirRelationExpr::Constant { typ, .. } => typ.column_types.len(),
1765 HirRelationExpr::Get { typ, .. } => typ.column_types.len(),
1766 HirRelationExpr::Let { body, .. } => body.arity(),
1767 HirRelationExpr::LetRec { body, .. } => body.arity(),
1768 HirRelationExpr::Project { outputs, .. } => outputs.len(),
1769 HirRelationExpr::Map { input, scalars } => input.arity() + scalars.len(),
1770 HirRelationExpr::CallTable { func, exprs: _ } => func.output_arity(),
1771 HirRelationExpr::Filter { input, .. }
1772 | HirRelationExpr::TopK { input, .. }
1773 | HirRelationExpr::Distinct { input }
1774 | HirRelationExpr::Negate { input }
1775 | HirRelationExpr::Threshold { input } => input.arity(),
1776 HirRelationExpr::Join { left, right, .. } => left.arity() + right.arity(),
1777 HirRelationExpr::Union { base, .. } => base.arity(),
1778 HirRelationExpr::Reduce {
1779 group_key,
1780 aggregates,
1781 ..
1782 } => group_key.len() + aggregates.len(),
1783 }
1784 }
1785
1786 pub fn relation_node_count(&self) -> usize {
1793 let mut count = 0;
1794 self.visit_post(&mut |_| count += 1);
1795 count
1796 }
1797
1798 pub fn as_const(&self) -> Option<(&Vec<Row>, &SqlRelationType)> {
1800 match self {
1801 Self::Constant { rows, typ } => Some((rows, typ)),
1802 _ => None,
1803 }
1804 }
1805
1806 pub fn is_correlated(&self) -> bool {
1809 let mut correlated = false;
1810 #[allow(deprecated)]
1811 self.visit_columns(0, &mut |depth, col| {
1812 if col.level > depth && col.level - depth == 1 {
1813 correlated = true;
1814 }
1815 });
1816 correlated
1817 }
1818
1819 pub fn is_join_identity(&self) -> bool {
1820 match self {
1821 HirRelationExpr::Constant { rows, .. } => rows.len() == 1 && self.arity() == 0,
1822 _ => false,
1823 }
1824 }
1825
1826 pub fn project(self, outputs: Vec<usize>) -> Self {
1827 if outputs.iter().copied().eq(0..self.arity()) {
1828 self
1830 } else {
1831 HirRelationExpr::Project {
1832 input: Box::new(self),
1833 outputs,
1834 }
1835 }
1836 }
1837
1838 pub fn map(mut self, scalars: Vec<HirScalarExpr>) -> Self {
1839 if scalars.is_empty() {
1840 self
1842 } else if let HirRelationExpr::Map {
1843 scalars: old_scalars,
1844 input: _,
1845 } = &mut self
1846 {
1847 old_scalars.extend(scalars);
1849 self
1850 } else {
1851 HirRelationExpr::Map {
1852 input: Box::new(self),
1853 scalars,
1854 }
1855 }
1856 }
1857
1858 pub fn filter(mut self, mut preds: Vec<HirScalarExpr>) -> Self {
1859 if let HirRelationExpr::Filter {
1860 input: _,
1861 predicates,
1862 } = &mut self
1863 {
1864 predicates.extend(preds);
1865 predicates.sort();
1866 predicates.dedup();
1867 self
1868 } else {
1869 preds.sort();
1870 preds.dedup();
1871 HirRelationExpr::Filter {
1872 input: Box::new(self),
1873 predicates: preds,
1874 }
1875 }
1876 }
1877
1878 pub fn reduce(
1879 self,
1880 group_key: Vec<usize>,
1881 aggregates: Vec<AggregateExpr>,
1882 expected_group_size: Option<u64>,
1883 ) -> Self {
1884 HirRelationExpr::Reduce {
1885 input: Box::new(self),
1886 group_key,
1887 aggregates,
1888 expected_group_size,
1889 }
1890 }
1891
1892 pub fn top_k(
1893 self,
1894 group_key: Vec<usize>,
1895 order_key: Vec<ColumnOrder>,
1896 limit: Option<HirScalarExpr>,
1897 offset: HirScalarExpr,
1898 expected_group_size: Option<u64>,
1899 ) -> Self {
1900 HirRelationExpr::TopK {
1901 input: Box::new(self),
1902 group_key,
1903 order_key,
1904 limit,
1905 offset,
1906 expected_group_size,
1907 }
1908 }
1909
1910 pub fn negate(self) -> Self {
1911 if let HirRelationExpr::Negate { input } = self {
1912 *input
1913 } else {
1914 HirRelationExpr::Negate {
1915 input: Box::new(self),
1916 }
1917 }
1918 }
1919
1920 pub fn distinct(self) -> Self {
1921 if let HirRelationExpr::Distinct { .. } = self {
1922 self
1923 } else {
1924 HirRelationExpr::Distinct {
1925 input: Box::new(self),
1926 }
1927 }
1928 }
1929
1930 pub fn threshold(self) -> Self {
1931 if let HirRelationExpr::Threshold { .. } = self {
1932 self
1933 } else {
1934 HirRelationExpr::Threshold {
1935 input: Box::new(self),
1936 }
1937 }
1938 }
1939
1940 pub fn union(self, other: Self) -> Self {
1941 let mut terms = Vec::new();
1942 if let HirRelationExpr::Union { base, inputs } = self {
1943 terms.push(*base);
1944 terms.extend(inputs);
1945 } else {
1946 terms.push(self);
1947 }
1948 if let HirRelationExpr::Union { base, inputs } = other {
1949 terms.push(*base);
1950 terms.extend(inputs);
1951 } else {
1952 terms.push(other);
1953 }
1954 HirRelationExpr::Union {
1955 base: Box::new(terms.remove(0)),
1956 inputs: terms,
1957 }
1958 }
1959
1960 pub fn exists(self) -> HirScalarExpr {
1961 HirScalarExpr::Exists(Box::new(self), NameMetadata::default())
1962 }
1963
1964 pub fn select(self) -> HirScalarExpr {
1965 HirScalarExpr::Select(Box::new(self), NameMetadata::default())
1966 }
1967
1968 pub fn join(
1969 self,
1970 mut right: HirRelationExpr,
1971 on: HirScalarExpr,
1972 kind: JoinKind,
1973 ) -> HirRelationExpr {
1974 if self.is_join_identity()
1975 && !right.is_correlated()
1976 && on == HirScalarExpr::literal_true()
1977 && kind.can_elide_identity_left_join()
1978 {
1979 #[allow(deprecated)]
1983 right.visit_columns_mut(0, &mut |depth, col| {
1984 if col.level > depth {
1985 col.level -= 1;
1986 }
1987 });
1988 right
1989 } else if right.is_join_identity()
1990 && on == HirScalarExpr::literal_true()
1991 && kind.can_elide_identity_right_join()
1992 {
1993 self
1994 } else {
1995 HirRelationExpr::Join {
1996 left: Box::new(self),
1997 right: Box::new(right),
1998 on,
1999 kind,
2000 }
2001 }
2002 }
2003
2004 pub fn take(&mut self) -> HirRelationExpr {
2005 mem::replace(
2006 self,
2007 HirRelationExpr::constant(vec![], SqlRelationType::new(Vec::new())),
2008 )
2009 }
2010
2011 #[deprecated = "Use `Visit::visit_post`."]
2012 pub fn visit<'a, F>(&'a self, depth: usize, f: &mut F)
2013 where
2014 F: FnMut(&'a Self, usize),
2015 {
2016 #[allow(deprecated)]
2017 let _ = self.visit_fallible(depth, &mut |e: &HirRelationExpr,
2018 depth: usize|
2019 -> Result<(), ()> {
2020 f(e, depth);
2021 Ok(())
2022 });
2023 }
2024
2025 #[deprecated = "Use `Visit::try_visit_post`."]
2026 pub fn visit_fallible<'a, F, E>(&'a self, depth: usize, f: &mut F) -> Result<(), E>
2027 where
2028 F: FnMut(&'a Self, usize) -> Result<(), E>,
2029 {
2030 #[allow(deprecated)]
2031 stack::maybe_grow(|| {
2034 self.visit1(depth, |e: &HirRelationExpr, depth: usize| {
2035 e.visit_fallible(depth, f)
2036 })
2037 })?;
2038 f(self, depth)
2039 }
2040
2041 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_children` instead."]
2046 pub fn visit1<'a, F, E>(&'a self, depth: usize, mut f: F) -> Result<(), E>
2047 where
2048 F: FnMut(&'a Self, usize) -> Result<(), E>,
2049 {
2050 match self {
2051 HirRelationExpr::Constant { .. }
2052 | HirRelationExpr::Get { .. }
2053 | HirRelationExpr::CallTable { .. } => (),
2054 HirRelationExpr::Let { body, value, .. } => {
2055 f(value, depth)?;
2056 f(body, depth)?;
2057 }
2058 HirRelationExpr::LetRec {
2059 limit: _,
2060 bindings,
2061 body,
2062 } => {
2063 for (_, _, value, _) in bindings.iter() {
2064 f(value, depth)?;
2065 }
2066 f(body, depth)?;
2067 }
2068 HirRelationExpr::Project { input, .. } => {
2069 f(input, depth)?;
2070 }
2071 HirRelationExpr::Map { input, .. } => {
2072 f(input, depth)?;
2073 }
2074 HirRelationExpr::Filter { input, .. } => {
2075 f(input, depth)?;
2076 }
2077 HirRelationExpr::Join { left, right, .. } => {
2078 f(left, depth)?;
2079 f(right, depth + 1)?;
2080 }
2081 HirRelationExpr::Reduce { input, .. } => {
2082 f(input, depth)?;
2083 }
2084 HirRelationExpr::Distinct { input } => {
2085 f(input, depth)?;
2086 }
2087 HirRelationExpr::TopK { input, .. } => {
2088 f(input, depth)?;
2089 }
2090 HirRelationExpr::Negate { input } => {
2091 f(input, depth)?;
2092 }
2093 HirRelationExpr::Threshold { input } => {
2094 f(input, depth)?;
2095 }
2096 HirRelationExpr::Union { base, inputs } => {
2097 f(base, depth)?;
2098 for input in inputs {
2099 f(input, depth)?;
2100 }
2101 }
2102 }
2103 Ok(())
2104 }
2105
2106 #[deprecated = "Use `Visit::visit_mut_post` instead."]
2107 pub fn visit_mut<F>(&mut self, depth: usize, f: &mut F)
2108 where
2109 F: FnMut(&mut Self, usize),
2110 {
2111 #[allow(deprecated)]
2112 let _ = self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2113 depth: usize|
2114 -> Result<(), ()> {
2115 f(e, depth);
2116 Ok(())
2117 });
2118 }
2119
2120 #[deprecated = "Use `Visit::try_visit_mut_post` instead."]
2121 pub fn visit_mut_fallible<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2122 where
2123 F: FnMut(&mut Self, usize) -> Result<(), E>,
2124 {
2125 #[allow(deprecated)]
2126 stack::maybe_grow(|| {
2129 self.visit1_mut(depth, |e: &mut HirRelationExpr, depth: usize| {
2130 e.visit_mut_fallible(depth, f)
2131 })
2132 })?;
2133 f(self, depth)
2134 }
2135
2136 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_mut_children` instead."]
2141 pub fn visit1_mut<'a, F, E>(&'a mut self, depth: usize, mut f: F) -> Result<(), E>
2142 where
2143 F: FnMut(&'a mut Self, usize) -> Result<(), E>,
2144 {
2145 match self {
2146 HirRelationExpr::Constant { .. }
2147 | HirRelationExpr::Get { .. }
2148 | HirRelationExpr::CallTable { .. } => (),
2149 HirRelationExpr::Let { body, value, .. } => {
2150 f(value, depth)?;
2151 f(body, depth)?;
2152 }
2153 HirRelationExpr::LetRec {
2154 limit: _,
2155 bindings,
2156 body,
2157 } => {
2158 for (_, _, value, _) in bindings.iter_mut() {
2159 f(value, depth)?;
2160 }
2161 f(body, depth)?;
2162 }
2163 HirRelationExpr::Project { input, .. } => {
2164 f(input, depth)?;
2165 }
2166 HirRelationExpr::Map { input, .. } => {
2167 f(input, depth)?;
2168 }
2169 HirRelationExpr::Filter { input, .. } => {
2170 f(input, depth)?;
2171 }
2172 HirRelationExpr::Join { left, right, .. } => {
2173 f(left, depth)?;
2174 f(right, depth + 1)?;
2175 }
2176 HirRelationExpr::Reduce { input, .. } => {
2177 f(input, depth)?;
2178 }
2179 HirRelationExpr::Distinct { input } => {
2180 f(input, depth)?;
2181 }
2182 HirRelationExpr::TopK { input, .. } => {
2183 f(input, depth)?;
2184 }
2185 HirRelationExpr::Negate { input } => {
2186 f(input, depth)?;
2187 }
2188 HirRelationExpr::Threshold { input } => {
2189 f(input, depth)?;
2190 }
2191 HirRelationExpr::Union { base, inputs } => {
2192 f(base, depth)?;
2193 for input in inputs {
2194 f(input, depth)?;
2195 }
2196 }
2197 }
2198 Ok(())
2199 }
2200
2201 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2202 pub fn visit_scalar_expressions<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
2214 where
2215 F: FnMut(&HirScalarExpr, usize) -> Result<(), E>,
2216 {
2217 #[allow(deprecated)]
2218 self.visit_fallible(depth, &mut |e: &HirRelationExpr,
2219 depth: usize|
2220 -> Result<(), E> {
2221 match e {
2222 HirRelationExpr::Join { on, .. } => {
2223 f(on, depth)?;
2224 }
2225 HirRelationExpr::Map { scalars, .. } => {
2226 for scalar in scalars {
2227 f(scalar, depth)?;
2228 }
2229 }
2230 HirRelationExpr::CallTable { exprs, .. } => {
2231 for expr in exprs {
2232 f(expr, depth)?;
2233 }
2234 }
2235 HirRelationExpr::Filter { predicates, .. } => {
2236 for predicate in predicates {
2237 f(predicate, depth)?;
2238 }
2239 }
2240 HirRelationExpr::Reduce { aggregates, .. } => {
2241 for aggregate in aggregates {
2242 f(&aggregate.expr, depth)?;
2243 }
2244 }
2245 HirRelationExpr::TopK { limit, offset, .. } => {
2246 if let Some(limit) = limit {
2247 f(limit, depth)?;
2248 }
2249 f(offset, depth)?;
2250 }
2251 HirRelationExpr::Union { .. }
2252 | HirRelationExpr::Let { .. }
2253 | HirRelationExpr::LetRec { .. }
2254 | HirRelationExpr::Project { .. }
2255 | HirRelationExpr::Distinct { .. }
2256 | HirRelationExpr::Negate { .. }
2257 | HirRelationExpr::Threshold { .. }
2258 | HirRelationExpr::Constant { .. }
2259 | HirRelationExpr::Get { .. } => (),
2260 }
2261 Ok(())
2262 })
2263 }
2264
2265 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2266 pub fn visit_scalar_expressions_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2272 where
2273 F: FnMut(&mut HirScalarExpr, usize) -> Result<(), E>,
2274 {
2275 #[allow(deprecated)]
2276 self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2277 depth: usize|
2278 -> Result<(), E> {
2279 match e {
2280 HirRelationExpr::Join { on, .. } => {
2281 f(on, depth)?;
2282 }
2283 HirRelationExpr::Map { scalars, .. } => {
2284 for scalar in scalars.iter_mut() {
2285 f(scalar, depth)?;
2286 }
2287 }
2288 HirRelationExpr::CallTable { exprs, .. } => {
2289 for expr in exprs.iter_mut() {
2290 f(expr, depth)?;
2291 }
2292 }
2293 HirRelationExpr::Filter { predicates, .. } => {
2294 for predicate in predicates.iter_mut() {
2295 f(predicate, depth)?;
2296 }
2297 }
2298 HirRelationExpr::Reduce { aggregates, .. } => {
2299 for aggregate in aggregates.iter_mut() {
2300 f(&mut aggregate.expr, depth)?;
2301 }
2302 }
2303 HirRelationExpr::TopK { limit, offset, .. } => {
2304 if let Some(limit) = limit {
2305 f(limit, depth)?;
2306 }
2307 f(offset, depth)?;
2308 }
2309 HirRelationExpr::Union { .. }
2310 | HirRelationExpr::Let { .. }
2311 | HirRelationExpr::LetRec { .. }
2312 | HirRelationExpr::Project { .. }
2313 | HirRelationExpr::Distinct { .. }
2314 | HirRelationExpr::Negate { .. }
2315 | HirRelationExpr::Threshold { .. }
2316 | HirRelationExpr::Constant { .. }
2317 | HirRelationExpr::Get { .. } => (),
2318 }
2319 Ok(())
2320 })
2321 }
2322
2323 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2324 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
2330 where
2331 F: FnMut(usize, &ColumnRef),
2332 {
2333 #[allow(deprecated)]
2334 let _ = self.visit_scalar_expressions(depth, &mut |e: &HirScalarExpr,
2335 depth: usize|
2336 -> Result<(), ()> {
2337 e.visit_columns(depth, f);
2338 Ok(())
2339 });
2340 }
2341
2342 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2343 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
2345 where
2346 F: FnMut(usize, &mut ColumnRef),
2347 {
2348 #[allow(deprecated)]
2349 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2350 depth: usize|
2351 -> Result<(), ()> {
2352 e.visit_columns_mut(depth, f);
2353 Ok(())
2354 });
2355 }
2356
2357 pub fn bind_parameters_and_simplify_offset(
2367 &mut self,
2368 scx: &StatementContext,
2369 lifetime: QueryLifetime,
2370 params: &Params,
2371 ) -> Result<(), PlanError> {
2372 #[allow(deprecated)]
2373 self.visit_scalar_expressions_mut(0, &mut |e: &mut HirScalarExpr, _: usize| {
2374 e.bind_parameters_and_simplify_offset(scx, lifetime, params)
2375 })?;
2376
2377 self.try_visit_mut_pre(&mut |expr| {
2380 if let HirRelationExpr::TopK { offset, .. } = expr {
2381 let offset_value = offset_into_value(offset.take())?;
2382 *offset = HirScalarExpr::literal(Datum::Int64(offset_value), SqlScalarType::Int64);
2383 }
2384 Ok::<(), PlanError>(())
2385 })
2386 }
2390
2391 pub fn contains_parameters(&self) -> Result<bool, PlanError> {
2392 let mut contains_parameters = false;
2393 #[allow(deprecated)]
2394 self.visit_scalar_expressions(0, &mut |e: &HirScalarExpr, _: usize| {
2395 if e.contains_parameters() {
2396 contains_parameters = true;
2397 }
2398 Ok::<(), PlanError>(())
2399 })?;
2400 Ok(contains_parameters)
2401 }
2402
2403 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
2405 #[allow(deprecated)]
2406 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2407 depth: usize|
2408 -> Result<(), ()> {
2409 e.splice_parameters(params, depth);
2410 Ok(())
2411 });
2412 }
2413
2414 pub fn constant(rows: Vec<Vec<Datum>>, typ: SqlRelationType) -> Self {
2416 let rows = rows
2417 .into_iter()
2418 .map(move |datums| Row::pack_slice(&datums))
2419 .collect();
2420 HirRelationExpr::Constant { rows, typ }
2421 }
2422
2423 pub fn finish_maintained(
2429 &mut self,
2430 finishing: &mut RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2431 group_size_hints: GroupSizeHints,
2432 ) {
2433 if !HirRelationExpr::is_trivial_row_set_finishing_hir(finishing, self.arity()) {
2434 let old_finishing = mem::replace(
2435 finishing,
2436 HirRelationExpr::trivial_row_set_finishing_hir(finishing.project.len()),
2437 );
2438 *self = HirRelationExpr::top_k(
2439 std::mem::replace(
2440 self,
2441 HirRelationExpr::Constant {
2442 rows: vec![],
2443 typ: SqlRelationType::new(Vec::new()),
2444 },
2445 ),
2446 vec![],
2447 old_finishing.order_by,
2448 old_finishing.limit,
2449 old_finishing.offset,
2450 group_size_hints.limit_input_group_size,
2451 )
2452 .project(old_finishing.project);
2453 }
2454 }
2455
2456 pub fn trivial_row_set_finishing_hir(
2461 arity: usize,
2462 ) -> RowSetFinishing<HirScalarExpr, HirScalarExpr> {
2463 RowSetFinishing {
2464 order_by: Vec::new(),
2465 limit: None,
2466 offset: HirScalarExpr::literal(Datum::Int64(0), SqlScalarType::Int64),
2467 project: (0..arity).collect(),
2468 }
2469 }
2470
2471 pub fn is_trivial_row_set_finishing_hir(
2476 rsf: &RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2477 arity: usize,
2478 ) -> bool {
2479 rsf.limit.is_none()
2480 && rsf.order_by.is_empty()
2481 && rsf
2482 .offset
2483 .clone()
2484 .try_into_literal_int64()
2485 .is_ok_and(|o| o == 0)
2486 && rsf.project.iter().copied().eq(0..arity)
2487 }
2488
2489 pub fn could_run_expensive_function(&self) -> bool {
2499 let mut result = false;
2500 self.visit_pre(&mut |e: &HirRelationExpr| {
2501 use HirRelationExpr::*;
2502 use HirScalarExpr::*;
2503
2504 e.visit_children(|scalar: &HirScalarExpr| {
2505 scalar.visit_pre(&mut |scalar: &HirScalarExpr| {
2506 result |= match scalar {
2507 Column(..)
2508 | Literal(..)
2509 | CallUnmaterializable(..)
2510 | If { .. }
2511 | Parameter(..)
2512 | Select(..)
2513 | Exists(..) => false,
2514 CallUnary { .. }
2516 | CallBinary { .. }
2517 | CallVariadic { .. }
2518 | Windowing(..) => true,
2519 };
2520 })
2521 });
2522
2523 result |= matches!(e, CallTable { .. } | Reduce { .. });
2526 });
2527
2528 result
2529 }
2530
2531 pub fn contains_temporal(&self) -> bool {
2533 let mut contains = false;
2534 self.visit_post(&mut |expr| {
2535 expr.visit_children(|expr: &HirScalarExpr| {
2536 contains = contains || expr.contains_temporal()
2537 })
2538 });
2539 contains
2540 }
2541
2542 pub fn contains_unmaterializable(&self) -> bool {
2544 let mut contains = false;
2545 self.visit_post(&mut |expr| {
2546 expr.visit_children(|expr: &HirScalarExpr| {
2547 contains = contains || expr.contains_unmaterializable()
2548 })
2549 });
2550 contains
2551 }
2552
2553 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
2556 let mut contains = false;
2557 self.visit_post(&mut |expr| {
2558 expr.visit_children(|expr: &HirScalarExpr| {
2559 contains = contains || expr.contains_unmaterializable_except_temporal()
2560 })
2561 });
2562 contains
2563 }
2564}
2565
2566impl CollectionPlan for HirRelationExpr {
2567 fn depends_on_into(&self, out: &mut BTreeSet<GlobalId>) {
2574 if let Self::Get {
2575 id: Id::Global(id), ..
2576 } = self
2577 {
2578 out.insert(*id);
2579 }
2580 self.visit_children(|expr: &HirRelationExpr| expr.depends_on_into(out))
2581 }
2582}
2583
2584impl VisitChildren<Self> for HirRelationExpr {
2590 fn visit_children<F>(&self, mut f: F)
2591 where
2592 F: FnMut(&Self),
2593 {
2594 VisitChildren::visit_children(self, |expr: &HirScalarExpr| {
2598 expr.visit_direct_subqueries(&mut f);
2599 });
2600
2601 use HirRelationExpr::*;
2602 match self {
2603 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2604 Let {
2605 name: _,
2606 id: _,
2607 value,
2608 body,
2609 } => {
2610 f(value);
2611 f(body);
2612 }
2613 LetRec {
2614 limit: _,
2615 bindings,
2616 body,
2617 } => {
2618 for (_, _, value, _) in bindings.iter() {
2619 f(value);
2620 }
2621 f(body);
2622 }
2623 Project { input, outputs: _ } => f(input),
2624 Map { input, scalars: _ } => {
2625 f(input);
2626 }
2627 CallTable { func: _, exprs: _ } => (),
2628 Filter {
2629 input,
2630 predicates: _,
2631 } => {
2632 f(input);
2633 }
2634 Join {
2635 left,
2636 right,
2637 on: _,
2638 kind: _,
2639 } => {
2640 f(left);
2641 f(right);
2642 }
2643 Reduce {
2644 input,
2645 group_key: _,
2646 aggregates: _,
2647 expected_group_size: _,
2648 } => {
2649 f(input);
2650 }
2651 Distinct { input }
2652 | TopK {
2653 input,
2654 group_key: _,
2655 order_key: _,
2656 limit: _,
2657 offset: _,
2658 expected_group_size: _,
2659 }
2660 | Negate { input }
2661 | Threshold { input } => {
2662 f(input);
2663 }
2664 Union { base, inputs } => {
2665 f(base);
2666 for input in inputs {
2667 f(input);
2668 }
2669 }
2670 }
2671 }
2672
2673 fn visit_mut_children<F>(&mut self, mut f: F)
2674 where
2675 F: FnMut(&mut Self),
2676 {
2677 VisitChildren::visit_mut_children(self, |expr: &mut HirScalarExpr| {
2681 expr.visit_direct_subqueries_mut(&mut f);
2682 });
2683
2684 use HirRelationExpr::*;
2685 match self {
2686 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2687 Let {
2688 name: _,
2689 id: _,
2690 value,
2691 body,
2692 } => {
2693 f(value);
2694 f(body);
2695 }
2696 LetRec {
2697 limit: _,
2698 bindings,
2699 body,
2700 } => {
2701 for (_, _, value, _) in bindings.iter_mut() {
2702 f(value);
2703 }
2704 f(body);
2705 }
2706 Project { input, outputs: _ } => f(input),
2707 Map { input, scalars: _ } => {
2708 f(input);
2709 }
2710 CallTable { func: _, exprs: _ } => (),
2711 Filter {
2712 input,
2713 predicates: _,
2714 } => {
2715 f(input);
2716 }
2717 Join {
2718 left,
2719 right,
2720 on: _,
2721 kind: _,
2722 } => {
2723 f(left);
2724 f(right);
2725 }
2726 Reduce {
2727 input,
2728 group_key: _,
2729 aggregates: _,
2730 expected_group_size: _,
2731 } => {
2732 f(input);
2733 }
2734 Distinct { input }
2735 | TopK {
2736 input,
2737 group_key: _,
2738 order_key: _,
2739 limit: _,
2740 offset: _,
2741 expected_group_size: _,
2742 }
2743 | Negate { input }
2744 | Threshold { input } => {
2745 f(input);
2746 }
2747 Union { base, inputs } => {
2748 f(base);
2749 for input in inputs {
2750 f(input);
2751 }
2752 }
2753 }
2754 }
2755
2756 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
2757 where
2758 F: FnMut(&Self) -> Result<(), E>,
2759 {
2760 VisitChildren::try_visit_children(self, |expr: &HirScalarExpr| {
2764 expr.try_visit_direct_subqueries(&mut f)
2765 })?;
2766
2767 use HirRelationExpr::*;
2768 match self {
2769 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2770 Let {
2771 name: _,
2772 id: _,
2773 value,
2774 body,
2775 } => {
2776 f(value)?;
2777 f(body)?;
2778 }
2779 LetRec {
2780 limit: _,
2781 bindings,
2782 body,
2783 } => {
2784 for (_, _, value, _) in bindings.iter() {
2785 f(value)?;
2786 }
2787 f(body)?;
2788 }
2789 Project { input, outputs: _ } => f(input)?,
2790 Map { input, scalars: _ } => {
2791 f(input)?;
2792 }
2793 CallTable { func: _, exprs: _ } => (),
2794 Filter {
2795 input,
2796 predicates: _,
2797 } => {
2798 f(input)?;
2799 }
2800 Join {
2801 left,
2802 right,
2803 on: _,
2804 kind: _,
2805 } => {
2806 f(left)?;
2807 f(right)?;
2808 }
2809 Reduce {
2810 input,
2811 group_key: _,
2812 aggregates: _,
2813 expected_group_size: _,
2814 } => {
2815 f(input)?;
2816 }
2817 Distinct { input }
2818 | TopK {
2819 input,
2820 group_key: _,
2821 order_key: _,
2822 limit: _,
2823 offset: _,
2824 expected_group_size: _,
2825 }
2826 | Negate { input }
2827 | Threshold { input } => {
2828 f(input)?;
2829 }
2830 Union { base, inputs } => {
2831 f(base)?;
2832 for input in inputs {
2833 f(input)?;
2834 }
2835 }
2836 }
2837 Ok(())
2838 }
2839
2840 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
2841 where
2842 F: FnMut(&mut Self) -> Result<(), E>,
2843 {
2844 VisitChildren::try_visit_mut_children(self, |expr: &mut HirScalarExpr| {
2848 expr.try_visit_direct_subqueries_mut(&mut f)
2849 })?;
2850
2851 use HirRelationExpr::*;
2852 match self {
2853 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2854 Let {
2855 name: _,
2856 id: _,
2857 value,
2858 body,
2859 } => {
2860 f(value)?;
2861 f(body)?;
2862 }
2863 LetRec {
2864 limit: _,
2865 bindings,
2866 body,
2867 } => {
2868 for (_, _, value, _) in bindings.iter_mut() {
2869 f(value)?;
2870 }
2871 f(body)?;
2872 }
2873 Project { input, outputs: _ } => f(input)?,
2874 Map { input, scalars: _ } => {
2875 f(input)?;
2876 }
2877 CallTable { func: _, exprs: _ } => (),
2878 Filter {
2879 input,
2880 predicates: _,
2881 } => {
2882 f(input)?;
2883 }
2884 Join {
2885 left,
2886 right,
2887 on: _,
2888 kind: _,
2889 } => {
2890 f(left)?;
2891 f(right)?;
2892 }
2893 Reduce {
2894 input,
2895 group_key: _,
2896 aggregates: _,
2897 expected_group_size: _,
2898 } => {
2899 f(input)?;
2900 }
2901 Distinct { input }
2902 | TopK {
2903 input,
2904 group_key: _,
2905 order_key: _,
2906 limit: _,
2907 offset: _,
2908 expected_group_size: _,
2909 }
2910 | Negate { input }
2911 | Threshold { input } => {
2912 f(input)?;
2913 }
2914 Union { base, inputs } => {
2915 f(base)?;
2916 for input in inputs {
2917 f(input)?;
2918 }
2919 }
2920 }
2921 Ok(())
2922 }
2923
2924 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
2925 where
2926 Self: 'a,
2927 {
2928 let mut v: Vec<&HirRelationExpr> = vec![];
2930 use HirRelationExpr::*;
2931 match self {
2932 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2933 Let {
2934 name: _,
2935 id: _,
2936 value,
2937 body,
2938 } => {
2939 v.push(&*value);
2940 v.push(&*body);
2941 }
2942 LetRec {
2943 limit: _,
2944 bindings,
2945 body,
2946 } => {
2947 v.extend(bindings.iter().map(|(_, _, value, _)| value));
2948 v.push(&*body);
2949 }
2950 Map { input, scalars }
2951 | Filter {
2952 input,
2953 predicates: scalars,
2954 } => {
2955 for scalar in scalars {
2956 v.append(&mut scalar.direct_subqueries());
2957 }
2958 v.push(&*input);
2959 }
2960 Reduce {
2961 input,
2962 group_key: _,
2963 aggregates,
2964 expected_group_size: _,
2965 } => {
2966 for agg in aggregates {
2967 v.append(&mut agg.expr.direct_subqueries());
2968 }
2969 v.push(&*input);
2970 }
2971 TopK {
2972 input,
2973 group_key: _,
2974 order_key: _,
2975 limit,
2976 offset,
2977 expected_group_size: _,
2978 } => {
2979 if let Some(limit) = limit {
2980 v.append(&mut limit.direct_subqueries());
2981 }
2982 v.append(&mut offset.direct_subqueries());
2983 v.push(&*input);
2984 }
2985 Project { input, outputs: _ }
2986 | Distinct { input }
2987 | Negate { input }
2988 | Threshold { input } => v.push(&*input),
2989 CallTable { func: _, exprs } => v.extend(
2990 exprs
2991 .iter()
2992 .map(|scalar| scalar.direct_subqueries())
2993 .flatten(),
2994 ),
2995 Join {
2996 left,
2997 right,
2998 on,
2999 kind: _,
3000 } => {
3001 v.append(&mut on.direct_subqueries());
3002 v.push(&*left);
3003 v.push(&*right);
3004 }
3005 Union { base, inputs } => {
3006 v.push(&*base);
3007 v.extend(inputs.iter());
3008 }
3009 }
3010
3011 v.into_iter()
3012 }
3013
3014 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
3015 where
3016 Self: 'a,
3017 {
3018 let mut v = vec![];
3020 use HirRelationExpr::*;
3021 match self {
3022 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
3023 Let {
3024 name: _,
3025 id: _,
3026 value,
3027 body,
3028 } => {
3029 v.push(&mut **value);
3030 v.push(&mut **body);
3031 }
3032 LetRec {
3033 limit: _,
3034 bindings,
3035 body,
3036 } => {
3037 v.extend(bindings.iter_mut().map(|(_, _, value, _)| value));
3038 v.push(&mut **body);
3039 }
3040 Map { input, scalars }
3041 | Filter {
3042 input,
3043 predicates: scalars,
3044 } => {
3045 for scalar in scalars {
3046 v.append(&mut scalar.direct_subqueries_mut());
3047 }
3048 v.push(&mut **input);
3049 }
3050 Reduce {
3051 input,
3052 group_key: _,
3053 aggregates,
3054 expected_group_size: _,
3055 } => {
3056 for agg in aggregates {
3057 v.append(&mut agg.expr.direct_subqueries_mut());
3058 }
3059 v.push(&mut **input);
3060 }
3061 TopK {
3062 input,
3063 group_key: _,
3064 order_key: _,
3065 limit,
3066 offset,
3067 expected_group_size: _,
3068 } => {
3069 if let Some(limit) = limit {
3070 v.append(&mut limit.direct_subqueries_mut());
3071 }
3072 v.append(&mut offset.direct_subqueries_mut());
3073 v.push(&mut **input);
3074 }
3075 Project { input, outputs: _ }
3076 | Distinct { input }
3077 | Negate { input }
3078 | Threshold { input } => v.push(&mut **input),
3079 CallTable { func: _, exprs } => v.extend(
3080 exprs
3081 .iter_mut()
3082 .map(|scalar| scalar.direct_subqueries_mut())
3083 .flatten(),
3084 ),
3085 Join {
3086 left,
3087 right,
3088 on,
3089 kind: _,
3090 } => {
3091 v.append(&mut on.direct_subqueries_mut());
3092 v.push(&mut **left);
3093 v.push(&mut **right);
3094 }
3095 Union { base, inputs } => {
3096 v.push(&mut **base);
3097 v.extend(inputs.iter_mut());
3098 }
3099 }
3100
3101 v.into_iter()
3102 }
3103}
3104
3105impl VisitChildren<HirScalarExpr> for HirRelationExpr {
3109 fn visit_children<F>(&self, mut f: F)
3110 where
3111 F: FnMut(&HirScalarExpr),
3112 {
3113 use HirRelationExpr::*;
3114 match self {
3115 Constant { rows: _, typ: _ }
3116 | Get { id: _, typ: _ }
3117 | Let {
3118 name: _,
3119 id: _,
3120 value: _,
3121 body: _,
3122 }
3123 | LetRec {
3124 limit: _,
3125 bindings: _,
3126 body: _,
3127 }
3128 | Project {
3129 input: _,
3130 outputs: _,
3131 } => (),
3132 Map { input: _, scalars } => {
3133 for scalar in scalars {
3134 f(scalar);
3135 }
3136 }
3137 CallTable { func: _, exprs } => {
3138 for expr in exprs {
3139 f(expr);
3140 }
3141 }
3142 Filter {
3143 input: _,
3144 predicates,
3145 } => {
3146 for predicate in predicates {
3147 f(predicate);
3148 }
3149 }
3150 Join {
3151 left: _,
3152 right: _,
3153 on,
3154 kind: _,
3155 } => f(on),
3156 Reduce {
3157 input: _,
3158 group_key: _,
3159 aggregates,
3160 expected_group_size: _,
3161 } => {
3162 for aggregate in aggregates {
3163 f(aggregate.expr.as_ref());
3164 }
3165 }
3166 TopK {
3167 input: _,
3168 group_key: _,
3169 order_key: _,
3170 limit,
3171 offset,
3172 expected_group_size: _,
3173 } => {
3174 if let Some(limit) = limit {
3175 f(limit)
3176 }
3177 f(offset)
3178 }
3179 Distinct { input: _ }
3180 | Negate { input: _ }
3181 | Threshold { input: _ }
3182 | Union { base: _, inputs: _ } => (),
3183 }
3184 }
3185
3186 fn visit_mut_children<F>(&mut self, mut f: F)
3187 where
3188 F: FnMut(&mut HirScalarExpr),
3189 {
3190 use HirRelationExpr::*;
3191 match self {
3192 Constant { rows: _, typ: _ }
3193 | Get { id: _, typ: _ }
3194 | Let {
3195 name: _,
3196 id: _,
3197 value: _,
3198 body: _,
3199 }
3200 | LetRec {
3201 limit: _,
3202 bindings: _,
3203 body: _,
3204 }
3205 | Project {
3206 input: _,
3207 outputs: _,
3208 } => (),
3209 Map { input: _, scalars } => {
3210 for scalar in scalars {
3211 f(scalar);
3212 }
3213 }
3214 CallTable { func: _, exprs } => {
3215 for expr in exprs {
3216 f(expr);
3217 }
3218 }
3219 Filter {
3220 input: _,
3221 predicates,
3222 } => {
3223 for predicate in predicates {
3224 f(predicate);
3225 }
3226 }
3227 Join {
3228 left: _,
3229 right: _,
3230 on,
3231 kind: _,
3232 } => f(on),
3233 Reduce {
3234 input: _,
3235 group_key: _,
3236 aggregates,
3237 expected_group_size: _,
3238 } => {
3239 for aggregate in aggregates {
3240 f(aggregate.expr.as_mut());
3241 }
3242 }
3243 TopK {
3244 input: _,
3245 group_key: _,
3246 order_key: _,
3247 limit,
3248 offset,
3249 expected_group_size: _,
3250 } => {
3251 if let Some(limit) = limit {
3252 f(limit)
3253 }
3254 f(offset)
3255 }
3256 Distinct { input: _ }
3257 | Negate { input: _ }
3258 | Threshold { input: _ }
3259 | Union { base: _, inputs: _ } => (),
3260 }
3261 }
3262
3263 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
3264 where
3265 F: FnMut(&HirScalarExpr) -> Result<(), E>,
3266 {
3267 use HirRelationExpr::*;
3268 match self {
3269 Constant { rows: _, typ: _ }
3270 | Get { id: _, typ: _ }
3271 | Let {
3272 name: _,
3273 id: _,
3274 value: _,
3275 body: _,
3276 }
3277 | LetRec {
3278 limit: _,
3279 bindings: _,
3280 body: _,
3281 }
3282 | Project {
3283 input: _,
3284 outputs: _,
3285 } => (),
3286 Map { input: _, scalars } => {
3287 for scalar in scalars {
3288 f(scalar)?;
3289 }
3290 }
3291 CallTable { func: _, exprs } => {
3292 for expr in exprs {
3293 f(expr)?;
3294 }
3295 }
3296 Filter {
3297 input: _,
3298 predicates,
3299 } => {
3300 for predicate in predicates {
3301 f(predicate)?;
3302 }
3303 }
3304 Join {
3305 left: _,
3306 right: _,
3307 on,
3308 kind: _,
3309 } => f(on)?,
3310 Reduce {
3311 input: _,
3312 group_key: _,
3313 aggregates,
3314 expected_group_size: _,
3315 } => {
3316 for aggregate in aggregates {
3317 f(aggregate.expr.as_ref())?;
3318 }
3319 }
3320 TopK {
3321 input: _,
3322 group_key: _,
3323 order_key: _,
3324 limit,
3325 offset,
3326 expected_group_size: _,
3327 } => {
3328 if let Some(limit) = limit {
3329 f(limit)?
3330 }
3331 f(offset)?
3332 }
3333 Distinct { input: _ }
3334 | Negate { input: _ }
3335 | Threshold { input: _ }
3336 | Union { base: _, inputs: _ } => (),
3337 }
3338 Ok(())
3339 }
3340
3341 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
3342 where
3343 F: FnMut(&mut HirScalarExpr) -> Result<(), E>,
3344 {
3345 use HirRelationExpr::*;
3346 match self {
3347 Constant { rows: _, typ: _ }
3348 | Get { id: _, typ: _ }
3349 | Let {
3350 name: _,
3351 id: _,
3352 value: _,
3353 body: _,
3354 }
3355 | LetRec {
3356 limit: _,
3357 bindings: _,
3358 body: _,
3359 }
3360 | Project {
3361 input: _,
3362 outputs: _,
3363 } => (),
3364 Map { input: _, scalars } => {
3365 for scalar in scalars {
3366 f(scalar)?;
3367 }
3368 }
3369 CallTable { func: _, exprs } => {
3370 for expr in exprs {
3371 f(expr)?;
3372 }
3373 }
3374 Filter {
3375 input: _,
3376 predicates,
3377 } => {
3378 for predicate in predicates {
3379 f(predicate)?;
3380 }
3381 }
3382 Join {
3383 left: _,
3384 right: _,
3385 on,
3386 kind: _,
3387 } => f(on)?,
3388 Reduce {
3389 input: _,
3390 group_key: _,
3391 aggregates,
3392 expected_group_size: _,
3393 } => {
3394 for aggregate in aggregates {
3395 f(aggregate.expr.as_mut())?;
3396 }
3397 }
3398 TopK {
3399 input: _,
3400 group_key: _,
3401 order_key: _,
3402 limit,
3403 offset,
3404 expected_group_size: _,
3405 } => {
3406 if let Some(limit) = limit {
3407 f(limit)?
3408 }
3409 f(offset)?
3410 }
3411 Distinct { input: _ }
3412 | Negate { input: _ }
3413 | Threshold { input: _ }
3414 | Union { base: _, inputs: _ } => (),
3415 }
3416 Ok(())
3417 }
3418
3419 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
3420 where
3421 HirScalarExpr: 'a,
3422 {
3423 use HirRelationExpr::*;
3424 match self {
3425 Constant { rows: _, typ: _ }
3426 | Get { id: _, typ: _ }
3427 | Let {
3428 name: _,
3429 id: _,
3430 value: _,
3431 body: _,
3432 }
3433 | LetRec {
3434 limit: _,
3435 bindings: _,
3436 body: _,
3437 }
3438 | Project {
3439 input: _,
3440 outputs: _,
3441 }
3442 | Distinct { input: _ }
3443 | Negate { input: _ }
3444 | Threshold { input: _ }
3445 | Union { base: _, inputs: _ } => vec![],
3446 Map { input: _, scalars }
3447 | CallTable {
3448 func: _,
3449 exprs: scalars,
3450 }
3451 | Filter {
3452 input: _,
3453 predicates: scalars,
3454 } => scalars.iter().collect(),
3455 Join {
3456 left: _,
3457 right: _,
3458 on,
3459 kind: _,
3460 } => vec![on],
3461 Reduce {
3462 input: _,
3463 group_key: _,
3464 aggregates,
3465 expected_group_size: _,
3466 } => aggregates.iter().map(|agg| &*agg.expr).collect(),
3467 TopK {
3468 input: _,
3469 group_key: _,
3470 order_key: _,
3471 limit,
3472 offset,
3473 expected_group_size: _,
3474 } => limit.iter().chain(std::iter::once(offset)).collect(),
3475 }
3476 .into_iter()
3477 }
3478
3479 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
3480 where
3481 HirScalarExpr: 'a,
3482 {
3483 use HirRelationExpr::*;
3484 match self {
3485 Constant { rows: _, typ: _ }
3486 | Get { id: _, typ: _ }
3487 | Let {
3488 name: _,
3489 id: _,
3490 value: _,
3491 body: _,
3492 }
3493 | LetRec {
3494 limit: _,
3495 bindings: _,
3496 body: _,
3497 }
3498 | Project {
3499 input: _,
3500 outputs: _,
3501 }
3502 | Distinct { input: _ }
3503 | Negate { input: _ }
3504 | Threshold { input: _ }
3505 | Union { base: _, inputs: _ } => vec![],
3506 Map { input: _, scalars }
3507 | CallTable {
3508 func: _,
3509 exprs: scalars,
3510 }
3511 | Filter {
3512 input: _,
3513 predicates: scalars,
3514 } => scalars.iter_mut().collect(),
3515 Join {
3516 left: _,
3517 right: _,
3518 on,
3519 kind: _,
3520 } => vec![on],
3521 Reduce {
3522 input: _,
3523 group_key: _,
3524 aggregates,
3525 expected_group_size: _,
3526 } => aggregates.iter_mut().map(|agg| &mut *agg.expr).collect(),
3527 TopK {
3528 input: _,
3529 group_key: _,
3530 order_key: _,
3531 limit,
3532 offset,
3533 expected_group_size: _,
3534 } => limit.iter_mut().chain(std::iter::once(offset)).collect(),
3535 }
3536 .into_iter()
3537 }
3538}
3539
3540impl HirScalarExpr {
3541 pub fn name(&self) -> Option<Arc<str>> {
3542 use HirScalarExpr::*;
3543 match self {
3544 Column(_, name)
3545 | Parameter(_, name)
3546 | Literal(_, _, name)
3547 | CallUnmaterializable(_, name)
3548 | CallUnary { name, .. }
3549 | CallBinary { name, .. }
3550 | CallVariadic { name, .. }
3551 | If { name, .. }
3552 | Exists(_, name)
3553 | Select(_, name)
3554 | Windowing(_, name) => name.0.clone(),
3555 }
3556 }
3557
3558 pub fn visit_direct_subqueries<F>(&self, mut f: F)
3560 where
3561 F: FnMut(&HirRelationExpr),
3562 {
3563 self.visit_post(&mut |e| {
3564 VisitChildren::<HirRelationExpr>::visit_children(e, &mut f);
3565 });
3566 }
3567
3568 pub fn visit_direct_subqueries_mut<F>(&mut self, mut f: F)
3570 where
3571 F: FnMut(&mut HirRelationExpr),
3572 {
3573 self.visit_mut_post(&mut |e| {
3574 VisitChildren::<HirRelationExpr>::visit_mut_children(e, &mut f);
3575 });
3576 }
3577
3578 pub fn try_visit_direct_subqueries<F, E>(&self, mut f: F) -> Result<(), E>
3580 where
3581 F: FnMut(&HirRelationExpr) -> Result<(), E>,
3582 {
3583 self.try_visit_post(&mut |e| {
3584 VisitChildren::<HirRelationExpr>::try_visit_children(e, &mut f)
3585 })
3586 }
3587
3588 pub fn try_visit_direct_subqueries_mut<F, E>(&mut self, mut f: F) -> Result<(), E>
3590 where
3591 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
3592 {
3593 self.try_visit_mut_post(&mut |e| {
3594 VisitChildren::<HirRelationExpr>::try_visit_mut_children(e, &mut f)
3595 })
3596 }
3597
3598 pub fn bind_parameters_and_simplify_offset(
3607 &mut self,
3608 scx: &StatementContext,
3609 lifetime: QueryLifetime,
3610 params: &Params,
3611 ) -> Result<(), PlanError> {
3612 self.try_visit_mut_post(&mut |e: &mut HirScalarExpr| {
3615 if let HirScalarExpr::Parameter(n, name) = e {
3616 let datum = match params.datums.iter().nth(*n - 1) {
3617 None => return Err(PlanError::UnknownParameter(*n)),
3618 Some(datum) => datum,
3619 };
3620 let scalar_type = ¶ms.execute_types[*n - 1];
3621 let row = Row::pack([datum]);
3622 let column_type = scalar_type.clone().nullable(datum.is_null());
3623
3624 let name = if let Some(name) = &name.0 {
3625 Some(Arc::clone(name))
3626 } else {
3627 Some(Arc::from(format!("${n}")))
3628 };
3629
3630 let qcx = QueryContext::root(scx, lifetime);
3631 let ecx = execute_expr_context(&qcx);
3632
3633 *e = plan_cast(
3634 &ecx,
3635 *EXECUTE_CAST_CONTEXT,
3636 HirScalarExpr::Literal(row, column_type, TreatAsEqual(name)),
3637 ¶ms.expected_types[*n - 1],
3638 )
3639 .expect("checked in plan_params");
3640 }
3641 Ok(())
3642 })?;
3643 self.try_visit_direct_subqueries_mut(|r: &mut HirRelationExpr| {
3646 r.bind_parameters_and_simplify_offset(scx, lifetime, params)
3647 })
3648 }
3649
3650 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
3661 #[allow(deprecated)]
3662 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3663 e: &mut HirScalarExpr|
3664 -> Result<(), ()> {
3665 if let HirScalarExpr::Parameter(i, _name) = e {
3666 *e = params[*i - 1].clone();
3667 e.visit_columns_mut(0, &mut |d: usize, col: &mut ColumnRef| {
3670 if col.level >= d {
3671 col.level += depth
3672 }
3673 });
3674 }
3675 Ok(())
3676 });
3677 }
3678
3679 pub fn contains_temporal(&self) -> bool {
3681 let mut contains = false;
3682 self.visit_post(&mut |e| {
3683 if let Self::CallUnmaterializable(UnmaterializableFunc::MzNow, _name) = e {
3684 contains = true;
3685 }
3686 });
3687 contains
3688 }
3689
3690 pub fn contains_unmaterializable(&self) -> bool {
3692 let mut contains = false;
3693 self.visit_post(&mut |e| {
3694 if let Self::CallUnmaterializable(_, _) = e {
3695 contains = true;
3696 }
3697 });
3698 contains
3699 }
3700
3701 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
3704 let mut contains = false;
3705 self.visit_post(&mut |e| {
3706 if let Self::CallUnmaterializable(f, _) = e {
3707 if *f != UnmaterializableFunc::MzNow {
3708 contains = true;
3709 }
3710 }
3711 });
3712 contains
3713 }
3714
3715 pub fn column(index: usize) -> HirScalarExpr {
3719 HirScalarExpr::Column(
3720 ColumnRef {
3721 level: 0,
3722 column: index,
3723 },
3724 TreatAsEqual(None),
3725 )
3726 }
3727
3728 pub fn unnamed_column(cr: ColumnRef) -> HirScalarExpr {
3730 HirScalarExpr::Column(cr, TreatAsEqual(None))
3731 }
3732
3733 pub fn named_column(cr: ColumnRef, name: Arc<str>) -> HirScalarExpr {
3736 HirScalarExpr::Column(cr, TreatAsEqual(Some(name)))
3737 }
3738
3739 pub fn parameter(n: usize) -> HirScalarExpr {
3740 HirScalarExpr::Parameter(n, TreatAsEqual(None))
3741 }
3742
3743 pub fn literal(datum: Datum, scalar_type: SqlScalarType) -> HirScalarExpr {
3744 let col_type = scalar_type.nullable(datum.is_null());
3745 soft_assert_or_log!(datum.is_instance_of_sql(&col_type), "type is correct");
3746 let row = Row::pack([datum]);
3747 HirScalarExpr::Literal(row, col_type, TreatAsEqual(None))
3748 }
3749
3750 pub fn literal_true() -> HirScalarExpr {
3751 HirScalarExpr::literal(Datum::True, SqlScalarType::Bool)
3752 }
3753
3754 pub fn literal_false() -> HirScalarExpr {
3755 HirScalarExpr::literal(Datum::False, SqlScalarType::Bool)
3756 }
3757
3758 pub fn literal_null(scalar_type: SqlScalarType) -> HirScalarExpr {
3759 HirScalarExpr::literal(Datum::Null, scalar_type)
3760 }
3761
3762 pub fn literal_1d_array(
3763 datums: Vec<Datum>,
3764 element_scalar_type: SqlScalarType,
3765 ) -> Result<HirScalarExpr, PlanError> {
3766 let scalar_type = match element_scalar_type {
3767 SqlScalarType::Array(_) => {
3768 sql_bail!("cannot build array from array type");
3769 }
3770 typ => SqlScalarType::Array(Box::new(typ)).nullable(false),
3771 };
3772
3773 let mut row = Row::default();
3774 row.packer()
3775 .try_push_array(
3776 &[ArrayDimension {
3777 lower_bound: 1,
3778 length: datums.len(),
3779 }],
3780 datums,
3781 )
3782 .expect("array constructed to be valid");
3783
3784 Ok(HirScalarExpr::Literal(row, scalar_type, TreatAsEqual(None)))
3785 }
3786
3787 pub fn as_literal(&self) -> Option<Datum<'_>> {
3788 if let HirScalarExpr::Literal(row, _column_type, _name) = self {
3789 Some(row.unpack_first())
3790 } else {
3791 None
3792 }
3793 }
3794
3795 pub fn is_literal_true(&self) -> bool {
3796 Some(Datum::True) == self.as_literal()
3797 }
3798
3799 pub fn is_literal_false(&self) -> bool {
3800 Some(Datum::False) == self.as_literal()
3801 }
3802
3803 pub fn is_literal_null(&self) -> bool {
3804 Some(Datum::Null) == self.as_literal()
3805 }
3806
3807 pub fn is_constant(&self) -> bool {
3810 let mut worklist = vec![self];
3811 while let Some(expr) = worklist.pop() {
3812 match expr {
3813 Self::Literal(..) => {
3814 }
3816 Self::CallUnary { expr, .. } => {
3817 worklist.push(expr);
3818 }
3819 Self::CallBinary {
3820 func: _,
3821 expr1,
3822 expr2,
3823 name: _,
3824 } => {
3825 worklist.push(expr1);
3826 worklist.push(expr2);
3827 }
3828 Self::CallVariadic {
3829 func: _,
3830 exprs,
3831 name: _,
3832 } => {
3833 worklist.extend(exprs.iter());
3834 }
3835 Self::If {
3837 cond,
3838 then,
3839 els,
3840 name: _,
3841 } => {
3842 worklist.push(cond);
3843 worklist.push(then);
3844 worklist.push(els);
3845 }
3846 _ => {
3847 return false; }
3849 }
3850 }
3851 true
3852 }
3853
3854 pub fn call_unary(self, func: UnaryFunc) -> Self {
3855 HirScalarExpr::CallUnary {
3856 func,
3857 expr: Box::new(self),
3858 name: NameMetadata::default(),
3859 }
3860 }
3861
3862 pub fn call_binary<B: Into<BinaryFunc>>(self, other: Self, func: B) -> Self {
3863 HirScalarExpr::CallBinary {
3864 func: func.into(),
3865 expr1: Box::new(self),
3866 expr2: Box::new(other),
3867 name: NameMetadata::default(),
3868 }
3869 }
3870
3871 pub fn call_unmaterializable(func: UnmaterializableFunc) -> Self {
3872 HirScalarExpr::CallUnmaterializable(func, NameMetadata::default())
3873 }
3874
3875 pub fn call_variadic<V: Into<VariadicFunc>>(func: V, exprs: Vec<Self>) -> Self {
3876 HirScalarExpr::CallVariadic {
3877 func: func.into(),
3878 exprs,
3879 name: NameMetadata::default(),
3880 }
3881 }
3882
3883 pub fn if_then_else(cond: Self, then: Self, els: Self) -> Self {
3884 HirScalarExpr::If {
3885 cond: Box::new(cond),
3886 then: Box::new(then),
3887 els: Box::new(els),
3888 name: NameMetadata::default(),
3889 }
3890 }
3891
3892 pub fn windowing(expr: WindowExpr) -> Self {
3893 HirScalarExpr::Windowing(expr, TreatAsEqual(None))
3894 }
3895
3896 pub fn or(self, other: Self) -> Self {
3897 HirScalarExpr::call_variadic(Or, vec![self, other])
3898 }
3899
3900 pub fn and(self, other: Self) -> Self {
3901 HirScalarExpr::call_variadic(And, vec![self, other])
3902 }
3903
3904 pub fn not(self) -> Self {
3905 self.call_unary(UnaryFunc::Not(func::Not))
3906 }
3907
3908 pub fn call_is_null(self) -> Self {
3909 self.call_unary(UnaryFunc::IsNull(func::IsNull))
3910 }
3911
3912 pub fn variadic_and(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3914 match args.len() {
3915 0 => HirScalarExpr::literal_true(), 1 => args.swap_remove(0),
3917 _ => HirScalarExpr::call_variadic(And, args),
3918 }
3919 }
3920
3921 pub fn variadic_or(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3923 match args.len() {
3924 0 => HirScalarExpr::literal_false(), 1 => args.swap_remove(0),
3926 _ => HirScalarExpr::call_variadic(Or, args),
3927 }
3928 }
3929
3930 pub fn take(&mut self) -> Self {
3931 mem::replace(self, HirScalarExpr::literal_null(SqlScalarType::String))
3932 }
3933
3934 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3935 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
3941 where
3942 F: FnMut(usize, &ColumnRef),
3943 {
3944 #[allow(deprecated)]
3945 let _ = self.visit_recursively(depth, &mut |depth: usize,
3946 e: &HirScalarExpr|
3947 -> Result<(), ()> {
3948 if let HirScalarExpr::Column(col, _name) = e {
3949 f(depth, col)
3950 }
3951 Ok(())
3952 });
3953 }
3954
3955 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3956 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
3958 where
3959 F: FnMut(usize, &mut ColumnRef),
3960 {
3961 #[allow(deprecated)]
3962 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3963 e: &mut HirScalarExpr|
3964 -> Result<(), ()> {
3965 if let HirScalarExpr::Column(col, _name) = e {
3966 f(depth, col)
3967 }
3968 Ok(())
3969 });
3970 }
3971
3972 pub fn visit_columns_referring_to_root_level<F>(&self, f: &mut F)
3978 where
3979 F: FnMut(usize),
3980 {
3981 #[allow(deprecated)]
3982 let _ = self.visit_recursively(0, &mut |depth: usize,
3983 e: &HirScalarExpr|
3984 -> Result<(), ()> {
3985 if let HirScalarExpr::Column(col, _name) = e {
3986 if col.level == depth {
3987 f(col.column)
3988 }
3989 }
3990 Ok(())
3991 });
3992 }
3993
3994 pub fn visit_columns_referring_to_root_level_mut<F>(&mut self, f: &mut F)
3996 where
3997 F: FnMut(&mut usize),
3998 {
3999 #[allow(deprecated)]
4000 let _ = self.visit_recursively_mut(0, &mut |depth: usize,
4001 e: &mut HirScalarExpr|
4002 -> Result<(), ()> {
4003 if let HirScalarExpr::Column(col, _name) = e {
4004 if col.level == depth {
4005 f(&mut col.column)
4006 }
4007 }
4008 Ok(())
4009 });
4010 }
4011
4012 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
4013 pub fn visit_recursively<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
4017 where
4018 F: FnMut(usize, &HirScalarExpr) -> Result<(), E>,
4019 {
4020 match self {
4021 HirScalarExpr::Literal(..)
4022 | HirScalarExpr::Parameter(..)
4023 | HirScalarExpr::CallUnmaterializable(..)
4024 | HirScalarExpr::Column(..) => (),
4025 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively(depth, f)?,
4026 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
4027 expr1.visit_recursively(depth, f)?;
4028 expr2.visit_recursively(depth, f)?;
4029 }
4030 HirScalarExpr::CallVariadic { exprs, .. } => {
4031 for expr in exprs {
4032 expr.visit_recursively(depth, f)?;
4033 }
4034 }
4035 HirScalarExpr::If {
4036 cond,
4037 then,
4038 els,
4039 name: _,
4040 } => {
4041 cond.visit_recursively(depth, f)?;
4042 then.visit_recursively(depth, f)?;
4043 els.visit_recursively(depth, f)?;
4044 }
4045 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4046 #[allow(deprecated)]
4047 expr.visit_scalar_expressions(depth + 1, &mut |e, depth| {
4048 e.visit_recursively(depth, f)
4049 })?;
4050 }
4051 HirScalarExpr::Windowing(expr, _name) => {
4052 expr.visit_expressions(&mut |e| e.visit_recursively(depth, f))?;
4053 }
4054 }
4055 f(depth, self)
4056 }
4057
4058 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
4059 pub fn visit_recursively_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
4061 where
4062 F: FnMut(usize, &mut HirScalarExpr) -> Result<(), E>,
4063 {
4064 match self {
4065 HirScalarExpr::Literal(..)
4066 | HirScalarExpr::Parameter(..)
4067 | HirScalarExpr::CallUnmaterializable(..)
4068 | HirScalarExpr::Column(..) => (),
4069 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively_mut(depth, f)?,
4070 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
4071 expr1.visit_recursively_mut(depth, f)?;
4072 expr2.visit_recursively_mut(depth, f)?;
4073 }
4074 HirScalarExpr::CallVariadic { exprs, .. } => {
4075 for expr in exprs {
4076 expr.visit_recursively_mut(depth, f)?;
4077 }
4078 }
4079 HirScalarExpr::If {
4080 cond,
4081 then,
4082 els,
4083 name: _,
4084 } => {
4085 cond.visit_recursively_mut(depth, f)?;
4086 then.visit_recursively_mut(depth, f)?;
4087 els.visit_recursively_mut(depth, f)?;
4088 }
4089 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4090 #[allow(deprecated)]
4091 expr.visit_scalar_expressions_mut(depth + 1, &mut |e, depth| {
4092 e.visit_recursively_mut(depth, f)
4093 })?;
4094 }
4095 HirScalarExpr::Windowing(expr, _name) => {
4096 expr.visit_expressions_mut(&mut |e| e.visit_recursively_mut(depth, f))?;
4097 }
4098 }
4099 f(depth, self)
4100 }
4101
4102 fn simplify_to_literal(self) -> Option<Row> {
4111 let mut expr = self
4112 .lower_uncorrelated(crate::plan::lowering::Config::default())
4113 .ok()?;
4114 if expr.contains_column() {
4116 return None;
4117 }
4118 expr.reduce(&[]);
4122 match expr {
4123 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Some(row),
4124 _ => None,
4125 }
4126 }
4127
4128 fn simplify_to_literal_with_result(self) -> Result<Row, PlanError> {
4141 let mut expr = self
4142 .lower_uncorrelated(crate::plan::lowering::Config::default())
4143 .map_err(|err| {
4144 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes())
4145 })?;
4146 if expr.contains_column() {
4148 return Err(PlanError::ConstantExpressionSimplificationFailed(
4149 "Not a constant".to_string(),
4150 ));
4151 }
4152 expr.reduce(&[]);
4156 match expr {
4157 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Ok(row),
4158 mz_expr::MirScalarExpr::Literal(Err(err), _) => Err(
4159 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes()),
4160 ),
4161 _ => Err(PlanError::ConstantExpressionSimplificationFailed(
4162 "Not a constant".to_string(),
4163 )),
4164 }
4165 }
4166
4167 pub fn into_literal_int64(self) -> Option<i64> {
4176 self.simplify_to_literal().and_then(|row| {
4177 let datum = row.unpack_first();
4178 if datum.is_null() {
4179 None
4180 } else {
4181 Some(datum.unwrap_int64())
4182 }
4183 })
4184 }
4185
4186 pub fn into_literal_string(self) -> Option<String> {
4195 self.simplify_to_literal().and_then(|row| {
4196 let datum = row.unpack_first();
4197 if datum.is_null() {
4198 None
4199 } else {
4200 Some(datum.unwrap_str().to_owned())
4201 }
4202 })
4203 }
4204
4205 pub fn into_literal_mz_timestamp(self) -> Option<Timestamp> {
4218 self.simplify_to_literal().and_then(|row| {
4219 let datum = row.unpack_first();
4220 if datum.is_null() {
4221 None
4222 } else {
4223 Some(datum.unwrap_mz_timestamp())
4224 }
4225 })
4226 }
4227
4228 pub fn try_into_literal_int64(self) -> Result<i64, PlanError> {
4240 match self.clone().try_into_nullable_literal_int64()? {
4241 Some(value) => Ok(value),
4242 None => Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4243 "Expected an expression that evaluates to a non-null value, got {}",
4244 self
4245 ))),
4246 }
4247 }
4248
4249 pub fn try_into_nullable_literal_int64(self) -> Result<Option<i64>, PlanError> {
4252 if !self.is_constant() {
4258 return Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4259 "Expected a constant expression, got {}",
4260 self
4261 )));
4262 }
4263 self.simplify_to_literal_with_result().map(|row| {
4264 let datum = row.unpack_first();
4265 if datum.is_null() {
4266 None
4267 } else {
4268 Some(datum.unwrap_int64())
4269 }
4270 })
4271 }
4272
4273 pub fn contains_parameters(&self) -> bool {
4274 let mut contains_parameters = false;
4275 #[allow(deprecated)]
4276 let _ = self.visit_recursively(0, &mut |_depth: usize,
4277 expr: &HirScalarExpr|
4278 -> Result<(), ()> {
4279 if let HirScalarExpr::Parameter(..) = expr {
4280 contains_parameters = true;
4281 }
4282 Ok(())
4283 });
4284 contains_parameters
4285 }
4286
4287 fn direct_subqueries(&self) -> Vec<&HirRelationExpr> {
4288 let mut subqueries: Vec<&HirRelationExpr> = vec![];
4289
4290 let mut worklist = vec![self];
4291 while let Some(elt) = worklist.pop() {
4292 match elt {
4293 HirScalarExpr::Column(_, _)
4294 | HirScalarExpr::Parameter(_, _)
4295 | HirScalarExpr::Literal(_, _, _)
4296 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4297 HirScalarExpr::CallUnary {
4298 func: _,
4299 expr,
4300 name: _,
4301 } => worklist.push(&*expr),
4302 HirScalarExpr::CallBinary {
4303 func: _,
4304 expr1,
4305 expr2,
4306 name: _name,
4307 } => {
4308 worklist.push(&*expr2);
4310 worklist.push(&*expr1);
4311 }
4312 HirScalarExpr::CallVariadic {
4313 func: _,
4314 exprs,
4315 name: _name,
4316 } => {
4317 worklist.extend(exprs.iter().rev());
4318 }
4319 HirScalarExpr::If {
4320 cond,
4321 then,
4322 els,
4323 name: _,
4324 } => {
4325 worklist.push(&*els);
4326 worklist.push(&*then);
4327 worklist.push(&*cond);
4328 }
4329 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4330 subqueries.push(&*hir);
4331 }
4332 HirScalarExpr::Windowing(
4333 WindowExpr {
4334 func,
4335 partition_by,
4336 order_by,
4337 },
4338 _,
4339 ) => {
4340 worklist.extend(order_by.iter().rev());
4343 worklist.extend(partition_by.iter().rev());
4344 match func {
4345 WindowExprType::Scalar(_) => (),
4346 WindowExprType::Value(val) => worklist.push(&*val.args),
4347 WindowExprType::Aggregate(agg) => worklist.push(&*agg.aggregate_expr.expr),
4348 }
4349 }
4350 }
4351 }
4352
4353 subqueries
4354 }
4355
4356 fn direct_subqueries_mut(&mut self) -> Vec<&mut HirRelationExpr> {
4357 let mut subqueries: Vec<&mut HirRelationExpr> = vec![];
4358
4359 let mut worklist = vec![self];
4360 while let Some(elt) = worklist.pop() {
4361 match elt {
4362 HirScalarExpr::Column(_, _)
4363 | HirScalarExpr::Parameter(_, _)
4364 | HirScalarExpr::Literal(_, _, _)
4365 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4366 HirScalarExpr::CallUnary {
4367 func: _,
4368 expr,
4369 name: _,
4370 } => worklist.push(&mut **expr),
4371 HirScalarExpr::CallBinary {
4372 func: _,
4373 expr1,
4374 expr2,
4375 name: _name,
4376 } => {
4377 worklist.push(&mut **expr2);
4379 worklist.push(&mut **expr1);
4380 }
4381 HirScalarExpr::CallVariadic {
4382 func: _,
4383 exprs,
4384 name: _name,
4385 } => {
4386 worklist.extend(exprs.iter_mut().rev());
4387 }
4388 HirScalarExpr::If {
4389 cond,
4390 then,
4391 els,
4392 name: _,
4393 } => {
4394 worklist.push(&mut **els);
4395 worklist.push(&mut **then);
4396 worklist.push(&mut **cond);
4397 }
4398 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4399 subqueries.push(&mut **hir);
4400 }
4401 HirScalarExpr::Windowing(
4402 WindowExpr {
4403 func,
4404 partition_by,
4405 order_by,
4406 },
4407 _,
4408 ) => {
4409 worklist.extend(order_by.iter_mut().rev());
4412 worklist.extend(partition_by.iter_mut().rev());
4413 match func {
4414 WindowExprType::Scalar(_) => (),
4415 WindowExprType::Value(val) => worklist.push(&mut val.args),
4416 WindowExprType::Aggregate(agg) => {
4417 worklist.push(&mut agg.aggregate_expr.expr)
4418 }
4419 }
4420 }
4421 }
4422 }
4423
4424 subqueries
4425 }
4426}
4427
4428impl VisitChildren<Self> for HirScalarExpr {
4434 fn visit_children<F>(&self, mut f: F)
4435 where
4436 F: FnMut(&Self),
4437 {
4438 use HirScalarExpr::*;
4439 match self {
4440 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4441 CallUnary { expr, .. } => f(expr),
4442 CallBinary { expr1, expr2, .. } => {
4443 f(expr1);
4444 f(expr2);
4445 }
4446 CallVariadic { exprs, .. } => {
4447 for expr in exprs {
4448 f(expr);
4449 }
4450 }
4451 If {
4452 cond,
4453 then,
4454 els,
4455 name: _,
4456 } => {
4457 f(cond);
4458 f(then);
4459 f(els);
4460 }
4461 Exists(..) | Select(..) => (),
4462 Windowing(expr, _name) => expr.visit_children(f),
4463 }
4464 }
4465
4466 fn visit_mut_children<F>(&mut self, mut f: F)
4467 where
4468 F: FnMut(&mut Self),
4469 {
4470 use HirScalarExpr::*;
4471 match self {
4472 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4473 CallUnary { expr, .. } => f(expr),
4474 CallBinary { expr1, expr2, .. } => {
4475 f(expr1);
4476 f(expr2);
4477 }
4478 CallVariadic { exprs, .. } => {
4479 for expr in exprs {
4480 f(expr);
4481 }
4482 }
4483 If {
4484 cond,
4485 then,
4486 els,
4487 name: _,
4488 } => {
4489 f(cond);
4490 f(then);
4491 f(els);
4492 }
4493 Exists(..) | Select(..) => (),
4494 Windowing(expr, _name) => expr.visit_mut_children(f),
4495 }
4496 }
4497
4498 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4499 where
4500 F: FnMut(&Self) -> Result<(), E>,
4501 {
4502 use HirScalarExpr::*;
4503 match self {
4504 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4505 CallUnary { expr, .. } => f(expr)?,
4506 CallBinary { expr1, expr2, .. } => {
4507 f(expr1)?;
4508 f(expr2)?;
4509 }
4510 CallVariadic { exprs, .. } => {
4511 for expr in exprs {
4512 f(expr)?;
4513 }
4514 }
4515 If {
4516 cond,
4517 then,
4518 els,
4519 name: _,
4520 } => {
4521 f(cond)?;
4522 f(then)?;
4523 f(els)?;
4524 }
4525 Exists(..) | Select(..) => (),
4526 Windowing(expr, _name) => expr.try_visit_children(f)?,
4527 }
4528 Ok(())
4529 }
4530
4531 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4532 where
4533 F: FnMut(&mut Self) -> Result<(), E>,
4534 {
4535 use HirScalarExpr::*;
4536 match self {
4537 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4538 CallUnary { expr, .. } => f(expr)?,
4539 CallBinary { expr1, expr2, .. } => {
4540 f(expr1)?;
4541 f(expr2)?;
4542 }
4543 CallVariadic { exprs, .. } => {
4544 for expr in exprs {
4545 f(expr)?;
4546 }
4547 }
4548 If {
4549 cond,
4550 then,
4551 els,
4552 name: _,
4553 } => {
4554 f(cond)?;
4555 f(then)?;
4556 f(els)?;
4557 }
4558 Exists(..) | Select(..) => (),
4559 Windowing(expr, _name) => expr.try_visit_mut_children(f)?,
4560 }
4561 Ok(())
4562 }
4563
4564 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
4565 where
4566 Self: 'a,
4567 {
4568 use HirScalarExpr::*;
4569 let v: Vec<&Self> = match self {
4570 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4571 CallUnary { expr, .. } => vec![&*expr],
4572 CallBinary { expr1, expr2, .. } => {
4573 vec![&*expr1, &*expr2]
4574 }
4575 CallVariadic { exprs, .. } => exprs.iter().collect(),
4576 If {
4577 cond,
4578 then,
4579 els,
4580 name: _,
4581 } => {
4582 vec![&*cond, &*then, &*els]
4583 }
4584 Exists(..) | Select(..) => vec![],
4585 Windowing(expr, _name) => expr.children().collect(),
4586 };
4587 v.into_iter()
4588 }
4589
4590 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
4591 where
4592 Self: 'a,
4593 {
4594 use HirScalarExpr::*;
4595 let v: Vec<&mut Self> = match self {
4596 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4597 CallUnary { expr, .. } => vec![&mut **expr],
4598 CallBinary { expr1, expr2, .. } => {
4599 vec![&mut **expr1, &mut **expr2]
4600 }
4601 CallVariadic { exprs, .. } => exprs.iter_mut().collect(),
4602 If {
4603 cond,
4604 then,
4605 els,
4606 name: _,
4607 } => {
4608 vec![&mut **cond, &mut **then, &mut **els]
4609 }
4610 Exists(..) | Select(..) => vec![],
4611 Windowing(expr, _name) => expr.children_mut().collect(),
4612 };
4613 v.into_iter()
4614 }
4615}
4616
4617impl VisitChildren<HirRelationExpr> for HirScalarExpr {
4620 fn visit_children<F>(&self, mut f: F)
4621 where
4622 F: FnMut(&HirRelationExpr),
4623 {
4624 use HirScalarExpr::*;
4625 match self {
4626 Column(..)
4627 | Parameter(..)
4628 | Literal(..)
4629 | CallUnmaterializable(..)
4630 | CallUnary { .. }
4631 | CallBinary { .. }
4632 | CallVariadic { .. }
4633 | If { .. }
4634 | Windowing(..) => (),
4635 Exists(expr, _name) | Select(expr, _name) => f(expr),
4636 }
4637 }
4638
4639 fn visit_mut_children<F>(&mut self, mut f: F)
4640 where
4641 F: FnMut(&mut HirRelationExpr),
4642 {
4643 use HirScalarExpr::*;
4644 match self {
4645 Column(..)
4646 | Parameter(..)
4647 | Literal(..)
4648 | CallUnmaterializable(..)
4649 | CallUnary { .. }
4650 | CallBinary { .. }
4651 | CallVariadic { .. }
4652 | If { .. }
4653 | Windowing(..) => (),
4654 Exists(expr, _name) | Select(expr, _name) => f(expr),
4655 }
4656 }
4657
4658 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4659 where
4660 F: FnMut(&HirRelationExpr) -> Result<(), E>,
4661 {
4662 use HirScalarExpr::*;
4663 match self {
4664 Column(..)
4665 | Parameter(..)
4666 | Literal(..)
4667 | CallUnmaterializable(..)
4668 | CallUnary { .. }
4669 | CallBinary { .. }
4670 | CallVariadic { .. }
4671 | If { .. }
4672 | Windowing(..) => (),
4673 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4674 }
4675 Ok(())
4676 }
4677
4678 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4679 where
4680 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
4681 {
4682 use HirScalarExpr::*;
4683 match self {
4684 Column(..)
4685 | Parameter(..)
4686 | Literal(..)
4687 | CallUnmaterializable(..)
4688 | CallUnary { .. }
4689 | CallBinary { .. }
4690 | CallVariadic { .. }
4691 | If { .. }
4692 | Windowing(..) => (),
4693 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4694 }
4695 Ok(())
4696 }
4697
4698 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirRelationExpr>
4699 where
4700 HirRelationExpr: 'a,
4701 {
4702 let mut child: Option<&HirRelationExpr> = None;
4703 use HirScalarExpr::*;
4704 match self {
4705 Column(..)
4706 | Parameter(..)
4707 | Literal(..)
4708 | CallUnmaterializable(..)
4709 | CallUnary { .. }
4710 | CallBinary { .. }
4711 | CallVariadic { .. }
4712 | If { .. }
4713 | Windowing(..) => (),
4714 Exists(expr, _name) | Select(expr, _name) => child = Some(&*expr),
4715 }
4716
4717 child.into_iter()
4718 }
4719
4720 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirRelationExpr>
4721 where
4722 HirRelationExpr: 'a,
4723 {
4724 let mut child: Option<&mut HirRelationExpr> = None;
4725 use HirScalarExpr::*;
4726 match self {
4727 Column(..)
4728 | Parameter(..)
4729 | Literal(..)
4730 | CallUnmaterializable(..)
4731 | CallUnary { .. }
4732 | CallBinary { .. }
4733 | CallVariadic { .. }
4734 | If { .. }
4735 | Windowing(..) => (),
4736 Exists(expr, _name) | Select(expr, _name) => child = Some(&mut **expr),
4737 }
4738
4739 child.into_iter()
4740 }
4741}
4742
4743impl AbstractExpr for HirScalarExpr {
4744 type Type = SqlColumnType;
4745
4746 fn typ(
4747 &self,
4748 outers: &[SqlRelationType],
4749 inner: &SqlRelationType,
4750 params: &BTreeMap<usize, SqlScalarType>,
4751 ) -> Self::Type {
4752 stack::maybe_grow(|| match self {
4753 HirScalarExpr::Column(ColumnRef { level, column }, _name) => {
4754 if *level == 0 {
4755 inner.column_types[*column].clone()
4756 } else {
4757 outers[*level - 1].column_types[*column].clone()
4758 }
4759 }
4760 HirScalarExpr::Parameter(n, _name) => params[n].clone().nullable(true),
4761 HirScalarExpr::Literal(_, typ, _name) => typ.clone(),
4762 HirScalarExpr::CallUnmaterializable(func, _name) => func.output_sql_type(),
4763 HirScalarExpr::CallUnary {
4764 expr,
4765 func,
4766 name: _,
4767 } => func.output_sql_type(expr.typ(outers, inner, params)),
4768 HirScalarExpr::CallBinary {
4769 expr1,
4770 expr2,
4771 func,
4772 name: _,
4773 } => func.output_sql_type(&[
4774 expr1.typ(outers, inner, params),
4775 expr2.typ(outers, inner, params),
4776 ]),
4777 HirScalarExpr::CallVariadic {
4778 exprs,
4779 func,
4780 name: _,
4781 } => func.output_sql_type(exprs.iter().map(|e| e.typ(outers, inner, params)).collect()),
4782 HirScalarExpr::If {
4783 cond: _,
4784 then,
4785 els,
4786 name: _,
4787 } => {
4788 let then_type = then.typ(outers, inner, params);
4789 let else_type = els.typ(outers, inner, params);
4790 then_type.sql_union(&else_type).unwrap() }
4792 HirScalarExpr::Exists(_, _name) => SqlScalarType::Bool.nullable(true),
4793 HirScalarExpr::Select(expr, _name) => {
4794 let mut outers = outers.to_vec();
4795 outers.insert(0, inner.clone());
4796 expr.typ(&outers, params)
4797 .column_types
4798 .into_element()
4799 .nullable(true)
4800 }
4801 HirScalarExpr::Windowing(expr, _name) => expr.func.typ(outers, inner, params),
4802 })
4803 }
4804}
4805
4806impl AggregateExpr {
4807 pub fn typ(
4808 &self,
4809 outers: &[SqlRelationType],
4810 inner: &SqlRelationType,
4811 params: &BTreeMap<usize, SqlScalarType>,
4812 ) -> SqlColumnType {
4813 self.func
4814 .output_sql_type(self.expr.typ(outers, inner, params))
4815 }
4816
4817 pub fn is_count_asterisk(&self) -> bool {
4825 self.func == AggregateFunc::Count && self.expr.is_literal_true() && !self.distinct
4826 }
4827}