Skip to content

Commit df31e89

Browse files
committed
update
1 parent a2ba03d commit df31e89

File tree

15 files changed

+400
-144
lines changed

15 files changed

+400
-144
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ pub struct RollingWindow {
2626
pub trailing: Option<String>,
2727
pub leading: Option<String>,
2828
pub offset: Option<String>,
29+
#[serde(rename = "type")]
30+
pub rolling_type: Option<String>,
31+
pub granularity: Option<String>,
2932
}
3033

3134
#[derive(Serialize, Deserialize, Debug)]

rust/cubesqlplanner/cubesqlplanner/src/plan/join.rs

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
use super::{Expr, SingleAliasedSource};
2+
use crate::planner::query_tools::QueryTools;
23
use crate::planner::sql_templates::PlanSqlTemplates;
34
use crate::planner::{BaseJoinCondition, VisitorContext};
45
use cubenativeutils::CubeError;
56
use lazy_static::lazy_static;
67

78
use std::rc::Rc;
89

9-
pub struct RollingWindowJoinCondition {
10+
pub struct RegularRollingWindowJoinCondition {
1011
time_series_source: String,
1112
trailing_interval: Option<String>,
1213
leading_interval: Option<String>,
1314
offset: String,
1415
time_dimension: Expr,
1516
}
1617

17-
impl RollingWindowJoinCondition {
18+
impl RegularRollingWindowJoinCondition {
1819
pub fn new(
1920
time_series_source: String,
2021
trailing_interval: Option<String>,
@@ -87,6 +88,50 @@ impl RollingWindowJoinCondition {
8788
}
8889
}
8990

91+
pub struct ToDateRollingWindowJoinCondition {
92+
time_series_source: String,
93+
granularity: String,
94+
time_dimension: Expr,
95+
query_tools: Rc<QueryTools>,
96+
}
97+
98+
impl ToDateRollingWindowJoinCondition {
99+
pub fn new(
100+
time_series_source: String,
101+
granularity: String,
102+
time_dimension: Expr,
103+
query_tools: Rc<QueryTools>,
104+
) -> Self {
105+
Self {
106+
time_series_source,
107+
granularity,
108+
time_dimension,
109+
query_tools,
110+
}
111+
}
112+
113+
pub fn to_sql(
114+
&self,
115+
templates: &PlanSqlTemplates,
116+
context: Rc<VisitorContext>,
117+
) -> Result<String, CubeError> {
118+
let date_column = self.time_dimension.to_sql(templates, context)?;
119+
120+
//(dateFrom, dateTo, dateField, dimensionDateFrom, dimensionDateTo, isFromStartToEnd) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${dateTo}`
121+
122+
let date_from =
123+
templates.column_reference(&Some(self.time_series_source.clone()), "date_to")?;
124+
let date_to =
125+
templates.column_reference(&Some(self.time_series_source.clone()), "date_from")?;
126+
let grouped_from = self
127+
.query_tools
128+
.base_tools()
129+
.time_grouped_column(self.granularity.clone(), date_from)?;
130+
let result = format!("{date_column} >= {grouped_from} and {date_column} <= {date_to}");
131+
Ok(result)
132+
}
133+
}
134+
90135
pub struct DimensionJoinCondition {
91136
// AND (... OR ...)
92137
conditions: Vec<Vec<(Expr, Expr)>>,
@@ -145,22 +190,23 @@ impl DimensionJoinCondition {
145190
pub enum JoinCondition {
146191
DimensionJoinCondition(DimensionJoinCondition),
147192
BaseJoinCondition(Rc<dyn BaseJoinCondition>),
148-
RollingWindowJoinCondition(RollingWindowJoinCondition),
193+
RegularRollingWindowJoinCondition(RegularRollingWindowJoinCondition),
194+
ToDateRollingWindowJoinCondition(ToDateRollingWindowJoinCondition),
149195
}
150196

151197
impl JoinCondition {
152198
pub fn new_dimension_join(conditions: Vec<Vec<(Expr, Expr)>>, null_check: bool) -> Self {
153199
Self::DimensionJoinCondition(DimensionJoinCondition::new(conditions, null_check))
154200
}
155201

156-
pub fn new_rolling_join(
202+
pub fn new_regular_rolling_join(
157203
time_series_source: String,
158204
trailing_interval: Option<String>,
159205
leading_interval: Option<String>,
160206
offset: String,
161207
time_dimension: Expr,
162208
) -> Self {
163-
Self::RollingWindowJoinCondition(RollingWindowJoinCondition::new(
209+
Self::RegularRollingWindowJoinCondition(RegularRollingWindowJoinCondition::new(
164210
time_series_source,
165211
trailing_interval,
166212
leading_interval,
@@ -169,6 +215,20 @@ impl JoinCondition {
169215
))
170216
}
171217

218+
pub fn new_to_date_rolling_join(
219+
time_series_source: String,
220+
granularity: String,
221+
time_dimension: Expr,
222+
query_tools: Rc<QueryTools>,
223+
) -> Self {
224+
Self::ToDateRollingWindowJoinCondition(ToDateRollingWindowJoinCondition::new(
225+
time_series_source,
226+
granularity,
227+
time_dimension,
228+
query_tools,
229+
))
230+
}
231+
172232
pub fn new_base_join(base: Rc<dyn BaseJoinCondition>) -> Self {
173233
Self::BaseJoinCondition(base)
174234
}
@@ -181,7 +241,12 @@ impl JoinCondition {
181241
match &self {
182242
JoinCondition::DimensionJoinCondition(cond) => cond.to_sql(templates, context),
183243
JoinCondition::BaseJoinCondition(cond) => cond.to_sql(context, templates),
184-
JoinCondition::RollingWindowJoinCondition(cond) => cond.to_sql(templates, context),
244+
JoinCondition::RegularRollingWindowJoinCondition(cond) => {
245+
cond.to_sql(templates, context)
246+
}
247+
JoinCondition::ToDateRollingWindowJoinCondition(cond) => {
248+
cond.to_sql(templates, context)
249+
}
185250
}
186251
}
187252
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub use cte::Cte;
1616
pub use expression::{Expr, MemberExpression};
1717
pub use filter::{Filter, FilterGroup, FilterItem};
1818
pub use from::{From, FromSource, SingleAliasedSource, SingleSource};
19-
pub use join::{Join, JoinCondition, JoinItem, RollingWindowJoinCondition};
19+
pub use join::{Join, JoinCondition, JoinItem, RegularRollingWindowJoinCondition};
2020
pub use order::OrderBy;
2121
pub use query_plan::QueryPlan;
2222
pub use schema::{QualifiedColumnName, Schema, SchemaColumn};

rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ impl BaseMemberHelper {
4444
members.iter().map(|m| m.alias_name()).collect_vec()
4545
}
4646

47+
pub fn extract_symbols_from_members(members: &Vec<Rc<dyn BaseMember>>) -> Vec<Rc<MemberSymbol>> {
48+
members.iter().map(|m| m.member_evaluator()).collect_vec()
49+
}
50+
4751
pub fn default_alias(
4852
cube_name: &String,
4953
member_name: &String,

rust/cubesqlplanner/cubesqlplanner/src/planner/base_query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<IT: InnerTypes> BaseQuery<IT> {
4141
pub fn build_sql_and_params(&self) -> Result<NativeObjectHandle<IT>, CubeError> {
4242
let templates = PlanSqlTemplates::new(self.query_tools.templates_render());
4343
let query_planner = QueryPlanner::new(self.request.clone(), self.query_tools.clone());
44-
let plan = query_planner.build_sql()?;
44+
let plan = query_planner.plan()?;
4545

4646
let sql = plan.to_sql(&templates)?;
4747
let (result_sql, params) = self.query_tools.build_sql_and_params(&sql, true)?;

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

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ impl BaseFilter {
114114
FilterOperator::Equal => self.equals_where(&member_sql)?,
115115
FilterOperator::NotEqual => self.not_equals_where(&member_sql)?,
116116
FilterOperator::InDateRange => self.in_date_range(&member_sql)?,
117-
FilterOperator::InDateRangeExtended => self.in_date_range_extended(&member_sql)?,
117+
FilterOperator::RegularRollingWindowDateRange => {
118+
self.regular_rolling_window_date_range(&member_sql)?
119+
}
120+
FilterOperator::ToDateRollingWindowDateRange => {
121+
self.to_date_rolling_window_date_range(&member_sql)?
122+
}
118123
FilterOperator::In => self.in_where(&member_sql)?,
119124
FilterOperator::NotIn => self.not_in_where(&member_sql)?,
120125
FilterOperator::Set => self.set_where(&member_sql)?,
@@ -211,7 +216,7 @@ impl BaseFilter {
211216
}
212217

213218
fn in_date_range(&self, member_sql: &str) -> Result<String, CubeError> {
214-
let (from, to) = self.allocate_date_params()?;
219+
let (from, to) = self.allocate_date_params(true)?;
215220
self.templates
216221
.time_range_filter(member_sql.to_string(), from, to)
217222
}
@@ -236,8 +241,9 @@ impl BaseFilter {
236241
Ok(date.to_string())
237242
}
238243
}
239-
fn in_date_range_extended(&self, member_sql: &str) -> Result<String, CubeError> {
240-
let (from, to) = self.allocate_date_params()?;
244+
245+
fn regular_rolling_window_date_range(&self, member_sql: &str) -> Result<String, CubeError> {
246+
let (from, to) = self.allocate_date_params(false)?;
241247

242248
let from = if self.values.len() >= 3 {
243249
self.extend_date_range_bound(from, &self.values[2], true)?
@@ -251,8 +257,37 @@ impl BaseFilter {
251257
to
252258
};
253259

254-
self.templates
255-
.time_range_filter(member_sql.to_string(), from, to)
260+
let date_field = self
261+
.query_tools
262+
.base_tools()
263+
.convert_tz(member_sql.to_string())?;
264+
self.templates.time_range_filter(date_field, from, to)
265+
}
266+
267+
fn to_date_rolling_window_date_range(&self, member_sql: &str) -> Result<String, CubeError> {
268+
let (from, to) = self.allocate_date_params(false)?;
269+
270+
let from = if self.values.len() >= 3 {
271+
if let Some(granularity) = &self.values[2] {
272+
self.query_tools
273+
.base_tools()
274+
.time_grouped_column(granularity.clone(), from)?
275+
} else {
276+
return Err(CubeError::user(format!(
277+
"Granularity required for to_date rolling window"
278+
)));
279+
}
280+
} else {
281+
return Err(CubeError::user(format!(
282+
"Granularity required for to_date rolling window"
283+
)));
284+
};
285+
286+
let date_field = self
287+
.query_tools
288+
.base_tools()
289+
.convert_tz(member_sql.to_string())?;
290+
self.templates.time_range_filter(date_field, from, to)
256291
}
257292

258293
fn in_where(&self, member_sql: &str) -> Result<String, CubeError> {
@@ -353,22 +388,30 @@ impl BaseFilter {
353388
))
354389
}
355390

356-
fn allocate_date_params(&self) -> Result<(String, String), CubeError> {
391+
fn allocate_date_params(&self, use_db_time_zone: bool) -> Result<(String, String), CubeError> {
357392
if self.values.len() >= 2 {
358393
let from = if let Some(from_str) = &self.values[0] {
359-
self.query_tools
360-
.base_tools()
361-
.in_db_time_zone(self.format_from_date(&from_str)?)?
394+
let from = self.format_from_date(&from_str)?;
395+
396+
if use_db_time_zone {
397+
self.query_tools.base_tools().in_db_time_zone(from)?
398+
} else {
399+
from
400+
}
362401
} else {
363402
return Err(CubeError::user(format!(
364403
"Arguments for date range is not valid"
365404
)));
366405
};
367406

368407
let to = if let Some(to_str) = &self.values[1] {
369-
self.query_tools
370-
.base_tools()
371-
.in_db_time_zone(self.format_to_date(&to_str)?)?
408+
let to = self.format_to_date(&to_str)?;
409+
410+
if use_db_time_zone {
411+
self.query_tools.base_tools().in_db_time_zone(to)?
412+
} else {
413+
to
414+
}
372415
} else {
373416
return Err(CubeError::user(format!(
374417
"Arguments for date range is not valid"
@@ -411,11 +454,7 @@ impl BaseFilter {
411454
"0".repeat(precision as usize)
412455
));
413456
}
414-
//FIXME chrono don't support parsing date without specified format
415-
Err(CubeError::user(format!(
416-
"Unsupported date format: {}",
417-
date
418-
)))
457+
Ok(date.to_string())
419458
}
420459

421460
fn format_to_date(&self, date: &str) -> Result<String, CubeError> {
@@ -447,11 +486,8 @@ impl BaseFilter {
447486
"9".repeat(precision as usize)
448487
));
449488
}
450-
//FIXME chrono don't support parsing date without specified format
451-
Err(CubeError::user(format!(
452-
"Unsupported date format: {}",
453-
date
454-
)))
489+
490+
Ok(date.to_string())
455491
}
456492

457493
fn allocate_param(&self, param: &str) -> String {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ pub enum FilterOperator {
66
Equal,
77
NotEqual,
88
InDateRange,
9-
InDateRangeExtended,
9+
RegularRollingWindowDateRange,
10+
ToDateRollingWindowDateRange,
1011
In,
1112
NotIn,
1213
Set,

rust/cubesqlplanner/cubesqlplanner/src/planner/planners/dimension_subquery_planner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl DimensionSubqueryPlanner {
125125
false,
126126
)?;
127127
let query_planner = QueryPlanner::new(sub_query_properties, self.query_tools.clone());
128-
let sub_query = query_planner.build_sql()?;
128+
let sub_query = query_planner.plan()?;
129129
let sub_query_alias = format!("{cube_name}_{dim_name}_subquery");
130130

131131
let conditions = primary_keys_dimensions

0 commit comments

Comments
 (0)