@@ -29,7 +29,7 @@ use mz_ore::collections::CollectionExt;
2929use mz_ore:: iter:: IteratorExt ;
3030use mz_ore:: stack:: RecursionLimitError ;
3131use mz_ore:: vec:: swap_remove_multiple;
32- use mz_repr:: { GlobalId , Row } ;
32+ use mz_repr:: { GlobalId , RelationType , Row } ;
3333
3434use crate :: canonicalize_mfp:: CanonicalizeMfp ;
3535use crate :: notice:: IndexTooWideForLiteralConstraints ;
@@ -70,7 +70,9 @@ impl LiteralConstraints {
7070 relation. try_visit_mut_children ( |e| self . action ( e, transform_ctx) ) ?;
7171
7272 if let MirRelationExpr :: Get {
73- id : Id :: Global ( id) , ..
73+ id : Id :: Global ( id) ,
74+ ref typ,
75+ ..
7476 } = * relation
7577 {
7678 let orig_mfp = mfp. clone ( ) ;
@@ -87,10 +89,11 @@ impl LiteralConstraints {
8789 mfp : & mut MapFilterProject ,
8890 orig_mfp : & MapFilterProject ,
8991 relation : & MirRelationExpr ,
92+ relation_type : RelationType ,
9093 ) {
9194 // undo list_of_predicates_to_and_of_predicates, distribute_and_over_or, unary_and
9295 // (It undoes the latter 2 through `MirScalarExp::reduce`.)
93- LiteralConstraints :: canonicalize_predicates ( mfp, relation) ;
96+ LiteralConstraints :: canonicalize_predicates ( mfp, relation, relation_type ) ;
9497 // undo inline_literal_constraints
9598 mfp. optimize ( ) ;
9699 // We can usually undo, but sometimes not (see comment on `distribute_and_over_or`),
@@ -109,14 +112,16 @@ impl LiteralConstraints {
109112 // todo: We might want to also call `canonicalize_equivalences`,
110113 // see near the end of literal_constraints.slt.
111114
115+ let inp_typ = typ. clone ( ) ;
116+
112117 let key_val = Self :: detect_literal_constraints ( & mfp, id, transform_ctx) ;
113118
114119 match key_val {
115120 None => {
116121 // We didn't find a usable index, so no chance to remove literal constraints.
117122 // But, we might have removed contradicting OR args.
118123 if removed_contradicting_or_args {
119- undo_preparation ( & mut mfp, & orig_mfp, relation) ;
124+ undo_preparation ( & mut mfp, & orig_mfp, relation, inp_typ ) ;
120125 } else {
121126 // We didn't remove anything, so let's go with the original MFP.
122127 mfp = orig_mfp;
@@ -130,7 +135,7 @@ impl LiteralConstraints {
130135 {
131136 // We were able to remove the literal constraints or contradicting OR args,
132137 // so we would like to use this new MFP, so we try undoing the preparation.
133- undo_preparation ( & mut mfp, & orig_mfp, relation) ;
138+ undo_preparation ( & mut mfp, & orig_mfp, relation, inp_typ . clone ( ) ) ;
134139 } else {
135140 // We were not able to remove the literal constraint, so `mfp` is
136141 // equivalent to `orig_mfp`, but `orig_mfp` is often simpler (or the same).
@@ -140,7 +145,6 @@ impl LiteralConstraints {
140145 // We transform the Get into a semi-join with a constant collection.
141146
142147 let inp_id = id. clone ( ) ;
143- let inp_typ = relation. typ ( ) ;
144148 let filter_list = MirRelationExpr :: Constant {
145149 rows : Ok ( possible_vals. iter ( ) . map ( |val| ( val. clone ( ) , 1 ) ) . collect ( ) ) ,
146150 typ : mz_repr:: RelationType {
@@ -164,10 +168,7 @@ impl LiteralConstraints {
164168 if possible_vals. is_empty ( ) {
165169 // Even better than what we were hoping for: Found contradicting
166170 // literal constraints, so the whole relation is empty.
167- * relation = MirRelationExpr :: Constant {
168- rows : Ok ( Vec :: new ( ) ) ,
169- typ : relation. typ ( ) ,
170- } ;
171+ relation. take_safely ( Some ( inp_typ) ) ;
171172 } else {
172173 // The common case: We need to build the join which is the main point of
173174 // this transform.
@@ -610,9 +611,16 @@ impl LiteralConstraints {
610611 }
611612
612613 /// Call [mz_expr::canonicalize::canonicalize_predicates] on each of the predicates in the MFP.
613- fn canonicalize_predicates ( mfp : & mut MapFilterProject , relation : & MirRelationExpr ) {
614+ fn canonicalize_predicates (
615+ mfp : & mut MapFilterProject ,
616+ relation : & MirRelationExpr ,
617+ relation_type : RelationType ,
618+ ) {
614619 let ( map, mut predicates, project) = mfp. as_map_filter_project ( ) ;
615- let typ_after_map = relation. clone ( ) . map ( map. clone ( ) ) . typ ( ) ;
620+ let typ_after_map = relation
621+ . clone ( )
622+ . map ( map. clone ( ) )
623+ . typ_with_input_types ( & [ relation_type] ) ;
616624 canonicalize_predicates ( & mut predicates, & typ_after_map. column_types ) ;
617625 // Rebuild the MFP with the new predicates.
618626 * mfp = MapFilterProject :: new ( mfp. input_arity )
0 commit comments