Skip to content

Commit d041a7e

Browse files
authored
chore(tesseract): Refactor: remove tables from symbols (cube-js#10475)
1 parent 0572494 commit d041a7e

36 files changed

Lines changed: 521 additions & 244 deletions

rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::query_tools::QueryTools;
2-
use super::sql_evaluator::MemberSymbol;
3-
use super::{evaluate_with_context, VisitorContext};
2+
use super::sql_evaluator::{CubeRef, CubeTableSymbol};
3+
use super::VisitorContext;
44
use crate::cube_bridge::cube_definition::CubeDefinition;
55
use crate::planner::sql_templates::PlanSqlTemplates;
66
use cubenativeutils::CubeError;
@@ -10,15 +10,15 @@ use std::rc::Rc;
1010
pub struct BaseCube {
1111
cube_name: String,
1212
members: HashSet<String>,
13-
member_evaluator: Rc<MemberSymbol>,
13+
cube_table_symbol: Rc<CubeTableSymbol>,
1414
definition: Rc<dyn CubeDefinition>,
1515
query_tools: Rc<QueryTools>,
1616
}
1717
impl BaseCube {
1818
pub fn try_new(
1919
cube_name: String,
2020
query_tools: Rc<QueryTools>,
21-
member_evaluator: Rc<MemberSymbol>,
21+
cube_table_symbol: Rc<CubeTableSymbol>,
2222
) -> Result<Rc<Self>, CubeError> {
2323
let definition = query_tools
2424
.cube_evaluator()
@@ -32,7 +32,7 @@ impl BaseCube {
3232
Ok(Rc::new(Self {
3333
cube_name,
3434
members,
35-
member_evaluator,
35+
cube_table_symbol,
3636
definition,
3737
query_tools,
3838
}))
@@ -43,8 +43,13 @@ impl BaseCube {
4343
context: Rc<VisitorContext>,
4444
templates: &PlanSqlTemplates,
4545
) -> Result<String, CubeError> {
46-
let cube_sql = evaluate_with_context(&self.member_evaluator, context, templates)?;
47-
Ok(cube_sql)
46+
let cube_ref = CubeRef::Table {
47+
symbol: self.cube_table_symbol.clone(),
48+
path: vec![],
49+
};
50+
let visitor = context.make_visitor(context.query_tools());
51+
let node_processor = context.node_processor();
52+
visitor.evaluate_cube_ref(&cube_ref, node_processor, templates)
4853
}
4954

5055
pub fn name(&self) -> &String {

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/collectors/calc_group_dims_collector.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ impl TraversalVisitor for CalcGroupDimsCollector {
4141
return self.on_node_traverse(e.base_symbol(), path, &())
4242
}
4343
MemberSymbol::Measure(_) => {}
44-
MemberSymbol::CubeName(_) => {}
45-
MemberSymbol::CubeTable(_) => {}
4644
MemberSymbol::MemberExpression(_) => {}
4745
};
4846
Ok(Some(()))

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/collectors/cube_names_collector.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::planner::sql_evaluator::{MemberSymbol, TraversalVisitor};
1+
use crate::planner::sql_evaluator::{CubeRef, MemberSymbol, TraversalVisitor};
22
use cubenativeutils::CubeError;
33
use std::collections::HashSet;
44
use std::rc::Rc;
@@ -56,19 +56,22 @@ impl TraversalVisitor for CubeNamesCollector {
5656
}
5757
}
5858
}
59-
MemberSymbol::CubeName(e) => {
60-
if !path.is_empty() {
61-
for p in path {
62-
self.names.insert(p.clone());
63-
}
64-
}
65-
self.names.insert(e.cube_name().clone());
66-
}
67-
MemberSymbol::CubeTable(_) => {}
6859
MemberSymbol::MemberExpression(_) => {}
6960
};
7061
Ok(Some(()))
7162
}
63+
64+
fn on_cube_ref(&mut self, cube_ref: &CubeRef, _state: &Self::State) -> Result<(), CubeError> {
65+
if let CubeRef::Name { symbol, path, .. } = cube_ref {
66+
if !path.is_empty() {
67+
for p in path {
68+
self.names.insert(p.clone());
69+
}
70+
}
71+
self.names.insert(symbol.cube_name().clone());
72+
}
73+
Ok(())
74+
}
7275
}
7376

7477
pub fn collect_cube_names(node: &Rc<MemberSymbol>) -> Result<Vec<String>, CubeError> {

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/collectors/join_hints_collector.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cube_bridge::join_hints::JoinHintItem;
2-
use crate::planner::sql_evaluator::{MemberSymbol, TraversalVisitor};
2+
use crate::planner::sql_evaluator::{CubeRef, MemberSymbol, TraversalVisitor};
33
use cubenativeutils::CubeError;
44
use itertools::Itertools;
55
use std::rc::Rc;
@@ -77,20 +77,24 @@ impl TraversalVisitor for JoinHintsCollector {
7777
}
7878
}
7979
}
80-
MemberSymbol::CubeName(e) => {
81-
if !path.is_empty() {
82-
let mut path = path.clone();
83-
path.push(e.cube_name().clone());
84-
self.hints.push(JoinHintItem::Vector(path));
85-
} else {
86-
self.hints.push(JoinHintItem::Single(e.cube_name().clone()));
87-
}
88-
}
89-
MemberSymbol::CubeTable(_) => {}
9080
MemberSymbol::MemberExpression(_) => {}
9181
};
9282
Ok(Some(()))
9383
}
84+
85+
fn on_cube_ref(&mut self, cube_ref: &CubeRef, _state: &Self::State) -> Result<(), CubeError> {
86+
if let CubeRef::Name { symbol, path, .. } = cube_ref {
87+
if !path.is_empty() {
88+
let mut path = path.clone();
89+
path.push(symbol.cube_name().clone());
90+
self.hints.push(JoinHintItem::Vector(path));
91+
} else {
92+
self.hints
93+
.push(JoinHintItem::Single(symbol.cube_name().clone()));
94+
}
95+
}
96+
Ok(())
97+
}
9498
}
9599

96100
pub fn collect_join_hints(node: &Rc<MemberSymbol>) -> Result<Vec<JoinHintItem>, CubeError> {

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/collectors/member_childs_collector.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ impl TraversalVisitor for MemberChildsCollector {
3838
) -> Result<Option<Self::State>, CubeError> {
3939
if state.is_root {
4040
let new_state = MemberChildsCollectorState::new(false);
41-
match node.as_ref() {
42-
MemberSymbol::Measure(_) => Ok(Some(new_state)),
43-
MemberSymbol::Dimension(_) => Ok(Some(new_state)),
44-
MemberSymbol::TimeDimension(_) => Ok(Some(new_state)),
45-
MemberSymbol::MemberExpression(_) => Ok(Some(new_state)),
46-
_ => Ok(None),
47-
}
41+
Ok(Some(new_state))
4842
} else {
4943
match node.as_ref() {
5044
MemberSymbol::Measure(_) | MemberSymbol::Dimension(_) => {

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/compiler.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::symbols::{MemberExpressionExpression, MemberExpressionSymbol, MemberS
33
use super::SymbolPath;
44
use super::SymbolPathType;
55
use super::{
6-
CubeNameSymbolFactory, CubeTableSymbolFactory, DimensionSymbolFactory, MeasureSymbolFactory,
7-
SqlCall, SymbolFactory, TraversalVisitor,
6+
CubeNameSymbol, CubeNameSymbolFactory, CubeTableSymbol, CubeTableSymbolFactory,
7+
DimensionSymbolFactory, MeasureSymbolFactory, SqlCall, SymbolFactory, TraversalVisitor,
88
};
99
use crate::cube_bridge::base_tools::BaseTools;
1010
use crate::cube_bridge::evaluator::CubeEvaluator;
@@ -23,8 +23,6 @@ enum CacheSymbolType {
2323
Dimension,
2424
Measure,
2525
Segment,
26-
CubeTable,
27-
CubeName,
2826
}
2927

3028
pub struct Compiler {
@@ -33,6 +31,8 @@ pub struct Compiler {
3331
security_context: Rc<dyn SecurityContext>,
3432
timezone: Tz,
3533
members: HashMap<(CacheSymbolType, String), Rc<MemberSymbol>>,
34+
cube_names: HashMap<String, Rc<CubeNameSymbol>>,
35+
cube_tables: HashMap<String, Rc<CubeTableSymbol>>,
3636
}
3737

3838
impl Compiler {
@@ -48,6 +48,8 @@ impl Compiler {
4848
base_tools,
4949
timezone,
5050
members: HashMap::new(),
51+
cube_names: HashMap::new(),
52+
cube_tables: HashMap::new(),
5153
}
5254
}
5355

@@ -150,27 +152,27 @@ impl Compiler {
150152
pub fn add_cube_name_evaluator(
151153
&mut self,
152154
cube_name: String,
153-
) -> Result<Rc<MemberSymbol>, CubeError> {
154-
if let Some(exists) = self.exists_member(CacheSymbolType::CubeName, &cube_name) {
155+
) -> Result<Rc<CubeNameSymbol>, CubeError> {
156+
if let Some(exists) = self.cube_names.get(&cube_name) {
155157
Ok(exists.clone())
156158
} else {
157159
let result = CubeNameSymbolFactory::try_new(&cube_name, self.cube_evaluator.clone())?
158160
.build(self)?;
159-
self.validate_and_cache_result(CacheSymbolType::CubeName, result.clone())?;
161+
self.cube_names.insert(cube_name, result.clone());
160162
Ok(result)
161163
}
162164
}
163165

164166
pub fn add_cube_table_evaluator(
165167
&mut self,
166168
cube_name: String,
167-
) -> Result<Rc<MemberSymbol>, CubeError> {
168-
if let Some(exists) = self.exists_member(CacheSymbolType::CubeTable, &cube_name) {
169+
) -> Result<Rc<CubeTableSymbol>, CubeError> {
170+
if let Some(exists) = self.cube_tables.get(&cube_name) {
169171
Ok(exists.clone())
170172
} else {
171173
let result = CubeTableSymbolFactory::try_new(&cube_name, self.cube_evaluator.clone())?
172174
.build(self)?;
173-
self.validate_and_cache_result(CacheSymbolType::CubeTable, result.clone())?;
175+
self.cube_tables.insert(cube_name, result.clone());
174176
Ok(result)
175177
}
176178
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use super::sql_nodes::SqlNode;
2+
use super::SqlEvaluatorVisitor;
3+
use crate::planner::query_tools::QueryTools;
4+
use crate::planner::sql_evaluator::sql_call::CubeRef;
5+
use crate::planner::sql_templates::PlanSqlTemplates;
6+
use cubenativeutils::CubeError;
7+
use std::collections::HashMap;
8+
use std::rc::Rc;
9+
10+
pub struct CubeRefEvaluator {
11+
cube_name_references: HashMap<String, String>,
12+
original_sql_pre_aggregations: HashMap<String, String>,
13+
}
14+
15+
impl CubeRefEvaluator {
16+
pub fn new(
17+
cube_name_references: HashMap<String, String>,
18+
original_sql_pre_aggregations: HashMap<String, String>,
19+
) -> Self {
20+
Self {
21+
cube_name_references,
22+
original_sql_pre_aggregations,
23+
}
24+
}
25+
26+
pub fn evaluate(
27+
&self,
28+
cube_ref: &CubeRef,
29+
visitor: &SqlEvaluatorVisitor,
30+
node_processor: Rc<dyn SqlNode>,
31+
query_tools: Rc<QueryTools>,
32+
templates: &PlanSqlTemplates,
33+
) -> Result<String, CubeError> {
34+
match cube_ref {
35+
CubeRef::Name { symbol, .. } => {
36+
let name = symbol.evaluate_sql()?;
37+
let alias = self.resolve_cube_alias(&name);
38+
templates.quote_identifier(&alias)
39+
}
40+
CubeRef::Table { symbol, .. } => {
41+
if let Some(pre_agg) = self.original_sql_pre_aggregations.get(symbol.cube_name()) {
42+
return Ok(pre_agg.clone());
43+
}
44+
symbol.evaluate_sql(visitor, node_processor, query_tools, templates)
45+
}
46+
}
47+
}
48+
49+
fn resolve_cube_alias(&self, name: &String) -> String {
50+
if let Some(alias) = self.cube_name_references.get(name) {
51+
alias.clone()
52+
} else {
53+
name.clone()
54+
}
55+
}
56+
}

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod collectors;
22
pub mod compiler;
3+
pub mod cube_ref_evaluator;
34
pub mod references_builder;
45
pub mod sql_call;
56
mod sql_call_builder;
@@ -10,6 +11,7 @@ pub mod visitor;
1011

1112
pub use crate::utils::debug::DebugSql;
1213
pub use compiler::Compiler;
14+
pub use cube_ref_evaluator::CubeRefEvaluator;
1315
pub use references_builder::ReferencesBuilder;
1416
pub use sql_call::*;
1517
pub use sql_visitor::SqlEvaluatorVisitor;

0 commit comments

Comments
 (0)