Skip to content

Commit 4adb658

Browse files
committed
in work
1 parent f5a78b9 commit 4adb658

Some content is hidden

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

49 files changed

+1306
-752
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,6 +3250,7 @@ export class BaseQuery {
32503250
group_by_exprs: '{{ group_by | map(attribute=\'index\') | join(\', \') }}',
32513251
},
32523252
expressions: {
3253+
column_reference: '{% if table_name %}{{ table_name }}.{% endif %}{{ name }}',
32533254
column_aliased: '{{expr}} {{quoted_alias}}',
32543255
case: 'CASE{% if expr %} {{ expr }}{% endif %}{% for when, then in when_then %} WHEN {{ when }} THEN {{ then }}{% endfor %}{% if else_expr %} ELSE {{ else_expr }}{% endif %} END',
32553256
is_null: '{{ expr }} IS {% if negate %}NOT {% endif %}NULL',

packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ describe('SQL Generation', () => {
538538
});
539539
`);
540540

541-
it('simple join', async () => {
541+
it('simple join 1', async () => {
542542
await compiler.compile();
543543

544544
console.log(joinGraph.buildJoin(['visitor_checkins', 'visitors']));
@@ -2372,7 +2372,7 @@ describe('SQL Generation', () => {
23722372
}]
23732373
));
23742374

2375-
it('multi stage measure with multiple dependencies', async () => runQueryTest(
2375+
it('multi stage measure with multiple dependencies 1', async () => runQueryTest(
23762376
{
23772377
measures: ['visitors.second_rank_sum', 'visitors.visitor_revenue', 'visitors.revenue_rank'],
23782378
dimensions: ['visitors.source'],

rust/cubesqlplanner/cubesqlplanner/src/plan/builder.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use crate::plan::{Join, JoinCondition, JoinItem, QueryPlan, Schema, Select, SingleAliasedSource};
2+
use crate::planner::BaseCube;
3+
use std::rc::Rc;
4+
5+
pub struct JoinBuilder {
6+
root: SingleAliasedSource,
7+
joins: Vec<JoinItem>,
8+
}
9+
10+
impl JoinBuilder {
11+
pub fn new(root: SingleAliasedSource) -> Self {
12+
Self {
13+
root,
14+
joins: vec![],
15+
}
16+
}
17+
18+
pub fn new_from_cube(cube: Rc<BaseCube>, alias: Option<String>) -> Self {
19+
Self::new(SingleAliasedSource::new_from_cube(cube, alias))
20+
}
21+
22+
pub fn new_from_table_reference(
23+
reference: String,
24+
schema: Rc<Schema>,
25+
alias: Option<String>,
26+
) -> Self {
27+
Self::new(SingleAliasedSource::new_from_table_reference(
28+
reference, schema, alias,
29+
))
30+
}
31+
32+
pub fn new_from_subquery(plan: Rc<QueryPlan>, alias: String) -> Self {
33+
Self::new(SingleAliasedSource::new_from_subquery(plan, alias))
34+
}
35+
36+
pub fn new_from_subselect(plan: Rc<Select>, alias: String) -> Self {
37+
Self::new(SingleAliasedSource::new_from_subquery(
38+
Rc::new(QueryPlan::Select(plan)),
39+
alias,
40+
))
41+
}
42+
43+
pub fn left_join_subselect(&mut self, subquery: Rc<Select>, alias: String, on: JoinCondition) {
44+
self.join_subselect(subquery, alias, on, false)
45+
}
46+
47+
pub fn inner_join_subselect(&mut self, subquery: Rc<Select>, alias: String, on: JoinCondition) {
48+
self.join_subselect(subquery, alias, on, true)
49+
}
50+
51+
pub fn left_join_cube(&mut self, cube: Rc<BaseCube>, alias: Option<String>, on: JoinCondition) {
52+
self.join_cube(cube, alias, on, false)
53+
}
54+
55+
pub fn inner_join_cube(
56+
&mut self,
57+
cube: Rc<BaseCube>,
58+
alias: Option<String>,
59+
on: JoinCondition,
60+
) {
61+
self.join_cube(cube, alias, on, true)
62+
}
63+
64+
pub fn left_join_table_reference(
65+
&mut self,
66+
reference: String,
67+
schema: Rc<Schema>,
68+
alias: Option<String>,
69+
on: JoinCondition,
70+
) {
71+
self.join_table_reference(reference, schema, alias, on, false)
72+
}
73+
74+
pub fn inner_join_table_reference(
75+
&mut self,
76+
reference: String,
77+
schema: Rc<Schema>,
78+
alias: Option<String>,
79+
on: JoinCondition,
80+
) {
81+
self.join_table_reference(reference, schema, alias, on, true)
82+
}
83+
84+
pub fn build(self) -> Rc<Join> {
85+
Rc::new(Join {
86+
root: self.root,
87+
joins: self.joins,
88+
})
89+
}
90+
91+
fn join_subselect(
92+
&mut self,
93+
subquery: Rc<Select>,
94+
alias: String,
95+
on: JoinCondition,
96+
is_inner: bool,
97+
) {
98+
let subquery = Rc::new(QueryPlan::Select(subquery));
99+
let from = SingleAliasedSource::new_from_subquery(subquery, alias);
100+
self.joins.push(JoinItem { from, on, is_inner })
101+
}
102+
103+
fn join_cube(
104+
&mut self,
105+
cube: Rc<BaseCube>,
106+
alias: Option<String>,
107+
on: JoinCondition,
108+
is_inner: bool,
109+
) {
110+
let from = SingleAliasedSource::new_from_cube(cube, alias);
111+
self.joins.push(JoinItem { from, on, is_inner })
112+
}
113+
114+
fn join_table_reference(
115+
&mut self,
116+
reference: String,
117+
schema: Rc<Schema>,
118+
alias: Option<String>,
119+
on: JoinCondition,
120+
is_inner: bool,
121+
) {
122+
let from = SingleAliasedSource::new_from_table_reference(reference, schema, alias);
123+
self.joins.push(JoinItem { from, on, is_inner })
124+
}
125+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod join;
2+
pub mod select;
3+
4+
pub use join::JoinBuilder;
5+
pub use select::SelectBuilder;
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use crate::plan::{
2+
AliasedExpr, Cte, Expr, Filter, From, MemberExpression, OrderBy, Schema, Select,
3+
};
4+
use crate::planner::{BaseMember, VisitorContext};
5+
use std::rc::Rc;
6+
7+
pub struct SelectBuilder {
8+
projection_columns: Vec<AliasedExpr>,
9+
from: From,
10+
filter: Option<Filter>,
11+
group_by: Vec<Expr>,
12+
having: Option<Filter>,
13+
order_by: Vec<OrderBy>,
14+
context: Rc<VisitorContext>,
15+
ctes: Vec<Rc<Cte>>,
16+
is_distinct: bool,
17+
limit: Option<usize>,
18+
offset: Option<usize>,
19+
input_schema: Rc<Schema>,
20+
}
21+
22+
impl SelectBuilder {
23+
pub fn new(from: From, context: VisitorContext) -> Self {
24+
let input_schema = from.schema.clone();
25+
Self {
26+
projection_columns: vec![],
27+
from,
28+
filter: None,
29+
group_by: vec![],
30+
having: None,
31+
order_by: vec![],
32+
context: Rc::new(context),
33+
ctes: vec![],
34+
is_distinct: false,
35+
limit: None,
36+
offset: None,
37+
input_schema,
38+
}
39+
}
40+
41+
pub fn add_projection_member(
42+
&mut self,
43+
member: &Rc<dyn BaseMember>,
44+
source: Option<String>,
45+
alias: Option<String>,
46+
) {
47+
let alias = if let Some(alias) = alias {
48+
alias
49+
} else {
50+
self.input_schema.resolve_member_alias(&member, &source)
51+
};
52+
let expr = Expr::Member(MemberExpression::new(member.clone(), source));
53+
let aliased_expr = AliasedExpr {
54+
expr,
55+
alias: alias.clone(),
56+
};
57+
58+
self.projection_columns.push(aliased_expr);
59+
}
60+
61+
pub fn set_filter(&mut self, filter: Option<Filter>) {
62+
self.filter = filter;
63+
}
64+
65+
pub fn set_group_by(&mut self, group_by: Vec<Expr>) {
66+
self.group_by = group_by;
67+
}
68+
69+
pub fn set_having(&mut self, having: Option<Filter>) {
70+
self.having = having;
71+
}
72+
73+
pub fn set_order_by(&mut self, order_by: Vec<OrderBy>) {
74+
self.order_by = order_by;
75+
}
76+
77+
pub fn set_distinct(&mut self) {
78+
self.is_distinct = true;
79+
}
80+
81+
pub fn set_limit(&mut self, limit: Option<usize>) {
82+
self.limit = limit;
83+
}
84+
85+
pub fn set_offset(&mut self, offset: Option<usize>) {
86+
self.offset = offset;
87+
}
88+
pub fn set_ctes(&mut self, ctes: Vec<Rc<Cte>>) {
89+
self.ctes = ctes;
90+
}
91+
92+
pub fn build(self) -> Select {
93+
Select {
94+
projection_columns: self.projection_columns,
95+
from: self.from,
96+
filter: self.filter,
97+
group_by: self.group_by,
98+
having: self.having,
99+
order_by: self.order_by,
100+
context: self.context.clone(),
101+
ctes: self.ctes,
102+
is_distinct: self.is_distinct,
103+
limit: self.limit,
104+
offset: self.offset,
105+
}
106+
}
107+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use super::{QueryPlan, Schema, Select};
2+
use crate::planner::sql_templates::PlanSqlTemplates;
3+
use cubenativeutils::CubeError;
4+
5+
use std::rc::Rc;
6+
7+
#[derive(Clone)]
8+
pub struct Cte {
9+
query: Rc<QueryPlan>,
10+
name: String,
11+
}
12+
13+
impl Cte {
14+
pub fn new(query: Rc<QueryPlan>, name: String) -> Self {
15+
Self { query, name }
16+
}
17+
18+
pub fn new_from_select(select: Rc<Select>, name: String) -> Self {
19+
Self {
20+
query: Rc::new(QueryPlan::Select(select)),
21+
name,
22+
}
23+
}
24+
25+
pub fn make_schema(&self) -> Schema {
26+
self.query.make_schema(Some(self.name().clone()))
27+
}
28+
29+
pub fn query(&self) -> &Rc<QueryPlan> {
30+
&self.query
31+
}
32+
33+
pub fn name(&self) -> &String {
34+
&self.name
35+
}
36+
37+
pub fn to_sql(&self, templates: &PlanSqlTemplates) -> Result<String, CubeError> {
38+
let sql = format!("({})", self.query.to_sql(templates)?);
39+
Ok(sql)
40+
}
41+
}
Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,51 @@
1+
use super::Schema;
12
use crate::planner::sql_templates::PlanSqlTemplates;
23
use crate::planner::{BaseMember, VisitorContext};
34
use cubenativeutils::CubeError;
45
use std::rc::Rc;
56

7+
#[derive(Clone)]
8+
pub struct MemberExpression {
9+
pub member: Rc<dyn BaseMember>,
10+
pub source: Option<String>,
11+
}
12+
13+
impl MemberExpression {
14+
pub fn new(member: Rc<dyn BaseMember>, source: Option<String>) -> Self {
15+
Self { member, source }
16+
}
17+
18+
pub fn to_sql(
19+
&self,
20+
templates: &PlanSqlTemplates,
21+
context: Rc<VisitorContext>,
22+
schema: Rc<Schema>,
23+
) -> Result<String, CubeError> {
24+
if let Some(reference_column) = context
25+
.source_schema()
26+
.find_column_for_member(&self.member.full_name(), &self.source)
27+
{
28+
templates.column_reference(&reference_column.table_name, &reference_column.alias)
29+
} else {
30+
self.member.to_sql(context, schema)
31+
}
32+
}
33+
}
34+
635
#[derive(Clone)]
736
pub enum Expr {
8-
Field(Rc<dyn BaseMember>),
9-
Reference(Option<String>, String),
10-
Asterix,
37+
Member(MemberExpression),
1138
}
1239

1340
impl Expr {
1441
pub fn to_sql(
1542
&self,
1643
templates: &PlanSqlTemplates,
1744
context: Rc<VisitorContext>,
45+
schema: Rc<Schema>,
1846
) -> Result<String, CubeError> {
1947
match self {
20-
Expr::Field(field) => {
21-
let sql = field.to_sql(context)?;
22-
Ok(sql)
23-
}
24-
Expr::Reference(cube_alias, field_alias) => {
25-
if let Some(cube_alias) = cube_alias {
26-
Ok(format!("{}.{}", cube_alias, field_alias))
27-
} else {
28-
Ok(field_alias.clone())
29-
}
30-
}
31-
Expr::Asterix => Ok("*".to_string()),
48+
Expr::Member(member) => member.to_sql(templates, context, schema),
3249
}
3350
}
3451
}

0 commit comments

Comments
 (0)