Skip to content

Commit eef6fb7

Browse files
committed
views support
1 parent 764da0f commit eef6fb7

File tree

4 files changed

+145
-94
lines changed

4 files changed

+145
-94
lines changed

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/memeber_sql.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::rc::Rc;
1919
pub struct MemberSqlStruct {
2020
pub sql_fn: Option<String>,
2121
pub to_string_fn: Option<String>,
22-
pub properties: HashMap<String, String>,
22+
pub properties: HashMap<String, MemberSqlArg>,
2323
}
2424

2525
pub enum ContextSymbolArg {
@@ -64,6 +64,39 @@ impl<IT: InnerTypes> NativeSerialize<IT> for MemberSqlStruct {
6464
}
6565
}
6666

67+
impl<IT: InnerTypes> NativeSerialize<IT> for MemberSqlArg {
68+
fn to_native(
69+
&self,
70+
context_holder: NativeContextHolder<IT>,
71+
) -> Result<NativeObjectHandle<IT>, CubeError> {
72+
let res = match self {
73+
MemberSqlArg::String(s) => s.to_native(context_holder.clone()),
74+
MemberSqlArg::Struct(s) => s.to_native(context_holder.clone()),
75+
MemberSqlArg::ContextSymbol(symbol) => match symbol {
76+
ContextSymbolArg::SecurityContext(context) => context
77+
.clone()
78+
.as_any()
79+
.downcast::<NativeSecurityContext<IT>>()
80+
.unwrap()
81+
.to_native(context_holder.clone()),
82+
ContextSymbolArg::FilterParams(params) => params
83+
.clone()
84+
.as_any()
85+
.downcast::<NativeFilterParams<IT>>()
86+
.unwrap()
87+
.to_native(context_holder.clone()),
88+
ContextSymbolArg::FilterGroup(group) => group
89+
.clone()
90+
.as_any()
91+
.downcast::<NativeFilterGroup<IT>>()
92+
.unwrap()
93+
.to_native(context_holder.clone()),
94+
},
95+
}?;
96+
Ok(NativeObjectHandle::new(res.into_object()))
97+
}
98+
}
99+
67100
impl<IT: InnerTypes> NativeMemberSql<IT> {
68101
pub fn try_new(native_object: NativeObjectHandle<IT>) -> Result<Self, CubeError> {
69102
let args_names = native_object.to_function()?.args_names()?;
@@ -89,27 +122,7 @@ impl<IT: InnerTypes> MemberSql for NativeMemberSql<IT> {
89122
let context_holder = NativeContextHolder::<IT>::new(self.native_object.get_context());
90123
let native_args = args
91124
.into_iter()
92-
.map(|a| match a {
93-
MemberSqlArg::String(s) => s.to_native(context_holder.clone()),
94-
MemberSqlArg::Struct(s) => s.to_native(context_holder.clone()),
95-
MemberSqlArg::ContextSymbol(symbol) => match symbol {
96-
ContextSymbolArg::SecurityContext(context) => context
97-
.as_any()
98-
.downcast::<NativeSecurityContext<IT>>()
99-
.unwrap()
100-
.to_native(context_holder.clone()),
101-
ContextSymbolArg::FilterParams(params) => params
102-
.as_any()
103-
.downcast::<NativeFilterParams<IT>>()
104-
.unwrap()
105-
.to_native(context_holder.clone()),
106-
ContextSymbolArg::FilterGroup(group) => group
107-
.as_any()
108-
.downcast::<NativeFilterGroup<IT>>()
109-
.unwrap()
110-
.to_native(context_holder.clone()),
111-
},
112-
})
125+
.map(|a| a.to_native(context_holder.clone()))
113126
.collect::<Result<Vec<_>, _>>()?;
114127

115128
let res = self.native_object.to_function()?.call(native_args)?;

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

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{Compiler, EvaluationNode};
2-
use crate::cube_bridge::evaluator::CubeEvaluator;
2+
use crate::cube_bridge::evaluator::{CallDep, CubeEvaluator};
33
use crate::cube_bridge::memeber_sql::MemberSql;
44
use cubenativeutils::CubeError;
55
use std::collections::HashMap;
@@ -72,6 +72,7 @@ impl<'a> DependenciesBuilder<'a> {
7272
childs[parent].push(i);
7373
}
7474
}
75+
7576
let mut result = Vec::new();
7677

7778
for (i, dep) in call_deps.iter().enumerate() {
@@ -87,46 +88,59 @@ impl<'a> DependenciesBuilder<'a> {
8788
self.build_evaluator(&cube_name, &dep.name)?,
8889
));
8990
} else {
90-
let new_cube_name = if self.is_current_cube(&dep.name) {
91-
cube_name.clone()
92-
} else {
93-
dep.name.clone()
94-
};
95-
let mut sql_fn = None;
96-
let mut to_string_fn: Option<Rc<EvaluationNode>> = None;
97-
let mut properties = HashMap::new();
98-
for child_ind in childs[i].iter() {
99-
let name = &call_deps[*child_ind].name;
100-
if name.as_str() == "sql" {
101-
sql_fn = Some(
102-
self.compiler
103-
.add_cube_table_evaluator(new_cube_name.clone())?,
104-
);
105-
} else if name.as_str() == "toString" {
106-
to_string_fn = Some(
107-
self.compiler
108-
.add_cube_name_evaluator(new_cube_name.clone())?,
109-
);
110-
} else {
111-
properties.insert(
112-
name.clone(),
113-
Dependency::SingleDependency(
114-
self.build_evaluator(&new_cube_name, &name)?,
115-
),
116-
);
117-
}
118-
}
119-
result.push(Dependency::StructDependency(StructDependency::new(
120-
sql_fn,
121-
to_string_fn,
122-
properties,
123-
)));
91+
let dep = self.build_struct_dependency(&cube_name, i, &call_deps, &childs)?;
92+
result.push(Dependency::StructDependency(dep));
12493
}
12594
}
12695

12796
Ok(result)
12897
}
12998

99+
fn build_struct_dependency(
100+
&mut self,
101+
cube_name: &String,
102+
dep_index: usize,
103+
call_deps: &Vec<CallDep>,
104+
call_childs: &Vec<Vec<usize>>,
105+
) -> Result<StructDependency, CubeError> {
106+
let dep = &call_deps[dep_index];
107+
let new_cube_name = if self.is_current_cube(&dep.name) {
108+
cube_name.clone()
109+
} else {
110+
dep.name.clone()
111+
};
112+
let mut sql_fn = None;
113+
let mut to_string_fn: Option<Rc<EvaluationNode>> = None;
114+
let mut properties = HashMap::new();
115+
for child_ind in call_childs[dep_index].iter() {
116+
let name = &call_deps[*child_ind].name;
117+
if name.as_str() == "sql" {
118+
sql_fn = Some(
119+
self.compiler
120+
.add_cube_table_evaluator(new_cube_name.clone())?,
121+
);
122+
} else if name.as_str() == "toString" {
123+
to_string_fn = Some(
124+
self.compiler
125+
.add_cube_name_evaluator(new_cube_name.clone())?,
126+
);
127+
} else {
128+
let child_dep = if call_childs[*child_ind].is_empty() {
129+
Dependency::SingleDependency(self.build_evaluator(&new_cube_name, &name)?)
130+
} else {
131+
Dependency::StructDependency(self.build_struct_dependency(
132+
&new_cube_name,
133+
*child_ind,
134+
call_deps,
135+
call_childs,
136+
)?)
137+
};
138+
properties.insert(name.clone(), child_dep);
139+
}
140+
}
141+
Ok(StructDependency::new(sql_fn, to_string_fn, properties))
142+
}
143+
130144
fn build_context_dep(&self, name: &str) -> Option<Dependency> {
131145
match name {
132146
"USER_CONTEXT" | "SECURITY_CONTEXT" => Some(Dependency::ContextDependency(

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

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::dependecy::{ContextSymbolDep, Dependency};
1+
use super::dependecy::{ContextSymbolDep, Dependency, StructDependency};
22
use super::sql_nodes::SqlNode;
33
use super::EvaluationNode;
44
use crate::cube_bridge::memeber_sql::{ContextSymbolArg, MemberSqlArg, MemberSqlStruct};
@@ -69,28 +69,42 @@ impl SqlEvaluatorVisitor {
6969
self.apply(dep, node_processor.clone())?,
7070
)),
7171
Dependency::StructDependency(dep) => {
72-
let mut res = MemberSqlStruct::default();
73-
if let Some(sql_fn) = &dep.sql_fn {
74-
res.sql_fn = Some(self.apply(sql_fn, node_processor.clone())?);
75-
}
76-
if let Some(to_string_fn) = &dep.to_string_fn {
77-
res.to_string_fn = Some(self.apply(to_string_fn, node_processor.clone())?);
78-
}
79-
for (k, v) in dep.properties.iter() {
80-
match v {
81-
Dependency::SingleDependency(dep) => {
82-
res.properties
83-
.insert(k.clone(), self.apply(dep, node_processor.clone())?);
84-
}
85-
Dependency::StructDependency(_) => unimplemented!(),
86-
Dependency::ContextDependency(_) => unimplemented!(),
87-
}
88-
}
89-
Ok(MemberSqlArg::Struct(res))
72+
self.evaluate_struct_dep(dep, node_processor.clone())
9073
}
9174
Dependency::ContextDependency(contex_symbol) => {
9275
self.apply_context_symbol(contex_symbol)
9376
}
9477
}
9578
}
79+
80+
fn evaluate_struct_dep(
81+
&mut self,
82+
dep: &StructDependency,
83+
node_processor: Rc<dyn SqlNode>,
84+
) -> Result<MemberSqlArg, CubeError> {
85+
let mut res = MemberSqlStruct::default();
86+
if let Some(sql_fn) = &dep.sql_fn {
87+
res.sql_fn = Some(self.apply(sql_fn, node_processor.clone())?);
88+
}
89+
if let Some(to_string_fn) = &dep.to_string_fn {
90+
res.to_string_fn = Some(self.apply(to_string_fn, node_processor.clone())?);
91+
}
92+
for (k, v) in dep.properties.iter() {
93+
let prop_res = match v {
94+
Dependency::SingleDependency(dep) => {
95+
MemberSqlArg::String(self.apply(dep, node_processor.clone())?)
96+
}
97+
Dependency::StructDependency(dep) => {
98+
self.evaluate_struct_dep(dep, node_processor.clone())?
99+
}
100+
Dependency::ContextDependency(_) => {
101+
return Err(CubeError::internal(format!(
102+
"Context dependency in struct dependency is not supported"
103+
)))
104+
}
105+
};
106+
res.properties.insert(k.clone(), prop_res);
107+
}
108+
Ok(MemberSqlArg::Struct(res))
109+
}
96110
}

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

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use super::{dependecy::Dependency, EvaluationNode};
1+
use super::{
2+
dependecy::{Dependency, StructDependency},
3+
EvaluationNode,
4+
};
25
use cubenativeutils::CubeError;
36
use std::rc::Rc;
47

@@ -36,25 +39,32 @@ pub trait TraversalVisitor {
3639
) -> Result<(), CubeError> {
3740
match dep {
3841
Dependency::SingleDependency(dep) => self.apply(dep, state),
39-
Dependency::StructDependency(dep) => {
40-
if dep.sql_fn.is_some() {
41-
self.apply(node, state)?;
42-
}
43-
if let Some(to_string_fn) = &dep.to_string_fn {
44-
self.apply(to_string_fn, state)?;
45-
}
46-
for (_, v) in dep.properties.iter() {
47-
match v {
48-
Dependency::SingleDependency(dep) => {
49-
self.apply(dep, state)?;
50-
}
51-
Dependency::StructDependency(_) => unimplemented!(),
52-
Dependency::ContextDependency(_) => {}
53-
}
42+
Dependency::StructDependency(dep) => self.traverse_struct_dep(dep, node, state),
43+
Dependency::ContextDependency(_) => Ok(()),
44+
}
45+
}
46+
47+
fn traverse_struct_dep(
48+
&mut self,
49+
dep: &StructDependency,
50+
node: &Rc<EvaluationNode>,
51+
state: &Self::State,
52+
) -> Result<(), CubeError> {
53+
if dep.sql_fn.is_some() {
54+
self.apply(node, state)?;
55+
}
56+
if let Some(to_string_fn) = &dep.to_string_fn {
57+
self.apply(to_string_fn, state)?;
58+
}
59+
for (_, v) in dep.properties.iter() {
60+
match v {
61+
Dependency::SingleDependency(dep) => {
62+
self.apply(dep, state)?;
5463
}
55-
Ok(())
64+
Dependency::StructDependency(dep) => self.traverse_struct_dep(dep, node, state)?,
65+
Dependency::ContextDependency(_) => {}
5666
}
57-
Dependency::ContextDependency(_) => Ok(()),
5867
}
68+
Ok(())
5969
}
6070
}

0 commit comments

Comments
 (0)