Skip to content

Commit bf94b02

Browse files
authored
chore(tesseract): DebugSql for symbols and filters (#10195)
1 parent 32e368f commit bf94b02

File tree

18 files changed

+620
-1
lines changed

18 files changed

+620
-1
lines changed

rust/cubesqlplanner/Cargo.lock

Lines changed: 53 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/cubesqlplanner/cubesqlplanner/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ indoc = "2.0.7"
2626
[dev-dependencies]
2727
petgraph = "0.6"
2828
serde_yaml = "0.9"
29+
insta = "1.34"
2930

3031
[dependencies.neon]
3132
version = "=1"
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use super::filter::{Filter, FilterGroup, FilterGroupOperator, FilterItem};
2+
use crate::planner::filter::BaseFilter;
3+
use crate::planner::sql_evaluator::DebugSql;
4+
5+
impl DebugSql for BaseFilter {
6+
fn debug_sql(&self, expand_deps: bool) -> String {
7+
let member = if expand_deps {
8+
self.member_evaluator().debug_sql(true)
9+
} else {
10+
format!("{{{}}}", self.member_evaluator().full_name())
11+
};
12+
13+
let values_str = self
14+
.values()
15+
.iter()
16+
.map(|v| match v {
17+
Some(val) => format!("'{}'", val),
18+
None => "NULL".to_string(),
19+
})
20+
.collect::<Vec<_>>()
21+
.join(", ");
22+
23+
format!(
24+
"{} {}: [{}]",
25+
member,
26+
self.filter_operator().to_string(),
27+
values_str
28+
)
29+
}
30+
}
31+
32+
impl DebugSql for FilterItem {
33+
fn debug_sql(&self, expand_deps: bool) -> String {
34+
match self {
35+
FilterItem::Group(group) => group.debug_sql(expand_deps),
36+
FilterItem::Item(filter) => filter.debug_sql(expand_deps),
37+
FilterItem::Segment(segment) => {
38+
let member = if expand_deps {
39+
segment.member_evaluator().debug_sql(true)
40+
} else {
41+
format!("{{{}}}", segment.member_evaluator().full_name())
42+
};
43+
format!("SEGMENT({})", member)
44+
}
45+
}
46+
}
47+
}
48+
49+
impl DebugSql for FilterGroup {
50+
fn debug_sql(&self, expand_deps: bool) -> String {
51+
if self.items.is_empty() {
52+
return format!("{}: []", self.operator);
53+
}
54+
55+
let items_str = self
56+
.items
57+
.iter()
58+
.map(|item| {
59+
let item_str = item.debug_sql(expand_deps);
60+
// Indent each line of the item
61+
item_str
62+
.lines()
63+
.map(|line| format!(" {}", line))
64+
.collect::<Vec<_>>()
65+
.join("\n")
66+
})
67+
.collect::<Vec<_>>()
68+
.join(",\n");
69+
70+
format!("{}: [\n{}\n]", self.operator, items_str)
71+
}
72+
}
73+
74+
impl DebugSql for Filter {
75+
fn debug_sql(&self, expand_deps: bool) -> String {
76+
if self.items.is_empty() {
77+
return "Filter: []".to_string();
78+
}
79+
80+
if self.items.len() == 1 {
81+
return self.items[0].debug_sql(expand_deps);
82+
}
83+
84+
// Multiple items treated as AND group
85+
let group = FilterGroup::new(FilterGroupOperator::And, self.items.clone());
86+
group.debug_sql(expand_deps)
87+
}
88+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub mod calc_groups_join;
33
pub mod cte;
44
pub mod expression;
55
pub mod filter;
6+
pub mod filter_debug;
67
pub mod from;
78
pub mod join;
89
pub mod order;

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod sql_visitor;
88
pub mod symbols;
99
pub mod visitor;
1010

11+
pub use crate::utils::debug::DebugSql;
1112
pub use compiler::Compiler;
1213
pub use references_builder::ReferencesBuilder;
1314
pub use sql_call::*;

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/sql_call.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,57 @@ impl SqlCall {
327327
Ok(Rc::new(result))
328328
}
329329
}
330+
331+
impl crate::utils::debug::DebugSql for SqlCall {
332+
fn debug_sql(&self, expand_deps: bool) -> String {
333+
let template_str = match &self.template {
334+
SqlTemplate::String(s) => s.clone(),
335+
SqlTemplate::StringVec(vec) => {
336+
format!("[{}]", vec.join(", "))
337+
}
338+
};
339+
340+
let deps = self
341+
.deps
342+
.iter()
343+
.map(|dep| {
344+
if expand_deps {
345+
dep.symbol.debug_sql(true)
346+
} else {
347+
format!("{{{}}}", dep.symbol.full_name())
348+
}
349+
})
350+
.collect_vec();
351+
352+
let filter_params = self
353+
.filter_params
354+
.iter()
355+
.enumerate()
356+
.map(|(i, _filter_param)| format!("{{FILTER_PARAMS[{}]}}", i))
357+
.collect_vec();
358+
359+
let filter_groups = self
360+
.filter_groups
361+
.iter()
362+
.enumerate()
363+
.map(|(i, _filter_group)| format!("{{FILTER_GROUP[{}]}}", i))
364+
.collect_vec();
365+
366+
let context_values = self
367+
.security_context
368+
.values
369+
.iter()
370+
.enumerate()
371+
.map(|(key, _value)| format!("{{SECURITY_CONTEXT[{}]}}", key))
372+
.collect_vec();
373+
374+
Self::substitute_template(
375+
&template_str,
376+
&deps,
377+
&filter_params,
378+
&filter_groups,
379+
&context_values,
380+
)
381+
.unwrap()
382+
}
383+
}

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/symbols/common/case.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,58 @@ impl Case {
371371
}
372372
}
373373
}
374+
375+
impl crate::utils::debug::DebugSql for Case {
376+
fn debug_sql(&self, expand_deps: bool) -> String {
377+
match self {
378+
Case::Case(case_def) => {
379+
let mut result = "CASE\n".to_string();
380+
381+
for when in &case_def.items {
382+
let condition = when.sql.debug_sql(expand_deps);
383+
let then = match &when.label {
384+
CaseLabel::String(s) => format!("'{}'", s),
385+
CaseLabel::Sql(sql) => sql.debug_sql(expand_deps),
386+
};
387+
result.push_str(&format!(" WHEN {} THEN {}\n", condition, then));
388+
}
389+
390+
let else_sql = match &case_def.else_label {
391+
CaseLabel::String(s) => format!("'{}'", s),
392+
CaseLabel::Sql(sql) => sql.debug_sql(expand_deps),
393+
};
394+
result.push_str(&format!(" ELSE {}\n", else_sql));
395+
396+
result.push_str("END");
397+
result
398+
}
399+
Case::CaseSwitch(case_switch) => {
400+
let switch_sql = match &case_switch.switch {
401+
CaseSwitchItem::Sql(sql) => sql.debug_sql(expand_deps),
402+
CaseSwitchItem::Member(member) => {
403+
if expand_deps {
404+
member.debug_sql(true)
405+
} else {
406+
format!("{{{}}}", member.full_name())
407+
}
408+
}
409+
};
410+
411+
let mut result = format!("CASE {}\n", switch_sql);
412+
413+
for when in &case_switch.items {
414+
let then = when.sql.debug_sql(expand_deps);
415+
result.push_str(&format!(" WHEN '{}' THEN {}\n", when.value, then));
416+
}
417+
418+
if let Some(else_sql) = &case_switch.else_sql {
419+
let else_sql_str = else_sql.debug_sql(expand_deps);
420+
result.push_str(&format!(" ELSE {}\n", else_sql_str));
421+
}
422+
423+
result.push_str("END");
424+
result
425+
}
426+
}
427+
}
428+
}

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_evaluator/symbols/cube_symbol.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,20 @@ impl SymbolFactory for CubeTableSymbolFactory {
214214
)))
215215
}
216216
}
217+
218+
impl crate::utils::debug::DebugSql for CubeNameSymbol {
219+
fn debug_sql(&self, _expand_deps: bool) -> String {
220+
self.cube_name().clone()
221+
}
222+
}
223+
224+
impl crate::utils::debug::DebugSql for CubeTableSymbol {
225+
fn debug_sql(&self, expand_deps: bool) -> String {
226+
let sql_debug = if let Some(sql) = &self.member_sql {
227+
sql.debug_sql(expand_deps)
228+
} else {
229+
"NULL".to_string()
230+
};
231+
format!("{}({})", self.cube_name(), sql_debug)
232+
}
233+
}

0 commit comments

Comments
 (0)