Skip to content

Commit 49e9aec

Browse files
authored
chore(tesseract): MemberSymbols decompositions (cube-js#10458)
1 parent b07de3b commit 49e9aec

43 files changed

Lines changed: 2606 additions & 513 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rust/cubesqlplanner/cubesqlplanner/src/logical_plan/optimizers/pre_aggregation/pre_aggregations_compiler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl PreAggregationsCompiler {
510510
"Pre-aggregation time dimension must be a dimension"
511511
))
512512
})?;
513-
if dimension.dimension_type() != "time" {
513+
if !dimension.is_time() {
514514
return Err(CubeError::user(format!(
515515
"Pre-aggregation time dimension must be a dimension"
516516
)));

rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,11 @@ impl BaseFilter {
146146
let filters_context = context.filters_context();
147147
let symbol = self.member_evaluator();
148148
let member_type = match symbol.as_ref() {
149-
MemberSymbol::Dimension(dimension_symbol) => Some(
150-
dimension_symbol
151-
.definition()
152-
.static_data()
153-
.dimension_type
154-
.clone(),
155-
),
149+
MemberSymbol::Dimension(dimension_symbol) => {
150+
Some(dimension_symbol.dimension_type().to_string())
151+
}
156152
MemberSymbol::Measure(measure_symbol) => {
157-
Some(measure_symbol.measure_type().clone())
153+
Some(measure_symbol.measure_type().to_string())
158154
}
159155
_ => None,
160156
};

rust/cubesqlplanner/cubesqlplanner/src/planner/planners/multi_stage/applied_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl MultiStageAppliedState {
181181
m.resolve_reference_chain()
182182
};
183183
if let Ok(dim) = symbol.as_dimension() {
184-
if dim.dimension_type() == "time" {
184+
if dim.is_time() {
185185
Some(symbol)
186186
} else {
187187
None

rust/cubesqlplanner/cubesqlplanner/src/planner/planners/multi_stage/multi_stage_query_planner.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::planner::sql_evaluator::collectors::member_childs;
1616
use crate::planner::sql_evaluator::Case;
1717
use crate::planner::sql_evaluator::CaseSwitchDefinition;
1818
use crate::planner::sql_evaluator::CaseSwitchItem;
19+
use crate::planner::sql_evaluator::MeasureKind;
1920
use crate::planner::sql_evaluator::MemberSymbol;
2021
use crate::planner::GranularityHelper;
2122
use crate::planner::QueryProperties;
@@ -114,12 +115,10 @@ impl MultiStageQueryPlanner {
114115
resolved_multi_stage_dimensions: &mut HashSet<String>,
115116
) -> Result<(MultiStageInodeMember, bool), CubeError> {
116117
let inode = if let Ok(measure) = base_member.as_measure() {
117-
let member_type = if measure.measure_type() == "rank" {
118-
MultiStageInodeMemberType::Rank
119-
} else if !measure.is_calculated() {
120-
MultiStageInodeMemberType::Aggregate
121-
} else {
122-
MultiStageInodeMemberType::Calculate
118+
let member_type = match measure.kind() {
119+
MeasureKind::Rank => MultiStageInodeMemberType::Rank,
120+
MeasureKind::Calculated(_) => MultiStageInodeMemberType::Calculate,
121+
_ => MultiStageInodeMemberType::Aggregate,
123122
};
124123

125124
let time_shift = measure.time_shift().clone();

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ impl TraversalVisitor for HasMultiStageMembersCollector {
3232
MemberSymbol::Measure(s) => {
3333
if s.is_multi_stage() {
3434
self.has_multi_stage = true;
35-
} else if !self.ignore_cumulative
36-
&& (s.is_rolling_window() || s.measure_type() == "runningTotal")
37-
{
35+
} else if !self.ignore_cumulative && s.is_cumulative() {
3836
self.has_multi_stage = true;
3937
}
4038
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'a> SqlCallBuilder<'a> {
132132
) -> Option<SqlCallDependency> {
133133
if let Ok(member_symbol) = self.build_evaluator(&current_cube_name, &path_tail[0]) {
134134
if let Ok(dimension) = member_symbol.as_dimension() {
135-
if dimension.dimension_type() == "time" && path_tail.len() == 2 {
135+
if dimension.is_time() && path_tail.len() == 2 {
136136
let granularity = &path_tail[1];
137137
if let Ok(Some(granularity_obj)) = GranularityHelper::make_granularity_obj(
138138
self.cube_evaluator.clone(),

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/sql_nodes/evaluate_sql.rs

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,42 +38,12 @@ impl SqlNode for EvaluateSqlNode {
3838
let res = visitor.apply(&ev.base_symbol(), node_processor.clone(), templates)?;
3939
Ok(res)
4040
}
41-
MemberSymbol::Measure(ev) => {
42-
let res = if ev.has_sql() {
43-
ev.evaluate_sql(
44-
visitor,
45-
node_processor.clone(),
46-
query_tools.clone(),
47-
templates,
48-
)?
49-
} else if ev.pk_sqls().len() > 1 {
50-
let pk_strings = ev
51-
.pk_sqls()
52-
.iter()
53-
.map(|pk| -> Result<_, CubeError> {
54-
let res = pk.eval(
55-
&visitor,
56-
node_processor.clone(),
57-
query_tools.clone(),
58-
templates,
59-
)?;
60-
templates.cast_to_string(&res)
61-
})
62-
.collect::<Result<Vec<_>, _>>()?;
63-
templates.concat_strings(&pk_strings)?
64-
} else if ev.pk_sqls().len() == 1 {
65-
let pk_sql = ev.pk_sqls().first().unwrap();
66-
pk_sql.eval(
67-
&visitor,
68-
node_processor.clone(),
69-
query_tools.clone(),
70-
templates,
71-
)?
72-
} else {
73-
format!("*")
74-
};
75-
Ok(res)
76-
}
41+
MemberSymbol::Measure(ev) => ev.evaluate_sql(
42+
visitor,
43+
node_processor.clone(),
44+
query_tools.clone(),
45+
templates,
46+
),
7747
MemberSymbol::CubeTable(ev) => ev.evaluate_sql(
7848
visitor,
7949
node_processor.clone(),

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/sql_nodes/final_measure.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::SqlNode;
22
use crate::planner::query_tools::QueryTools;
3-
use crate::planner::sql_evaluator::MeasureSymbol;
3+
use crate::planner::sql_evaluator::symbols::{AggregateWrap, MeasureSymbol};
44
use crate::planner::sql_evaluator::MemberSymbol;
55
use crate::planner::sql_evaluator::SqlEvaluatorVisitor;
66
use crate::planner::sql_templates::PlanSqlTemplates;
@@ -32,12 +32,27 @@ impl FinalMeasureSqlNode {
3232
&self.input
3333
}
3434

35-
fn is_count_distinct(&self, symbol: &MeasureSymbol) -> bool {
36-
symbol.measure_type() == "countDistinct"
37-
|| (symbol.measure_type() == "count"
38-
&& self
39-
.rendered_as_multiplied_measures
40-
.contains(&symbol.full_name()))
35+
fn wrap_aggregate(
36+
&self,
37+
ev: &MeasureSymbol,
38+
input: String,
39+
templates: &PlanSqlTemplates,
40+
) -> Result<String, CubeError> {
41+
let is_multiplied = self
42+
.rendered_as_multiplied_measures
43+
.contains(&ev.full_name());
44+
match ev.kind().aggregate_wrap(is_multiplied) {
45+
AggregateWrap::PassThrough => Ok(input),
46+
AggregateWrap::Function(name) => Ok(format!("{}({})", name, input)),
47+
AggregateWrap::CountDistinct => templates.count_distinct(&input),
48+
AggregateWrap::CountDistinctApprox => {
49+
if self.count_approx_as_state {
50+
templates.hll_init(input)
51+
} else {
52+
templates.count_distinct_approx(input)
53+
}
54+
}
55+
}
4156
}
4257
}
4358

@@ -59,26 +74,7 @@ impl SqlNode for FinalMeasureSqlNode {
5974
node_processor.clone(),
6075
templates,
6176
)?;
62-
63-
if ev.is_calculated() || ev.measure_type() == "numberAgg" {
64-
input
65-
} else if ev.measure_type() == "countDistinctApprox" {
66-
if self.count_approx_as_state {
67-
templates.hll_init(input)?
68-
} else {
69-
templates.count_distinct_approx(input)?
70-
}
71-
} else if self.is_count_distinct(ev) {
72-
templates.count_distinct(&input)?
73-
} else {
74-
let measure_type = if ev.measure_type() == "runningTotal" {
75-
"sum"
76-
} else {
77-
&ev.measure_type()
78-
};
79-
80-
format!("{}({})", measure_type, input)
81-
}
77+
self.wrap_aggregate(ev, input, templates)?
8278
}
8379
_ => {
8480
return Err(CubeError::internal(format!(

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/sql_nodes/final_pre_aggregation_measure.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::SqlNode;
22
use crate::planner::query_tools::QueryTools;
33
use crate::planner::sql_evaluator::sql_nodes::RenderReferences;
44
use crate::planner::sql_evaluator::sql_nodes::RenderReferencesType;
5+
use crate::planner::sql_evaluator::symbols::AggregateWrap;
56
use crate::planner::sql_evaluator::MemberSymbol;
67
use crate::planner::sql_evaluator::SqlEvaluatorVisitor;
78
use crate::planner::sql_templates::PlanSqlTemplates;
@@ -48,14 +49,14 @@ impl SqlNode for FinalPreAggregationMeasureSqlNode {
4849
table_ref,
4950
templates.quote_identifier(&column_name.name())?
5051
);
51-
if ev.measure_type() == "count" || ev.measure_type() == "sum" {
52-
format!("sum({})", pre_aggregation_measure)
53-
} else if ev.measure_type() == "countDistinctApprox" {
54-
templates.count_distinct_approx(pre_aggregation_measure)?
55-
} else if ev.measure_type() == "min" || ev.measure_type() == "max" {
56-
format!("{}({})", ev.measure_type(), pre_aggregation_measure)
57-
} else {
58-
format!("sum({})", pre_aggregation_measure)
52+
match ev.kind().pre_aggregate_wrap() {
53+
AggregateWrap::CountDistinctApprox => {
54+
templates.count_distinct_approx(pre_aggregation_measure)?
55+
}
56+
AggregateWrap::Function(name) => {
57+
format!("{}({})", name, pre_aggregation_measure)
58+
}
59+
_ => format!("sum({})", pre_aggregation_measure),
5960
}
6061
}
6162
RenderReferencesType::LiteralValue(value) => {

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/sql_nodes/geo_dimension.rs

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::SqlNode;
22
use crate::planner::query_tools::QueryTools;
3+
use crate::planner::sql_evaluator::symbols::DimensionKind;
34
use crate::planner::sql_evaluator::MemberSymbol;
45
use crate::planner::sql_evaluator::SqlEvaluatorVisitor;
56
use crate::planner::sql_templates::PlanSqlTemplates;
@@ -32,31 +33,20 @@ impl SqlNode for GeoDimensionSqlNode {
3233
) -> Result<String, CubeError> {
3334
let res = match node.as_ref() {
3435
MemberSymbol::Dimension(ev) => {
35-
if ev.dimension_type() == "geo" {
36-
if let (Some(latitude), Some(longitude)) = (ev.latitude(), ev.longitude()) {
37-
let latitude_str = latitude.eval(
38-
visitor,
39-
node_processor.clone(),
40-
query_tools.clone(),
41-
templates,
42-
)?;
43-
let longitude_str = longitude.eval(
44-
visitor,
45-
node_processor.clone(),
46-
query_tools.clone(),
47-
templates,
48-
)?;
49-
templates.concat_strings(&vec![
50-
latitude_str,
51-
format!("','"),
52-
longitude_str,
53-
])?
54-
} else {
55-
return Err(CubeError::user(format!(
56-
"Geo dimension '{}' must have latitude and longitude",
57-
ev.full_name()
58-
)));
59-
}
36+
if let DimensionKind::Geo(geo) = ev.kind() {
37+
let latitude_str = geo.latitude().eval(
38+
visitor,
39+
node_processor.clone(),
40+
query_tools.clone(),
41+
templates,
42+
)?;
43+
let longitude_str = geo.longitude().eval(
44+
visitor,
45+
node_processor.clone(),
46+
query_tools.clone(),
47+
templates,
48+
)?;
49+
templates.concat_strings(&vec![latitude_str, format!("','"), longitude_str])?
6050
} else {
6151
self.input.to_sql(
6252
visitor,

0 commit comments

Comments
 (0)