Skip to content

Commit

Permalink
fix(tesseract): sqlAlias support
Browse files Browse the repository at this point in the history
  • Loading branch information
waralexrom authored Jan 6, 2025
1 parent e1911d4 commit f254f64
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
}

#[nativebridge::native_bridge(CubeDefinitionStatic)]
Expand Down
7 changes: 1 addition & 6 deletions rust/cubesqlplanner/cubesqlplanner/src/plan/schema/schema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::SchemaColumn;
use crate::planner::sql_templates::PlanSqlTemplates;
use crate::planner::BaseMember;
use itertools::Itertools;
use std::rc::Rc;
Expand Down Expand Up @@ -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()
}
}

Expand Down
16 changes: 15 additions & 1 deletion rust/cubesqlplanner/cubesqlplanner/src/planner/base_cube.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -9,6 +10,7 @@ pub struct BaseCube {
cube_name: String,
members: HashSet<String>,
member_evaluator: Rc<MemberSymbol>,
definition: Rc<dyn CubeDefinition>,
query_tools: Rc<QueryTools>,
}
impl BaseCube {
Expand All @@ -17,6 +19,9 @@ impl BaseCube {
query_tools: Rc<QueryTools>,
member_evaluator: Rc<MemberSymbol>,
) -> Result<Rc<Self>, 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())?
Expand All @@ -27,6 +32,7 @@ impl BaseCube {
cube_name,
members,
member_evaluator,
definition,
query_tools,
}))
}
Expand All @@ -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<String> {
&self.definition.static_data().sql_alias
}

pub fn default_alias_with_prefix(&self, prefix: &Option<String>) -> String {
Expand Down
32 changes: 19 additions & 13 deletions rust/cubesqlplanner/cubesqlplanner/src/planner/base_dimension.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -10,6 +10,7 @@ pub struct BaseDimension {
member_evaluator: Rc<MemberSymbol>,
cube_name: String,
name: String,
default_alias: String,
}

impl BaseMember for BaseDimension {
Expand All @@ -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<MemberSymbol> {
Expand All @@ -44,13 +45,22 @@ impl BaseDimension {
query_tools: Rc<QueryTools>,
) -> Result<Option<Rc<Self>>, 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)
Expand All @@ -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)
}
}
17 changes: 11 additions & 6 deletions rust/cubesqlplanner/cubesqlplanner/src/planner/base_measure.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand Down Expand Up @@ -70,13 +70,15 @@ pub struct BaseMeasure {
time_shifts: Vec<MeasureTimeShift>,
cube_name: String,
name: String,
default_alias: String,
}

impl Debug for BaseMeasure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BaseMeasure")
.field("measure", &self.measure)
.field("time_shifts", &self.time_shifts)
.field("default_alias", &self.default_alias)
.finish()
}
}
Expand All @@ -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<MemberSymbol> {
Expand Down Expand Up @@ -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(),
Expand All @@ -123,6 +131,7 @@ impl BaseMeasure {
cube_name: s.cube_name().clone(),
name: s.name().clone(),
time_shifts,
default_alias,
}))
}
_ => None,
Expand Down Expand Up @@ -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)
}
}
23 changes: 23 additions & 0 deletions rust/cubesqlplanner/cubesqlplanner/src/planner/base_member.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -37,4 +39,25 @@ impl BaseMemberHelper {
pub fn to_alias_vec(members: &Vec<Rc<dyn BaseMember>>) -> Vec<String> {
members.iter().map(|m| m.alias_name()).collect_vec()
}

pub fn default_alias(
cube_name: &String,
member_name: &String,
member_suffix: &Option<String>,
query_tools: Rc<QueryTools>,
) -> Result<String, CubeError> {
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,
))
}
}
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -10,6 +10,7 @@ pub struct BaseTimeDimension {
query_tools: Rc<QueryTools>,
granularity: Option<String>,
date_range: Option<Vec<String>>,
default_alias: String,
alias_suffix: String,
}

Expand All @@ -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<MemberSymbol> {
Expand Down Expand Up @@ -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,
}))
}

Expand All @@ -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(),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Join>, 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()),
}
} */
}
Original file line number Diff line number Diff line change
Expand Up @@ -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>) -> String {
pub fn memeber_alias_name(cube_name: &str, name: &str, suffix: &Option<String>) -> String {
let suffix = if let Some(suffix) = suffix {
format!("_{}", suffix)
} else {
Expand Down

0 comments on commit f254f64

Please sign in to comment.