Skip to content

Commit 3450277

Browse files
committed
multi stage
1 parent d9fc705 commit 3450277

File tree

27 files changed

+657
-278
lines changed

27 files changed

+657
-278
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export class BaseQuery {
237237
this.multiStageTimeDimensions = (this.options.multiStageTimeDimensions || []).map(this.newTimeDimension.bind(this));
238238
this.segments = (this.options.segments || []).map(this.newSegment.bind(this));
239239

240+
240241
const filters = this.extractFiltersAsTree(this.options.filters || []);
241242

242243
// measure_filter (the one extracted from filters parameter on measure and
@@ -639,6 +640,9 @@ export class BaseQuery {
639640
cubeEvaluator: this.cubeEvaluator,
640641
order: this.options.order,
641642
filters: this.options.filters,
643+
limit: this.options.limit ? this.options.limit.toString() : null,
644+
rowLimit: this.options.rowLimit ? this.options.rowLimit.toString() : null,
645+
offset: this.options.offset ? this.options.offset.toString() : null,
642646
baseTools: this,
643647

644648
};
@@ -2463,7 +2467,6 @@ export class BaseQuery {
24632467
fn,
24642468
context
24652469
);
2466-
24672470
return context.joinHints;
24682471
}
24692472

packages/cubejs-schema-compiler/src/compiler/JoinGraph.js

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,34 +96,29 @@ export class JoinGraph {
9696
}
9797

9898
buildJoin(cubesToJoin) {
99-
console.log("!!!! here ", cubesToJoin);
100-
try {
101-
if (!cubesToJoin.length) {
102-
return null;
103-
}
104-
const key = JSON.stringify(cubesToJoin);
105-
if (!this.builtJoins[key]) {
106-
const join = R.pipe(
107-
R.map(
108-
cube => this.buildJoinTreeForRoot(cube, R.without([cube], cubesToJoin))
109-
),
110-
R.filter(R.identity),
111-
R.sortBy(joinTree => joinTree.joins.length)
112-
)(cubesToJoin)[0];
113-
if (!join) {
114-
throw new UserError(`Can't find join path to join ${cubesToJoin.map(v => `'${v}'`).join(', ')}`);
115-
}
116-
this.builtJoins[key] = Object.assign(join, {
117-
multiplicationFactor: R.compose(
118-
R.fromPairs,
119-
R.map(v => [this.cubeFromPath(v), this.findMultiplicationFactorFor(this.cubeFromPath(v), join.joins)])
120-
)(cubesToJoin)
121-
});
99+
if (!cubesToJoin.length) {
100+
return null;
101+
}
102+
const key = JSON.stringify(cubesToJoin);
103+
if (!this.builtJoins[key]) {
104+
const join = R.pipe(
105+
R.map(
106+
cube => this.buildJoinTreeForRoot(cube, R.without([cube], cubesToJoin))
107+
),
108+
R.filter(R.identity),
109+
R.sortBy(joinTree => joinTree.joins.length)
110+
)(cubesToJoin)[0];
111+
if (!join) {
112+
throw new UserError(`Can't find join path to join ${cubesToJoin.map(v => `'${v}'`).join(', ')}`);
122113
}
123-
return this.builtJoins[key];
124-
} catch (e) {
125-
console.log("!!!! errr ", e);
114+
this.builtJoins[key] = Object.assign(join, {
115+
multiplicationFactor: R.compose(
116+
R.fromPairs,
117+
R.map(v => [this.cubeFromPath(v), this.findMultiplicationFactorFor(this.cubeFromPath(v), join.joins)])
118+
)(cubesToJoin)
119+
});
126120
}
121+
return this.builtJoins[key];
127122
}
128123

129124
cubeFromPath(cubePath) {

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('SQL Generation', () => {
9797
type: 'prior',
9898
}]
9999
},
100-
cagr_1d: {
100+
cagr_day: {
101101
multi_stage: true,
102102
sql: \`ROUND(100 * \${revenue} / NULLIF(\${revenue_day_ago}, 0))\`,
103103
type: 'number',
@@ -603,7 +603,7 @@ describe('SQL Generation', () => {
603603

604604
//console.log(query.buildSqlAndParams());
605605

606-
const res = await dbRunner.testQuery(query.buildSqlAndParamsTest());
606+
const res = await dbRunner.testQuery(query.buildSqlAndParams());
607607
console.log(JSON.stringify(res));
608608

609609
expect(res).toEqual(
@@ -836,7 +836,7 @@ describe('SQL Generation', () => {
836836
measures: [
837837
'visitors.revenue',
838838
'visitors.revenue_day_ago',
839-
'visitors.cagr_1d'
839+
'visitors.cagr_day'
840840
],
841841
timeDimensions: [{
842842
dimension: 'visitors.created_at',
@@ -848,8 +848,8 @@ describe('SQL Generation', () => {
848848
}],
849849
timezone: 'America/Los_Angeles'
850850
}, [
851-
{ visitors__created_at_day: '2017-01-05T00:00:00.000Z', visitors__cagr_1d: '150', visitors__revenue: '300', visitors__revenue_day_ago: '200' },
852-
{ visitors__created_at_day: '2017-01-06T00:00:00.000Z', visitors__cagr_1d: '300', visitors__revenue: '900', visitors__revenue_day_ago: '300' }
851+
{ visitors__created_at_day: '2017-01-05T00:00:00.000Z', visitors__cagr_day: '150', visitors__revenue: '300', visitors__revenue_day_ago: '200' },
852+
{ visitors__created_at_day: '2017-01-06T00:00:00.000Z', visitors__cagr_day: '300', visitors__revenue: '900', visitors__revenue_day_ago: '300' }
853853
]));
854854

855855
it('sql utils', async () => runQueryTest({
@@ -2529,7 +2529,7 @@ describe('SQL Generation', () => {
25292529
}]
25302530
));
25312531

2532-
it('multi stage complex graph with time dimension through view 1', async () => runQueryTest(
2532+
it('multi stage complex graph with time dimension through view', async () => runQueryTest(
25332533
{
25342534
measures: ['visitors_multi_stage.adjusted_rank_sum', 'visitors_multi_stage.visitor_revenue'],
25352535
dimensions: ['visitors_multi_stage.source'],

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/base_query_options.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ pub struct BaseQueryOptionsStatic {
5656
pub timezone: Option<String>,
5757
pub filters: Option<Vec<FilterItem>>,
5858
pub order: Option<Vec<OrderByItem>>,
59+
pub limit: Option<String>,
60+
#[serde(rename = "rowLimit")]
61+
pub row_limit: Option<String>,
62+
pub offset: Option<String>,
5963
}
6064

6165
#[nativebridge::native_bridge(BaseQueryOptionsStatic)]

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/dimension_definition.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::rc::Rc;
1313
pub struct DimenstionDefinitionStatic {
1414
#[serde(rename = "type")]
1515
pub dimension_type: String,
16+
#[serde(rename = "ownedByCube")]
1617
pub owned_by_cube: Option<bool>,
1718
#[serde(rename = "multiStage")]
1819
pub multi_stage: Option<bool>,

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/measure_definition.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,20 @@ use serde::{Deserialize, Serialize};
1212
use std::any::Any;
1313
use std::rc::Rc;
1414

15+
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
16+
pub struct TimeShiftReference {
17+
pub interval: String,
18+
#[serde(rename = "type")]
19+
pub shift_type: Option<String>,
20+
#[serde(rename = "timeDimension")]
21+
pub time_dimension: String,
22+
}
23+
1524
#[derive(Serialize, Deserialize, Debug)]
1625
pub struct MeasureDefinitionStatic {
1726
#[serde(rename = "type")]
1827
pub measure_type: String,
28+
#[serde(rename = "ownedByCube")]
1929
pub owned_by_cube: Option<bool>,
2030
#[serde(rename = "multiStage")]
2131
pub multi_stage: Option<bool>,
@@ -25,6 +35,8 @@ pub struct MeasureDefinitionStatic {
2535
pub add_group_by_references: Option<Vec<String>>,
2636
#[serde(rename = "groupByReferences")]
2737
pub group_by_references: Option<Vec<String>>,
38+
#[serde(rename = "timeShiftReferences")]
39+
pub time_shift_references: Option<Vec<TimeShiftReference>>,
2840
}
2941

3042
#[nativebridge::native_bridge(MeasureDefinitionStatic)]

rust/cubesqlplanner/cubesqlplanner/src/plan/filter.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ use cubenativeutils::CubeError;
44
use std::fmt;
55
use std::rc::Rc;
66

7+
#[derive(Clone)]
78
pub enum FilterGroupOperator {
89
Or,
910
And,
1011
}
1112

13+
#[derive(Clone)]
1214
pub struct FilterGroup {
13-
operator: FilterGroupOperator,
14-
items: Vec<FilterItem>,
15+
pub operator: FilterGroupOperator,
16+
pub items: Vec<FilterItem>,
1517
}
1618

1719
impl FilterGroup {
@@ -49,7 +51,11 @@ impl FilterItem {
4951
.iter()
5052
.map(|itm| itm.to_sql(context.clone()))
5153
.collect::<Result<Vec<_>, _>>()?;
52-
format!("({})", items_sql.join(&operator))
54+
if items_sql.is_empty() {
55+
format!("( 1 = 1 )")
56+
} else {
57+
format!("({})", items_sql.join(&operator))
58+
}
5359
}
5460
FilterItem::Item(item) => {
5561
let sql = item.to_sql(context.clone())?;

rust/cubesqlplanner/cubesqlplanner/src/plan/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub mod subquery;
1010
pub mod union;
1111

1212
pub use expression::Expr;
13-
pub use filter::{Filter, FilterItem};
13+
pub use filter::{Filter, FilterGroup, FilterItem};
1414
pub use from::{From, FromSource};
1515
pub use join::{Join, JoinItem, JoinSource};
1616
pub use order::OrderBy;

rust/cubesqlplanner/cubesqlplanner/src/plan/select.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pub struct Select {
1515
pub context: Rc<VisitorContext>,
1616
pub ctes: Vec<Rc<Subquery>>,
1717
pub is_distinct: bool,
18+
pub limit: Option<usize>,
19+
pub offset: Option<usize>,
1820
}
1921

2022
impl Select {
@@ -77,12 +79,22 @@ impl Select {
7779

7880
let distinct = if self.is_distinct { "DISTINCT " } else { "" };
7981
let from = self.from.to_sql(self.context.clone())?;
82+
let limit = if let Some(limit) = self.limit {
83+
format!(" LIMIT {limit}")
84+
} else {
85+
format!("")
86+
};
87+
let offset = if let Some(offset) = self.offset {
88+
format!(" OFFSET {offset}")
89+
} else {
90+
format!("")
91+
};
8092

8193
let res = format!(
8294
"{ctes}SELECT\
8395
\n {distinct}{projection}\
8496
\n FROM\
85-
\n{from}{where_condition}{group_by}{having}{order_by}",
97+
\n{from}{where_condition}{group_by}{having}{order_by}{limit}{offset}",
8698
);
8799
Ok(res)
88100
}

0 commit comments

Comments
 (0)