Skip to content

Commit d4eeb4c

Browse files
waralexrommarianore-muttdata
authored andcommitted
feat(tesseract): Logical plan (cube-js#9497)
1 parent 9c31084 commit d4eeb4c

Some content is hidden

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

51 files changed

+3322
-1185
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
pub mod cube_bridge;
2+
pub mod logical_plan;
3+
pub mod physical_plan_builder;
24
pub mod plan;
35
pub mod planner;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use super::pretty_print::*;
2+
use super::*;
3+
use crate::planner::BaseCube;
4+
use std::rc::Rc;
5+
6+
pub enum AggregateMultipliedSubquerySouce {
7+
Cube,
8+
MeasureSubquery(Rc<MeasureSubquery>),
9+
}
10+
11+
pub struct AggregateMultipliedSubquery {
12+
pub schema: Rc<LogicalSchema>,
13+
pub dimension_subqueries: Vec<Rc<DimensionSubQuery>>,
14+
pub keys_subquery: Rc<KeysSubQuery>,
15+
pub pk_cube: Rc<BaseCube>, //FIXME may be duplication with information in keys_subquery
16+
pub source: Rc<AggregateMultipliedSubquerySouce>,
17+
}
18+
19+
impl PrettyPrint for AggregateMultipliedSubquery {
20+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
21+
result.println("AggregateMultipliedSubquery: ", state);
22+
let state = state.new_level();
23+
let details_state = state.new_level();
24+
result.println("schema:", &state);
25+
self.schema.pretty_print(result, &details_state);
26+
if !self.dimension_subqueries.is_empty() {
27+
result.println("dimension_subqueries:", &state);
28+
for subquery in self.dimension_subqueries.iter() {
29+
subquery.pretty_print(result, &details_state);
30+
}
31+
}
32+
result.println("keys_subquery:", &state);
33+
self.keys_subquery.pretty_print(result, &details_state);
34+
result.println("source:", &state);
35+
match self.source.as_ref() {
36+
AggregateMultipliedSubquerySouce::Cube => {
37+
result.println(&format!("Cube: {}", self.pk_cube.name()), &details_state);
38+
}
39+
AggregateMultipliedSubquerySouce::MeasureSubquery(measure_subquery) => {
40+
result.println(
41+
&format!("MeasureSubquery: {}", measure_subquery.measures.len()),
42+
&details_state,
43+
);
44+
measure_subquery.pretty_print(result, &details_state);
45+
}
46+
}
47+
}
48+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use crate::planner::BaseCube;
2+
use std::rc::Rc;
3+
#[derive(Clone)]
4+
pub struct Cube {
5+
pub name: String,
6+
pub cube: Rc<BaseCube>,
7+
}
8+
9+
impl Cube {
10+
pub fn new(cube: Rc<BaseCube>) -> Rc<Self> {
11+
Rc::new(Self {
12+
name: cube.name().clone(),
13+
cube,
14+
})
15+
}
16+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use super::pretty_print::*;
2+
use super::*;
3+
use crate::planner::sql_evaluator::MemberSymbol;
4+
use std::rc::Rc;
5+
6+
pub struct DimensionSubQuery {
7+
pub query: Rc<Query>,
8+
pub primary_keys_dimensions: Vec<Rc<MemberSymbol>>,
9+
pub subquery_dimension: Rc<MemberSymbol>,
10+
pub measure_for_subquery_dimension: Rc<MemberSymbol>,
11+
}
12+
13+
impl PrettyPrint for DimensionSubQuery {
14+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
15+
result.println("DimensionSubQuery: ", state);
16+
let state = state.new_level();
17+
let details_state = state.new_level();
18+
result.println(&format!("query: "), &state);
19+
self.query.pretty_print(result, &details_state);
20+
result.println(
21+
&format!(
22+
"-primary_keys_dimensions: {}",
23+
print_symbols(&self.primary_keys_dimensions)
24+
),
25+
&state,
26+
);
27+
result.println(
28+
&format!(
29+
"-subquery_dimension: {}",
30+
self.subquery_dimension.full_name()
31+
),
32+
&state,
33+
);
34+
result.println(
35+
&format!(
36+
"-measure_for_subquery_dimension: {}",
37+
self.measure_for_subquery_dimension.full_name()
38+
),
39+
&state,
40+
);
41+
}
42+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use super::pretty_print::*;
2+
use crate::plan::{Filter, FilterItem};
3+
use itertools::Itertools;
4+
5+
pub struct LogicalFilter {
6+
pub dimensions_filters: Vec<FilterItem>,
7+
pub time_dimensions_filters: Vec<FilterItem>,
8+
pub measures_filter: Vec<FilterItem>,
9+
pub segments: Vec<FilterItem>,
10+
}
11+
12+
impl LogicalFilter {
13+
pub fn all_filters(&self) -> Option<Filter> {
14+
let items = self
15+
.time_dimensions_filters
16+
.iter()
17+
.chain(self.dimensions_filters.iter())
18+
.chain(self.segments.iter())
19+
.cloned()
20+
.collect_vec();
21+
if items.is_empty() {
22+
None
23+
} else {
24+
Some(Filter { items })
25+
}
26+
}
27+
}
28+
29+
impl PrettyPrint for LogicalFilter {
30+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
31+
let details_state = state.new_level();
32+
result.println("dimensions_filters:", &state);
33+
for filter in self.dimensions_filters.iter() {
34+
pretty_print_filter_item(result, &details_state, filter);
35+
}
36+
result.println("time_dimensions_filters:", &state);
37+
for filter in self.time_dimensions_filters.iter() {
38+
pretty_print_filter_item(result, &details_state, filter);
39+
}
40+
result.println("measures_filter:", &state);
41+
for filter in self.measures_filter.iter() {
42+
pretty_print_filter_item(result, &details_state, filter);
43+
}
44+
result.println("segments:", &state);
45+
for filter in self.segments.iter() {
46+
pretty_print_filter_item(result, &details_state, filter);
47+
}
48+
}
49+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use super::*;
2+
use crate::planner::sql_evaluator::MemberSymbol;
3+
use std::rc::Rc;
4+
5+
pub struct MultiStageSubqueryRef {
6+
pub name: String,
7+
}
8+
9+
impl PrettyPrint for MultiStageSubqueryRef {
10+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
11+
result.println(&format!("MultiStageSubqueryRef: {}", self.name), state);
12+
}
13+
}
14+
15+
pub enum FullKeyAggregateSource {
16+
ResolveMultipliedMeasures(Rc<ResolveMultipliedMeasures>),
17+
MultiStageSubqueryRef(Rc<MultiStageSubqueryRef>),
18+
}
19+
20+
impl PrettyPrint for FullKeyAggregateSource {
21+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
22+
match self {
23+
Self::ResolveMultipliedMeasures(resolve_multiplied_measures) => {
24+
resolve_multiplied_measures.pretty_print(result, state);
25+
}
26+
Self::MultiStageSubqueryRef(subquery_ref) => {
27+
subquery_ref.pretty_print(result, state);
28+
}
29+
}
30+
}
31+
}
32+
33+
pub struct FullKeyAggregate {
34+
pub join_dimensions: Vec<Rc<MemberSymbol>>,
35+
pub use_full_join_and_coalesce: bool,
36+
pub sources: Vec<FullKeyAggregateSource>,
37+
}
38+
39+
impl PrettyPrint for FullKeyAggregate {
40+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
41+
result.println("FullKeyAggregate: ", state);
42+
let state = state.new_level();
43+
let details_state = state.new_level();
44+
result.println(
45+
&format!("join_dimensions: {}", print_symbols(&self.join_dimensions)),
46+
&state,
47+
);
48+
result.println(
49+
&format!(
50+
"use_full_join_and_coalesce: {}",
51+
self.use_full_join_and_coalesce
52+
),
53+
&state,
54+
);
55+
result.println("sources:", &state);
56+
for source in self.sources.iter() {
57+
source.pretty_print(result, &details_state);
58+
}
59+
}
60+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use super::*;
2+
use crate::planner::query_properties::OrderByItem;
3+
use std::rc::Rc;
4+
5+
pub struct FullKeyAggregateQuery {
6+
pub multistage_members: Vec<Rc<LogicalMultiStageMember>>,
7+
pub schema: Rc<LogicalSchema>,
8+
pub filter: Rc<LogicalFilter>,
9+
pub offset: Option<usize>,
10+
pub limit: Option<usize>,
11+
pub ungrouped: bool,
12+
pub order_by: Vec<OrderByItem>,
13+
pub source: Rc<FullKeyAggregate>,
14+
}
15+
16+
impl PrettyPrint for FullKeyAggregateQuery {
17+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
18+
result.println("FullKeyAggregateQuery: ", state);
19+
let state = state.new_level();
20+
let details_state = state.new_level();
21+
if !self.multistage_members.is_empty() {
22+
result.println("multistage_members:", &state);
23+
for member in self.multistage_members.iter() {
24+
member.pretty_print(result, &details_state);
25+
}
26+
}
27+
28+
result.println("schema:", &state);
29+
self.schema.pretty_print(result, &details_state);
30+
result.println("filter:", &state);
31+
self.filter.pretty_print(result, &details_state);
32+
if let Some(offset) = &self.offset {
33+
result.println(&format!("offset:{}", offset), &state);
34+
}
35+
if let Some(limit) = &self.limit {
36+
result.println(&format!("limit:{}", limit), &state);
37+
}
38+
result.println(&format!("ungrouped:{}", self.ungrouped), &state);
39+
if !self.order_by.is_empty() {
40+
result.println("order_by:", &state);
41+
for order_by in self.order_by.iter() {
42+
result.println(
43+
&format!(
44+
"{} {}",
45+
order_by.name(),
46+
if order_by.desc() { "desc" } else { "asc" }
47+
),
48+
&details_state,
49+
);
50+
}
51+
}
52+
result.println("source:", &state);
53+
self.source.pretty_print(result, &details_state);
54+
}
55+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use super::pretty_print::*;
2+
use super::Cube;
3+
use super::SimpleQuery;
4+
use crate::planner::sql_evaluator::{MemberSymbol, SqlCall};
5+
use std::rc::Rc;
6+
7+
#[derive(Clone)]
8+
pub struct CubeJoinItem {
9+
pub cube: Rc<Cube>,
10+
pub on_sql: Rc<SqlCall>,
11+
}
12+
13+
impl PrettyPrint for CubeJoinItem {
14+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
15+
result.println(&format!("CubeJoinItem for cube: {}", self.cube.name), state);
16+
}
17+
}
18+
19+
#[derive(Clone)]
20+
pub struct SubqueryDimensionJoinItem {
21+
pub subquery: Rc<SimpleQuery>,
22+
pub dimension: Rc<MemberSymbol>,
23+
pub primary_keys_dimensions: Vec<Rc<MemberSymbol>>,
24+
}
25+
26+
impl PrettyPrint for SubqueryDimensionJoinItem {
27+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
28+
result.println(
29+
&format!(
30+
"SubqueryDimensionJoinItem for dimension `{}`: ",
31+
self.dimension.full_name()
32+
),
33+
state,
34+
);
35+
result.println("subquery:", state);
36+
result.println("primary_keys_dimensions:", state);
37+
let state = state.new_level();
38+
for dim in self.primary_keys_dimensions.iter() {
39+
result.println(&format!("- {}", dim.full_name()), &state);
40+
}
41+
}
42+
}
43+
44+
#[derive(Clone)]
45+
pub enum LogicalJoinItem {
46+
CubeJoinItem(CubeJoinItem),
47+
}
48+
49+
impl PrettyPrint for LogicalJoinItem {
50+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
51+
match self {
52+
LogicalJoinItem::CubeJoinItem(item) => item.pretty_print(result, state),
53+
}
54+
}
55+
}
56+
57+
#[derive(Clone)]
58+
pub struct LogicalJoin {
59+
pub root: Rc<Cube>,
60+
pub joins: Vec<LogicalJoinItem>,
61+
}
62+
63+
impl PrettyPrint for LogicalJoin {
64+
fn pretty_print(&self, result: &mut PrettyPrintResult, state: &PrettyPrintState) {
65+
result.println(&format!("Join: "), state);
66+
let state = state.new_level();
67+
result.println(&format!("root: {}", self.root.name), &state);
68+
result.println(&format!("joins: "), &state);
69+
let state = state.new_level();
70+
for join in self.joins.iter() {
71+
join.pretty_print(result, &state);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)