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 MinNumeric,
1313 MinInt16,
1314 MinInt32,
1315 MinInt64,
1316 MinUInt16,
1317 MinUInt32,
1318 MinUInt64,
1319 MinMzTimestamp,
1320 MinFloat32,
1321 MinFloat64,
1322 MinBool,
1323 MinString,
1324 MinDate,
1325 MinTimestamp,
1326 MinTimestampTz,
1327 MinInterval,
1328 MinTime,
1329 SumInt16,
1330 SumInt32,
1331 SumInt64,
1332 SumUInt16,
1333 SumUInt32,
1334 SumUInt64,
1335 SumFloat32,
1336 SumFloat64,
1337 SumNumeric,
1338 Count,
1339 Any,
1340 All,
1341 JsonbAgg {
1348 order_by: Vec<ColumnOrder>,
1349 },
1350 JsonbObjectAgg {
1353 order_by: Vec<ColumnOrder>,
1354 },
1355 MapAgg {
1359 order_by: Vec<ColumnOrder>,
1360 value_type: SqlScalarType,
1361 },
1362 ArrayConcat {
1365 order_by: Vec<ColumnOrder>,
1366 },
1367 ListConcat {
1370 order_by: Vec<ColumnOrder>,
1371 },
1372 StringAgg {
1373 order_by: Vec<ColumnOrder>,
1374 },
1375 FusedWindowAgg {
1381 funcs: Vec<AggregateFunc>,
1382 },
1383 Dummy,
1388}
1389
1390impl AggregateFunc {
1391 pub fn into_expr(self) -> mz_expr::AggregateFunc {
1393 match self {
1394 AggregateFunc::MaxNumeric => mz_expr::AggregateFunc::MaxNumeric,
1395 AggregateFunc::MaxInt16 => mz_expr::AggregateFunc::MaxInt16,
1396 AggregateFunc::MaxInt32 => mz_expr::AggregateFunc::MaxInt32,
1397 AggregateFunc::MaxInt64 => mz_expr::AggregateFunc::MaxInt64,
1398 AggregateFunc::MaxUInt16 => mz_expr::AggregateFunc::MaxUInt16,
1399 AggregateFunc::MaxUInt32 => mz_expr::AggregateFunc::MaxUInt32,
1400 AggregateFunc::MaxUInt64 => mz_expr::AggregateFunc::MaxUInt64,
1401 AggregateFunc::MaxMzTimestamp => mz_expr::AggregateFunc::MaxMzTimestamp,
1402 AggregateFunc::MaxFloat32 => mz_expr::AggregateFunc::MaxFloat32,
1403 AggregateFunc::MaxFloat64 => mz_expr::AggregateFunc::MaxFloat64,
1404 AggregateFunc::MaxBool => mz_expr::AggregateFunc::MaxBool,
1405 AggregateFunc::MaxString => mz_expr::AggregateFunc::MaxString,
1406 AggregateFunc::MaxDate => mz_expr::AggregateFunc::MaxDate,
1407 AggregateFunc::MaxTimestamp => mz_expr::AggregateFunc::MaxTimestamp,
1408 AggregateFunc::MaxTimestampTz => mz_expr::AggregateFunc::MaxTimestampTz,
1409 AggregateFunc::MaxInterval => mz_expr::AggregateFunc::MaxInterval,
1410 AggregateFunc::MaxTime => mz_expr::AggregateFunc::MaxTime,
1411 AggregateFunc::MinNumeric => mz_expr::AggregateFunc::MinNumeric,
1412 AggregateFunc::MinInt16 => mz_expr::AggregateFunc::MinInt16,
1413 AggregateFunc::MinInt32 => mz_expr::AggregateFunc::MinInt32,
1414 AggregateFunc::MinInt64 => mz_expr::AggregateFunc::MinInt64,
1415 AggregateFunc::MinUInt16 => mz_expr::AggregateFunc::MinUInt16,
1416 AggregateFunc::MinUInt32 => mz_expr::AggregateFunc::MinUInt32,
1417 AggregateFunc::MinUInt64 => mz_expr::AggregateFunc::MinUInt64,
1418 AggregateFunc::MinMzTimestamp => mz_expr::AggregateFunc::MinMzTimestamp,
1419 AggregateFunc::MinFloat32 => mz_expr::AggregateFunc::MinFloat32,
1420 AggregateFunc::MinFloat64 => mz_expr::AggregateFunc::MinFloat64,
1421 AggregateFunc::MinBool => mz_expr::AggregateFunc::MinBool,
1422 AggregateFunc::MinString => mz_expr::AggregateFunc::MinString,
1423 AggregateFunc::MinDate => mz_expr::AggregateFunc::MinDate,
1424 AggregateFunc::MinTimestamp => mz_expr::AggregateFunc::MinTimestamp,
1425 AggregateFunc::MinTimestampTz => mz_expr::AggregateFunc::MinTimestampTz,
1426 AggregateFunc::MinInterval => mz_expr::AggregateFunc::MinInterval,
1427 AggregateFunc::MinTime => mz_expr::AggregateFunc::MinTime,
1428 AggregateFunc::SumInt16 => mz_expr::AggregateFunc::SumInt16,
1429 AggregateFunc::SumInt32 => mz_expr::AggregateFunc::SumInt32,
1430 AggregateFunc::SumInt64 => mz_expr::AggregateFunc::SumInt64,
1431 AggregateFunc::SumUInt16 => mz_expr::AggregateFunc::SumUInt16,
1432 AggregateFunc::SumUInt32 => mz_expr::AggregateFunc::SumUInt32,
1433 AggregateFunc::SumUInt64 => mz_expr::AggregateFunc::SumUInt64,
1434 AggregateFunc::SumFloat32 => mz_expr::AggregateFunc::SumFloat32,
1435 AggregateFunc::SumFloat64 => mz_expr::AggregateFunc::SumFloat64,
1436 AggregateFunc::SumNumeric => mz_expr::AggregateFunc::SumNumeric,
1437 AggregateFunc::Count => mz_expr::AggregateFunc::Count,
1438 AggregateFunc::Any => mz_expr::AggregateFunc::Any,
1439 AggregateFunc::All => mz_expr::AggregateFunc::All,
1440 AggregateFunc::JsonbAgg { order_by } => mz_expr::AggregateFunc::JsonbAgg { order_by },
1441 AggregateFunc::JsonbObjectAgg { order_by } => {
1442 mz_expr::AggregateFunc::JsonbObjectAgg { order_by }
1443 }
1444 AggregateFunc::MapAgg {
1445 order_by,
1446 value_type,
1447 } => mz_expr::AggregateFunc::MapAgg {
1448 order_by,
1449 value_type,
1450 },
1451 AggregateFunc::ArrayConcat { order_by } => {
1452 mz_expr::AggregateFunc::ArrayConcat { order_by }
1453 }
1454 AggregateFunc::ListConcat { order_by } => {
1455 mz_expr::AggregateFunc::ListConcat { order_by }
1456 }
1457 AggregateFunc::StringAgg { order_by } => mz_expr::AggregateFunc::StringAgg { order_by },
1458 AggregateFunc::FusedWindowAgg { funcs: _ } => {
1461 panic!("into_expr called on FusedWindowAgg")
1462 }
1463 AggregateFunc::Dummy => mz_expr::AggregateFunc::Dummy,
1464 }
1465 }
1466
1467 pub fn identity_datum(&self) -> Datum<'static> {
1474 match self {
1475 AggregateFunc::Any => Datum::False,
1476 AggregateFunc::All => Datum::True,
1477 AggregateFunc::Dummy => Datum::Dummy,
1478 AggregateFunc::ArrayConcat { .. } => Datum::empty_array(),
1479 AggregateFunc::ListConcat { .. } => Datum::empty_list(),
1480 AggregateFunc::MaxNumeric
1481 | AggregateFunc::MaxInt16
1482 | AggregateFunc::MaxInt32
1483 | AggregateFunc::MaxInt64
1484 | AggregateFunc::MaxUInt16
1485 | AggregateFunc::MaxUInt32
1486 | AggregateFunc::MaxUInt64
1487 | AggregateFunc::MaxMzTimestamp
1488 | AggregateFunc::MaxFloat32
1489 | AggregateFunc::MaxFloat64
1490 | AggregateFunc::MaxBool
1491 | AggregateFunc::MaxString
1492 | AggregateFunc::MaxDate
1493 | AggregateFunc::MaxTimestamp
1494 | AggregateFunc::MaxTimestampTz
1495 | AggregateFunc::MaxInterval
1496 | AggregateFunc::MaxTime
1497 | AggregateFunc::MinNumeric
1498 | AggregateFunc::MinInt16
1499 | AggregateFunc::MinInt32
1500 | AggregateFunc::MinInt64
1501 | AggregateFunc::MinUInt16
1502 | AggregateFunc::MinUInt32
1503 | AggregateFunc::MinUInt64
1504 | AggregateFunc::MinMzTimestamp
1505 | AggregateFunc::MinFloat32
1506 | AggregateFunc::MinFloat64
1507 | AggregateFunc::MinBool
1508 | AggregateFunc::MinString
1509 | AggregateFunc::MinDate
1510 | AggregateFunc::MinTimestamp
1511 | AggregateFunc::MinTimestampTz
1512 | AggregateFunc::MinInterval
1513 | AggregateFunc::MinTime
1514 | AggregateFunc::SumInt16
1515 | AggregateFunc::SumInt32
1516 | AggregateFunc::SumInt64
1517 | AggregateFunc::SumUInt16
1518 | AggregateFunc::SumUInt32
1519 | AggregateFunc::SumUInt64
1520 | AggregateFunc::SumFloat32
1521 | AggregateFunc::SumFloat64
1522 | AggregateFunc::SumNumeric
1523 | AggregateFunc::Count
1524 | AggregateFunc::JsonbAgg { .. }
1525 | AggregateFunc::JsonbObjectAgg { .. }
1526 | AggregateFunc::MapAgg { .. }
1527 | AggregateFunc::StringAgg { .. } => Datum::Null,
1528 AggregateFunc::FusedWindowAgg { funcs: _ } => {
1529 panic!("FusedWindowAgg doesn't have an identity_datum")
1539 }
1540 }
1541 }
1542
1543 pub fn output_sql_type(&self, input_type: SqlColumnType) -> SqlColumnType {
1549 let scalar_type = match self {
1550 AggregateFunc::Count => SqlScalarType::Int64,
1551 AggregateFunc::Any => SqlScalarType::Bool,
1552 AggregateFunc::All => SqlScalarType::Bool,
1553 AggregateFunc::JsonbAgg { .. } => SqlScalarType::Jsonb,
1554 AggregateFunc::JsonbObjectAgg { .. } => SqlScalarType::Jsonb,
1555 AggregateFunc::StringAgg { .. } => SqlScalarType::String,
1556 AggregateFunc::SumInt16 | AggregateFunc::SumInt32 => SqlScalarType::Int64,
1557 AggregateFunc::SumInt64 => SqlScalarType::Numeric {
1558 max_scale: Some(NumericMaxScale::ZERO),
1559 },
1560 AggregateFunc::SumUInt16 | AggregateFunc::SumUInt32 => SqlScalarType::UInt64,
1561 AggregateFunc::SumUInt64 => SqlScalarType::Numeric {
1562 max_scale: Some(NumericMaxScale::ZERO),
1563 },
1564 AggregateFunc::MapAgg { value_type, .. } => SqlScalarType::Map {
1565 value_type: Box::new(value_type.clone()),
1566 custom_id: None,
1567 },
1568 AggregateFunc::ArrayConcat { .. } | AggregateFunc::ListConcat { .. } => {
1569 match input_type.scalar_type {
1570 SqlScalarType::Record { fields, .. } => fields[0].1.scalar_type.clone(),
1572 _ => unreachable!(),
1573 }
1574 }
1575 AggregateFunc::MaxNumeric
1576 | AggregateFunc::MaxInt16
1577 | AggregateFunc::MaxInt32
1578 | AggregateFunc::MaxInt64
1579 | AggregateFunc::MaxUInt16
1580 | AggregateFunc::MaxUInt32
1581 | AggregateFunc::MaxUInt64
1582 | AggregateFunc::MaxMzTimestamp
1583 | AggregateFunc::MaxFloat32
1584 | AggregateFunc::MaxFloat64
1585 | AggregateFunc::MaxBool
1586 | AggregateFunc::MaxString
1587 | AggregateFunc::MaxDate
1588 | AggregateFunc::MaxTimestamp
1589 | AggregateFunc::MaxTimestampTz
1590 | AggregateFunc::MaxInterval
1591 | AggregateFunc::MaxTime
1592 | AggregateFunc::MinNumeric
1593 | AggregateFunc::MinInt16
1594 | AggregateFunc::MinInt32
1595 | AggregateFunc::MinInt64
1596 | AggregateFunc::MinUInt16
1597 | AggregateFunc::MinUInt32
1598 | AggregateFunc::MinUInt64
1599 | AggregateFunc::MinMzTimestamp
1600 | AggregateFunc::MinFloat32
1601 | AggregateFunc::MinFloat64
1602 | AggregateFunc::MinBool
1603 | AggregateFunc::MinString
1604 | AggregateFunc::MinDate
1605 | AggregateFunc::MinTimestamp
1606 | AggregateFunc::MinTimestampTz
1607 | AggregateFunc::MinInterval
1608 | AggregateFunc::MinTime
1609 | AggregateFunc::SumFloat32
1610 | AggregateFunc::SumFloat64
1611 | AggregateFunc::SumNumeric
1612 | AggregateFunc::Dummy => input_type.scalar_type,
1613 AggregateFunc::FusedWindowAgg { funcs } => {
1614 let input_types = input_type.scalar_type.unwrap_record_element_column_type();
1615 SqlScalarType::Record {
1616 fields: funcs
1617 .iter()
1618 .zip_eq(input_types)
1619 .map(|(f, t)| (ColumnName::from(""), f.output_sql_type(t.clone())))
1620 .collect(),
1621 custom_id: None,
1622 }
1623 }
1624 };
1625 let nullable = !matches!(self, AggregateFunc::Count);
1627 scalar_type.nullable(nullable)
1628 }
1629
1630 pub fn is_order_sensitive(&self) -> bool {
1631 use AggregateFunc::*;
1632 matches!(
1633 self,
1634 JsonbAgg { .. }
1635 | JsonbObjectAgg { .. }
1636 | MapAgg { .. }
1637 | ArrayConcat { .. }
1638 | ListConcat { .. }
1639 | StringAgg { .. }
1640 )
1641 }
1642}
1643
1644impl HirRelationExpr {
1645 pub fn top_level_typ(&self) -> SqlRelationType {
1647 self.typ(&[], &BTreeMap::new())
1648 }
1649
1650 pub fn typ(
1655 &self,
1656 outers: &[SqlRelationType],
1657 params: &BTreeMap<usize, SqlScalarType>,
1658 ) -> SqlRelationType {
1659 stack::maybe_grow(|| match self {
1660 HirRelationExpr::Constant { typ, .. } => typ.clone(),
1661 HirRelationExpr::Get { typ, .. } => typ.clone(),
1662 HirRelationExpr::Let { body, .. } => body.typ(outers, params),
1663 HirRelationExpr::LetRec { body, .. } => body.typ(outers, params),
1664 HirRelationExpr::Project { input, outputs } => {
1665 let input_typ = input.typ(outers, params);
1666 SqlRelationType::new(
1667 outputs
1668 .iter()
1669 .map(|&i| input_typ.column_types[i].clone())
1670 .collect(),
1671 )
1672 }
1673 HirRelationExpr::Map { input, scalars } => {
1674 let mut typ = input.typ(outers, params);
1675 for scalar in scalars {
1676 typ.column_types.push(scalar.typ(outers, &typ, params));
1677 }
1678 typ
1679 }
1680 HirRelationExpr::CallTable { func, exprs: _ } => func.output_sql_type(),
1681 HirRelationExpr::Filter { input, .. } | HirRelationExpr::TopK { input, .. } => {
1682 input.typ(outers, params)
1683 }
1684 HirRelationExpr::Join {
1685 left, right, kind, ..
1686 } => {
1687 let left_nullable = matches!(kind, JoinKind::RightOuter | JoinKind::FullOuter);
1688 let right_nullable =
1689 matches!(kind, JoinKind::LeftOuter { .. } | JoinKind::FullOuter);
1690 let lt = left.typ(outers, params).column_types.into_iter().map(|t| {
1691 let nullable = t.nullable || left_nullable;
1692 t.nullable(nullable)
1693 });
1694 let mut outers = outers.to_vec();
1695 outers.insert(0, SqlRelationType::new(lt.clone().collect()));
1696 let rt = right
1697 .typ(&outers, params)
1698 .column_types
1699 .into_iter()
1700 .map(|t| {
1701 let nullable = t.nullable || right_nullable;
1702 t.nullable(nullable)
1703 });
1704 SqlRelationType::new(lt.chain(rt).collect())
1705 }
1706 HirRelationExpr::Reduce {
1707 input,
1708 group_key,
1709 aggregates,
1710 expected_group_size: _,
1711 } => {
1712 let input_typ = input.typ(outers, params);
1713 let mut column_types = group_key
1714 .iter()
1715 .map(|&i| input_typ.column_types[i].clone())
1716 .collect::<Vec<_>>();
1717 for agg in aggregates {
1718 column_types.push(agg.typ(outers, &input_typ, params));
1719 }
1720 SqlRelationType::new(column_types)
1722 }
1723 HirRelationExpr::Distinct { input }
1725 | HirRelationExpr::Negate { input }
1726 | HirRelationExpr::Threshold { input } => input.typ(outers, params),
1727 HirRelationExpr::Union { base, inputs } => {
1728 let mut base_cols = base.typ(outers, params).column_types;
1729 for input in inputs {
1730 for (base_col, col) in base_cols
1731 .iter_mut()
1732 .zip_eq(input.typ(outers, params).column_types)
1733 {
1734 *base_col = base_col.sql_union(&col).unwrap(); }
1736 }
1737 SqlRelationType::new(base_cols)
1738 }
1739 })
1740 }
1741
1742 pub fn arity(&self) -> usize {
1743 match self {
1744 HirRelationExpr::Constant { typ, .. } => typ.column_types.len(),
1745 HirRelationExpr::Get { typ, .. } => typ.column_types.len(),
1746 HirRelationExpr::Let { body, .. } => body.arity(),
1747 HirRelationExpr::LetRec { body, .. } => body.arity(),
1748 HirRelationExpr::Project { outputs, .. } => outputs.len(),
1749 HirRelationExpr::Map { input, scalars } => input.arity() + scalars.len(),
1750 HirRelationExpr::CallTable { func, exprs: _ } => func.output_arity(),
1751 HirRelationExpr::Filter { input, .. }
1752 | HirRelationExpr::TopK { input, .. }
1753 | HirRelationExpr::Distinct { input }
1754 | HirRelationExpr::Negate { input }
1755 | HirRelationExpr::Threshold { input } => input.arity(),
1756 HirRelationExpr::Join { left, right, .. } => left.arity() + right.arity(),
1757 HirRelationExpr::Union { base, .. } => base.arity(),
1758 HirRelationExpr::Reduce {
1759 group_key,
1760 aggregates,
1761 ..
1762 } => group_key.len() + aggregates.len(),
1763 }
1764 }
1765
1766 pub fn relation_node_count(&self) -> usize {
1773 let mut count = 0;
1774 self.visit_post(&mut |_| count += 1);
1775 count
1776 }
1777
1778 pub fn as_const(&self) -> Option<(&Vec<Row>, &SqlRelationType)> {
1780 match self {
1781 Self::Constant { rows, typ } => Some((rows, typ)),
1782 _ => None,
1783 }
1784 }
1785
1786 pub fn is_correlated(&self) -> bool {
1789 let mut correlated = false;
1790 #[allow(deprecated)]
1791 self.visit_columns(0, &mut |depth, col| {
1792 if col.level > depth && col.level - depth == 1 {
1793 correlated = true;
1794 }
1795 });
1796 correlated
1797 }
1798
1799 pub fn is_join_identity(&self) -> bool {
1800 match self {
1801 HirRelationExpr::Constant { rows, .. } => rows.len() == 1 && self.arity() == 0,
1802 _ => false,
1803 }
1804 }
1805
1806 pub fn project(self, outputs: Vec<usize>) -> Self {
1807 if outputs.iter().copied().eq(0..self.arity()) {
1808 self
1810 } else {
1811 HirRelationExpr::Project {
1812 input: Box::new(self),
1813 outputs,
1814 }
1815 }
1816 }
1817
1818 pub fn map(mut self, scalars: Vec<HirScalarExpr>) -> Self {
1819 if scalars.is_empty() {
1820 self
1822 } else if let HirRelationExpr::Map {
1823 scalars: old_scalars,
1824 input: _,
1825 } = &mut self
1826 {
1827 old_scalars.extend(scalars);
1829 self
1830 } else {
1831 HirRelationExpr::Map {
1832 input: Box::new(self),
1833 scalars,
1834 }
1835 }
1836 }
1837
1838 pub fn filter(mut self, mut preds: Vec<HirScalarExpr>) -> Self {
1839 if let HirRelationExpr::Filter {
1840 input: _,
1841 predicates,
1842 } = &mut self
1843 {
1844 predicates.extend(preds);
1845 predicates.sort();
1846 predicates.dedup();
1847 self
1848 } else {
1849 preds.sort();
1850 preds.dedup();
1851 HirRelationExpr::Filter {
1852 input: Box::new(self),
1853 predicates: preds,
1854 }
1855 }
1856 }
1857
1858 pub fn reduce(
1859 self,
1860 group_key: Vec<usize>,
1861 aggregates: Vec<AggregateExpr>,
1862 expected_group_size: Option<u64>,
1863 ) -> Self {
1864 HirRelationExpr::Reduce {
1865 input: Box::new(self),
1866 group_key,
1867 aggregates,
1868 expected_group_size,
1869 }
1870 }
1871
1872 pub fn top_k(
1873 self,
1874 group_key: Vec<usize>,
1875 order_key: Vec<ColumnOrder>,
1876 limit: Option<HirScalarExpr>,
1877 offset: HirScalarExpr,
1878 expected_group_size: Option<u64>,
1879 ) -> Self {
1880 HirRelationExpr::TopK {
1881 input: Box::new(self),
1882 group_key,
1883 order_key,
1884 limit,
1885 offset,
1886 expected_group_size,
1887 }
1888 }
1889
1890 pub fn negate(self) -> Self {
1891 if let HirRelationExpr::Negate { input } = self {
1892 *input
1893 } else {
1894 HirRelationExpr::Negate {
1895 input: Box::new(self),
1896 }
1897 }
1898 }
1899
1900 pub fn distinct(self) -> Self {
1901 if let HirRelationExpr::Distinct { .. } = self {
1902 self
1903 } else {
1904 HirRelationExpr::Distinct {
1905 input: Box::new(self),
1906 }
1907 }
1908 }
1909
1910 pub fn threshold(self) -> Self {
1911 if let HirRelationExpr::Threshold { .. } = self {
1912 self
1913 } else {
1914 HirRelationExpr::Threshold {
1915 input: Box::new(self),
1916 }
1917 }
1918 }
1919
1920 pub fn union(self, other: Self) -> Self {
1921 let mut terms = Vec::new();
1922 if let HirRelationExpr::Union { base, inputs } = self {
1923 terms.push(*base);
1924 terms.extend(inputs);
1925 } else {
1926 terms.push(self);
1927 }
1928 if let HirRelationExpr::Union { base, inputs } = other {
1929 terms.push(*base);
1930 terms.extend(inputs);
1931 } else {
1932 terms.push(other);
1933 }
1934 HirRelationExpr::Union {
1935 base: Box::new(terms.remove(0)),
1936 inputs: terms,
1937 }
1938 }
1939
1940 pub fn exists(self) -> HirScalarExpr {
1941 HirScalarExpr::Exists(Box::new(self), NameMetadata::default())
1942 }
1943
1944 pub fn select(self) -> HirScalarExpr {
1945 HirScalarExpr::Select(Box::new(self), NameMetadata::default())
1946 }
1947
1948 pub fn join(
1949 self,
1950 mut right: HirRelationExpr,
1951 on: HirScalarExpr,
1952 kind: JoinKind,
1953 ) -> HirRelationExpr {
1954 if self.is_join_identity()
1955 && !right.is_correlated()
1956 && on == HirScalarExpr::literal_true()
1957 && kind.can_elide_identity_left_join()
1958 {
1959 #[allow(deprecated)]
1963 right.visit_columns_mut(0, &mut |depth, col| {
1964 if col.level > depth {
1965 col.level -= 1;
1966 }
1967 });
1968 right
1969 } else if right.is_join_identity()
1970 && on == HirScalarExpr::literal_true()
1971 && kind.can_elide_identity_right_join()
1972 {
1973 self
1974 } else {
1975 HirRelationExpr::Join {
1976 left: Box::new(self),
1977 right: Box::new(right),
1978 on,
1979 kind,
1980 }
1981 }
1982 }
1983
1984 pub fn take(&mut self) -> HirRelationExpr {
1985 mem::replace(
1986 self,
1987 HirRelationExpr::constant(vec![], SqlRelationType::new(Vec::new())),
1988 )
1989 }
1990
1991 #[deprecated = "Use `Visit::visit_post`."]
1992 pub fn visit<'a, F>(&'a self, depth: usize, f: &mut F)
1993 where
1994 F: FnMut(&'a Self, usize),
1995 {
1996 #[allow(deprecated)]
1997 let _ = self.visit_fallible(depth, &mut |e: &HirRelationExpr,
1998 depth: usize|
1999 -> Result<(), ()> {
2000 f(e, depth);
2001 Ok(())
2002 });
2003 }
2004
2005 #[deprecated = "Use `Visit::try_visit_post`."]
2006 pub fn visit_fallible<'a, F, E>(&'a self, depth: usize, f: &mut F) -> Result<(), E>
2007 where
2008 F: FnMut(&'a Self, usize) -> Result<(), E>,
2009 {
2010 #[allow(deprecated)]
2011 stack::maybe_grow(|| {
2014 self.visit1(depth, |e: &HirRelationExpr, depth: usize| {
2015 e.visit_fallible(depth, f)
2016 })
2017 })?;
2018 f(self, depth)
2019 }
2020
2021 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_children` instead."]
2026 pub fn visit1<'a, F, E>(&'a self, depth: usize, mut f: F) -> Result<(), E>
2027 where
2028 F: FnMut(&'a Self, usize) -> Result<(), E>,
2029 {
2030 match self {
2031 HirRelationExpr::Constant { .. }
2032 | HirRelationExpr::Get { .. }
2033 | HirRelationExpr::CallTable { .. } => (),
2034 HirRelationExpr::Let { body, value, .. } => {
2035 f(value, depth)?;
2036 f(body, depth)?;
2037 }
2038 HirRelationExpr::LetRec {
2039 limit: _,
2040 bindings,
2041 body,
2042 } => {
2043 for (_, _, value, _) in bindings.iter() {
2044 f(value, depth)?;
2045 }
2046 f(body, depth)?;
2047 }
2048 HirRelationExpr::Project { input, .. } => {
2049 f(input, depth)?;
2050 }
2051 HirRelationExpr::Map { input, .. } => {
2052 f(input, depth)?;
2053 }
2054 HirRelationExpr::Filter { input, .. } => {
2055 f(input, depth)?;
2056 }
2057 HirRelationExpr::Join { left, right, .. } => {
2058 f(left, depth)?;
2059 f(right, depth + 1)?;
2060 }
2061 HirRelationExpr::Reduce { input, .. } => {
2062 f(input, depth)?;
2063 }
2064 HirRelationExpr::Distinct { input } => {
2065 f(input, depth)?;
2066 }
2067 HirRelationExpr::TopK { input, .. } => {
2068 f(input, depth)?;
2069 }
2070 HirRelationExpr::Negate { input } => {
2071 f(input, depth)?;
2072 }
2073 HirRelationExpr::Threshold { input } => {
2074 f(input, depth)?;
2075 }
2076 HirRelationExpr::Union { base, inputs } => {
2077 f(base, depth)?;
2078 for input in inputs {
2079 f(input, depth)?;
2080 }
2081 }
2082 }
2083 Ok(())
2084 }
2085
2086 #[deprecated = "Use `Visit::visit_mut_post` instead."]
2087 pub fn visit_mut<F>(&mut self, depth: usize, f: &mut F)
2088 where
2089 F: FnMut(&mut Self, usize),
2090 {
2091 #[allow(deprecated)]
2092 let _ = self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2093 depth: usize|
2094 -> Result<(), ()> {
2095 f(e, depth);
2096 Ok(())
2097 });
2098 }
2099
2100 #[deprecated = "Use `Visit::try_visit_mut_post` instead."]
2101 pub fn visit_mut_fallible<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2102 where
2103 F: FnMut(&mut Self, usize) -> Result<(), E>,
2104 {
2105 #[allow(deprecated)]
2106 stack::maybe_grow(|| {
2109 self.visit1_mut(depth, |e: &mut HirRelationExpr, depth: usize| {
2110 e.visit_mut_fallible(depth, f)
2111 })
2112 })?;
2113 f(self, depth)
2114 }
2115
2116 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_mut_children` instead."]
2121 pub fn visit1_mut<'a, F, E>(&'a mut self, depth: usize, mut f: F) -> Result<(), E>
2122 where
2123 F: FnMut(&'a mut Self, usize) -> Result<(), E>,
2124 {
2125 match self {
2126 HirRelationExpr::Constant { .. }
2127 | HirRelationExpr::Get { .. }
2128 | HirRelationExpr::CallTable { .. } => (),
2129 HirRelationExpr::Let { body, value, .. } => {
2130 f(value, depth)?;
2131 f(body, depth)?;
2132 }
2133 HirRelationExpr::LetRec {
2134 limit: _,
2135 bindings,
2136 body,
2137 } => {
2138 for (_, _, value, _) in bindings.iter_mut() {
2139 f(value, depth)?;
2140 }
2141 f(body, depth)?;
2142 }
2143 HirRelationExpr::Project { input, .. } => {
2144 f(input, depth)?;
2145 }
2146 HirRelationExpr::Map { input, .. } => {
2147 f(input, depth)?;
2148 }
2149 HirRelationExpr::Filter { input, .. } => {
2150 f(input, depth)?;
2151 }
2152 HirRelationExpr::Join { left, right, .. } => {
2153 f(left, depth)?;
2154 f(right, depth + 1)?;
2155 }
2156 HirRelationExpr::Reduce { input, .. } => {
2157 f(input, depth)?;
2158 }
2159 HirRelationExpr::Distinct { input } => {
2160 f(input, depth)?;
2161 }
2162 HirRelationExpr::TopK { input, .. } => {
2163 f(input, depth)?;
2164 }
2165 HirRelationExpr::Negate { input } => {
2166 f(input, depth)?;
2167 }
2168 HirRelationExpr::Threshold { input } => {
2169 f(input, depth)?;
2170 }
2171 HirRelationExpr::Union { base, inputs } => {
2172 f(base, depth)?;
2173 for input in inputs {
2174 f(input, depth)?;
2175 }
2176 }
2177 }
2178 Ok(())
2179 }
2180
2181 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2182 pub fn visit_scalar_expressions<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
2194 where
2195 F: FnMut(&HirScalarExpr, usize) -> Result<(), E>,
2196 {
2197 #[allow(deprecated)]
2198 self.visit_fallible(depth, &mut |e: &HirRelationExpr,
2199 depth: usize|
2200 -> Result<(), E> {
2201 match e {
2202 HirRelationExpr::Join { on, .. } => {
2203 f(on, depth)?;
2204 }
2205 HirRelationExpr::Map { scalars, .. } => {
2206 for scalar in scalars {
2207 f(scalar, depth)?;
2208 }
2209 }
2210 HirRelationExpr::CallTable { exprs, .. } => {
2211 for expr in exprs {
2212 f(expr, depth)?;
2213 }
2214 }
2215 HirRelationExpr::Filter { predicates, .. } => {
2216 for predicate in predicates {
2217 f(predicate, depth)?;
2218 }
2219 }
2220 HirRelationExpr::Reduce { aggregates, .. } => {
2221 for aggregate in aggregates {
2222 f(&aggregate.expr, depth)?;
2223 }
2224 }
2225 HirRelationExpr::TopK { limit, offset, .. } => {
2226 if let Some(limit) = limit {
2227 f(limit, depth)?;
2228 }
2229 f(offset, depth)?;
2230 }
2231 HirRelationExpr::Union { .. }
2232 | HirRelationExpr::Let { .. }
2233 | HirRelationExpr::LetRec { .. }
2234 | HirRelationExpr::Project { .. }
2235 | HirRelationExpr::Distinct { .. }
2236 | HirRelationExpr::Negate { .. }
2237 | HirRelationExpr::Threshold { .. }
2238 | HirRelationExpr::Constant { .. }
2239 | HirRelationExpr::Get { .. } => (),
2240 }
2241 Ok(())
2242 })
2243 }
2244
2245 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2246 pub fn visit_scalar_expressions_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2252 where
2253 F: FnMut(&mut HirScalarExpr, usize) -> Result<(), E>,
2254 {
2255 #[allow(deprecated)]
2256 self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2257 depth: usize|
2258 -> Result<(), E> {
2259 match e {
2260 HirRelationExpr::Join { on, .. } => {
2261 f(on, depth)?;
2262 }
2263 HirRelationExpr::Map { scalars, .. } => {
2264 for scalar in scalars.iter_mut() {
2265 f(scalar, depth)?;
2266 }
2267 }
2268 HirRelationExpr::CallTable { exprs, .. } => {
2269 for expr in exprs.iter_mut() {
2270 f(expr, depth)?;
2271 }
2272 }
2273 HirRelationExpr::Filter { predicates, .. } => {
2274 for predicate in predicates.iter_mut() {
2275 f(predicate, depth)?;
2276 }
2277 }
2278 HirRelationExpr::Reduce { aggregates, .. } => {
2279 for aggregate in aggregates.iter_mut() {
2280 f(&mut aggregate.expr, depth)?;
2281 }
2282 }
2283 HirRelationExpr::TopK { limit, offset, .. } => {
2284 if let Some(limit) = limit {
2285 f(limit, depth)?;
2286 }
2287 f(offset, depth)?;
2288 }
2289 HirRelationExpr::Union { .. }
2290 | HirRelationExpr::Let { .. }
2291 | HirRelationExpr::LetRec { .. }
2292 | HirRelationExpr::Project { .. }
2293 | HirRelationExpr::Distinct { .. }
2294 | HirRelationExpr::Negate { .. }
2295 | HirRelationExpr::Threshold { .. }
2296 | HirRelationExpr::Constant { .. }
2297 | HirRelationExpr::Get { .. } => (),
2298 }
2299 Ok(())
2300 })
2301 }
2302
2303 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2304 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
2310 where
2311 F: FnMut(usize, &ColumnRef),
2312 {
2313 #[allow(deprecated)]
2314 let _ = self.visit_scalar_expressions(depth, &mut |e: &HirScalarExpr,
2315 depth: usize|
2316 -> Result<(), ()> {
2317 e.visit_columns(depth, f);
2318 Ok(())
2319 });
2320 }
2321
2322 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2323 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
2325 where
2326 F: FnMut(usize, &mut ColumnRef),
2327 {
2328 #[allow(deprecated)]
2329 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2330 depth: usize|
2331 -> Result<(), ()> {
2332 e.visit_columns_mut(depth, f);
2333 Ok(())
2334 });
2335 }
2336
2337 pub fn bind_parameters_and_simplify_offset(
2347 &mut self,
2348 scx: &StatementContext,
2349 lifetime: QueryLifetime,
2350 params: &Params,
2351 ) -> Result<(), PlanError> {
2352 #[allow(deprecated)]
2353 self.visit_scalar_expressions_mut(0, &mut |e: &mut HirScalarExpr, _: usize| {
2354 e.bind_parameters_and_simplify_offset(scx, lifetime, params)
2355 })?;
2356
2357 self.try_visit_mut_pre(&mut |expr| {
2360 if let HirRelationExpr::TopK { offset, .. } = expr {
2361 let offset_value = offset_into_value(offset.take())?;
2362 *offset = HirScalarExpr::literal(Datum::Int64(offset_value), SqlScalarType::Int64);
2363 }
2364 Ok::<(), PlanError>(())
2365 })
2366 }
2370
2371 pub fn contains_parameters(&self) -> Result<bool, PlanError> {
2372 let mut contains_parameters = false;
2373 #[allow(deprecated)]
2374 self.visit_scalar_expressions(0, &mut |e: &HirScalarExpr, _: usize| {
2375 if e.contains_parameters() {
2376 contains_parameters = true;
2377 }
2378 Ok::<(), PlanError>(())
2379 })?;
2380 Ok(contains_parameters)
2381 }
2382
2383 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
2385 #[allow(deprecated)]
2386 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2387 depth: usize|
2388 -> Result<(), ()> {
2389 e.splice_parameters(params, depth);
2390 Ok(())
2391 });
2392 }
2393
2394 pub fn constant(rows: Vec<Vec<Datum>>, typ: SqlRelationType) -> Self {
2396 let rows = rows
2397 .into_iter()
2398 .map(move |datums| Row::pack_slice(&datums))
2399 .collect();
2400 HirRelationExpr::Constant { rows, typ }
2401 }
2402
2403 pub fn finish_maintained(
2409 &mut self,
2410 finishing: &mut RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2411 group_size_hints: GroupSizeHints,
2412 ) {
2413 if !HirRelationExpr::is_trivial_row_set_finishing_hir(finishing, self.arity()) {
2414 let old_finishing = mem::replace(
2415 finishing,
2416 HirRelationExpr::trivial_row_set_finishing_hir(finishing.project.len()),
2417 );
2418 *self = HirRelationExpr::top_k(
2419 std::mem::replace(
2420 self,
2421 HirRelationExpr::Constant {
2422 rows: vec![],
2423 typ: SqlRelationType::new(Vec::new()),
2424 },
2425 ),
2426 vec![],
2427 old_finishing.order_by,
2428 old_finishing.limit,
2429 old_finishing.offset,
2430 group_size_hints.limit_input_group_size,
2431 )
2432 .project(old_finishing.project);
2433 }
2434 }
2435
2436 pub fn trivial_row_set_finishing_hir(
2441 arity: usize,
2442 ) -> RowSetFinishing<HirScalarExpr, HirScalarExpr> {
2443 RowSetFinishing {
2444 order_by: Vec::new(),
2445 limit: None,
2446 offset: HirScalarExpr::literal(Datum::Int64(0), SqlScalarType::Int64),
2447 project: (0..arity).collect(),
2448 }
2449 }
2450
2451 pub fn is_trivial_row_set_finishing_hir(
2456 rsf: &RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2457 arity: usize,
2458 ) -> bool {
2459 rsf.limit.is_none()
2460 && rsf.order_by.is_empty()
2461 && rsf
2462 .offset
2463 .clone()
2464 .try_into_literal_int64()
2465 .is_ok_and(|o| o == 0)
2466 && rsf.project.iter().copied().eq(0..arity)
2467 }
2468
2469 pub fn could_run_expensive_function(&self) -> bool {
2479 let mut result = false;
2480 self.visit_pre(&mut |e: &HirRelationExpr| {
2481 use HirRelationExpr::*;
2482 use HirScalarExpr::*;
2483
2484 e.visit_children(|scalar: &HirScalarExpr| {
2485 scalar.visit_pre(&mut |scalar: &HirScalarExpr| {
2486 result |= match scalar {
2487 Column(..)
2488 | Literal(..)
2489 | CallUnmaterializable(..)
2490 | If { .. }
2491 | Parameter(..)
2492 | Select(..)
2493 | Exists(..) => false,
2494 CallUnary { .. }
2496 | CallBinary { .. }
2497 | CallVariadic { .. }
2498 | Windowing(..) => true,
2499 };
2500 })
2501 });
2502
2503 result |= matches!(e, CallTable { .. } | Reduce { .. });
2506 });
2507
2508 result
2509 }
2510
2511 pub fn contains_temporal(&self) -> bool {
2513 let mut contains = false;
2514 self.visit_post(&mut |expr| {
2515 expr.visit_children(|expr: &HirScalarExpr| {
2516 contains = contains || expr.contains_temporal()
2517 })
2518 });
2519 contains
2520 }
2521
2522 pub fn contains_unmaterializable(&self) -> bool {
2524 let mut contains = false;
2525 self.visit_post(&mut |expr| {
2526 expr.visit_children(|expr: &HirScalarExpr| {
2527 contains = contains || expr.contains_unmaterializable()
2528 })
2529 });
2530 contains
2531 }
2532
2533 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
2536 let mut contains = false;
2537 self.visit_post(&mut |expr| {
2538 expr.visit_children(|expr: &HirScalarExpr| {
2539 contains = contains || expr.contains_unmaterializable_except_temporal()
2540 })
2541 });
2542 contains
2543 }
2544}
2545
2546impl CollectionPlan for HirRelationExpr {
2547 fn depends_on_into(&self, out: &mut BTreeSet<GlobalId>) {
2554 if let Self::Get {
2555 id: Id::Global(id), ..
2556 } = self
2557 {
2558 out.insert(*id);
2559 }
2560 self.visit_children(|expr: &HirRelationExpr| expr.depends_on_into(out))
2561 }
2562}
2563
2564impl VisitChildren<Self> for HirRelationExpr {
2570 fn visit_children<F>(&self, mut f: F)
2571 where
2572 F: FnMut(&Self),
2573 {
2574 VisitChildren::visit_children(self, |expr: &HirScalarExpr| {
2578 expr.visit_direct_subqueries(&mut f);
2579 });
2580
2581 use HirRelationExpr::*;
2582 match self {
2583 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2584 Let {
2585 name: _,
2586 id: _,
2587 value,
2588 body,
2589 } => {
2590 f(value);
2591 f(body);
2592 }
2593 LetRec {
2594 limit: _,
2595 bindings,
2596 body,
2597 } => {
2598 for (_, _, value, _) in bindings.iter() {
2599 f(value);
2600 }
2601 f(body);
2602 }
2603 Project { input, outputs: _ } => f(input),
2604 Map { input, scalars: _ } => {
2605 f(input);
2606 }
2607 CallTable { func: _, exprs: _ } => (),
2608 Filter {
2609 input,
2610 predicates: _,
2611 } => {
2612 f(input);
2613 }
2614 Join {
2615 left,
2616 right,
2617 on: _,
2618 kind: _,
2619 } => {
2620 f(left);
2621 f(right);
2622 }
2623 Reduce {
2624 input,
2625 group_key: _,
2626 aggregates: _,
2627 expected_group_size: _,
2628 } => {
2629 f(input);
2630 }
2631 Distinct { input }
2632 | TopK {
2633 input,
2634 group_key: _,
2635 order_key: _,
2636 limit: _,
2637 offset: _,
2638 expected_group_size: _,
2639 }
2640 | Negate { input }
2641 | Threshold { input } => {
2642 f(input);
2643 }
2644 Union { base, inputs } => {
2645 f(base);
2646 for input in inputs {
2647 f(input);
2648 }
2649 }
2650 }
2651 }
2652
2653 fn visit_mut_children<F>(&mut self, mut f: F)
2654 where
2655 F: FnMut(&mut Self),
2656 {
2657 VisitChildren::visit_mut_children(self, |expr: &mut HirScalarExpr| {
2661 expr.visit_direct_subqueries_mut(&mut f);
2662 });
2663
2664 use HirRelationExpr::*;
2665 match self {
2666 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2667 Let {
2668 name: _,
2669 id: _,
2670 value,
2671 body,
2672 } => {
2673 f(value);
2674 f(body);
2675 }
2676 LetRec {
2677 limit: _,
2678 bindings,
2679 body,
2680 } => {
2681 for (_, _, value, _) in bindings.iter_mut() {
2682 f(value);
2683 }
2684 f(body);
2685 }
2686 Project { input, outputs: _ } => f(input),
2687 Map { input, scalars: _ } => {
2688 f(input);
2689 }
2690 CallTable { func: _, exprs: _ } => (),
2691 Filter {
2692 input,
2693 predicates: _,
2694 } => {
2695 f(input);
2696 }
2697 Join {
2698 left,
2699 right,
2700 on: _,
2701 kind: _,
2702 } => {
2703 f(left);
2704 f(right);
2705 }
2706 Reduce {
2707 input,
2708 group_key: _,
2709 aggregates: _,
2710 expected_group_size: _,
2711 } => {
2712 f(input);
2713 }
2714 Distinct { input }
2715 | TopK {
2716 input,
2717 group_key: _,
2718 order_key: _,
2719 limit: _,
2720 offset: _,
2721 expected_group_size: _,
2722 }
2723 | Negate { input }
2724 | Threshold { input } => {
2725 f(input);
2726 }
2727 Union { base, inputs } => {
2728 f(base);
2729 for input in inputs {
2730 f(input);
2731 }
2732 }
2733 }
2734 }
2735
2736 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
2737 where
2738 F: FnMut(&Self) -> Result<(), E>,
2739 {
2740 VisitChildren::try_visit_children(self, |expr: &HirScalarExpr| {
2744 expr.try_visit_direct_subqueries(&mut f)
2745 })?;
2746
2747 use HirRelationExpr::*;
2748 match self {
2749 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2750 Let {
2751 name: _,
2752 id: _,
2753 value,
2754 body,
2755 } => {
2756 f(value)?;
2757 f(body)?;
2758 }
2759 LetRec {
2760 limit: _,
2761 bindings,
2762 body,
2763 } => {
2764 for (_, _, value, _) in bindings.iter() {
2765 f(value)?;
2766 }
2767 f(body)?;
2768 }
2769 Project { input, outputs: _ } => f(input)?,
2770 Map { input, scalars: _ } => {
2771 f(input)?;
2772 }
2773 CallTable { func: _, exprs: _ } => (),
2774 Filter {
2775 input,
2776 predicates: _,
2777 } => {
2778 f(input)?;
2779 }
2780 Join {
2781 left,
2782 right,
2783 on: _,
2784 kind: _,
2785 } => {
2786 f(left)?;
2787 f(right)?;
2788 }
2789 Reduce {
2790 input,
2791 group_key: _,
2792 aggregates: _,
2793 expected_group_size: _,
2794 } => {
2795 f(input)?;
2796 }
2797 Distinct { input }
2798 | TopK {
2799 input,
2800 group_key: _,
2801 order_key: _,
2802 limit: _,
2803 offset: _,
2804 expected_group_size: _,
2805 }
2806 | Negate { input }
2807 | Threshold { input } => {
2808 f(input)?;
2809 }
2810 Union { base, inputs } => {
2811 f(base)?;
2812 for input in inputs {
2813 f(input)?;
2814 }
2815 }
2816 }
2817 Ok(())
2818 }
2819
2820 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
2821 where
2822 F: FnMut(&mut Self) -> Result<(), E>,
2823 {
2824 VisitChildren::try_visit_mut_children(self, |expr: &mut HirScalarExpr| {
2828 expr.try_visit_direct_subqueries_mut(&mut f)
2829 })?;
2830
2831 use HirRelationExpr::*;
2832 match self {
2833 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2834 Let {
2835 name: _,
2836 id: _,
2837 value,
2838 body,
2839 } => {
2840 f(value)?;
2841 f(body)?;
2842 }
2843 LetRec {
2844 limit: _,
2845 bindings,
2846 body,
2847 } => {
2848 for (_, _, value, _) in bindings.iter_mut() {
2849 f(value)?;
2850 }
2851 f(body)?;
2852 }
2853 Project { input, outputs: _ } => f(input)?,
2854 Map { input, scalars: _ } => {
2855 f(input)?;
2856 }
2857 CallTable { func: _, exprs: _ } => (),
2858 Filter {
2859 input,
2860 predicates: _,
2861 } => {
2862 f(input)?;
2863 }
2864 Join {
2865 left,
2866 right,
2867 on: _,
2868 kind: _,
2869 } => {
2870 f(left)?;
2871 f(right)?;
2872 }
2873 Reduce {
2874 input,
2875 group_key: _,
2876 aggregates: _,
2877 expected_group_size: _,
2878 } => {
2879 f(input)?;
2880 }
2881 Distinct { input }
2882 | TopK {
2883 input,
2884 group_key: _,
2885 order_key: _,
2886 limit: _,
2887 offset: _,
2888 expected_group_size: _,
2889 }
2890 | Negate { input }
2891 | Threshold { input } => {
2892 f(input)?;
2893 }
2894 Union { base, inputs } => {
2895 f(base)?;
2896 for input in inputs {
2897 f(input)?;
2898 }
2899 }
2900 }
2901 Ok(())
2902 }
2903
2904 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
2905 where
2906 Self: 'a,
2907 {
2908 let mut v: Vec<&HirRelationExpr> = vec![];
2910 use HirRelationExpr::*;
2911 match self {
2912 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2913 Let {
2914 name: _,
2915 id: _,
2916 value,
2917 body,
2918 } => {
2919 v.push(&*value);
2920 v.push(&*body);
2921 }
2922 LetRec {
2923 limit: _,
2924 bindings,
2925 body,
2926 } => {
2927 v.extend(bindings.iter().map(|(_, _, value, _)| value));
2928 v.push(&*body);
2929 }
2930 Map { input, scalars }
2931 | Filter {
2932 input,
2933 predicates: scalars,
2934 } => {
2935 for scalar in scalars {
2936 v.append(&mut scalar.direct_subqueries());
2937 }
2938 v.push(&*input);
2939 }
2940 Reduce {
2941 input,
2942 group_key: _,
2943 aggregates,
2944 expected_group_size: _,
2945 } => {
2946 for agg in aggregates {
2947 v.append(&mut agg.expr.direct_subqueries());
2948 }
2949 v.push(&*input);
2950 }
2951 TopK {
2952 input,
2953 group_key: _,
2954 order_key: _,
2955 limit,
2956 offset,
2957 expected_group_size: _,
2958 } => {
2959 if let Some(limit) = limit {
2960 v.append(&mut limit.direct_subqueries());
2961 }
2962 v.append(&mut offset.direct_subqueries());
2963 v.push(&*input);
2964 }
2965 Project { input, outputs: _ }
2966 | Distinct { input }
2967 | Negate { input }
2968 | Threshold { input } => v.push(&*input),
2969 CallTable { func: _, exprs } => v.extend(
2970 exprs
2971 .iter()
2972 .map(|scalar| scalar.direct_subqueries())
2973 .flatten(),
2974 ),
2975 Join {
2976 left,
2977 right,
2978 on,
2979 kind: _,
2980 } => {
2981 v.append(&mut on.direct_subqueries());
2982 v.push(&*left);
2983 v.push(&*right);
2984 }
2985 Union { base, inputs } => {
2986 v.push(&*base);
2987 v.extend(inputs.iter());
2988 }
2989 }
2990
2991 v.into_iter()
2992 }
2993
2994 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
2995 where
2996 Self: 'a,
2997 {
2998 let mut v = vec![];
3000 use HirRelationExpr::*;
3001 match self {
3002 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
3003 Let {
3004 name: _,
3005 id: _,
3006 value,
3007 body,
3008 } => {
3009 v.push(&mut **value);
3010 v.push(&mut **body);
3011 }
3012 LetRec {
3013 limit: _,
3014 bindings,
3015 body,
3016 } => {
3017 v.extend(bindings.iter_mut().map(|(_, _, value, _)| value));
3018 v.push(&mut **body);
3019 }
3020 Map { input, scalars }
3021 | Filter {
3022 input,
3023 predicates: scalars,
3024 } => {
3025 for scalar in scalars {
3026 v.append(&mut scalar.direct_subqueries_mut());
3027 }
3028 v.push(&mut **input);
3029 }
3030 Reduce {
3031 input,
3032 group_key: _,
3033 aggregates,
3034 expected_group_size: _,
3035 } => {
3036 for agg in aggregates {
3037 v.append(&mut agg.expr.direct_subqueries_mut());
3038 }
3039 v.push(&mut **input);
3040 }
3041 TopK {
3042 input,
3043 group_key: _,
3044 order_key: _,
3045 limit,
3046 offset,
3047 expected_group_size: _,
3048 } => {
3049 if let Some(limit) = limit {
3050 v.append(&mut limit.direct_subqueries_mut());
3051 }
3052 v.append(&mut offset.direct_subqueries_mut());
3053 v.push(&mut **input);
3054 }
3055 Project { input, outputs: _ }
3056 | Distinct { input }
3057 | Negate { input }
3058 | Threshold { input } => v.push(&mut **input),
3059 CallTable { func: _, exprs } => v.extend(
3060 exprs
3061 .iter_mut()
3062 .map(|scalar| scalar.direct_subqueries_mut())
3063 .flatten(),
3064 ),
3065 Join {
3066 left,
3067 right,
3068 on,
3069 kind: _,
3070 } => {
3071 v.append(&mut on.direct_subqueries_mut());
3072 v.push(&mut **left);
3073 v.push(&mut **right);
3074 }
3075 Union { base, inputs } => {
3076 v.push(&mut **base);
3077 v.extend(inputs.iter_mut());
3078 }
3079 }
3080
3081 v.into_iter()
3082 }
3083}
3084
3085impl VisitChildren<HirScalarExpr> for HirRelationExpr {
3089 fn visit_children<F>(&self, mut f: F)
3090 where
3091 F: FnMut(&HirScalarExpr),
3092 {
3093 use HirRelationExpr::*;
3094 match self {
3095 Constant { rows: _, typ: _ }
3096 | Get { id: _, typ: _ }
3097 | Let {
3098 name: _,
3099 id: _,
3100 value: _,
3101 body: _,
3102 }
3103 | LetRec {
3104 limit: _,
3105 bindings: _,
3106 body: _,
3107 }
3108 | Project {
3109 input: _,
3110 outputs: _,
3111 } => (),
3112 Map { input: _, scalars } => {
3113 for scalar in scalars {
3114 f(scalar);
3115 }
3116 }
3117 CallTable { func: _, exprs } => {
3118 for expr in exprs {
3119 f(expr);
3120 }
3121 }
3122 Filter {
3123 input: _,
3124 predicates,
3125 } => {
3126 for predicate in predicates {
3127 f(predicate);
3128 }
3129 }
3130 Join {
3131 left: _,
3132 right: _,
3133 on,
3134 kind: _,
3135 } => f(on),
3136 Reduce {
3137 input: _,
3138 group_key: _,
3139 aggregates,
3140 expected_group_size: _,
3141 } => {
3142 for aggregate in aggregates {
3143 f(aggregate.expr.as_ref());
3144 }
3145 }
3146 TopK {
3147 input: _,
3148 group_key: _,
3149 order_key: _,
3150 limit,
3151 offset,
3152 expected_group_size: _,
3153 } => {
3154 if let Some(limit) = limit {
3155 f(limit)
3156 }
3157 f(offset)
3158 }
3159 Distinct { input: _ }
3160 | Negate { input: _ }
3161 | Threshold { input: _ }
3162 | Union { base: _, inputs: _ } => (),
3163 }
3164 }
3165
3166 fn visit_mut_children<F>(&mut self, mut f: F)
3167 where
3168 F: FnMut(&mut HirScalarExpr),
3169 {
3170 use HirRelationExpr::*;
3171 match self {
3172 Constant { rows: _, typ: _ }
3173 | Get { id: _, typ: _ }
3174 | Let {
3175 name: _,
3176 id: _,
3177 value: _,
3178 body: _,
3179 }
3180 | LetRec {
3181 limit: _,
3182 bindings: _,
3183 body: _,
3184 }
3185 | Project {
3186 input: _,
3187 outputs: _,
3188 } => (),
3189 Map { input: _, scalars } => {
3190 for scalar in scalars {
3191 f(scalar);
3192 }
3193 }
3194 CallTable { func: _, exprs } => {
3195 for expr in exprs {
3196 f(expr);
3197 }
3198 }
3199 Filter {
3200 input: _,
3201 predicates,
3202 } => {
3203 for predicate in predicates {
3204 f(predicate);
3205 }
3206 }
3207 Join {
3208 left: _,
3209 right: _,
3210 on,
3211 kind: _,
3212 } => f(on),
3213 Reduce {
3214 input: _,
3215 group_key: _,
3216 aggregates,
3217 expected_group_size: _,
3218 } => {
3219 for aggregate in aggregates {
3220 f(aggregate.expr.as_mut());
3221 }
3222 }
3223 TopK {
3224 input: _,
3225 group_key: _,
3226 order_key: _,
3227 limit,
3228 offset,
3229 expected_group_size: _,
3230 } => {
3231 if let Some(limit) = limit {
3232 f(limit)
3233 }
3234 f(offset)
3235 }
3236 Distinct { input: _ }
3237 | Negate { input: _ }
3238 | Threshold { input: _ }
3239 | Union { base: _, inputs: _ } => (),
3240 }
3241 }
3242
3243 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
3244 where
3245 F: FnMut(&HirScalarExpr) -> Result<(), E>,
3246 {
3247 use HirRelationExpr::*;
3248 match self {
3249 Constant { rows: _, typ: _ }
3250 | Get { id: _, typ: _ }
3251 | Let {
3252 name: _,
3253 id: _,
3254 value: _,
3255 body: _,
3256 }
3257 | LetRec {
3258 limit: _,
3259 bindings: _,
3260 body: _,
3261 }
3262 | Project {
3263 input: _,
3264 outputs: _,
3265 } => (),
3266 Map { input: _, scalars } => {
3267 for scalar in scalars {
3268 f(scalar)?;
3269 }
3270 }
3271 CallTable { func: _, exprs } => {
3272 for expr in exprs {
3273 f(expr)?;
3274 }
3275 }
3276 Filter {
3277 input: _,
3278 predicates,
3279 } => {
3280 for predicate in predicates {
3281 f(predicate)?;
3282 }
3283 }
3284 Join {
3285 left: _,
3286 right: _,
3287 on,
3288 kind: _,
3289 } => f(on)?,
3290 Reduce {
3291 input: _,
3292 group_key: _,
3293 aggregates,
3294 expected_group_size: _,
3295 } => {
3296 for aggregate in aggregates {
3297 f(aggregate.expr.as_ref())?;
3298 }
3299 }
3300 TopK {
3301 input: _,
3302 group_key: _,
3303 order_key: _,
3304 limit,
3305 offset,
3306 expected_group_size: _,
3307 } => {
3308 if let Some(limit) = limit {
3309 f(limit)?
3310 }
3311 f(offset)?
3312 }
3313 Distinct { input: _ }
3314 | Negate { input: _ }
3315 | Threshold { input: _ }
3316 | Union { base: _, inputs: _ } => (),
3317 }
3318 Ok(())
3319 }
3320
3321 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
3322 where
3323 F: FnMut(&mut HirScalarExpr) -> Result<(), E>,
3324 {
3325 use HirRelationExpr::*;
3326 match self {
3327 Constant { rows: _, typ: _ }
3328 | Get { id: _, typ: _ }
3329 | Let {
3330 name: _,
3331 id: _,
3332 value: _,
3333 body: _,
3334 }
3335 | LetRec {
3336 limit: _,
3337 bindings: _,
3338 body: _,
3339 }
3340 | Project {
3341 input: _,
3342 outputs: _,
3343 } => (),
3344 Map { input: _, scalars } => {
3345 for scalar in scalars {
3346 f(scalar)?;
3347 }
3348 }
3349 CallTable { func: _, exprs } => {
3350 for expr in exprs {
3351 f(expr)?;
3352 }
3353 }
3354 Filter {
3355 input: _,
3356 predicates,
3357 } => {
3358 for predicate in predicates {
3359 f(predicate)?;
3360 }
3361 }
3362 Join {
3363 left: _,
3364 right: _,
3365 on,
3366 kind: _,
3367 } => f(on)?,
3368 Reduce {
3369 input: _,
3370 group_key: _,
3371 aggregates,
3372 expected_group_size: _,
3373 } => {
3374 for aggregate in aggregates {
3375 f(aggregate.expr.as_mut())?;
3376 }
3377 }
3378 TopK {
3379 input: _,
3380 group_key: _,
3381 order_key: _,
3382 limit,
3383 offset,
3384 expected_group_size: _,
3385 } => {
3386 if let Some(limit) = limit {
3387 f(limit)?
3388 }
3389 f(offset)?
3390 }
3391 Distinct { input: _ }
3392 | Negate { input: _ }
3393 | Threshold { input: _ }
3394 | Union { base: _, inputs: _ } => (),
3395 }
3396 Ok(())
3397 }
3398
3399 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
3400 where
3401 HirScalarExpr: 'a,
3402 {
3403 use HirRelationExpr::*;
3404 match self {
3405 Constant { rows: _, typ: _ }
3406 | Get { id: _, typ: _ }
3407 | Let {
3408 name: _,
3409 id: _,
3410 value: _,
3411 body: _,
3412 }
3413 | LetRec {
3414 limit: _,
3415 bindings: _,
3416 body: _,
3417 }
3418 | Project {
3419 input: _,
3420 outputs: _,
3421 }
3422 | Distinct { input: _ }
3423 | Negate { input: _ }
3424 | Threshold { input: _ }
3425 | Union { base: _, inputs: _ } => vec![],
3426 Map { input: _, scalars }
3427 | CallTable {
3428 func: _,
3429 exprs: scalars,
3430 }
3431 | Filter {
3432 input: _,
3433 predicates: scalars,
3434 } => scalars.iter().collect(),
3435 Join {
3436 left: _,
3437 right: _,
3438 on,
3439 kind: _,
3440 } => vec![on],
3441 Reduce {
3442 input: _,
3443 group_key: _,
3444 aggregates,
3445 expected_group_size: _,
3446 } => aggregates.iter().map(|agg| &*agg.expr).collect(),
3447 TopK {
3448 input: _,
3449 group_key: _,
3450 order_key: _,
3451 limit,
3452 offset,
3453 expected_group_size: _,
3454 } => limit.iter().chain(std::iter::once(offset)).collect(),
3455 }
3456 .into_iter()
3457 }
3458
3459 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
3460 where
3461 HirScalarExpr: 'a,
3462 {
3463 use HirRelationExpr::*;
3464 match self {
3465 Constant { rows: _, typ: _ }
3466 | Get { id: _, typ: _ }
3467 | Let {
3468 name: _,
3469 id: _,
3470 value: _,
3471 body: _,
3472 }
3473 | LetRec {
3474 limit: _,
3475 bindings: _,
3476 body: _,
3477 }
3478 | Project {
3479 input: _,
3480 outputs: _,
3481 }
3482 | Distinct { input: _ }
3483 | Negate { input: _ }
3484 | Threshold { input: _ }
3485 | Union { base: _, inputs: _ } => vec![],
3486 Map { input: _, scalars }
3487 | CallTable {
3488 func: _,
3489 exprs: scalars,
3490 }
3491 | Filter {
3492 input: _,
3493 predicates: scalars,
3494 } => scalars.iter_mut().collect(),
3495 Join {
3496 left: _,
3497 right: _,
3498 on,
3499 kind: _,
3500 } => vec![on],
3501 Reduce {
3502 input: _,
3503 group_key: _,
3504 aggregates,
3505 expected_group_size: _,
3506 } => aggregates.iter_mut().map(|agg| &mut *agg.expr).collect(),
3507 TopK {
3508 input: _,
3509 group_key: _,
3510 order_key: _,
3511 limit,
3512 offset,
3513 expected_group_size: _,
3514 } => limit.iter_mut().chain(std::iter::once(offset)).collect(),
3515 }
3516 .into_iter()
3517 }
3518}
3519
3520impl HirScalarExpr {
3521 pub fn name(&self) -> Option<Arc<str>> {
3522 use HirScalarExpr::*;
3523 match self {
3524 Column(_, name)
3525 | Parameter(_, name)
3526 | Literal(_, _, name)
3527 | CallUnmaterializable(_, name)
3528 | CallUnary { name, .. }
3529 | CallBinary { name, .. }
3530 | CallVariadic { name, .. }
3531 | If { name, .. }
3532 | Exists(_, name)
3533 | Select(_, name)
3534 | Windowing(_, name) => name.0.clone(),
3535 }
3536 }
3537
3538 pub fn visit_direct_subqueries<F>(&self, mut f: F)
3540 where
3541 F: FnMut(&HirRelationExpr),
3542 {
3543 self.visit_post(&mut |e| {
3544 VisitChildren::<HirRelationExpr>::visit_children(e, &mut f);
3545 });
3546 }
3547
3548 pub fn visit_direct_subqueries_mut<F>(&mut self, mut f: F)
3550 where
3551 F: FnMut(&mut HirRelationExpr),
3552 {
3553 self.visit_mut_post(&mut |e| {
3554 VisitChildren::<HirRelationExpr>::visit_mut_children(e, &mut f);
3555 });
3556 }
3557
3558 pub fn try_visit_direct_subqueries<F, E>(&self, mut f: F) -> Result<(), E>
3560 where
3561 F: FnMut(&HirRelationExpr) -> Result<(), E>,
3562 {
3563 self.try_visit_post(&mut |e| {
3564 VisitChildren::<HirRelationExpr>::try_visit_children(e, &mut f)
3565 })
3566 }
3567
3568 pub fn try_visit_direct_subqueries_mut<F, E>(&mut self, mut f: F) -> Result<(), E>
3570 where
3571 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
3572 {
3573 self.try_visit_mut_post(&mut |e| {
3574 VisitChildren::<HirRelationExpr>::try_visit_mut_children(e, &mut f)
3575 })
3576 }
3577
3578 pub fn bind_parameters_and_simplify_offset(
3587 &mut self,
3588 scx: &StatementContext,
3589 lifetime: QueryLifetime,
3590 params: &Params,
3591 ) -> Result<(), PlanError> {
3592 self.try_visit_mut_post(&mut |e: &mut HirScalarExpr| {
3595 if let HirScalarExpr::Parameter(n, name) = e {
3596 let datum = match params.datums.iter().nth(*n - 1) {
3597 None => return Err(PlanError::UnknownParameter(*n)),
3598 Some(datum) => datum,
3599 };
3600 let scalar_type = ¶ms.execute_types[*n - 1];
3601 let row = Row::pack([datum]);
3602 let column_type = scalar_type.clone().nullable(datum.is_null());
3603
3604 let name = if let Some(name) = &name.0 {
3605 Some(Arc::clone(name))
3606 } else {
3607 Some(Arc::from(format!("${n}")))
3608 };
3609
3610 let qcx = QueryContext::root(scx, lifetime);
3611 let ecx = execute_expr_context(&qcx);
3612
3613 *e = plan_cast(
3614 &ecx,
3615 *EXECUTE_CAST_CONTEXT,
3616 HirScalarExpr::Literal(row, column_type, TreatAsEqual(name)),
3617 ¶ms.expected_types[*n - 1],
3618 )
3619 .expect("checked in plan_params");
3620 }
3621 Ok(())
3622 })?;
3623 self.try_visit_direct_subqueries_mut(|r: &mut HirRelationExpr| {
3626 r.bind_parameters_and_simplify_offset(scx, lifetime, params)
3627 })
3628 }
3629
3630 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
3641 #[allow(deprecated)]
3642 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3643 e: &mut HirScalarExpr|
3644 -> Result<(), ()> {
3645 if let HirScalarExpr::Parameter(i, _name) = e {
3646 *e = params[*i - 1].clone();
3647 e.visit_columns_mut(0, &mut |d: usize, col: &mut ColumnRef| {
3650 if col.level >= d {
3651 col.level += depth
3652 }
3653 });
3654 }
3655 Ok(())
3656 });
3657 }
3658
3659 pub fn contains_temporal(&self) -> bool {
3661 let mut contains = false;
3662 self.visit_post(&mut |e| {
3663 if let Self::CallUnmaterializable(UnmaterializableFunc::MzNow, _name) = e {
3664 contains = true;
3665 }
3666 });
3667 contains
3668 }
3669
3670 pub fn contains_unmaterializable(&self) -> bool {
3672 let mut contains = false;
3673 self.visit_post(&mut |e| {
3674 if let Self::CallUnmaterializable(_, _) = e {
3675 contains = true;
3676 }
3677 });
3678 contains
3679 }
3680
3681 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
3684 let mut contains = false;
3685 self.visit_post(&mut |e| {
3686 if let Self::CallUnmaterializable(f, _) = e {
3687 if *f != UnmaterializableFunc::MzNow {
3688 contains = true;
3689 }
3690 }
3691 });
3692 contains
3693 }
3694
3695 pub fn column(index: usize) -> HirScalarExpr {
3699 HirScalarExpr::Column(
3700 ColumnRef {
3701 level: 0,
3702 column: index,
3703 },
3704 TreatAsEqual(None),
3705 )
3706 }
3707
3708 pub fn unnamed_column(cr: ColumnRef) -> HirScalarExpr {
3710 HirScalarExpr::Column(cr, TreatAsEqual(None))
3711 }
3712
3713 pub fn named_column(cr: ColumnRef, name: Arc<str>) -> HirScalarExpr {
3716 HirScalarExpr::Column(cr, TreatAsEqual(Some(name)))
3717 }
3718
3719 pub fn parameter(n: usize) -> HirScalarExpr {
3720 HirScalarExpr::Parameter(n, TreatAsEqual(None))
3721 }
3722
3723 pub fn literal(datum: Datum, scalar_type: SqlScalarType) -> HirScalarExpr {
3724 let col_type = scalar_type.nullable(datum.is_null());
3725 soft_assert_or_log!(datum.is_instance_of_sql(&col_type), "type is correct");
3726 let row = Row::pack([datum]);
3727 HirScalarExpr::Literal(row, col_type, TreatAsEqual(None))
3728 }
3729
3730 pub fn literal_true() -> HirScalarExpr {
3731 HirScalarExpr::literal(Datum::True, SqlScalarType::Bool)
3732 }
3733
3734 pub fn literal_false() -> HirScalarExpr {
3735 HirScalarExpr::literal(Datum::False, SqlScalarType::Bool)
3736 }
3737
3738 pub fn literal_null(scalar_type: SqlScalarType) -> HirScalarExpr {
3739 HirScalarExpr::literal(Datum::Null, scalar_type)
3740 }
3741
3742 pub fn literal_1d_array(
3743 datums: Vec<Datum>,
3744 element_scalar_type: SqlScalarType,
3745 ) -> Result<HirScalarExpr, PlanError> {
3746 let scalar_type = match element_scalar_type {
3747 SqlScalarType::Array(_) => {
3748 sql_bail!("cannot build array from array type");
3749 }
3750 typ => SqlScalarType::Array(Box::new(typ)).nullable(false),
3751 };
3752
3753 let mut row = Row::default();
3754 row.packer()
3755 .try_push_array(
3756 &[ArrayDimension {
3757 lower_bound: 1,
3758 length: datums.len(),
3759 }],
3760 datums,
3761 )
3762 .expect("array constructed to be valid");
3763
3764 Ok(HirScalarExpr::Literal(row, scalar_type, TreatAsEqual(None)))
3765 }
3766
3767 pub fn as_literal(&self) -> Option<Datum<'_>> {
3768 if let HirScalarExpr::Literal(row, _column_type, _name) = self {
3769 Some(row.unpack_first())
3770 } else {
3771 None
3772 }
3773 }
3774
3775 pub fn is_literal_true(&self) -> bool {
3776 Some(Datum::True) == self.as_literal()
3777 }
3778
3779 pub fn is_literal_false(&self) -> bool {
3780 Some(Datum::False) == self.as_literal()
3781 }
3782
3783 pub fn is_literal_null(&self) -> bool {
3784 Some(Datum::Null) == self.as_literal()
3785 }
3786
3787 pub fn is_constant(&self) -> bool {
3790 let mut worklist = vec![self];
3791 while let Some(expr) = worklist.pop() {
3792 match expr {
3793 Self::Literal(..) => {
3794 }
3796 Self::CallUnary { expr, .. } => {
3797 worklist.push(expr);
3798 }
3799 Self::CallBinary {
3800 func: _,
3801 expr1,
3802 expr2,
3803 name: _,
3804 } => {
3805 worklist.push(expr1);
3806 worklist.push(expr2);
3807 }
3808 Self::CallVariadic {
3809 func: _,
3810 exprs,
3811 name: _,
3812 } => {
3813 worklist.extend(exprs.iter());
3814 }
3815 Self::If {
3817 cond,
3818 then,
3819 els,
3820 name: _,
3821 } => {
3822 worklist.push(cond);
3823 worklist.push(then);
3824 worklist.push(els);
3825 }
3826 _ => {
3827 return false; }
3829 }
3830 }
3831 true
3832 }
3833
3834 pub fn call_unary(self, func: UnaryFunc) -> Self {
3835 HirScalarExpr::CallUnary {
3836 func,
3837 expr: Box::new(self),
3838 name: NameMetadata::default(),
3839 }
3840 }
3841
3842 pub fn call_binary<B: Into<BinaryFunc>>(self, other: Self, func: B) -> Self {
3843 HirScalarExpr::CallBinary {
3844 func: func.into(),
3845 expr1: Box::new(self),
3846 expr2: Box::new(other),
3847 name: NameMetadata::default(),
3848 }
3849 }
3850
3851 pub fn call_unmaterializable(func: UnmaterializableFunc) -> Self {
3852 HirScalarExpr::CallUnmaterializable(func, NameMetadata::default())
3853 }
3854
3855 pub fn call_variadic<V: Into<VariadicFunc>>(func: V, exprs: Vec<Self>) -> Self {
3856 HirScalarExpr::CallVariadic {
3857 func: func.into(),
3858 exprs,
3859 name: NameMetadata::default(),
3860 }
3861 }
3862
3863 pub fn if_then_else(cond: Self, then: Self, els: Self) -> Self {
3864 HirScalarExpr::If {
3865 cond: Box::new(cond),
3866 then: Box::new(then),
3867 els: Box::new(els),
3868 name: NameMetadata::default(),
3869 }
3870 }
3871
3872 pub fn windowing(expr: WindowExpr) -> Self {
3873 HirScalarExpr::Windowing(expr, TreatAsEqual(None))
3874 }
3875
3876 pub fn or(self, other: Self) -> Self {
3877 HirScalarExpr::call_variadic(Or, vec![self, other])
3878 }
3879
3880 pub fn and(self, other: Self) -> Self {
3881 HirScalarExpr::call_variadic(And, vec![self, other])
3882 }
3883
3884 pub fn not(self) -> Self {
3885 self.call_unary(UnaryFunc::Not(func::Not))
3886 }
3887
3888 pub fn call_is_null(self) -> Self {
3889 self.call_unary(UnaryFunc::IsNull(func::IsNull))
3890 }
3891
3892 pub fn variadic_and(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3894 match args.len() {
3895 0 => HirScalarExpr::literal_true(), 1 => args.swap_remove(0),
3897 _ => HirScalarExpr::call_variadic(And, args),
3898 }
3899 }
3900
3901 pub fn variadic_or(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3903 match args.len() {
3904 0 => HirScalarExpr::literal_false(), 1 => args.swap_remove(0),
3906 _ => HirScalarExpr::call_variadic(Or, args),
3907 }
3908 }
3909
3910 pub fn take(&mut self) -> Self {
3911 mem::replace(self, HirScalarExpr::literal_null(SqlScalarType::String))
3912 }
3913
3914 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3915 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
3921 where
3922 F: FnMut(usize, &ColumnRef),
3923 {
3924 #[allow(deprecated)]
3925 let _ = self.visit_recursively(depth, &mut |depth: usize,
3926 e: &HirScalarExpr|
3927 -> Result<(), ()> {
3928 if let HirScalarExpr::Column(col, _name) = e {
3929 f(depth, col)
3930 }
3931 Ok(())
3932 });
3933 }
3934
3935 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3936 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
3938 where
3939 F: FnMut(usize, &mut ColumnRef),
3940 {
3941 #[allow(deprecated)]
3942 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3943 e: &mut HirScalarExpr|
3944 -> Result<(), ()> {
3945 if let HirScalarExpr::Column(col, _name) = e {
3946 f(depth, col)
3947 }
3948 Ok(())
3949 });
3950 }
3951
3952 pub fn visit_columns_referring_to_root_level<F>(&self, f: &mut F)
3958 where
3959 F: FnMut(usize),
3960 {
3961 #[allow(deprecated)]
3962 let _ = self.visit_recursively(0, &mut |depth: usize,
3963 e: &HirScalarExpr|
3964 -> Result<(), ()> {
3965 if let HirScalarExpr::Column(col, _name) = e {
3966 if col.level == depth {
3967 f(col.column)
3968 }
3969 }
3970 Ok(())
3971 });
3972 }
3973
3974 pub fn visit_columns_referring_to_root_level_mut<F>(&mut self, f: &mut F)
3976 where
3977 F: FnMut(&mut usize),
3978 {
3979 #[allow(deprecated)]
3980 let _ = self.visit_recursively_mut(0, &mut |depth: usize,
3981 e: &mut HirScalarExpr|
3982 -> Result<(), ()> {
3983 if let HirScalarExpr::Column(col, _name) = e {
3984 if col.level == depth {
3985 f(&mut col.column)
3986 }
3987 }
3988 Ok(())
3989 });
3990 }
3991
3992 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3993 pub fn visit_recursively<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
3997 where
3998 F: FnMut(usize, &HirScalarExpr) -> Result<(), E>,
3999 {
4000 match self {
4001 HirScalarExpr::Literal(..)
4002 | HirScalarExpr::Parameter(..)
4003 | HirScalarExpr::CallUnmaterializable(..)
4004 | HirScalarExpr::Column(..) => (),
4005 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively(depth, f)?,
4006 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
4007 expr1.visit_recursively(depth, f)?;
4008 expr2.visit_recursively(depth, f)?;
4009 }
4010 HirScalarExpr::CallVariadic { exprs, .. } => {
4011 for expr in exprs {
4012 expr.visit_recursively(depth, f)?;
4013 }
4014 }
4015 HirScalarExpr::If {
4016 cond,
4017 then,
4018 els,
4019 name: _,
4020 } => {
4021 cond.visit_recursively(depth, f)?;
4022 then.visit_recursively(depth, f)?;
4023 els.visit_recursively(depth, f)?;
4024 }
4025 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4026 #[allow(deprecated)]
4027 expr.visit_scalar_expressions(depth + 1, &mut |e, depth| {
4028 e.visit_recursively(depth, f)
4029 })?;
4030 }
4031 HirScalarExpr::Windowing(expr, _name) => {
4032 expr.visit_expressions(&mut |e| e.visit_recursively(depth, f))?;
4033 }
4034 }
4035 f(depth, self)
4036 }
4037
4038 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
4039 pub fn visit_recursively_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
4041 where
4042 F: FnMut(usize, &mut HirScalarExpr) -> Result<(), E>,
4043 {
4044 match self {
4045 HirScalarExpr::Literal(..)
4046 | HirScalarExpr::Parameter(..)
4047 | HirScalarExpr::CallUnmaterializable(..)
4048 | HirScalarExpr::Column(..) => (),
4049 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively_mut(depth, f)?,
4050 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
4051 expr1.visit_recursively_mut(depth, f)?;
4052 expr2.visit_recursively_mut(depth, f)?;
4053 }
4054 HirScalarExpr::CallVariadic { exprs, .. } => {
4055 for expr in exprs {
4056 expr.visit_recursively_mut(depth, f)?;
4057 }
4058 }
4059 HirScalarExpr::If {
4060 cond,
4061 then,
4062 els,
4063 name: _,
4064 } => {
4065 cond.visit_recursively_mut(depth, f)?;
4066 then.visit_recursively_mut(depth, f)?;
4067 els.visit_recursively_mut(depth, f)?;
4068 }
4069 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4070 #[allow(deprecated)]
4071 expr.visit_scalar_expressions_mut(depth + 1, &mut |e, depth| {
4072 e.visit_recursively_mut(depth, f)
4073 })?;
4074 }
4075 HirScalarExpr::Windowing(expr, _name) => {
4076 expr.visit_expressions_mut(&mut |e| e.visit_recursively_mut(depth, f))?;
4077 }
4078 }
4079 f(depth, self)
4080 }
4081
4082 fn simplify_to_literal(self) -> Option<Row> {
4091 let mut expr = self
4092 .lower_uncorrelated(crate::plan::lowering::Config::default())
4093 .ok()?;
4094 expr.reduce(&[]);
4098 match expr {
4099 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Some(row),
4100 _ => None,
4101 }
4102 }
4103
4104 fn simplify_to_literal_with_result(self) -> Result<Row, PlanError> {
4117 let mut expr = self
4118 .lower_uncorrelated(crate::plan::lowering::Config::default())
4119 .map_err(|err| {
4120 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes())
4121 })?;
4122 expr.reduce(&[]);
4126 match expr {
4127 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Ok(row),
4128 mz_expr::MirScalarExpr::Literal(Err(err), _) => Err(
4129 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes()),
4130 ),
4131 _ => Err(PlanError::ConstantExpressionSimplificationFailed(
4132 "Not a constant".to_string(),
4133 )),
4134 }
4135 }
4136
4137 pub fn into_literal_int64(self) -> Option<i64> {
4146 self.simplify_to_literal().and_then(|row| {
4147 let datum = row.unpack_first();
4148 if datum.is_null() {
4149 None
4150 } else {
4151 Some(datum.unwrap_int64())
4152 }
4153 })
4154 }
4155
4156 pub fn into_literal_string(self) -> Option<String> {
4165 self.simplify_to_literal().and_then(|row| {
4166 let datum = row.unpack_first();
4167 if datum.is_null() {
4168 None
4169 } else {
4170 Some(datum.unwrap_str().to_owned())
4171 }
4172 })
4173 }
4174
4175 pub fn into_literal_mz_timestamp(self) -> Option<Timestamp> {
4188 self.simplify_to_literal().and_then(|row| {
4189 let datum = row.unpack_first();
4190 if datum.is_null() {
4191 None
4192 } else {
4193 Some(datum.unwrap_mz_timestamp())
4194 }
4195 })
4196 }
4197
4198 pub fn try_into_literal_int64(self) -> Result<i64, PlanError> {
4210 match self.clone().try_into_nullable_literal_int64()? {
4211 Some(value) => Ok(value),
4212 None => Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4213 "Expected an expression that evaluates to a non-null value, got {}",
4214 self
4215 ))),
4216 }
4217 }
4218
4219 pub fn try_into_nullable_literal_int64(self) -> Result<Option<i64>, PlanError> {
4222 if !self.is_constant() {
4228 return Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4229 "Expected a constant expression, got {}",
4230 self
4231 )));
4232 }
4233 self.simplify_to_literal_with_result().map(|row| {
4234 let datum = row.unpack_first();
4235 if datum.is_null() {
4236 None
4237 } else {
4238 Some(datum.unwrap_int64())
4239 }
4240 })
4241 }
4242
4243 pub fn contains_parameters(&self) -> bool {
4244 let mut contains_parameters = false;
4245 #[allow(deprecated)]
4246 let _ = self.visit_recursively(0, &mut |_depth: usize,
4247 expr: &HirScalarExpr|
4248 -> Result<(), ()> {
4249 if let HirScalarExpr::Parameter(..) = expr {
4250 contains_parameters = true;
4251 }
4252 Ok(())
4253 });
4254 contains_parameters
4255 }
4256
4257 fn direct_subqueries(&self) -> Vec<&HirRelationExpr> {
4258 let mut subqueries: Vec<&HirRelationExpr> = vec![];
4259
4260 let mut worklist = vec![self];
4261 while let Some(elt) = worklist.pop() {
4262 match elt {
4263 HirScalarExpr::Column(_, _)
4264 | HirScalarExpr::Parameter(_, _)
4265 | HirScalarExpr::Literal(_, _, _)
4266 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4267 HirScalarExpr::CallUnary {
4268 func: _,
4269 expr,
4270 name: _,
4271 } => worklist.push(&*expr),
4272 HirScalarExpr::CallBinary {
4273 func: _,
4274 expr1,
4275 expr2,
4276 name: _name,
4277 } => {
4278 worklist.push(&*expr2);
4280 worklist.push(&*expr1);
4281 }
4282 HirScalarExpr::CallVariadic {
4283 func: _,
4284 exprs,
4285 name: _name,
4286 } => {
4287 worklist.extend(exprs.iter().rev());
4288 }
4289 HirScalarExpr::If {
4290 cond,
4291 then,
4292 els,
4293 name: _,
4294 } => {
4295 worklist.push(&*els);
4296 worklist.push(&*then);
4297 worklist.push(&*cond);
4298 }
4299 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4300 subqueries.push(&*hir);
4301 }
4302 HirScalarExpr::Windowing(
4303 WindowExpr {
4304 func,
4305 partition_by,
4306 order_by,
4307 },
4308 _,
4309 ) => {
4310 worklist.extend(order_by.iter().rev());
4313 worklist.extend(partition_by.iter().rev());
4314 match func {
4315 WindowExprType::Scalar(_) => (),
4316 WindowExprType::Value(val) => worklist.push(&*val.args),
4317 WindowExprType::Aggregate(agg) => worklist.push(&*agg.aggregate_expr.expr),
4318 }
4319 }
4320 }
4321 }
4322
4323 subqueries
4324 }
4325
4326 fn direct_subqueries_mut(&mut self) -> Vec<&mut HirRelationExpr> {
4327 let mut subqueries: Vec<&mut HirRelationExpr> = vec![];
4328
4329 let mut worklist = vec![self];
4330 while let Some(elt) = worklist.pop() {
4331 match elt {
4332 HirScalarExpr::Column(_, _)
4333 | HirScalarExpr::Parameter(_, _)
4334 | HirScalarExpr::Literal(_, _, _)
4335 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4336 HirScalarExpr::CallUnary {
4337 func: _,
4338 expr,
4339 name: _,
4340 } => worklist.push(&mut **expr),
4341 HirScalarExpr::CallBinary {
4342 func: _,
4343 expr1,
4344 expr2,
4345 name: _name,
4346 } => {
4347 worklist.push(&mut **expr2);
4349 worklist.push(&mut **expr1);
4350 }
4351 HirScalarExpr::CallVariadic {
4352 func: _,
4353 exprs,
4354 name: _name,
4355 } => {
4356 worklist.extend(exprs.iter_mut().rev());
4357 }
4358 HirScalarExpr::If {
4359 cond,
4360 then,
4361 els,
4362 name: _,
4363 } => {
4364 worklist.push(&mut **els);
4365 worklist.push(&mut **then);
4366 worklist.push(&mut **cond);
4367 }
4368 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4369 subqueries.push(&mut **hir);
4370 }
4371 HirScalarExpr::Windowing(
4372 WindowExpr {
4373 func,
4374 partition_by,
4375 order_by,
4376 },
4377 _,
4378 ) => {
4379 worklist.extend(order_by.iter_mut().rev());
4382 worklist.extend(partition_by.iter_mut().rev());
4383 match func {
4384 WindowExprType::Scalar(_) => (),
4385 WindowExprType::Value(val) => worklist.push(&mut val.args),
4386 WindowExprType::Aggregate(agg) => {
4387 worklist.push(&mut agg.aggregate_expr.expr)
4388 }
4389 }
4390 }
4391 }
4392 }
4393
4394 subqueries
4395 }
4396}
4397
4398impl VisitChildren<Self> for HirScalarExpr {
4404 fn visit_children<F>(&self, mut f: F)
4405 where
4406 F: FnMut(&Self),
4407 {
4408 use HirScalarExpr::*;
4409 match self {
4410 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4411 CallUnary { expr, .. } => f(expr),
4412 CallBinary { expr1, expr2, .. } => {
4413 f(expr1);
4414 f(expr2);
4415 }
4416 CallVariadic { exprs, .. } => {
4417 for expr in exprs {
4418 f(expr);
4419 }
4420 }
4421 If {
4422 cond,
4423 then,
4424 els,
4425 name: _,
4426 } => {
4427 f(cond);
4428 f(then);
4429 f(els);
4430 }
4431 Exists(..) | Select(..) => (),
4432 Windowing(expr, _name) => expr.visit_children(f),
4433 }
4434 }
4435
4436 fn visit_mut_children<F>(&mut self, mut f: F)
4437 where
4438 F: FnMut(&mut Self),
4439 {
4440 use HirScalarExpr::*;
4441 match self {
4442 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4443 CallUnary { expr, .. } => f(expr),
4444 CallBinary { expr1, expr2, .. } => {
4445 f(expr1);
4446 f(expr2);
4447 }
4448 CallVariadic { exprs, .. } => {
4449 for expr in exprs {
4450 f(expr);
4451 }
4452 }
4453 If {
4454 cond,
4455 then,
4456 els,
4457 name: _,
4458 } => {
4459 f(cond);
4460 f(then);
4461 f(els);
4462 }
4463 Exists(..) | Select(..) => (),
4464 Windowing(expr, _name) => expr.visit_mut_children(f),
4465 }
4466 }
4467
4468 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4469 where
4470 F: FnMut(&Self) -> Result<(), E>,
4471 {
4472 use HirScalarExpr::*;
4473 match self {
4474 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4475 CallUnary { expr, .. } => f(expr)?,
4476 CallBinary { expr1, expr2, .. } => {
4477 f(expr1)?;
4478 f(expr2)?;
4479 }
4480 CallVariadic { exprs, .. } => {
4481 for expr in exprs {
4482 f(expr)?;
4483 }
4484 }
4485 If {
4486 cond,
4487 then,
4488 els,
4489 name: _,
4490 } => {
4491 f(cond)?;
4492 f(then)?;
4493 f(els)?;
4494 }
4495 Exists(..) | Select(..) => (),
4496 Windowing(expr, _name) => expr.try_visit_children(f)?,
4497 }
4498 Ok(())
4499 }
4500
4501 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4502 where
4503 F: FnMut(&mut Self) -> Result<(), E>,
4504 {
4505 use HirScalarExpr::*;
4506 match self {
4507 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4508 CallUnary { expr, .. } => f(expr)?,
4509 CallBinary { expr1, expr2, .. } => {
4510 f(expr1)?;
4511 f(expr2)?;
4512 }
4513 CallVariadic { exprs, .. } => {
4514 for expr in exprs {
4515 f(expr)?;
4516 }
4517 }
4518 If {
4519 cond,
4520 then,
4521 els,
4522 name: _,
4523 } => {
4524 f(cond)?;
4525 f(then)?;
4526 f(els)?;
4527 }
4528 Exists(..) | Select(..) => (),
4529 Windowing(expr, _name) => expr.try_visit_mut_children(f)?,
4530 }
4531 Ok(())
4532 }
4533
4534 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
4535 where
4536 Self: 'a,
4537 {
4538 use HirScalarExpr::*;
4539 let v: Vec<&Self> = match self {
4540 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4541 CallUnary { expr, .. } => vec![&*expr],
4542 CallBinary { expr1, expr2, .. } => {
4543 vec![&*expr1, &*expr2]
4544 }
4545 CallVariadic { exprs, .. } => exprs.iter().collect(),
4546 If {
4547 cond,
4548 then,
4549 els,
4550 name: _,
4551 } => {
4552 vec![&*cond, &*then, &*els]
4553 }
4554 Exists(..) | Select(..) => vec![],
4555 Windowing(expr, _name) => expr.children().collect(),
4556 };
4557 v.into_iter()
4558 }
4559
4560 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
4561 where
4562 Self: 'a,
4563 {
4564 use HirScalarExpr::*;
4565 let v: Vec<&mut Self> = match self {
4566 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4567 CallUnary { expr, .. } => vec![&mut **expr],
4568 CallBinary { expr1, expr2, .. } => {
4569 vec![&mut **expr1, &mut **expr2]
4570 }
4571 CallVariadic { exprs, .. } => exprs.iter_mut().collect(),
4572 If {
4573 cond,
4574 then,
4575 els,
4576 name: _,
4577 } => {
4578 vec![&mut **cond, &mut **then, &mut **els]
4579 }
4580 Exists(..) | Select(..) => vec![],
4581 Windowing(expr, _name) => expr.children_mut().collect(),
4582 };
4583 v.into_iter()
4584 }
4585}
4586
4587impl VisitChildren<HirRelationExpr> for HirScalarExpr {
4590 fn visit_children<F>(&self, mut f: F)
4591 where
4592 F: FnMut(&HirRelationExpr),
4593 {
4594 use HirScalarExpr::*;
4595 match self {
4596 Column(..)
4597 | Parameter(..)
4598 | Literal(..)
4599 | CallUnmaterializable(..)
4600 | CallUnary { .. }
4601 | CallBinary { .. }
4602 | CallVariadic { .. }
4603 | If { .. }
4604 | Windowing(..) => (),
4605 Exists(expr, _name) | Select(expr, _name) => f(expr),
4606 }
4607 }
4608
4609 fn visit_mut_children<F>(&mut self, mut f: F)
4610 where
4611 F: FnMut(&mut HirRelationExpr),
4612 {
4613 use HirScalarExpr::*;
4614 match self {
4615 Column(..)
4616 | Parameter(..)
4617 | Literal(..)
4618 | CallUnmaterializable(..)
4619 | CallUnary { .. }
4620 | CallBinary { .. }
4621 | CallVariadic { .. }
4622 | If { .. }
4623 | Windowing(..) => (),
4624 Exists(expr, _name) | Select(expr, _name) => f(expr),
4625 }
4626 }
4627
4628 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4629 where
4630 F: FnMut(&HirRelationExpr) -> Result<(), E>,
4631 {
4632 use HirScalarExpr::*;
4633 match self {
4634 Column(..)
4635 | Parameter(..)
4636 | Literal(..)
4637 | CallUnmaterializable(..)
4638 | CallUnary { .. }
4639 | CallBinary { .. }
4640 | CallVariadic { .. }
4641 | If { .. }
4642 | Windowing(..) => (),
4643 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4644 }
4645 Ok(())
4646 }
4647
4648 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4649 where
4650 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
4651 {
4652 use HirScalarExpr::*;
4653 match self {
4654 Column(..)
4655 | Parameter(..)
4656 | Literal(..)
4657 | CallUnmaterializable(..)
4658 | CallUnary { .. }
4659 | CallBinary { .. }
4660 | CallVariadic { .. }
4661 | If { .. }
4662 | Windowing(..) => (),
4663 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4664 }
4665 Ok(())
4666 }
4667
4668 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirRelationExpr>
4669 where
4670 HirRelationExpr: 'a,
4671 {
4672 let mut child: Option<&HirRelationExpr> = None;
4673 use HirScalarExpr::*;
4674 match self {
4675 Column(..)
4676 | Parameter(..)
4677 | Literal(..)
4678 | CallUnmaterializable(..)
4679 | CallUnary { .. }
4680 | CallBinary { .. }
4681 | CallVariadic { .. }
4682 | If { .. }
4683 | Windowing(..) => (),
4684 Exists(expr, _name) | Select(expr, _name) => child = Some(&*expr),
4685 }
4686
4687 child.into_iter()
4688 }
4689
4690 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirRelationExpr>
4691 where
4692 HirRelationExpr: 'a,
4693 {
4694 let mut child: Option<&mut HirRelationExpr> = None;
4695 use HirScalarExpr::*;
4696 match self {
4697 Column(..)
4698 | Parameter(..)
4699 | Literal(..)
4700 | CallUnmaterializable(..)
4701 | CallUnary { .. }
4702 | CallBinary { .. }
4703 | CallVariadic { .. }
4704 | If { .. }
4705 | Windowing(..) => (),
4706 Exists(expr, _name) | Select(expr, _name) => child = Some(&mut **expr),
4707 }
4708
4709 child.into_iter()
4710 }
4711}
4712
4713impl AbstractExpr for HirScalarExpr {
4714 type Type = SqlColumnType;
4715
4716 fn typ(
4717 &self,
4718 outers: &[SqlRelationType],
4719 inner: &SqlRelationType,
4720 params: &BTreeMap<usize, SqlScalarType>,
4721 ) -> Self::Type {
4722 stack::maybe_grow(|| match self {
4723 HirScalarExpr::Column(ColumnRef { level, column }, _name) => {
4724 if *level == 0 {
4725 inner.column_types[*column].clone()
4726 } else {
4727 outers[*level - 1].column_types[*column].clone()
4728 }
4729 }
4730 HirScalarExpr::Parameter(n, _name) => params[n].clone().nullable(true),
4731 HirScalarExpr::Literal(_, typ, _name) => typ.clone(),
4732 HirScalarExpr::CallUnmaterializable(func, _name) => func.output_sql_type(),
4733 HirScalarExpr::CallUnary {
4734 expr,
4735 func,
4736 name: _,
4737 } => func.output_sql_type(expr.typ(outers, inner, params)),
4738 HirScalarExpr::CallBinary {
4739 expr1,
4740 expr2,
4741 func,
4742 name: _,
4743 } => func.output_sql_type(&[
4744 expr1.typ(outers, inner, params),
4745 expr2.typ(outers, inner, params),
4746 ]),
4747 HirScalarExpr::CallVariadic {
4748 exprs,
4749 func,
4750 name: _,
4751 } => func.output_sql_type(exprs.iter().map(|e| e.typ(outers, inner, params)).collect()),
4752 HirScalarExpr::If {
4753 cond: _,
4754 then,
4755 els,
4756 name: _,
4757 } => {
4758 let then_type = then.typ(outers, inner, params);
4759 let else_type = els.typ(outers, inner, params);
4760 then_type.sql_union(&else_type).unwrap() }
4762 HirScalarExpr::Exists(_, _name) => SqlScalarType::Bool.nullable(true),
4763 HirScalarExpr::Select(expr, _name) => {
4764 let mut outers = outers.to_vec();
4765 outers.insert(0, inner.clone());
4766 expr.typ(&outers, params)
4767 .column_types
4768 .into_element()
4769 .nullable(true)
4770 }
4771 HirScalarExpr::Windowing(expr, _name) => expr.func.typ(outers, inner, params),
4772 })
4773 }
4774}
4775
4776impl AggregateExpr {
4777 pub fn typ(
4778 &self,
4779 outers: &[SqlRelationType],
4780 inner: &SqlRelationType,
4781 params: &BTreeMap<usize, SqlScalarType>,
4782 ) -> SqlColumnType {
4783 self.func
4784 .output_sql_type(self.expr.typ(outers, inner, params))
4785 }
4786
4787 pub fn is_count_asterisk(&self) -> bool {
4795 self.func == AggregateFunc::Count && self.expr.is_literal_true() && !self.distinct
4796 }
4797}