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 self.visit1(depth, |e: &HirRelationExpr, depth: usize| {
2012 e.visit_fallible(depth, f)
2013 })?;
2014 f(self, depth)
2015 }
2016
2017 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_children` instead."]
2022 pub fn visit1<'a, F, E>(&'a self, depth: usize, mut f: F) -> Result<(), E>
2023 where
2024 F: FnMut(&'a Self, usize) -> Result<(), E>,
2025 {
2026 match self {
2027 HirRelationExpr::Constant { .. }
2028 | HirRelationExpr::Get { .. }
2029 | HirRelationExpr::CallTable { .. } => (),
2030 HirRelationExpr::Let { body, value, .. } => {
2031 f(value, depth)?;
2032 f(body, depth)?;
2033 }
2034 HirRelationExpr::LetRec {
2035 limit: _,
2036 bindings,
2037 body,
2038 } => {
2039 for (_, _, value, _) in bindings.iter() {
2040 f(value, depth)?;
2041 }
2042 f(body, depth)?;
2043 }
2044 HirRelationExpr::Project { input, .. } => {
2045 f(input, depth)?;
2046 }
2047 HirRelationExpr::Map { input, .. } => {
2048 f(input, depth)?;
2049 }
2050 HirRelationExpr::Filter { input, .. } => {
2051 f(input, depth)?;
2052 }
2053 HirRelationExpr::Join { left, right, .. } => {
2054 f(left, depth)?;
2055 f(right, depth + 1)?;
2056 }
2057 HirRelationExpr::Reduce { input, .. } => {
2058 f(input, depth)?;
2059 }
2060 HirRelationExpr::Distinct { input } => {
2061 f(input, depth)?;
2062 }
2063 HirRelationExpr::TopK { input, .. } => {
2064 f(input, depth)?;
2065 }
2066 HirRelationExpr::Negate { input } => {
2067 f(input, depth)?;
2068 }
2069 HirRelationExpr::Threshold { input } => {
2070 f(input, depth)?;
2071 }
2072 HirRelationExpr::Union { base, inputs } => {
2073 f(base, depth)?;
2074 for input in inputs {
2075 f(input, depth)?;
2076 }
2077 }
2078 }
2079 Ok(())
2080 }
2081
2082 #[deprecated = "Use `Visit::visit_mut_post` instead."]
2083 pub fn visit_mut<F>(&mut self, depth: usize, f: &mut F)
2084 where
2085 F: FnMut(&mut Self, usize),
2086 {
2087 #[allow(deprecated)]
2088 let _ = self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2089 depth: usize|
2090 -> Result<(), ()> {
2091 f(e, depth);
2092 Ok(())
2093 });
2094 }
2095
2096 #[deprecated = "Use `Visit::try_visit_mut_post` instead."]
2097 pub fn visit_mut_fallible<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2098 where
2099 F: FnMut(&mut Self, usize) -> Result<(), E>,
2100 {
2101 #[allow(deprecated)]
2102 self.visit1_mut(depth, |e: &mut HirRelationExpr, depth: usize| {
2103 e.visit_mut_fallible(depth, f)
2104 })?;
2105 f(self, depth)
2106 }
2107
2108 #[deprecated = "Use `VisitChildren<HirRelationExpr>::try_visit_mut_children` instead."]
2113 pub fn visit1_mut<'a, F, E>(&'a mut self, depth: usize, mut f: F) -> Result<(), E>
2114 where
2115 F: FnMut(&'a mut Self, usize) -> Result<(), E>,
2116 {
2117 match self {
2118 HirRelationExpr::Constant { .. }
2119 | HirRelationExpr::Get { .. }
2120 | HirRelationExpr::CallTable { .. } => (),
2121 HirRelationExpr::Let { body, value, .. } => {
2122 f(value, depth)?;
2123 f(body, depth)?;
2124 }
2125 HirRelationExpr::LetRec {
2126 limit: _,
2127 bindings,
2128 body,
2129 } => {
2130 for (_, _, value, _) in bindings.iter_mut() {
2131 f(value, depth)?;
2132 }
2133 f(body, depth)?;
2134 }
2135 HirRelationExpr::Project { input, .. } => {
2136 f(input, depth)?;
2137 }
2138 HirRelationExpr::Map { input, .. } => {
2139 f(input, depth)?;
2140 }
2141 HirRelationExpr::Filter { input, .. } => {
2142 f(input, depth)?;
2143 }
2144 HirRelationExpr::Join { left, right, .. } => {
2145 f(left, depth)?;
2146 f(right, depth + 1)?;
2147 }
2148 HirRelationExpr::Reduce { input, .. } => {
2149 f(input, depth)?;
2150 }
2151 HirRelationExpr::Distinct { input } => {
2152 f(input, depth)?;
2153 }
2154 HirRelationExpr::TopK { input, .. } => {
2155 f(input, depth)?;
2156 }
2157 HirRelationExpr::Negate { input } => {
2158 f(input, depth)?;
2159 }
2160 HirRelationExpr::Threshold { input } => {
2161 f(input, depth)?;
2162 }
2163 HirRelationExpr::Union { base, inputs } => {
2164 f(base, depth)?;
2165 for input in inputs {
2166 f(input, depth)?;
2167 }
2168 }
2169 }
2170 Ok(())
2171 }
2172
2173 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2174 pub fn visit_scalar_expressions<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
2186 where
2187 F: FnMut(&HirScalarExpr, usize) -> Result<(), E>,
2188 {
2189 #[allow(deprecated)]
2190 self.visit_fallible(depth, &mut |e: &HirRelationExpr,
2191 depth: usize|
2192 -> Result<(), E> {
2193 match e {
2194 HirRelationExpr::Join { on, .. } => {
2195 f(on, depth)?;
2196 }
2197 HirRelationExpr::Map { scalars, .. } => {
2198 for scalar in scalars {
2199 f(scalar, depth)?;
2200 }
2201 }
2202 HirRelationExpr::CallTable { exprs, .. } => {
2203 for expr in exprs {
2204 f(expr, depth)?;
2205 }
2206 }
2207 HirRelationExpr::Filter { predicates, .. } => {
2208 for predicate in predicates {
2209 f(predicate, depth)?;
2210 }
2211 }
2212 HirRelationExpr::Reduce { aggregates, .. } => {
2213 for aggregate in aggregates {
2214 f(&aggregate.expr, depth)?;
2215 }
2216 }
2217 HirRelationExpr::TopK { limit, offset, .. } => {
2218 if let Some(limit) = limit {
2219 f(limit, depth)?;
2220 }
2221 f(offset, depth)?;
2222 }
2223 HirRelationExpr::Union { .. }
2224 | HirRelationExpr::Let { .. }
2225 | HirRelationExpr::LetRec { .. }
2226 | HirRelationExpr::Project { .. }
2227 | HirRelationExpr::Distinct { .. }
2228 | HirRelationExpr::Negate { .. }
2229 | HirRelationExpr::Threshold { .. }
2230 | HirRelationExpr::Constant { .. }
2231 | HirRelationExpr::Get { .. } => (),
2232 }
2233 Ok(())
2234 })
2235 }
2236
2237 #[deprecated = "Use a combination of `Visit` and `VisitChildren` methods."]
2238 pub fn visit_scalar_expressions_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
2244 where
2245 F: FnMut(&mut HirScalarExpr, usize) -> Result<(), E>,
2246 {
2247 #[allow(deprecated)]
2248 self.visit_mut_fallible(depth, &mut |e: &mut HirRelationExpr,
2249 depth: usize|
2250 -> Result<(), E> {
2251 match e {
2252 HirRelationExpr::Join { on, .. } => {
2253 f(on, depth)?;
2254 }
2255 HirRelationExpr::Map { scalars, .. } => {
2256 for scalar in scalars.iter_mut() {
2257 f(scalar, depth)?;
2258 }
2259 }
2260 HirRelationExpr::CallTable { exprs, .. } => {
2261 for expr in exprs.iter_mut() {
2262 f(expr, depth)?;
2263 }
2264 }
2265 HirRelationExpr::Filter { predicates, .. } => {
2266 for predicate in predicates.iter_mut() {
2267 f(predicate, depth)?;
2268 }
2269 }
2270 HirRelationExpr::Reduce { aggregates, .. } => {
2271 for aggregate in aggregates.iter_mut() {
2272 f(&mut aggregate.expr, depth)?;
2273 }
2274 }
2275 HirRelationExpr::TopK { limit, offset, .. } => {
2276 if let Some(limit) = limit {
2277 f(limit, depth)?;
2278 }
2279 f(offset, depth)?;
2280 }
2281 HirRelationExpr::Union { .. }
2282 | HirRelationExpr::Let { .. }
2283 | HirRelationExpr::LetRec { .. }
2284 | HirRelationExpr::Project { .. }
2285 | HirRelationExpr::Distinct { .. }
2286 | HirRelationExpr::Negate { .. }
2287 | HirRelationExpr::Threshold { .. }
2288 | HirRelationExpr::Constant { .. }
2289 | HirRelationExpr::Get { .. } => (),
2290 }
2291 Ok(())
2292 })
2293 }
2294
2295 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2296 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
2302 where
2303 F: FnMut(usize, &ColumnRef),
2304 {
2305 #[allow(deprecated)]
2306 let _ = self.visit_scalar_expressions(depth, &mut |e: &HirScalarExpr,
2307 depth: usize|
2308 -> Result<(), ()> {
2309 e.visit_columns(depth, f);
2310 Ok(())
2311 });
2312 }
2313
2314 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
2315 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
2317 where
2318 F: FnMut(usize, &mut ColumnRef),
2319 {
2320 #[allow(deprecated)]
2321 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2322 depth: usize|
2323 -> Result<(), ()> {
2324 e.visit_columns_mut(depth, f);
2325 Ok(())
2326 });
2327 }
2328
2329 pub fn bind_parameters_and_simplify_offset(
2339 &mut self,
2340 scx: &StatementContext,
2341 lifetime: QueryLifetime,
2342 params: &Params,
2343 ) -> Result<(), PlanError> {
2344 #[allow(deprecated)]
2345 self.visit_scalar_expressions_mut(0, &mut |e: &mut HirScalarExpr, _: usize| {
2346 e.bind_parameters_and_simplify_offset(scx, lifetime, params)
2347 })?;
2348
2349 self.try_visit_mut_pre(&mut |expr| {
2352 if let HirRelationExpr::TopK { offset, .. } = expr {
2353 let offset_value = offset_into_value(offset.take())?;
2354 *offset = HirScalarExpr::literal(Datum::Int64(offset_value), SqlScalarType::Int64);
2355 }
2356 Ok::<(), PlanError>(())
2357 })
2358 }
2362
2363 pub fn contains_parameters(&self) -> Result<bool, PlanError> {
2364 let mut contains_parameters = false;
2365 #[allow(deprecated)]
2366 self.visit_scalar_expressions(0, &mut |e: &HirScalarExpr, _: usize| {
2367 if e.contains_parameters() {
2368 contains_parameters = true;
2369 }
2370 Ok::<(), PlanError>(())
2371 })?;
2372 Ok(contains_parameters)
2373 }
2374
2375 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
2377 #[allow(deprecated)]
2378 let _ = self.visit_scalar_expressions_mut(depth, &mut |e: &mut HirScalarExpr,
2379 depth: usize|
2380 -> Result<(), ()> {
2381 e.splice_parameters(params, depth);
2382 Ok(())
2383 });
2384 }
2385
2386 pub fn constant(rows: Vec<Vec<Datum>>, typ: SqlRelationType) -> Self {
2388 let rows = rows
2389 .into_iter()
2390 .map(move |datums| Row::pack_slice(&datums))
2391 .collect();
2392 HirRelationExpr::Constant { rows, typ }
2393 }
2394
2395 pub fn finish_maintained(
2401 &mut self,
2402 finishing: &mut RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2403 group_size_hints: GroupSizeHints,
2404 ) {
2405 if !HirRelationExpr::is_trivial_row_set_finishing_hir(finishing, self.arity()) {
2406 let old_finishing = mem::replace(
2407 finishing,
2408 HirRelationExpr::trivial_row_set_finishing_hir(finishing.project.len()),
2409 );
2410 *self = HirRelationExpr::top_k(
2411 std::mem::replace(
2412 self,
2413 HirRelationExpr::Constant {
2414 rows: vec![],
2415 typ: SqlRelationType::new(Vec::new()),
2416 },
2417 ),
2418 vec![],
2419 old_finishing.order_by,
2420 old_finishing.limit,
2421 old_finishing.offset,
2422 group_size_hints.limit_input_group_size,
2423 )
2424 .project(old_finishing.project);
2425 }
2426 }
2427
2428 pub fn trivial_row_set_finishing_hir(
2433 arity: usize,
2434 ) -> RowSetFinishing<HirScalarExpr, HirScalarExpr> {
2435 RowSetFinishing {
2436 order_by: Vec::new(),
2437 limit: None,
2438 offset: HirScalarExpr::literal(Datum::Int64(0), SqlScalarType::Int64),
2439 project: (0..arity).collect(),
2440 }
2441 }
2442
2443 pub fn is_trivial_row_set_finishing_hir(
2448 rsf: &RowSetFinishing<HirScalarExpr, HirScalarExpr>,
2449 arity: usize,
2450 ) -> bool {
2451 rsf.limit.is_none()
2452 && rsf.order_by.is_empty()
2453 && rsf
2454 .offset
2455 .clone()
2456 .try_into_literal_int64()
2457 .is_ok_and(|o| o == 0)
2458 && rsf.project.iter().copied().eq(0..arity)
2459 }
2460
2461 pub fn could_run_expensive_function(&self) -> bool {
2471 let mut result = false;
2472 self.visit_pre(&mut |e: &HirRelationExpr| {
2473 use HirRelationExpr::*;
2474 use HirScalarExpr::*;
2475
2476 e.visit_children(|scalar: &HirScalarExpr| {
2477 scalar.visit_pre(&mut |scalar: &HirScalarExpr| {
2478 result |= match scalar {
2479 Column(..)
2480 | Literal(..)
2481 | CallUnmaterializable(..)
2482 | If { .. }
2483 | Parameter(..)
2484 | Select(..)
2485 | Exists(..) => false,
2486 CallUnary { .. }
2488 | CallBinary { .. }
2489 | CallVariadic { .. }
2490 | Windowing(..) => true,
2491 };
2492 })
2493 });
2494
2495 result |= matches!(e, CallTable { .. } | Reduce { .. });
2498 });
2499
2500 result
2501 }
2502
2503 pub fn contains_temporal(&self) -> bool {
2505 let mut contains = false;
2506 self.visit_post(&mut |expr| {
2507 expr.visit_children(|expr: &HirScalarExpr| {
2508 contains = contains || expr.contains_temporal()
2509 })
2510 });
2511 contains
2512 }
2513
2514 pub fn contains_unmaterializable(&self) -> bool {
2516 let mut contains = false;
2517 self.visit_post(&mut |expr| {
2518 expr.visit_children(|expr: &HirScalarExpr| {
2519 contains = contains || expr.contains_unmaterializable()
2520 })
2521 });
2522 contains
2523 }
2524
2525 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
2528 let mut contains = false;
2529 self.visit_post(&mut |expr| {
2530 expr.visit_children(|expr: &HirScalarExpr| {
2531 contains = contains || expr.contains_unmaterializable_except_temporal()
2532 })
2533 });
2534 contains
2535 }
2536}
2537
2538impl CollectionPlan for HirRelationExpr {
2539 fn depends_on_into(&self, out: &mut BTreeSet<GlobalId>) {
2546 if let Self::Get {
2547 id: Id::Global(id), ..
2548 } = self
2549 {
2550 out.insert(*id);
2551 }
2552 self.visit_children(|expr: &HirRelationExpr| expr.depends_on_into(out))
2553 }
2554}
2555
2556impl VisitChildren<Self> for HirRelationExpr {
2562 fn visit_children<F>(&self, mut f: F)
2563 where
2564 F: FnMut(&Self),
2565 {
2566 VisitChildren::visit_children(self, |expr: &HirScalarExpr| {
2570 expr.visit_direct_subqueries(&mut f);
2571 });
2572
2573 use HirRelationExpr::*;
2574 match self {
2575 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2576 Let {
2577 name: _,
2578 id: _,
2579 value,
2580 body,
2581 } => {
2582 f(value);
2583 f(body);
2584 }
2585 LetRec {
2586 limit: _,
2587 bindings,
2588 body,
2589 } => {
2590 for (_, _, value, _) in bindings.iter() {
2591 f(value);
2592 }
2593 f(body);
2594 }
2595 Project { input, outputs: _ } => f(input),
2596 Map { input, scalars: _ } => {
2597 f(input);
2598 }
2599 CallTable { func: _, exprs: _ } => (),
2600 Filter {
2601 input,
2602 predicates: _,
2603 } => {
2604 f(input);
2605 }
2606 Join {
2607 left,
2608 right,
2609 on: _,
2610 kind: _,
2611 } => {
2612 f(left);
2613 f(right);
2614 }
2615 Reduce {
2616 input,
2617 group_key: _,
2618 aggregates: _,
2619 expected_group_size: _,
2620 } => {
2621 f(input);
2622 }
2623 Distinct { input }
2624 | TopK {
2625 input,
2626 group_key: _,
2627 order_key: _,
2628 limit: _,
2629 offset: _,
2630 expected_group_size: _,
2631 }
2632 | Negate { input }
2633 | Threshold { input } => {
2634 f(input);
2635 }
2636 Union { base, inputs } => {
2637 f(base);
2638 for input in inputs {
2639 f(input);
2640 }
2641 }
2642 }
2643 }
2644
2645 fn visit_mut_children<F>(&mut self, mut f: F)
2646 where
2647 F: FnMut(&mut Self),
2648 {
2649 VisitChildren::visit_mut_children(self, |expr: &mut HirScalarExpr| {
2653 expr.visit_direct_subqueries_mut(&mut f);
2654 });
2655
2656 use HirRelationExpr::*;
2657 match self {
2658 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2659 Let {
2660 name: _,
2661 id: _,
2662 value,
2663 body,
2664 } => {
2665 f(value);
2666 f(body);
2667 }
2668 LetRec {
2669 limit: _,
2670 bindings,
2671 body,
2672 } => {
2673 for (_, _, value, _) in bindings.iter_mut() {
2674 f(value);
2675 }
2676 f(body);
2677 }
2678 Project { input, outputs: _ } => f(input),
2679 Map { input, scalars: _ } => {
2680 f(input);
2681 }
2682 CallTable { func: _, exprs: _ } => (),
2683 Filter {
2684 input,
2685 predicates: _,
2686 } => {
2687 f(input);
2688 }
2689 Join {
2690 left,
2691 right,
2692 on: _,
2693 kind: _,
2694 } => {
2695 f(left);
2696 f(right);
2697 }
2698 Reduce {
2699 input,
2700 group_key: _,
2701 aggregates: _,
2702 expected_group_size: _,
2703 } => {
2704 f(input);
2705 }
2706 Distinct { input }
2707 | TopK {
2708 input,
2709 group_key: _,
2710 order_key: _,
2711 limit: _,
2712 offset: _,
2713 expected_group_size: _,
2714 }
2715 | Negate { input }
2716 | Threshold { input } => {
2717 f(input);
2718 }
2719 Union { base, inputs } => {
2720 f(base);
2721 for input in inputs {
2722 f(input);
2723 }
2724 }
2725 }
2726 }
2727
2728 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
2729 where
2730 F: FnMut(&Self) -> Result<(), E>,
2731 {
2732 VisitChildren::try_visit_children(self, |expr: &HirScalarExpr| {
2736 expr.try_visit_direct_subqueries(&mut f)
2737 })?;
2738
2739 use HirRelationExpr::*;
2740 match self {
2741 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2742 Let {
2743 name: _,
2744 id: _,
2745 value,
2746 body,
2747 } => {
2748 f(value)?;
2749 f(body)?;
2750 }
2751 LetRec {
2752 limit: _,
2753 bindings,
2754 body,
2755 } => {
2756 for (_, _, value, _) in bindings.iter() {
2757 f(value)?;
2758 }
2759 f(body)?;
2760 }
2761 Project { input, outputs: _ } => f(input)?,
2762 Map { input, scalars: _ } => {
2763 f(input)?;
2764 }
2765 CallTable { func: _, exprs: _ } => (),
2766 Filter {
2767 input,
2768 predicates: _,
2769 } => {
2770 f(input)?;
2771 }
2772 Join {
2773 left,
2774 right,
2775 on: _,
2776 kind: _,
2777 } => {
2778 f(left)?;
2779 f(right)?;
2780 }
2781 Reduce {
2782 input,
2783 group_key: _,
2784 aggregates: _,
2785 expected_group_size: _,
2786 } => {
2787 f(input)?;
2788 }
2789 Distinct { input }
2790 | TopK {
2791 input,
2792 group_key: _,
2793 order_key: _,
2794 limit: _,
2795 offset: _,
2796 expected_group_size: _,
2797 }
2798 | Negate { input }
2799 | Threshold { input } => {
2800 f(input)?;
2801 }
2802 Union { base, inputs } => {
2803 f(base)?;
2804 for input in inputs {
2805 f(input)?;
2806 }
2807 }
2808 }
2809 Ok(())
2810 }
2811
2812 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
2813 where
2814 F: FnMut(&mut Self) -> Result<(), E>,
2815 {
2816 VisitChildren::try_visit_mut_children(self, |expr: &mut HirScalarExpr| {
2820 expr.try_visit_direct_subqueries_mut(&mut f)
2821 })?;
2822
2823 use HirRelationExpr::*;
2824 match self {
2825 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2826 Let {
2827 name: _,
2828 id: _,
2829 value,
2830 body,
2831 } => {
2832 f(value)?;
2833 f(body)?;
2834 }
2835 LetRec {
2836 limit: _,
2837 bindings,
2838 body,
2839 } => {
2840 for (_, _, value, _) in bindings.iter_mut() {
2841 f(value)?;
2842 }
2843 f(body)?;
2844 }
2845 Project { input, outputs: _ } => f(input)?,
2846 Map { input, scalars: _ } => {
2847 f(input)?;
2848 }
2849 CallTable { func: _, exprs: _ } => (),
2850 Filter {
2851 input,
2852 predicates: _,
2853 } => {
2854 f(input)?;
2855 }
2856 Join {
2857 left,
2858 right,
2859 on: _,
2860 kind: _,
2861 } => {
2862 f(left)?;
2863 f(right)?;
2864 }
2865 Reduce {
2866 input,
2867 group_key: _,
2868 aggregates: _,
2869 expected_group_size: _,
2870 } => {
2871 f(input)?;
2872 }
2873 Distinct { input }
2874 | TopK {
2875 input,
2876 group_key: _,
2877 order_key: _,
2878 limit: _,
2879 offset: _,
2880 expected_group_size: _,
2881 }
2882 | Negate { input }
2883 | Threshold { input } => {
2884 f(input)?;
2885 }
2886 Union { base, inputs } => {
2887 f(base)?;
2888 for input in inputs {
2889 f(input)?;
2890 }
2891 }
2892 }
2893 Ok(())
2894 }
2895
2896 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
2897 where
2898 Self: 'a,
2899 {
2900 let mut v: Vec<&HirRelationExpr> = vec![];
2902 use HirRelationExpr::*;
2903 match self {
2904 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2905 Let {
2906 name: _,
2907 id: _,
2908 value,
2909 body,
2910 } => {
2911 v.push(&*value);
2912 v.push(&*body);
2913 }
2914 LetRec {
2915 limit: _,
2916 bindings,
2917 body,
2918 } => {
2919 v.extend(bindings.iter().map(|(_, _, value, _)| value));
2920 v.push(&*body);
2921 }
2922 Map { input, scalars }
2923 | Filter {
2924 input,
2925 predicates: scalars,
2926 } => {
2927 for scalar in scalars {
2928 v.append(&mut scalar.direct_subqueries());
2929 }
2930 v.push(&*input);
2931 }
2932 Reduce {
2933 input,
2934 group_key: _,
2935 aggregates,
2936 expected_group_size: _,
2937 } => {
2938 for agg in aggregates {
2939 v.append(&mut agg.expr.direct_subqueries());
2940 }
2941 v.push(&*input);
2942 }
2943 TopK {
2944 input,
2945 group_key: _,
2946 order_key: _,
2947 limit,
2948 offset,
2949 expected_group_size: _,
2950 } => {
2951 if let Some(limit) = limit {
2952 v.append(&mut limit.direct_subqueries());
2953 }
2954 v.append(&mut offset.direct_subqueries());
2955 v.push(&*input);
2956 }
2957 Project { input, outputs: _ }
2958 | Distinct { input }
2959 | Negate { input }
2960 | Threshold { input } => v.push(&*input),
2961 CallTable { func: _, exprs } => v.extend(
2962 exprs
2963 .iter()
2964 .map(|scalar| scalar.direct_subqueries())
2965 .flatten(),
2966 ),
2967 Join {
2968 left,
2969 right,
2970 on,
2971 kind: _,
2972 } => {
2973 v.append(&mut on.direct_subqueries());
2974 v.push(&*left);
2975 v.push(&*right);
2976 }
2977 Union { base, inputs } => {
2978 v.push(&*base);
2979 v.extend(inputs.iter());
2980 }
2981 }
2982
2983 v.into_iter()
2984 }
2985
2986 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
2987 where
2988 Self: 'a,
2989 {
2990 let mut v = vec![];
2992 use HirRelationExpr::*;
2993 match self {
2994 Constant { rows: _, typ: _ } | Get { id: _, typ: _ } => (),
2995 Let {
2996 name: _,
2997 id: _,
2998 value,
2999 body,
3000 } => {
3001 v.push(&mut **value);
3002 v.push(&mut **body);
3003 }
3004 LetRec {
3005 limit: _,
3006 bindings,
3007 body,
3008 } => {
3009 v.extend(bindings.iter_mut().map(|(_, _, value, _)| value));
3010 v.push(&mut **body);
3011 }
3012 Map { input, scalars }
3013 | Filter {
3014 input,
3015 predicates: scalars,
3016 } => {
3017 for scalar in scalars {
3018 v.append(&mut scalar.direct_subqueries_mut());
3019 }
3020 v.push(&mut **input);
3021 }
3022 Reduce {
3023 input,
3024 group_key: _,
3025 aggregates,
3026 expected_group_size: _,
3027 } => {
3028 for agg in aggregates {
3029 v.append(&mut agg.expr.direct_subqueries_mut());
3030 }
3031 v.push(&mut **input);
3032 }
3033 TopK {
3034 input,
3035 group_key: _,
3036 order_key: _,
3037 limit,
3038 offset,
3039 expected_group_size: _,
3040 } => {
3041 if let Some(limit) = limit {
3042 v.append(&mut limit.direct_subqueries_mut());
3043 }
3044 v.append(&mut offset.direct_subqueries_mut());
3045 v.push(&mut **input);
3046 }
3047 Project { input, outputs: _ }
3048 | Distinct { input }
3049 | Negate { input }
3050 | Threshold { input } => v.push(&mut **input),
3051 CallTable { func: _, exprs } => v.extend(
3052 exprs
3053 .iter_mut()
3054 .map(|scalar| scalar.direct_subqueries_mut())
3055 .flatten(),
3056 ),
3057 Join {
3058 left,
3059 right,
3060 on,
3061 kind: _,
3062 } => {
3063 v.append(&mut on.direct_subqueries_mut());
3064 v.push(&mut **left);
3065 v.push(&mut **right);
3066 }
3067 Union { base, inputs } => {
3068 v.push(&mut **base);
3069 v.extend(inputs.iter_mut());
3070 }
3071 }
3072
3073 v.into_iter()
3074 }
3075}
3076
3077impl VisitChildren<HirScalarExpr> for HirRelationExpr {
3081 fn visit_children<F>(&self, mut f: F)
3082 where
3083 F: FnMut(&HirScalarExpr),
3084 {
3085 use HirRelationExpr::*;
3086 match self {
3087 Constant { rows: _, typ: _ }
3088 | Get { id: _, typ: _ }
3089 | Let {
3090 name: _,
3091 id: _,
3092 value: _,
3093 body: _,
3094 }
3095 | LetRec {
3096 limit: _,
3097 bindings: _,
3098 body: _,
3099 }
3100 | Project {
3101 input: _,
3102 outputs: _,
3103 } => (),
3104 Map { input: _, scalars } => {
3105 for scalar in scalars {
3106 f(scalar);
3107 }
3108 }
3109 CallTable { func: _, exprs } => {
3110 for expr in exprs {
3111 f(expr);
3112 }
3113 }
3114 Filter {
3115 input: _,
3116 predicates,
3117 } => {
3118 for predicate in predicates {
3119 f(predicate);
3120 }
3121 }
3122 Join {
3123 left: _,
3124 right: _,
3125 on,
3126 kind: _,
3127 } => f(on),
3128 Reduce {
3129 input: _,
3130 group_key: _,
3131 aggregates,
3132 expected_group_size: _,
3133 } => {
3134 for aggregate in aggregates {
3135 f(aggregate.expr.as_ref());
3136 }
3137 }
3138 TopK {
3139 input: _,
3140 group_key: _,
3141 order_key: _,
3142 limit,
3143 offset,
3144 expected_group_size: _,
3145 } => {
3146 if let Some(limit) = limit {
3147 f(limit)
3148 }
3149 f(offset)
3150 }
3151 Distinct { input: _ }
3152 | Negate { input: _ }
3153 | Threshold { input: _ }
3154 | Union { base: _, inputs: _ } => (),
3155 }
3156 }
3157
3158 fn visit_mut_children<F>(&mut self, mut f: F)
3159 where
3160 F: FnMut(&mut HirScalarExpr),
3161 {
3162 use HirRelationExpr::*;
3163 match self {
3164 Constant { rows: _, typ: _ }
3165 | Get { id: _, typ: _ }
3166 | Let {
3167 name: _,
3168 id: _,
3169 value: _,
3170 body: _,
3171 }
3172 | LetRec {
3173 limit: _,
3174 bindings: _,
3175 body: _,
3176 }
3177 | Project {
3178 input: _,
3179 outputs: _,
3180 } => (),
3181 Map { input: _, scalars } => {
3182 for scalar in scalars {
3183 f(scalar);
3184 }
3185 }
3186 CallTable { func: _, exprs } => {
3187 for expr in exprs {
3188 f(expr);
3189 }
3190 }
3191 Filter {
3192 input: _,
3193 predicates,
3194 } => {
3195 for predicate in predicates {
3196 f(predicate);
3197 }
3198 }
3199 Join {
3200 left: _,
3201 right: _,
3202 on,
3203 kind: _,
3204 } => f(on),
3205 Reduce {
3206 input: _,
3207 group_key: _,
3208 aggregates,
3209 expected_group_size: _,
3210 } => {
3211 for aggregate in aggregates {
3212 f(aggregate.expr.as_mut());
3213 }
3214 }
3215 TopK {
3216 input: _,
3217 group_key: _,
3218 order_key: _,
3219 limit,
3220 offset,
3221 expected_group_size: _,
3222 } => {
3223 if let Some(limit) = limit {
3224 f(limit)
3225 }
3226 f(offset)
3227 }
3228 Distinct { input: _ }
3229 | Negate { input: _ }
3230 | Threshold { input: _ }
3231 | Union { base: _, inputs: _ } => (),
3232 }
3233 }
3234
3235 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
3236 where
3237 F: FnMut(&HirScalarExpr) -> Result<(), E>,
3238 {
3239 use HirRelationExpr::*;
3240 match self {
3241 Constant { rows: _, typ: _ }
3242 | Get { id: _, typ: _ }
3243 | Let {
3244 name: _,
3245 id: _,
3246 value: _,
3247 body: _,
3248 }
3249 | LetRec {
3250 limit: _,
3251 bindings: _,
3252 body: _,
3253 }
3254 | Project {
3255 input: _,
3256 outputs: _,
3257 } => (),
3258 Map { input: _, scalars } => {
3259 for scalar in scalars {
3260 f(scalar)?;
3261 }
3262 }
3263 CallTable { func: _, exprs } => {
3264 for expr in exprs {
3265 f(expr)?;
3266 }
3267 }
3268 Filter {
3269 input: _,
3270 predicates,
3271 } => {
3272 for predicate in predicates {
3273 f(predicate)?;
3274 }
3275 }
3276 Join {
3277 left: _,
3278 right: _,
3279 on,
3280 kind: _,
3281 } => f(on)?,
3282 Reduce {
3283 input: _,
3284 group_key: _,
3285 aggregates,
3286 expected_group_size: _,
3287 } => {
3288 for aggregate in aggregates {
3289 f(aggregate.expr.as_ref())?;
3290 }
3291 }
3292 TopK {
3293 input: _,
3294 group_key: _,
3295 order_key: _,
3296 limit,
3297 offset,
3298 expected_group_size: _,
3299 } => {
3300 if let Some(limit) = limit {
3301 f(limit)?
3302 }
3303 f(offset)?
3304 }
3305 Distinct { input: _ }
3306 | Negate { input: _ }
3307 | Threshold { input: _ }
3308 | Union { base: _, inputs: _ } => (),
3309 }
3310 Ok(())
3311 }
3312
3313 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
3314 where
3315 F: FnMut(&mut HirScalarExpr) -> Result<(), E>,
3316 {
3317 use HirRelationExpr::*;
3318 match self {
3319 Constant { rows: _, typ: _ }
3320 | Get { id: _, typ: _ }
3321 | Let {
3322 name: _,
3323 id: _,
3324 value: _,
3325 body: _,
3326 }
3327 | LetRec {
3328 limit: _,
3329 bindings: _,
3330 body: _,
3331 }
3332 | Project {
3333 input: _,
3334 outputs: _,
3335 } => (),
3336 Map { input: _, scalars } => {
3337 for scalar in scalars {
3338 f(scalar)?;
3339 }
3340 }
3341 CallTable { func: _, exprs } => {
3342 for expr in exprs {
3343 f(expr)?;
3344 }
3345 }
3346 Filter {
3347 input: _,
3348 predicates,
3349 } => {
3350 for predicate in predicates {
3351 f(predicate)?;
3352 }
3353 }
3354 Join {
3355 left: _,
3356 right: _,
3357 on,
3358 kind: _,
3359 } => f(on)?,
3360 Reduce {
3361 input: _,
3362 group_key: _,
3363 aggregates,
3364 expected_group_size: _,
3365 } => {
3366 for aggregate in aggregates {
3367 f(aggregate.expr.as_mut())?;
3368 }
3369 }
3370 TopK {
3371 input: _,
3372 group_key: _,
3373 order_key: _,
3374 limit,
3375 offset,
3376 expected_group_size: _,
3377 } => {
3378 if let Some(limit) = limit {
3379 f(limit)?
3380 }
3381 f(offset)?
3382 }
3383 Distinct { input: _ }
3384 | Negate { input: _ }
3385 | Threshold { input: _ }
3386 | Union { base: _, inputs: _ } => (),
3387 }
3388 Ok(())
3389 }
3390
3391 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirScalarExpr>
3392 where
3393 HirScalarExpr: 'a,
3394 {
3395 use HirRelationExpr::*;
3396 match self {
3397 Constant { rows: _, typ: _ }
3398 | Get { id: _, typ: _ }
3399 | Let {
3400 name: _,
3401 id: _,
3402 value: _,
3403 body: _,
3404 }
3405 | LetRec {
3406 limit: _,
3407 bindings: _,
3408 body: _,
3409 }
3410 | Project {
3411 input: _,
3412 outputs: _,
3413 }
3414 | Distinct { input: _ }
3415 | Negate { input: _ }
3416 | Threshold { input: _ }
3417 | Union { base: _, inputs: _ } => vec![],
3418 Map { input: _, scalars }
3419 | CallTable {
3420 func: _,
3421 exprs: scalars,
3422 }
3423 | Filter {
3424 input: _,
3425 predicates: scalars,
3426 } => scalars.iter().collect(),
3427 Join {
3428 left: _,
3429 right: _,
3430 on,
3431 kind: _,
3432 } => vec![on],
3433 Reduce {
3434 input: _,
3435 group_key: _,
3436 aggregates,
3437 expected_group_size: _,
3438 } => aggregates.iter().map(|agg| &*agg.expr).collect(),
3439 TopK {
3440 input: _,
3441 group_key: _,
3442 order_key: _,
3443 limit,
3444 offset,
3445 expected_group_size: _,
3446 } => limit.iter().chain(std::iter::once(offset)).collect(),
3447 }
3448 .into_iter()
3449 }
3450
3451 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirScalarExpr>
3452 where
3453 HirScalarExpr: 'a,
3454 {
3455 use HirRelationExpr::*;
3456 match self {
3457 Constant { rows: _, typ: _ }
3458 | Get { id: _, typ: _ }
3459 | Let {
3460 name: _,
3461 id: _,
3462 value: _,
3463 body: _,
3464 }
3465 | LetRec {
3466 limit: _,
3467 bindings: _,
3468 body: _,
3469 }
3470 | Project {
3471 input: _,
3472 outputs: _,
3473 }
3474 | Distinct { input: _ }
3475 | Negate { input: _ }
3476 | Threshold { input: _ }
3477 | Union { base: _, inputs: _ } => vec![],
3478 Map { input: _, scalars }
3479 | CallTable {
3480 func: _,
3481 exprs: scalars,
3482 }
3483 | Filter {
3484 input: _,
3485 predicates: scalars,
3486 } => scalars.iter_mut().collect(),
3487 Join {
3488 left: _,
3489 right: _,
3490 on,
3491 kind: _,
3492 } => vec![on],
3493 Reduce {
3494 input: _,
3495 group_key: _,
3496 aggregates,
3497 expected_group_size: _,
3498 } => aggregates.iter_mut().map(|agg| &mut *agg.expr).collect(),
3499 TopK {
3500 input: _,
3501 group_key: _,
3502 order_key: _,
3503 limit,
3504 offset,
3505 expected_group_size: _,
3506 } => limit.iter_mut().chain(std::iter::once(offset)).collect(),
3507 }
3508 .into_iter()
3509 }
3510}
3511
3512impl HirScalarExpr {
3513 pub fn name(&self) -> Option<Arc<str>> {
3514 use HirScalarExpr::*;
3515 match self {
3516 Column(_, name)
3517 | Parameter(_, name)
3518 | Literal(_, _, name)
3519 | CallUnmaterializable(_, name)
3520 | CallUnary { name, .. }
3521 | CallBinary { name, .. }
3522 | CallVariadic { name, .. }
3523 | If { name, .. }
3524 | Exists(_, name)
3525 | Select(_, name)
3526 | Windowing(_, name) => name.0.clone(),
3527 }
3528 }
3529
3530 pub fn visit_direct_subqueries<F>(&self, mut f: F)
3532 where
3533 F: FnMut(&HirRelationExpr),
3534 {
3535 self.visit_post(&mut |e| {
3536 VisitChildren::<HirRelationExpr>::visit_children(e, &mut f);
3537 });
3538 }
3539
3540 pub fn visit_direct_subqueries_mut<F>(&mut self, mut f: F)
3542 where
3543 F: FnMut(&mut HirRelationExpr),
3544 {
3545 self.visit_mut_post(&mut |e| {
3546 VisitChildren::<HirRelationExpr>::visit_mut_children(e, &mut f);
3547 });
3548 }
3549
3550 pub fn try_visit_direct_subqueries<F, E>(&self, mut f: F) -> Result<(), E>
3552 where
3553 F: FnMut(&HirRelationExpr) -> Result<(), E>,
3554 {
3555 self.try_visit_post(&mut |e| {
3556 VisitChildren::<HirRelationExpr>::try_visit_children(e, &mut f)
3557 })
3558 }
3559
3560 pub fn try_visit_direct_subqueries_mut<F, E>(&mut self, mut f: F) -> Result<(), E>
3562 where
3563 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
3564 {
3565 self.try_visit_mut_post(&mut |e| {
3566 VisitChildren::<HirRelationExpr>::try_visit_mut_children(e, &mut f)
3567 })
3568 }
3569
3570 pub fn bind_parameters_and_simplify_offset(
3579 &mut self,
3580 scx: &StatementContext,
3581 lifetime: QueryLifetime,
3582 params: &Params,
3583 ) -> Result<(), PlanError> {
3584 self.try_visit_mut_post(&mut |e: &mut HirScalarExpr| {
3587 if let HirScalarExpr::Parameter(n, name) = e {
3588 let datum = match params.datums.iter().nth(*n - 1) {
3589 None => return Err(PlanError::UnknownParameter(*n)),
3590 Some(datum) => datum,
3591 };
3592 let scalar_type = ¶ms.execute_types[*n - 1];
3593 let row = Row::pack([datum]);
3594 let column_type = scalar_type.clone().nullable(datum.is_null());
3595
3596 let name = if let Some(name) = &name.0 {
3597 Some(Arc::clone(name))
3598 } else {
3599 Some(Arc::from(format!("${n}")))
3600 };
3601
3602 let qcx = QueryContext::root(scx, lifetime);
3603 let ecx = execute_expr_context(&qcx);
3604
3605 *e = plan_cast(
3606 &ecx,
3607 *EXECUTE_CAST_CONTEXT,
3608 HirScalarExpr::Literal(row, column_type, TreatAsEqual(name)),
3609 ¶ms.expected_types[*n - 1],
3610 )
3611 .expect("checked in plan_params");
3612 }
3613 Ok(())
3614 })?;
3615 self.try_visit_direct_subqueries_mut(|r: &mut HirRelationExpr| {
3618 r.bind_parameters_and_simplify_offset(scx, lifetime, params)
3619 })
3620 }
3621
3622 pub fn splice_parameters(&mut self, params: &[HirScalarExpr], depth: usize) {
3633 #[allow(deprecated)]
3634 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3635 e: &mut HirScalarExpr|
3636 -> Result<(), ()> {
3637 if let HirScalarExpr::Parameter(i, _name) = e {
3638 *e = params[*i - 1].clone();
3639 e.visit_columns_mut(0, &mut |d: usize, col: &mut ColumnRef| {
3642 if col.level >= d {
3643 col.level += depth
3644 }
3645 });
3646 }
3647 Ok(())
3648 });
3649 }
3650
3651 pub fn contains_temporal(&self) -> bool {
3653 let mut contains = false;
3654 self.visit_post(&mut |e| {
3655 if let Self::CallUnmaterializable(UnmaterializableFunc::MzNow, _name) = e {
3656 contains = true;
3657 }
3658 });
3659 contains
3660 }
3661
3662 pub fn contains_unmaterializable(&self) -> bool {
3664 let mut contains = false;
3665 self.visit_post(&mut |e| {
3666 if let Self::CallUnmaterializable(_, _) = e {
3667 contains = true;
3668 }
3669 });
3670 contains
3671 }
3672
3673 pub fn contains_unmaterializable_except_temporal(&self) -> bool {
3676 let mut contains = false;
3677 self.visit_post(&mut |e| {
3678 if let Self::CallUnmaterializable(f, _) = e {
3679 if *f != UnmaterializableFunc::MzNow {
3680 contains = true;
3681 }
3682 }
3683 });
3684 contains
3685 }
3686
3687 pub fn column(index: usize) -> HirScalarExpr {
3691 HirScalarExpr::Column(
3692 ColumnRef {
3693 level: 0,
3694 column: index,
3695 },
3696 TreatAsEqual(None),
3697 )
3698 }
3699
3700 pub fn unnamed_column(cr: ColumnRef) -> HirScalarExpr {
3702 HirScalarExpr::Column(cr, TreatAsEqual(None))
3703 }
3704
3705 pub fn named_column(cr: ColumnRef, name: Arc<str>) -> HirScalarExpr {
3708 HirScalarExpr::Column(cr, TreatAsEqual(Some(name)))
3709 }
3710
3711 pub fn parameter(n: usize) -> HirScalarExpr {
3712 HirScalarExpr::Parameter(n, TreatAsEqual(None))
3713 }
3714
3715 pub fn literal(datum: Datum, scalar_type: SqlScalarType) -> HirScalarExpr {
3716 let col_type = scalar_type.nullable(datum.is_null());
3717 soft_assert_or_log!(datum.is_instance_of_sql(&col_type), "type is correct");
3718 let row = Row::pack([datum]);
3719 HirScalarExpr::Literal(row, col_type, TreatAsEqual(None))
3720 }
3721
3722 pub fn literal_true() -> HirScalarExpr {
3723 HirScalarExpr::literal(Datum::True, SqlScalarType::Bool)
3724 }
3725
3726 pub fn literal_false() -> HirScalarExpr {
3727 HirScalarExpr::literal(Datum::False, SqlScalarType::Bool)
3728 }
3729
3730 pub fn literal_null(scalar_type: SqlScalarType) -> HirScalarExpr {
3731 HirScalarExpr::literal(Datum::Null, scalar_type)
3732 }
3733
3734 pub fn literal_1d_array(
3735 datums: Vec<Datum>,
3736 element_scalar_type: SqlScalarType,
3737 ) -> Result<HirScalarExpr, PlanError> {
3738 let scalar_type = match element_scalar_type {
3739 SqlScalarType::Array(_) => {
3740 sql_bail!("cannot build array from array type");
3741 }
3742 typ => SqlScalarType::Array(Box::new(typ)).nullable(false),
3743 };
3744
3745 let mut row = Row::default();
3746 row.packer()
3747 .try_push_array(
3748 &[ArrayDimension {
3749 lower_bound: 1,
3750 length: datums.len(),
3751 }],
3752 datums,
3753 )
3754 .expect("array constructed to be valid");
3755
3756 Ok(HirScalarExpr::Literal(row, scalar_type, TreatAsEqual(None)))
3757 }
3758
3759 pub fn as_literal(&self) -> Option<Datum<'_>> {
3760 if let HirScalarExpr::Literal(row, _column_type, _name) = self {
3761 Some(row.unpack_first())
3762 } else {
3763 None
3764 }
3765 }
3766
3767 pub fn is_literal_true(&self) -> bool {
3768 Some(Datum::True) == self.as_literal()
3769 }
3770
3771 pub fn is_literal_false(&self) -> bool {
3772 Some(Datum::False) == self.as_literal()
3773 }
3774
3775 pub fn is_literal_null(&self) -> bool {
3776 Some(Datum::Null) == self.as_literal()
3777 }
3778
3779 pub fn is_constant(&self) -> bool {
3782 let mut worklist = vec![self];
3783 while let Some(expr) = worklist.pop() {
3784 match expr {
3785 Self::Literal(..) => {
3786 }
3788 Self::CallUnary { expr, .. } => {
3789 worklist.push(expr);
3790 }
3791 Self::CallBinary {
3792 func: _,
3793 expr1,
3794 expr2,
3795 name: _,
3796 } => {
3797 worklist.push(expr1);
3798 worklist.push(expr2);
3799 }
3800 Self::CallVariadic {
3801 func: _,
3802 exprs,
3803 name: _,
3804 } => {
3805 worklist.extend(exprs.iter());
3806 }
3807 Self::If {
3809 cond,
3810 then,
3811 els,
3812 name: _,
3813 } => {
3814 worklist.push(cond);
3815 worklist.push(then);
3816 worklist.push(els);
3817 }
3818 _ => {
3819 return false; }
3821 }
3822 }
3823 true
3824 }
3825
3826 pub fn call_unary(self, func: UnaryFunc) -> Self {
3827 HirScalarExpr::CallUnary {
3828 func,
3829 expr: Box::new(self),
3830 name: NameMetadata::default(),
3831 }
3832 }
3833
3834 pub fn call_binary<B: Into<BinaryFunc>>(self, other: Self, func: B) -> Self {
3835 HirScalarExpr::CallBinary {
3836 func: func.into(),
3837 expr1: Box::new(self),
3838 expr2: Box::new(other),
3839 name: NameMetadata::default(),
3840 }
3841 }
3842
3843 pub fn call_unmaterializable(func: UnmaterializableFunc) -> Self {
3844 HirScalarExpr::CallUnmaterializable(func, NameMetadata::default())
3845 }
3846
3847 pub fn call_variadic<V: Into<VariadicFunc>>(func: V, exprs: Vec<Self>) -> Self {
3848 HirScalarExpr::CallVariadic {
3849 func: func.into(),
3850 exprs,
3851 name: NameMetadata::default(),
3852 }
3853 }
3854
3855 pub fn if_then_else(cond: Self, then: Self, els: Self) -> Self {
3856 HirScalarExpr::If {
3857 cond: Box::new(cond),
3858 then: Box::new(then),
3859 els: Box::new(els),
3860 name: NameMetadata::default(),
3861 }
3862 }
3863
3864 pub fn windowing(expr: WindowExpr) -> Self {
3865 HirScalarExpr::Windowing(expr, TreatAsEqual(None))
3866 }
3867
3868 pub fn or(self, other: Self) -> Self {
3869 HirScalarExpr::call_variadic(Or, vec![self, other])
3870 }
3871
3872 pub fn and(self, other: Self) -> Self {
3873 HirScalarExpr::call_variadic(And, vec![self, other])
3874 }
3875
3876 pub fn not(self) -> Self {
3877 self.call_unary(UnaryFunc::Not(func::Not))
3878 }
3879
3880 pub fn call_is_null(self) -> Self {
3881 self.call_unary(UnaryFunc::IsNull(func::IsNull))
3882 }
3883
3884 pub fn variadic_and(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3886 match args.len() {
3887 0 => HirScalarExpr::literal_true(), 1 => args.swap_remove(0),
3889 _ => HirScalarExpr::call_variadic(And, args),
3890 }
3891 }
3892
3893 pub fn variadic_or(mut args: Vec<HirScalarExpr>) -> HirScalarExpr {
3895 match args.len() {
3896 0 => HirScalarExpr::literal_false(), 1 => args.swap_remove(0),
3898 _ => HirScalarExpr::call_variadic(Or, args),
3899 }
3900 }
3901
3902 pub fn take(&mut self) -> Self {
3903 mem::replace(self, HirScalarExpr::literal_null(SqlScalarType::String))
3904 }
3905
3906 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3907 pub fn visit_columns<F>(&self, depth: usize, f: &mut F)
3913 where
3914 F: FnMut(usize, &ColumnRef),
3915 {
3916 #[allow(deprecated)]
3917 let _ = self.visit_recursively(depth, &mut |depth: usize,
3918 e: &HirScalarExpr|
3919 -> Result<(), ()> {
3920 if let HirScalarExpr::Column(col, _name) = e {
3921 f(depth, col)
3922 }
3923 Ok(())
3924 });
3925 }
3926
3927 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3928 pub fn visit_columns_mut<F>(&mut self, depth: usize, f: &mut F)
3930 where
3931 F: FnMut(usize, &mut ColumnRef),
3932 {
3933 #[allow(deprecated)]
3934 let _ = self.visit_recursively_mut(depth, &mut |depth: usize,
3935 e: &mut HirScalarExpr|
3936 -> Result<(), ()> {
3937 if let HirScalarExpr::Column(col, _name) = e {
3938 f(depth, col)
3939 }
3940 Ok(())
3941 });
3942 }
3943
3944 pub fn visit_columns_referring_to_root_level<F>(&self, f: &mut F)
3950 where
3951 F: FnMut(usize),
3952 {
3953 #[allow(deprecated)]
3954 let _ = self.visit_recursively(0, &mut |depth: usize,
3955 e: &HirScalarExpr|
3956 -> Result<(), ()> {
3957 if let HirScalarExpr::Column(col, _name) = e {
3958 if col.level == depth {
3959 f(col.column)
3960 }
3961 }
3962 Ok(())
3963 });
3964 }
3965
3966 pub fn visit_columns_referring_to_root_level_mut<F>(&mut self, f: &mut F)
3968 where
3969 F: FnMut(&mut usize),
3970 {
3971 #[allow(deprecated)]
3972 let _ = self.visit_recursively_mut(0, &mut |depth: usize,
3973 e: &mut HirScalarExpr|
3974 -> Result<(), ()> {
3975 if let HirScalarExpr::Column(col, _name) = e {
3976 if col.level == depth {
3977 f(&mut col.column)
3978 }
3979 }
3980 Ok(())
3981 });
3982 }
3983
3984 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
3985 pub fn visit_recursively<F, E>(&self, depth: usize, f: &mut F) -> Result<(), E>
3989 where
3990 F: FnMut(usize, &HirScalarExpr) -> Result<(), E>,
3991 {
3992 match self {
3993 HirScalarExpr::Literal(..)
3994 | HirScalarExpr::Parameter(..)
3995 | HirScalarExpr::CallUnmaterializable(..)
3996 | HirScalarExpr::Column(..) => (),
3997 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively(depth, f)?,
3998 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
3999 expr1.visit_recursively(depth, f)?;
4000 expr2.visit_recursively(depth, f)?;
4001 }
4002 HirScalarExpr::CallVariadic { exprs, .. } => {
4003 for expr in exprs {
4004 expr.visit_recursively(depth, f)?;
4005 }
4006 }
4007 HirScalarExpr::If {
4008 cond,
4009 then,
4010 els,
4011 name: _,
4012 } => {
4013 cond.visit_recursively(depth, f)?;
4014 then.visit_recursively(depth, f)?;
4015 els.visit_recursively(depth, f)?;
4016 }
4017 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4018 #[allow(deprecated)]
4019 expr.visit_scalar_expressions(depth + 1, &mut |e, depth| {
4020 e.visit_recursively(depth, f)
4021 })?;
4022 }
4023 HirScalarExpr::Windowing(expr, _name) => {
4024 expr.visit_expressions(&mut |e| e.visit_recursively(depth, f))?;
4025 }
4026 }
4027 f(depth, self)
4028 }
4029
4030 #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."]
4031 pub fn visit_recursively_mut<F, E>(&mut self, depth: usize, f: &mut F) -> Result<(), E>
4033 where
4034 F: FnMut(usize, &mut HirScalarExpr) -> Result<(), E>,
4035 {
4036 match self {
4037 HirScalarExpr::Literal(..)
4038 | HirScalarExpr::Parameter(..)
4039 | HirScalarExpr::CallUnmaterializable(..)
4040 | HirScalarExpr::Column(..) => (),
4041 HirScalarExpr::CallUnary { expr, .. } => expr.visit_recursively_mut(depth, f)?,
4042 HirScalarExpr::CallBinary { expr1, expr2, .. } => {
4043 expr1.visit_recursively_mut(depth, f)?;
4044 expr2.visit_recursively_mut(depth, f)?;
4045 }
4046 HirScalarExpr::CallVariadic { exprs, .. } => {
4047 for expr in exprs {
4048 expr.visit_recursively_mut(depth, f)?;
4049 }
4050 }
4051 HirScalarExpr::If {
4052 cond,
4053 then,
4054 els,
4055 name: _,
4056 } => {
4057 cond.visit_recursively_mut(depth, f)?;
4058 then.visit_recursively_mut(depth, f)?;
4059 els.visit_recursively_mut(depth, f)?;
4060 }
4061 HirScalarExpr::Exists(expr, _name) | HirScalarExpr::Select(expr, _name) => {
4062 #[allow(deprecated)]
4063 expr.visit_scalar_expressions_mut(depth + 1, &mut |e, depth| {
4064 e.visit_recursively_mut(depth, f)
4065 })?;
4066 }
4067 HirScalarExpr::Windowing(expr, _name) => {
4068 expr.visit_expressions_mut(&mut |e| e.visit_recursively_mut(depth, f))?;
4069 }
4070 }
4071 f(depth, self)
4072 }
4073
4074 fn simplify_to_literal(self) -> Option<Row> {
4083 let mut expr = self
4084 .lower_uncorrelated(crate::plan::lowering::Config::default())
4085 .ok()?;
4086 expr.reduce(&[]);
4090 match expr {
4091 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Some(row),
4092 _ => None,
4093 }
4094 }
4095
4096 fn simplify_to_literal_with_result(self) -> Result<Row, PlanError> {
4109 let mut expr = self
4110 .lower_uncorrelated(crate::plan::lowering::Config::default())
4111 .map_err(|err| {
4112 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes())
4113 })?;
4114 expr.reduce(&[]);
4118 match expr {
4119 mz_expr::MirScalarExpr::Literal(Ok(row), _) => Ok(row),
4120 mz_expr::MirScalarExpr::Literal(Err(err), _) => Err(
4121 PlanError::ConstantExpressionSimplificationFailed(err.to_string_with_causes()),
4122 ),
4123 _ => Err(PlanError::ConstantExpressionSimplificationFailed(
4124 "Not a constant".to_string(),
4125 )),
4126 }
4127 }
4128
4129 pub fn into_literal_int64(self) -> Option<i64> {
4138 self.simplify_to_literal().and_then(|row| {
4139 let datum = row.unpack_first();
4140 if datum.is_null() {
4141 None
4142 } else {
4143 Some(datum.unwrap_int64())
4144 }
4145 })
4146 }
4147
4148 pub fn into_literal_string(self) -> Option<String> {
4157 self.simplify_to_literal().and_then(|row| {
4158 let datum = row.unpack_first();
4159 if datum.is_null() {
4160 None
4161 } else {
4162 Some(datum.unwrap_str().to_owned())
4163 }
4164 })
4165 }
4166
4167 pub fn into_literal_mz_timestamp(self) -> Option<Timestamp> {
4180 self.simplify_to_literal().and_then(|row| {
4181 let datum = row.unpack_first();
4182 if datum.is_null() {
4183 None
4184 } else {
4185 Some(datum.unwrap_mz_timestamp())
4186 }
4187 })
4188 }
4189
4190 pub fn try_into_literal_int64(self) -> Result<i64, PlanError> {
4202 if !self.is_constant() {
4208 return Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4209 "Expected a constant expression, got {}",
4210 self
4211 )));
4212 }
4213 self.clone()
4214 .simplify_to_literal_with_result()
4215 .and_then(|row| {
4216 let datum = row.unpack_first();
4217 if datum.is_null() {
4218 Err(PlanError::ConstantExpressionSimplificationFailed(format!(
4219 "Expected an expression that evaluates to a non-null value, got {}",
4220 self
4221 )))
4222 } else {
4223 Ok(datum.unwrap_int64())
4224 }
4225 })
4226 }
4227
4228 pub fn contains_parameters(&self) -> bool {
4229 let mut contains_parameters = false;
4230 #[allow(deprecated)]
4231 let _ = self.visit_recursively(0, &mut |_depth: usize,
4232 expr: &HirScalarExpr|
4233 -> Result<(), ()> {
4234 if let HirScalarExpr::Parameter(..) = expr {
4235 contains_parameters = true;
4236 }
4237 Ok(())
4238 });
4239 contains_parameters
4240 }
4241
4242 fn direct_subqueries(&self) -> Vec<&HirRelationExpr> {
4243 let mut subqueries: Vec<&HirRelationExpr> = vec![];
4244
4245 let mut worklist = vec![self];
4246 while let Some(elt) = worklist.pop() {
4247 match elt {
4248 HirScalarExpr::Column(_, _)
4249 | HirScalarExpr::Parameter(_, _)
4250 | HirScalarExpr::Literal(_, _, _)
4251 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4252 HirScalarExpr::CallUnary {
4253 func: _,
4254 expr,
4255 name: _,
4256 } => worklist.push(&*expr),
4257 HirScalarExpr::CallBinary {
4258 func: _,
4259 expr1,
4260 expr2,
4261 name: _name,
4262 } => {
4263 worklist.push(&*expr2);
4265 worklist.push(&*expr1);
4266 }
4267 HirScalarExpr::CallVariadic {
4268 func: _,
4269 exprs,
4270 name: _name,
4271 } => {
4272 worklist.extend(exprs.iter().rev());
4273 }
4274 HirScalarExpr::If {
4275 cond,
4276 then,
4277 els,
4278 name: _,
4279 } => {
4280 worklist.push(&*els);
4281 worklist.push(&*then);
4282 worklist.push(&*cond);
4283 }
4284 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4285 subqueries.push(&*hir);
4286 }
4287 HirScalarExpr::Windowing(
4288 WindowExpr {
4289 func,
4290 partition_by,
4291 order_by,
4292 },
4293 _,
4294 ) => {
4295 worklist.extend(order_by.iter().rev());
4298 worklist.extend(partition_by.iter().rev());
4299 match func {
4300 WindowExprType::Scalar(_) => (),
4301 WindowExprType::Value(val) => worklist.push(&*val.args),
4302 WindowExprType::Aggregate(agg) => worklist.push(&*agg.aggregate_expr.expr),
4303 }
4304 }
4305 }
4306 }
4307
4308 subqueries
4309 }
4310
4311 fn direct_subqueries_mut(&mut self) -> Vec<&mut HirRelationExpr> {
4312 let mut subqueries: Vec<&mut HirRelationExpr> = vec![];
4313
4314 let mut worklist = vec![self];
4315 while let Some(elt) = worklist.pop() {
4316 match elt {
4317 HirScalarExpr::Column(_, _)
4318 | HirScalarExpr::Parameter(_, _)
4319 | HirScalarExpr::Literal(_, _, _)
4320 | HirScalarExpr::CallUnmaterializable(_, _) => (),
4321 HirScalarExpr::CallUnary {
4322 func: _,
4323 expr,
4324 name: _,
4325 } => worklist.push(&mut **expr),
4326 HirScalarExpr::CallBinary {
4327 func: _,
4328 expr1,
4329 expr2,
4330 name: _name,
4331 } => {
4332 worklist.push(&mut **expr2);
4334 worklist.push(&mut **expr1);
4335 }
4336 HirScalarExpr::CallVariadic {
4337 func: _,
4338 exprs,
4339 name: _name,
4340 } => {
4341 worklist.extend(exprs.iter_mut().rev());
4342 }
4343 HirScalarExpr::If {
4344 cond,
4345 then,
4346 els,
4347 name: _,
4348 } => {
4349 worklist.push(&mut **els);
4350 worklist.push(&mut **then);
4351 worklist.push(&mut **cond);
4352 }
4353 HirScalarExpr::Exists(hir, _) | HirScalarExpr::Select(hir, _) => {
4354 subqueries.push(&mut **hir);
4355 }
4356 HirScalarExpr::Windowing(
4357 WindowExpr {
4358 func,
4359 partition_by,
4360 order_by,
4361 },
4362 _,
4363 ) => {
4364 worklist.extend(order_by.iter_mut().rev());
4367 worklist.extend(partition_by.iter_mut().rev());
4368 match func {
4369 WindowExprType::Scalar(_) => (),
4370 WindowExprType::Value(val) => worklist.push(&mut val.args),
4371 WindowExprType::Aggregate(agg) => {
4372 worklist.push(&mut agg.aggregate_expr.expr)
4373 }
4374 }
4375 }
4376 }
4377 }
4378
4379 subqueries
4380 }
4381}
4382
4383impl VisitChildren<Self> for HirScalarExpr {
4389 fn visit_children<F>(&self, mut f: F)
4390 where
4391 F: FnMut(&Self),
4392 {
4393 use HirScalarExpr::*;
4394 match self {
4395 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4396 CallUnary { expr, .. } => f(expr),
4397 CallBinary { expr1, expr2, .. } => {
4398 f(expr1);
4399 f(expr2);
4400 }
4401 CallVariadic { exprs, .. } => {
4402 for expr in exprs {
4403 f(expr);
4404 }
4405 }
4406 If {
4407 cond,
4408 then,
4409 els,
4410 name: _,
4411 } => {
4412 f(cond);
4413 f(then);
4414 f(els);
4415 }
4416 Exists(..) | Select(..) => (),
4417 Windowing(expr, _name) => expr.visit_children(f),
4418 }
4419 }
4420
4421 fn visit_mut_children<F>(&mut self, mut f: F)
4422 where
4423 F: FnMut(&mut Self),
4424 {
4425 use HirScalarExpr::*;
4426 match self {
4427 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4428 CallUnary { expr, .. } => f(expr),
4429 CallBinary { expr1, expr2, .. } => {
4430 f(expr1);
4431 f(expr2);
4432 }
4433 CallVariadic { exprs, .. } => {
4434 for expr in exprs {
4435 f(expr);
4436 }
4437 }
4438 If {
4439 cond,
4440 then,
4441 els,
4442 name: _,
4443 } => {
4444 f(cond);
4445 f(then);
4446 f(els);
4447 }
4448 Exists(..) | Select(..) => (),
4449 Windowing(expr, _name) => expr.visit_mut_children(f),
4450 }
4451 }
4452
4453 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4454 where
4455 F: FnMut(&Self) -> Result<(), E>,
4456 {
4457 use HirScalarExpr::*;
4458 match self {
4459 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4460 CallUnary { expr, .. } => f(expr)?,
4461 CallBinary { expr1, expr2, .. } => {
4462 f(expr1)?;
4463 f(expr2)?;
4464 }
4465 CallVariadic { exprs, .. } => {
4466 for expr in exprs {
4467 f(expr)?;
4468 }
4469 }
4470 If {
4471 cond,
4472 then,
4473 els,
4474 name: _,
4475 } => {
4476 f(cond)?;
4477 f(then)?;
4478 f(els)?;
4479 }
4480 Exists(..) | Select(..) => (),
4481 Windowing(expr, _name) => expr.try_visit_children(f)?,
4482 }
4483 Ok(())
4484 }
4485
4486 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4487 where
4488 F: FnMut(&mut Self) -> Result<(), E>,
4489 {
4490 use HirScalarExpr::*;
4491 match self {
4492 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (),
4493 CallUnary { expr, .. } => f(expr)?,
4494 CallBinary { expr1, expr2, .. } => {
4495 f(expr1)?;
4496 f(expr2)?;
4497 }
4498 CallVariadic { exprs, .. } => {
4499 for expr in exprs {
4500 f(expr)?;
4501 }
4502 }
4503 If {
4504 cond,
4505 then,
4506 els,
4507 name: _,
4508 } => {
4509 f(cond)?;
4510 f(then)?;
4511 f(els)?;
4512 }
4513 Exists(..) | Select(..) => (),
4514 Windowing(expr, _name) => expr.try_visit_mut_children(f)?,
4515 }
4516 Ok(())
4517 }
4518
4519 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self>
4520 where
4521 Self: 'a,
4522 {
4523 use HirScalarExpr::*;
4524 let v: Vec<&Self> = match self {
4525 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4526 CallUnary { expr, .. } => vec![&*expr],
4527 CallBinary { expr1, expr2, .. } => {
4528 vec![&*expr1, &*expr2]
4529 }
4530 CallVariadic { exprs, .. } => exprs.iter().collect(),
4531 If {
4532 cond,
4533 then,
4534 els,
4535 name: _,
4536 } => {
4537 vec![&*cond, &*then, &*els]
4538 }
4539 Exists(..) | Select(..) => vec![],
4540 Windowing(expr, _name) => expr.children().collect(),
4541 };
4542 v.into_iter()
4543 }
4544
4545 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut Self>
4546 where
4547 Self: 'a,
4548 {
4549 use HirScalarExpr::*;
4550 let v: Vec<&mut Self> = match self {
4551 Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => vec![],
4552 CallUnary { expr, .. } => vec![&mut **expr],
4553 CallBinary { expr1, expr2, .. } => {
4554 vec![&mut **expr1, &mut **expr2]
4555 }
4556 CallVariadic { exprs, .. } => exprs.iter_mut().collect(),
4557 If {
4558 cond,
4559 then,
4560 els,
4561 name: _,
4562 } => {
4563 vec![&mut **cond, &mut **then, &mut **els]
4564 }
4565 Exists(..) | Select(..) => vec![],
4566 Windowing(expr, _name) => expr.children_mut().collect(),
4567 };
4568 v.into_iter()
4569 }
4570}
4571
4572impl VisitChildren<HirRelationExpr> for HirScalarExpr {
4575 fn visit_children<F>(&self, mut f: F)
4576 where
4577 F: FnMut(&HirRelationExpr),
4578 {
4579 use HirScalarExpr::*;
4580 match self {
4581 Column(..)
4582 | Parameter(..)
4583 | Literal(..)
4584 | CallUnmaterializable(..)
4585 | CallUnary { .. }
4586 | CallBinary { .. }
4587 | CallVariadic { .. }
4588 | If { .. }
4589 | Windowing(..) => (),
4590 Exists(expr, _name) | Select(expr, _name) => f(expr),
4591 }
4592 }
4593
4594 fn visit_mut_children<F>(&mut self, mut f: F)
4595 where
4596 F: FnMut(&mut HirRelationExpr),
4597 {
4598 use HirScalarExpr::*;
4599 match self {
4600 Column(..)
4601 | Parameter(..)
4602 | Literal(..)
4603 | CallUnmaterializable(..)
4604 | CallUnary { .. }
4605 | CallBinary { .. }
4606 | CallVariadic { .. }
4607 | If { .. }
4608 | Windowing(..) => (),
4609 Exists(expr, _name) | Select(expr, _name) => f(expr),
4610 }
4611 }
4612
4613 fn try_visit_children<F, E>(&self, mut f: F) -> Result<(), E>
4614 where
4615 F: FnMut(&HirRelationExpr) -> Result<(), E>,
4616 {
4617 use HirScalarExpr::*;
4618 match self {
4619 Column(..)
4620 | Parameter(..)
4621 | Literal(..)
4622 | CallUnmaterializable(..)
4623 | CallUnary { .. }
4624 | CallBinary { .. }
4625 | CallVariadic { .. }
4626 | If { .. }
4627 | Windowing(..) => (),
4628 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4629 }
4630 Ok(())
4631 }
4632
4633 fn try_visit_mut_children<F, E>(&mut self, mut f: F) -> Result<(), E>
4634 where
4635 F: FnMut(&mut HirRelationExpr) -> Result<(), E>,
4636 {
4637 use HirScalarExpr::*;
4638 match self {
4639 Column(..)
4640 | Parameter(..)
4641 | Literal(..)
4642 | CallUnmaterializable(..)
4643 | CallUnary { .. }
4644 | CallBinary { .. }
4645 | CallVariadic { .. }
4646 | If { .. }
4647 | Windowing(..) => (),
4648 Exists(expr, _name) | Select(expr, _name) => f(expr)?,
4649 }
4650 Ok(())
4651 }
4652
4653 fn children<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a HirRelationExpr>
4654 where
4655 HirRelationExpr: 'a,
4656 {
4657 let mut child: Option<&HirRelationExpr> = None;
4658 use HirScalarExpr::*;
4659 match self {
4660 Column(..)
4661 | Parameter(..)
4662 | Literal(..)
4663 | CallUnmaterializable(..)
4664 | CallUnary { .. }
4665 | CallBinary { .. }
4666 | CallVariadic { .. }
4667 | If { .. }
4668 | Windowing(..) => (),
4669 Exists(expr, _name) | Select(expr, _name) => child = Some(&*expr),
4670 }
4671
4672 child.into_iter()
4673 }
4674
4675 fn children_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut HirRelationExpr>
4676 where
4677 HirRelationExpr: 'a,
4678 {
4679 let mut child: Option<&mut HirRelationExpr> = None;
4680 use HirScalarExpr::*;
4681 match self {
4682 Column(..)
4683 | Parameter(..)
4684 | Literal(..)
4685 | CallUnmaterializable(..)
4686 | CallUnary { .. }
4687 | CallBinary { .. }
4688 | CallVariadic { .. }
4689 | If { .. }
4690 | Windowing(..) => (),
4691 Exists(expr, _name) | Select(expr, _name) => child = Some(&mut **expr),
4692 }
4693
4694 child.into_iter()
4695 }
4696}
4697
4698impl AbstractExpr for HirScalarExpr {
4699 type Type = SqlColumnType;
4700
4701 fn typ(
4702 &self,
4703 outers: &[SqlRelationType],
4704 inner: &SqlRelationType,
4705 params: &BTreeMap<usize, SqlScalarType>,
4706 ) -> Self::Type {
4707 stack::maybe_grow(|| match self {
4708 HirScalarExpr::Column(ColumnRef { level, column }, _name) => {
4709 if *level == 0 {
4710 inner.column_types[*column].clone()
4711 } else {
4712 outers[*level - 1].column_types[*column].clone()
4713 }
4714 }
4715 HirScalarExpr::Parameter(n, _name) => params[n].clone().nullable(true),
4716 HirScalarExpr::Literal(_, typ, _name) => typ.clone(),
4717 HirScalarExpr::CallUnmaterializable(func, _name) => func.output_sql_type(),
4718 HirScalarExpr::CallUnary {
4719 expr,
4720 func,
4721 name: _,
4722 } => func.output_sql_type(expr.typ(outers, inner, params)),
4723 HirScalarExpr::CallBinary {
4724 expr1,
4725 expr2,
4726 func,
4727 name: _,
4728 } => func.output_sql_type(&[
4729 expr1.typ(outers, inner, params),
4730 expr2.typ(outers, inner, params),
4731 ]),
4732 HirScalarExpr::CallVariadic {
4733 exprs,
4734 func,
4735 name: _,
4736 } => func.output_sql_type(exprs.iter().map(|e| e.typ(outers, inner, params)).collect()),
4737 HirScalarExpr::If {
4738 cond: _,
4739 then,
4740 els,
4741 name: _,
4742 } => {
4743 let then_type = then.typ(outers, inner, params);
4744 let else_type = els.typ(outers, inner, params);
4745 then_type.sql_union(&else_type).unwrap() }
4747 HirScalarExpr::Exists(_, _name) => SqlScalarType::Bool.nullable(true),
4748 HirScalarExpr::Select(expr, _name) => {
4749 let mut outers = outers.to_vec();
4750 outers.insert(0, inner.clone());
4751 expr.typ(&outers, params)
4752 .column_types
4753 .into_element()
4754 .nullable(true)
4755 }
4756 HirScalarExpr::Windowing(expr, _name) => expr.func.typ(outers, inner, params),
4757 })
4758 }
4759}
4760
4761impl AggregateExpr {
4762 pub fn typ(
4763 &self,
4764 outers: &[SqlRelationType],
4765 inner: &SqlRelationType,
4766 params: &BTreeMap<usize, SqlScalarType>,
4767 ) -> SqlColumnType {
4768 self.func
4769 .output_sql_type(self.expr.typ(outers, inner, params))
4770 }
4771
4772 pub fn is_count_asterisk(&self) -> bool {
4780 self.func == AggregateFunc::Count && self.expr.is_literal_true() && !self.distinct
4781 }
4782}