Skip to content

Commit 035d97e

Browse files
committed
introduce IdPred and make AttributeRefPred store table id and attr index
1 parent 51da144 commit 035d97e

File tree

6 files changed

+75
-29
lines changed

6 files changed

+75
-29
lines changed

optd-cost-model/src/common/nodes.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub enum PredicateType {
5151
Constant(ConstantType),
5252
AttributeRef,
5353
ExternAttributeRef,
54+
Id,
5455
UnOp(UnOpType),
5556
BinOp(BinOpType),
5657
LogOp(LogOpType),
@@ -79,16 +80,6 @@ pub struct PredicateNode {
7980
/// Child predicate nodes, always materialized
8081
pub children: Vec<ArcPredicateNode>,
8182
/// Data associated with the predicate, if any
82-
/// TODO: If it is PredicateType::AttributeRef, then
83-
/// the data is attribute index. But we need more information
84-
/// to represent this attribute in case it is a derived attribute.
85-
/// 1. We can use Vec<Value>, but the disadvantage is that the optimizer
86-
/// may need to do some memory copy. (However, if we want to provide a
87-
/// general API, the memory copy is unavoidable. It applies for both 1
88-
/// and 2 designs). And Vec<Value> lacks readability.
89-
/// 2. Also we can use enum, but if Rust uses something like `union` to
90-
/// implement enum, then if some members are large, it will waste memory space,
91-
/// also causing unnecessary memory copy. But enum provides better readability.
9283
pub data: Option<Value>,
9384
}
9485

optd-cost-model/src/common/predicates/attr_ref_pred.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
1-
use crate::common::{
2-
nodes::{ArcPredicateNode, PredicateNode, PredicateType, ReprPredicateNode},
3-
values::Value,
4-
};
1+
use crate::common::nodes::{ArcPredicateNode, PredicateNode, PredicateType, ReprPredicateNode};
52

3+
use super::id_pred::IdPred;
4+
5+
/// [`AttributeRefPred`] represents a reference to a column in a relation.
6+
///
7+
/// An [`AttributeRefPred`] has two children:
8+
/// 1. The table id, represented by an [`IdPred`].
9+
/// 2. The index of the column, represented by an [`IdPred`].
610
#[derive(Clone, Debug)]
711
pub struct AttributeRefPred(pub ArcPredicateNode);
812

913
impl AttributeRefPred {
10-
/// Creates a new `ColumnRef` expression.
11-
pub fn new(attribute_idx: usize) -> AttributeRefPred {
12-
// this conversion is always safe since usize is at most u64
13-
let u64_attribute_idx = attribute_idx as u64;
14+
pub fn new(table_id: usize, attribute_idx: usize) -> AttributeRefPred {
1415
AttributeRefPred(
1516
PredicateNode {
1617
typ: PredicateType::AttributeRef,
17-
children: vec![],
18-
data: Some(Value::UInt64(u64_attribute_idx)),
18+
children: vec![
19+
IdPred::new(table_id).into_pred_node(),
20+
IdPred::new(attribute_idx).into_pred_node(),
21+
],
22+
data: None,
1923
}
2024
.into(),
2125
)
2226
}
2327

24-
fn get_data_usize(&self) -> usize {
25-
self.0.data.as_ref().unwrap().as_u64() as usize
28+
/// Gets the table id.
29+
pub fn table_id(&self) -> usize {
30+
self.0.child(0).data.as_ref().unwrap().as_u64() as usize
2631
}
2732

28-
/// Gets the column index.
29-
pub fn index(&self) -> usize {
30-
self.get_data_usize()
33+
/// Gets the attribute index.
34+
pub fn attr_index(&self) -> usize {
35+
self.0.child(1).data.as_ref().unwrap().as_u64() as usize
3136
}
3237
}
3338

optd-cost-model/src/common/predicates/cast_pred.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ use crate::common::nodes::{ArcPredicateNode, PredicateNode, PredicateType, ReprP
44

55
use super::data_type_pred::DataTypePred;
66

7+
/// [`CastPred`] casts a column from one data type to another.
8+
///
9+
/// A [`CastPred`] has two children:
10+
/// 1. The original data to cast
11+
/// 2. The target data type to cast to
712
#[derive(Clone, Debug)]
813
pub struct CastPred(pub ArcPredicateNode);
914

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::common::{
2+
nodes::{ArcPredicateNode, PredicateNode, PredicateType, ReprPredicateNode},
3+
values::Value,
4+
};
5+
6+
/// [`IdPred`] holds an id or an index, e.g. table id.
7+
///
8+
/// The data is of uint64 type, because an id or an index can always be
9+
/// represented by uint64.
10+
#[derive(Clone, Debug)]
11+
pub struct IdPred(pub ArcPredicateNode);
12+
13+
impl IdPred {
14+
pub fn new(id: usize) -> IdPred {
15+
// This conversion is always safe since usize is at most u64.
16+
let u64_id = id as u64;
17+
IdPred(
18+
PredicateNode {
19+
typ: PredicateType::Id,
20+
children: vec![],
21+
data: Some(Value::UInt64(u64_id)),
22+
}
23+
.into(),
24+
)
25+
}
26+
}
27+
28+
impl ReprPredicateNode for IdPred {
29+
fn into_pred_node(self) -> ArcPredicateNode {
30+
self.0
31+
}
32+
33+
fn from_pred_node(pred_node: ArcPredicateNode) -> Option<Self> {
34+
if let PredicateType::Id = pred_node.typ {
35+
Some(Self(pred_node))
36+
} else {
37+
None
38+
}
39+
}
40+
}

optd-cost-model/src/common/predicates/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod cast_pred;
44
pub mod constant_pred;
55
pub mod data_type_pred;
66
pub mod func_pred;
7+
pub mod id_pred;
78
pub mod in_list_pred;
89
pub mod like_pred;
910
pub mod list_pred;

optd-cost-model/src/cost/filter.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
189189
let attr_ref_expr = attr_ref_exprs
190190
.first()
191191
.expect("we just checked that attr_ref_exprs.len() == 1");
192-
let attr_ref_idx = attr_ref_expr.index();
192+
let attr_ref_idx = attr_ref_expr.attr_index();
193193

194194
// TODO: Consider attribute is a derived attribute
195195
if values.len() == 1 {
@@ -415,7 +415,9 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
415415
return Ok(UNIMPLEMENTED_SEL);
416416
}
417417

418-
let attr_ref_idx = AttributeRefPred::from_pred_node(child).unwrap().index();
418+
let attr_ref_idx = AttributeRefPred::from_pred_node(child)
419+
.unwrap()
420+
.attr_index();
419421

420422
// TODO: Consider attribute is a derived attribute
421423
let pattern = ConstantPred::from_pred_node(pattern)
@@ -486,7 +488,9 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
486488
}
487489

488490
// Convert child and const expressions to concrete types.
489-
let attr_ref_idx = AttributeRefPred::from_pred_node(child).unwrap().index();
491+
let attr_ref_idx = AttributeRefPred::from_pred_node(child)
492+
.unwrap()
493+
.attr_index();
490494
let list_exprs = list_exprs
491495
.into_iter()
492496
.map(|expr| {
@@ -581,7 +585,7 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
581585
PredicateType::AttributeRef => {
582586
let attr_ref_expr = AttributeRefPred::from_pred_node(cast_expr_child)
583587
.expect("we already checked that the type is AttributeRef");
584-
let attr_ref_idx = attr_ref_expr.index();
588+
let attr_ref_idx = attr_ref_expr.attr_index();
585589
cast_node = attr_ref_expr.into_pred_node();
586590
// The "invert" cast is to invert the cast so that we're casting the
587591
// non_cast_node to the attribute's original type.

0 commit comments

Comments
 (0)