diff --git a/rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/cube_definition.rs b/rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/cube_definition.rs index ead66c3433594..6fa531ddbce7b 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/cube_definition.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/cube_definition.rs @@ -12,6 +12,8 @@ use std::rc::Rc; #[derive(Serialize, Deserialize, Debug)] pub struct CubeDefinitionStatic { pub name: String, + #[serde(rename = "sqlAlias")] + pub sql_alias: Option, } #[nativebridge::native_bridge(CubeDefinitionStatic)] diff --git a/rust/cubesqlplanner/cubesqlplanner/src/plan/schema/schema.rs b/rust/cubesqlplanner/cubesqlplanner/src/plan/schema/schema.rs index 29c519dba835f..52ed83390c10e 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/plan/schema/schema.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/plan/schema/schema.rs @@ -1,5 +1,4 @@ use super::SchemaColumn; -use crate::planner::sql_templates::PlanSqlTemplates; use crate::planner::BaseMember; use itertools::Itertools; use std::rc::Rc; @@ -39,11 +38,7 @@ impl Schema { if let Some(column) = self.find_column_for_member(&member.full_name()) { column.name().clone() } else { - PlanSqlTemplates::memeber_alias_name( - member.cube_name(), - member.name(), - member.alias_suffix(), - ) + member.alias_name() } } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs index ee9e8116f8506..49107d4af1a50 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs @@ -1,6 +1,7 @@ use super::query_tools::QueryTools; use super::sql_evaluator::MemberSymbol; use super::{evaluate_with_context, VisitorContext}; +use crate::cube_bridge::cube_definition::CubeDefinition; use cubenativeutils::CubeError; use std::collections::HashSet; use std::rc::Rc; @@ -9,6 +10,7 @@ pub struct BaseCube { cube_name: String, members: HashSet, member_evaluator: Rc, + definition: Rc, query_tools: Rc, } impl BaseCube { @@ -17,6 +19,9 @@ impl BaseCube { query_tools: Rc, member_evaluator: Rc, ) -> Result, CubeError> { + let definition = query_tools + .cube_evaluator() + .cube_from_path(cube_name.clone())?; let members = query_tools .base_tools() .all_cube_members(cube_name.clone())? @@ -27,6 +32,7 @@ impl BaseCube { cube_name, members, member_evaluator, + definition, query_tools, })) } @@ -50,7 +56,15 @@ impl BaseCube { } pub fn default_alias(&self) -> String { - self.query_tools.alias_name(&self.cube_name) + if let Some(alias) = self.sql_alias() { + alias.clone() + } else { + self.query_tools.alias_name(&self.cube_name) + } + } + + pub fn sql_alias(&self) -> &Option { + &self.definition.static_data().sql_alias } pub fn default_alias_with_prefix(&self, prefix: &Option) -> String { diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_dimension.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_dimension.rs index 6a1bca2d280de..bca6d99ca2a34 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_dimension.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_dimension.rs @@ -1,6 +1,6 @@ use super::query_tools::QueryTools; use super::sql_evaluator::MemberSymbol; -use super::{evaluate_with_context, BaseMember, VisitorContext}; +use super::{evaluate_with_context, BaseMember, BaseMemberHelper, VisitorContext}; use cubenativeutils::CubeError; use std::rc::Rc; @@ -10,6 +10,7 @@ pub struct BaseDimension { member_evaluator: Rc, cube_name: String, name: String, + default_alias: String, } impl BaseMember for BaseDimension { @@ -18,7 +19,7 @@ impl BaseMember for BaseDimension { } fn alias_name(&self) -> String { - self.unescaped_alias_name() + self.default_alias.clone() } fn member_evaluator(&self) -> Rc { @@ -44,13 +45,22 @@ impl BaseDimension { query_tools: Rc, ) -> Result>, CubeError> { let result = match evaluation_node.as_ref() { - MemberSymbol::Dimension(s) => Some(Rc::new(Self { - dimension: s.full_name(), - query_tools: query_tools.clone(), - member_evaluator: evaluation_node.clone(), - cube_name: s.cube_name().clone(), - name: s.name().clone(), - })), + MemberSymbol::Dimension(s) => { + let default_alias = BaseMemberHelper::default_alias( + &s.cube_name(), + &s.name(), + &None, + query_tools.clone(), + )?; + Some(Rc::new(Self { + dimension: s.full_name(), + query_tools: query_tools.clone(), + member_evaluator: evaluation_node.clone(), + cube_name: s.cube_name().clone(), + name: s.name().clone(), + default_alias, + })) + } _ => None, }; Ok(result) @@ -76,8 +86,4 @@ impl BaseDimension { pub fn dimension(&self) -> &String { &self.dimension } - - pub fn unescaped_alias_name(&self) -> String { - self.query_tools.alias_name(&self.dimension) - } } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_measure.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_measure.rs index db215ec1eeaf1..e61724563d367 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_measure.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_measure.rs @@ -1,6 +1,6 @@ use super::query_tools::QueryTools; use super::sql_evaluator::MemberSymbol; -use super::{evaluate_with_context, BaseMember, VisitorContext}; +use super::{evaluate_with_context, BaseMember, BaseMemberHelper, VisitorContext}; use crate::cube_bridge::measure_definition::{ MeasureDefinition, RollingWindow, TimeShiftReference, }; @@ -70,6 +70,7 @@ pub struct BaseMeasure { time_shifts: Vec, cube_name: String, name: String, + default_alias: String, } impl Debug for BaseMeasure { @@ -77,6 +78,7 @@ impl Debug for BaseMeasure { f.debug_struct("BaseMeasure") .field("measure", &self.measure) .field("time_shifts", &self.time_shifts) + .field("default_alias", &self.default_alias) .finish() } } @@ -87,7 +89,7 @@ impl BaseMember for BaseMeasure { } fn alias_name(&self) -> String { - self.unescaped_alias_name() + self.default_alias.clone() } fn member_evaluator(&self) -> Rc { @@ -115,6 +117,12 @@ impl BaseMeasure { let res = match evaluation_node.as_ref() { MemberSymbol::Measure(s) => { let time_shifts = Self::parse_time_shifts(&s.definition())?; + let default_alias = BaseMemberHelper::default_alias( + &s.cube_name(), + &s.name(), + &None, + query_tools.clone(), + )?; Some(Rc::new(Self { measure: s.full_name(), query_tools: query_tools.clone(), @@ -123,6 +131,7 @@ impl BaseMeasure { cube_name: s.cube_name().clone(), name: s.name().clone(), time_shifts, + default_alias, })) } _ => None, @@ -224,8 +233,4 @@ impl BaseMeasure { pub fn is_multi_stage_ungroupped(&self) -> bool { self.is_calculated() || self.definition.static_data().measure_type == "rank" } - - fn unescaped_alias_name(&self) -> String { - self.query_tools.alias_name(&self.measure) - } } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs index 7b60dedbbb728..0618a9101b1f2 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs @@ -1,4 +1,6 @@ +use super::query_tools::QueryTools; use super::sql_evaluator::MemberSymbol; +use super::sql_templates::PlanSqlTemplates; use super::VisitorContext; use cubenativeutils::CubeError; use itertools::Itertools; @@ -37,4 +39,25 @@ impl BaseMemberHelper { pub fn to_alias_vec(members: &Vec>) -> Vec { members.iter().map(|m| m.alias_name()).collect_vec() } + + pub fn default_alias( + cube_name: &String, + member_name: &String, + member_suffix: &Option, + query_tools: Rc, + ) -> Result { + let cube_definition = query_tools + .cube_evaluator() + .cube_from_path(cube_name.clone())?; + let cube_alias = if let Some(sql_alias) = &cube_definition.static_data().sql_alias { + sql_alias + } else { + cube_name + }; + Ok(PlanSqlTemplates::memeber_alias_name( + &cube_alias, + &member_name, + member_suffix, + )) + } } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_time_dimension.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_time_dimension.rs index 296ba7c9161c7..cd0ad89812f1d 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/base_time_dimension.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/base_time_dimension.rs @@ -1,7 +1,7 @@ use super::query_tools::QueryTools; use super::sql_evaluator::MemberSymbol; use super::BaseDimension; -use super::{BaseMember, VisitorContext}; +use super::{BaseMember, BaseMemberHelper, VisitorContext}; use cubenativeutils::CubeError; use std::rc::Rc; @@ -10,6 +10,7 @@ pub struct BaseTimeDimension { query_tools: Rc, granularity: Option, date_range: Option>, + default_alias: String, alias_suffix: String, } @@ -19,7 +20,7 @@ impl BaseMember for BaseTimeDimension { } fn alias_name(&self) -> String { - self.unescaped_alias_name() + self.default_alias.clone() } fn member_evaluator(&self) -> Rc { @@ -55,12 +56,20 @@ impl BaseTimeDimension { } else { "day".to_string() }; + let dimension = BaseDimension::try_new_required(member_evaluator, query_tools.clone())?; + let default_alias = BaseMemberHelper::default_alias( + &dimension.cube_name(), + &dimension.name(), + &Some(alias_suffix.clone()), + query_tools.clone(), + )?; Ok(Rc::new(Self { - dimension: BaseDimension::try_new_required(member_evaluator, query_tools.clone())?, + dimension, query_tools, granularity, date_range, alias_suffix, + default_alias, })) } @@ -71,6 +80,7 @@ impl BaseTimeDimension { granularity: new_granularity, date_range: self.date_range.clone(), alias_suffix: self.alias_suffix.clone(), + default_alias: self.default_alias.clone(), }) } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/references_builder.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/references_builder.rs index f14f6f15e500d..d12bc60ce6773 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/references_builder.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/references_builder.rs @@ -259,52 +259,4 @@ impl ReferencesBuilder { ) }) } - - /* fn validate_reference(&self, reference: &QualifiedColumnName) -> Result<(), CubeError> { - if self.is_source_has_reference(reference) { - Ok(()) - } else { - Err(CubeError::internal(format!( - "Error while planning: schema does not have reference {}", - reference - ))) - } - } - - fn is_source_has_reference(&self, reference: &QualifiedColumnName) -> bool { - match &self.source.source { - crate::plan::FromSource::Empty => false, - crate::plan::FromSource::Single(source) => { - self.is_single_source_has_reference(&source, reference) - } - crate::plan::FromSource::Join(join) => self.is_join_has_reference(&join, reference), - } - } - - fn is_join_has_reference(&self, join: &Rc, reference: &QualifiedColumnName) -> bool { - if self.is_single_source_has_reference(&join.root, reference) { - return true; - } - join.joins - .iter() - .any(|item| self.is_single_source_has_reference(&item.from, reference)) - } - - fn is_single_source_has_reference( - &self, - source: &SingleAliasedSource, - reference: &QualifiedColumnName, - ) -> bool { - if let Some(reference_source) = &reference.source() { - if reference_source != &source.alias { - return false; - } - } - - match &source.source { - SingleSource::Subquery(query_plan) => query_plan.schema().has_column(reference.name()), - SingleSource::Cube(_) => false, - SingleSource::TableReference(_, schema) => schema.has_column(reference.name()), - } - } */ } diff --git a/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs b/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs index 04b716de0256d..f93a915533c4d 100644 --- a/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs +++ b/rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs @@ -20,7 +20,7 @@ impl PlanSqlTemplates { name.to_case(Case::Snake).replace(".", "__") } - pub fn memeber_alias_name(cube_name: &str, name: &str, suffix: Option) -> String { + pub fn memeber_alias_name(cube_name: &str, name: &str, suffix: &Option) -> String { let suffix = if let Some(suffix) = suffix { format!("_{}", suffix) } else {