7
7
// the Business Source License, use of this software will be governed
8
8
// by the Apache License, Version 2.0.
9
9
10
- //! Defines the [`NonNullRequirements `] attribute.
10
+ //! Defines the [`PropagatedNulls `] attribute.
11
11
//!
12
12
//! The attribute value is a vector of column references corresponding
13
13
//! to the columns of the associated `QueryBox`.
@@ -20,15 +20,15 @@ use crate::query_model::model::{BoxId, BoxScalarExpr, ColumnReference, Model};
20
20
use std:: collections:: HashSet ;
21
21
22
22
#[ derive( Debug , PartialEq , Eq , Clone , Hash ) ]
23
- pub ( crate ) struct NonNullRequirements ;
23
+ pub ( crate ) struct PropagatedNulls ;
24
24
25
- impl AttributeKey for NonNullRequirements {
25
+ impl AttributeKey for PropagatedNulls {
26
26
type Value = Vec < HashSet < ColumnReference > > ;
27
27
}
28
28
29
- impl Attribute for NonNullRequirements {
29
+ impl Attribute for PropagatedNulls {
30
30
fn attr_id ( & self ) -> & ' static str {
31
- "NonNullRequirements "
31
+ "PropagatedNulls "
32
32
}
33
33
34
34
fn requires ( & self ) -> Vec < Box < dyn Attribute > > {
@@ -41,19 +41,19 @@ impl Attribute for NonNullRequirements {
41
41
let value = r#box
42
42
. columns
43
43
. iter ( )
44
- . map ( |x| non_null_requirements ( & x. expr ) )
44
+ . map ( |x| propagated_nulls ( & x. expr ) )
45
45
. collect :: < Vec < _ > > ( ) ;
46
46
47
47
// TODO: remove this
48
48
// println!("|box[{}].columns| = {:?}", box_id, r#box.columns.len());
49
49
// println!("attr[{}] = {:?}", box_id, value);
50
50
51
- r#box. attributes . set :: < NonNullRequirements > ( value) ;
51
+ r#box. attributes . set :: < PropagatedNulls > ( value) ;
52
52
}
53
53
}
54
54
55
55
/// Returns all columns that *must* be non-Null for the `expr` to be non-Null.
56
- pub ( crate ) fn non_null_requirements ( expr : & BoxScalarExpr ) -> HashSet < ColumnReference > {
56
+ pub ( crate ) fn propagated_nulls ( expr : & BoxScalarExpr ) -> HashSet < ColumnReference > {
57
57
use BoxScalarExpr :: * ;
58
58
let mut result = HashSet :: new ( ) ;
59
59
@@ -86,9 +86,12 @@ pub(crate) fn non_null_requirements(expr: &BoxScalarExpr) -> HashSet<ColumnRefer
86
86
Some ( vec ! [ ] )
87
87
}
88
88
}
89
- // The branches of an if are computed lazily, but the condition is not
90
- // so we can descend into it safely
91
- If { cond, .. } => Some ( vec ! [ cond] ) ,
89
+ // The branches of an if are computed lazily, but the condition is not.
90
+ // However, nulls propagate to the condition are cast to false.
91
+ // Consequently, we currently don't do anything here.
92
+ // TODO: I think we might be able to take use the intersection of the
93
+ // results in the two branches.
94
+ If { .. } => Some ( vec ! [ ] ) ,
92
95
// TODO the non-null requeriments of an aggregate expression can
93
96
// be pused down to, for example, convert an outer join into an
94
97
// inner join
@@ -133,19 +136,19 @@ mod tests {
133
136
exp:: gt ( exp:: cref ( q_id, 0 ) , exp:: cref ( q_id, 1 ) ) ,
134
137
exp:: gt ( exp:: cref ( q_id, 2 ) , exp:: cref ( q_id, 3 ) ) ,
135
138
) ) ;
136
- // C1 : (#0 > #1) && isnull(#1)
139
+ // C2 : (#0 > #1) && isnull(#1)
137
140
b. add_column ( exp:: and (
138
141
exp:: gt ( exp:: cref ( q_id, 0 ) , exp:: cref ( q_id, 1 ) ) ,
139
142
exp:: not ( exp:: isnull ( exp:: cref ( q_id, 1 ) ) ) ,
140
143
) ) ;
141
144
}
142
145
143
- NonNullRequirements . derive ( & mut model, s_id) ;
146
+ PropagatedNulls . derive ( & mut model, s_id) ;
144
147
145
148
{
146
149
let s_box = model. get_box ( s_id) ;
147
150
148
- let act_value = s_box. attributes . get :: < NonNullRequirements > ( ) ;
151
+ let act_value = s_box. attributes . get :: < PropagatedNulls > ( ) ;
149
152
let exp_value = & vec ! [
150
153
HashSet :: from( [ cref( q_id, 0 ) , cref( q_id, 1 ) , cref( q_id, 2 ) , cref( q_id, 3 ) ] ) ,
151
154
HashSet :: from( [ ] ) ,
0 commit comments