Skip to content

Commit 764da0f

Browse files
committed
some fixes
1 parent d22c327 commit 764da0f

30 files changed

+681
-143
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,38 @@ export class BaseQuery {
605605
}
606606
}
607607

608+
buildSqlAndParamsTest(exportAnnotatedSql) {
609+
if (!this.options.preAggregationQuery && !this.options.disableExternalPreAggregations && this.externalQueryClass) {
610+
if (this.externalPreAggregationQuery()) { // TODO performance
611+
return this.externalQuery().buildSqlAndParams(exportAnnotatedSql);
612+
}
613+
}
614+
const js_res = this.compilers.compiler.withQuery(
615+
this,
616+
() => this.cacheValue(
617+
['buildSqlAndParams', exportAnnotatedSql],
618+
() => this.paramAllocator.buildSqlAndParams(
619+
this.buildParamAnnotatedSql(),
620+
exportAnnotatedSql,
621+
this.shouldReuseParams
622+
),
623+
{ cache: this.queryCache }
624+
)
625+
);
626+
console.log('js result: ', js_res[0]);
627+
const rust = this.buildSqlAndParamsRust(exportAnnotatedSql);
628+
console.log('rust result: ', rust[0]);
629+
return js_res;
630+
}
631+
608632
buildSqlAndParamsRust(exportAnnotatedSql) {
633+
634+
635+
const order = this.options.order && R.pipe(
636+
R.map((hash) => (!hash || !hash.id) ? null : hash),
637+
R.reject(R.isNil),
638+
)(this.options.order);
639+
609640
const queryParams = {
610641
measures: this.options.measures,
611642
dimensions: this.options.dimensions,
@@ -614,12 +645,13 @@ export class BaseQuery {
614645
joinRoot: this.join.root,
615646
joinGraph: this.joinGraph,
616647
cubeEvaluator: this.cubeEvaluator,
617-
order: this.options.order,
648+
order: order,
618649
filters: this.options.filters,
619650
limit: this.options.limit ? this.options.limit.toString() : null,
620651
rowLimit: this.options.rowLimit ? this.options.rowLimit.toString() : null,
621652
offset: this.options.offset ? this.options.offset.toString() : null,
622653
baseTools: this,
654+
ungrouped: this.options.ungrouped
623655

624656
};
625657
const res = nativeBuildSqlAndParams(queryParams);
@@ -628,6 +660,10 @@ export class BaseQuery {
628660
return res;
629661
}
630662

663+
getAllocatedParams() {
664+
return this.paramAllocator.getParams()
665+
}
666+
631667
// FIXME helper for native generator, maybe should be moved entire to rust
632668
generateTimeSeries(granularity, dateRange) {
633669
return timeSeriesBase(granularity, dateRange);
@@ -806,6 +842,7 @@ export class BaseQuery {
806842
} = this.fullKeyQueryAggregateMeasures();
807843

808844
if (!multipliedMeasures.length && !cumulativeMeasures.length && !multiStageMembers.length) {
845+
console.log("!!!!! LLLOOOO!!!!");
809846
return this.simpleQuery();
810847
}
811848

@@ -1019,6 +1056,8 @@ export class BaseQuery {
10191056
const allMemberChildren = this.collectAllMemberChildren(context);
10201057
const memberToIsMultiStage = this.collectAllMultiStageMembers(allMemberChildren);
10211058

1059+
console.log("!!! measure to her ", measureToHierarchy);
1060+
10221061
const hasMultiStageMembers = (m) => {
10231062
if (memberToIsMultiStage[m]) {
10241063
return true;
@@ -1036,10 +1075,8 @@ export class BaseQuery {
10361075
R.uniq,
10371076
R.map(m => this.newMeasure(m))
10381077
);
1039-
console.log("!!!! meas hierarchy", measureToHierarchy);
10401078

10411079
const multipliedMeasures = measuresToRender(true, false)(measureToHierarchy);
1042-
console.log("!!! mul meas", multipliedMeasures);
10431080
const regularMeasures = measuresToRender(false, false)(measureToHierarchy);
10441081

10451082
const cumulativeMeasures =
@@ -1777,7 +1814,6 @@ export class BaseQuery {
17771814
return measures.map(measure => {
17781815
const cubes = this.collectFrom([measure], this.collectCubeNamesFor.bind(this), 'collectCubeNamesFor');
17791816
const joinHints = this.collectFrom([measure], this.collectJoinHintsFor.bind(this), 'collectJoinHintsFor');
1780-
console.log("!!! cubes: ", cubes, " ", joinHints);
17811817
if (R.any(cubeName => keyCubeName !== cubeName, cubes)) {
17821818
const measuresJoin = this.joinGraph.buildJoin(joinHints);
17831819
if (measuresJoin.multiplicationFactor[keyCubeName]) {
@@ -2484,7 +2520,6 @@ export class BaseQuery {
24842520
fn,
24852521
renderContext
24862522
);
2487-
console.log("!!!!! renderContext.measuresToRender.length ", renderContext.measuresToRender.length);
24882523
return renderContext.measuresToRender.length ?
24892524
R.uniq(renderContext.measuresToRender) :
24902525
[renderContext.rootMeasure.value];
@@ -3293,7 +3328,7 @@ export class BaseQuery {
32933328
lt: '{{ column }} < {{ param }}',
32943329
lte: '{{ column }} <= {{ param }}',
32953330
like_pattern: '{% if start_wild %}\'%\' || {% endif %}{{ value }}{% if end_wild %}|| \'%\'{% endif %}',
3296-
always_true: '1 == 1'
3331+
always_true: '1 = 1'
32973332

32983333
},
32993334
quotes: {

packages/cubejs-schema-compiler/src/adapter/ParamAllocator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export class ParamAllocator {
5151
return `$${paramIndex}$`;
5252
}
5353

54+
public getParams() {
55+
return this.params;
56+
}
57+
5458
// eslint-disable-next-line no-unused-vars
5559
protected paramPlaceHolder(paramIndex) {
5660
return '?';

packages/cubejs-schema-compiler/test/integration/postgres/sql-generation-logic.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ describe('SQL Generation', () => {
453453
}
454454
});
455455

456-
it('having filter with operator OR', async () => {
456+
it('having filter with operator OR 1', async () => {
457457
await compiler.compile();
458458

459459
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
@@ -486,7 +486,7 @@ describe('SQL Generation', () => {
486486
}]
487487
});
488488

489-
console.log(query.buildSqlAndParams());
489+
console.log(query.buildSqlAndParamsTest());
490490

491491
return dbRunner.testQuery(query.buildSqlAndParams()).then(res => {
492492
console.log(JSON.stringify(res));
@@ -648,7 +648,7 @@ describe('SQL Generation', () => {
648648
});
649649
});
650650

651-
it('where filter with operators OR & AND', async () => {
651+
it('where filter with operators OR & AND 1', async () => {
652652
await compiler.compile();
653653

654654
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/base_query_options.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub struct BaseQueryOptionsStatic {
6060
#[serde(rename = "rowLimit")]
6161
pub row_limit: Option<String>,
6262
pub offset: Option<String>,
63+
pub ungrouped: Option<bool>,
6364
}
6465

6566
#[nativebridge::native_bridge(BaseQueryOptionsStatic)]

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/base_tools.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ pub trait BaseTools {
4343
granularity: String,
4444
date_range: Vec<String>,
4545
) -> Result<Vec<Vec<String>>, CubeError>;
46+
fn get_allocated_params(&self) -> Result<Vec<String>, CubeError>;
4647
}

rust/cubesqlplanner/cubesqlplanner/src/plan/filter.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ impl FilterItem {
6363
.items
6464
.iter()
6565
.map(|itm| itm.to_sql(templates, context.clone(), schema.clone()))
66-
.collect::<Result<Vec<_>, _>>()?;
67-
let result = if items_sql.is_empty() {
68-
templates.always_true()?
66+
.collect::<Result<Vec<_>, _>>()?
67+
.into_iter()
68+
.filter(|itm| !itm.is_empty())
69+
.collect::<Vec<_>>();
70+
if items_sql.is_empty() {
71+
"".to_string()
6972
} else {
70-
items_sql.join(&operator)
71-
};
72-
format!("({})", result)
73+
let result = items_sql.join(&operator);
74+
format!("({})", result)
75+
}
7376
}
7477
FilterItem::Item(item) => {
7578
let sql = item.to_sql(context.clone(), schema)?;

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,29 @@ impl<IT: InnerTypes> BaseQuery<IT> {
5959
}
6060

6161
fn build_sql_and_params_impl(&self) -> Result<Select, CubeError> {
62+
let nodes_factory = if self.request.ungrouped() {
63+
SqlNodesFactory::new_ungroupped()
64+
} else {
65+
SqlNodesFactory::new()
66+
};
67+
6268
if self.request.is_simple_query()? {
63-
println!("!!!! IS SIMPLE");
6469
let planner = SimpleQueryPlanner::new(
6570
self.query_tools.clone(),
6671
self.request.clone(),
67-
SqlNodesFactory::new(),
72+
nodes_factory.clone(),
6873
);
6974
planner.plan()
7075
} else {
7176
let multiplied_measures_query_planner = MultipliedMeasuresQueryPlanner::new(
7277
self.query_tools.clone(),
7378
self.request.clone(),
74-
SqlNodesFactory::new(),
79+
nodes_factory.clone(),
7580
);
7681
let multi_stage_query_planner =
7782
MultiStageQueryPlanner::new(self.query_tools.clone(), self.request.clone());
7883
let full_key_aggregate_planner =
79-
FullKeyAggregateQueryPlanner::new(self.request.clone(), SqlNodesFactory::new());
84+
FullKeyAggregateQueryPlanner::new(self.request.clone(), nodes_factory.clone());
8085
let mut subqueries = multiplied_measures_query_planner.plan_queries()?;
8186
let (multi_stage_ctes, multi_stage_subqueries) =
8287
multi_stage_query_planner.plan_queries()?;

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,12 @@ impl BaseFilter {
403403
}
404404

405405
fn allocate_param(&self, param: &str) -> String {
406-
let index = self.query_tools.allocaate_param(param);
407-
format!("${}$", index)
406+
self.query_tools.allocate_param(param)
408407
}
409408

410409
fn allocate_timestamp_param(&self, param: &str) -> String {
411-
let index = self.query_tools.allocaate_param(param);
412-
format!("${}$::timestamptz", index)
410+
let placeholder = self.query_tools.allocate_param(param);
411+
format!("{}::timestamptz", placeholder)
413412
}
414413

415414
fn first_param(&self) -> Result<String, CubeError> {

rust/cubesqlplanner/cubesqlplanner/src/planner/params_allocator.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::HashMap;
55

66
//const PARAMS_MATCH_REGEXP = /\$(\d+)\$/g;
77
lazy_static! {
8-
static ref PARAMS_MATCH_RE: Regex = Regex::new(r"\$(\d+)\$").unwrap();
8+
static ref PARAMS_MATCH_RE: Regex = Regex::new(r"\$_(\d+)_\$").unwrap();
99
}
1010
pub struct ParamsAllocator {
1111
params: Vec<String>,
@@ -16,9 +16,13 @@ impl ParamsAllocator {
1616
ParamsAllocator { params: Vec::new() }
1717
}
1818

19-
pub fn allocate_param(&mut self, name: &str) -> usize {
19+
pub fn make_placeholder(&self, index: usize) -> String {
20+
format!("$_{}_$", index)
21+
}
22+
23+
pub fn allocate_param(&mut self, name: &str) -> String {
2024
self.params.push(name.to_string());
21-
self.params.len() - 1
25+
self.make_placeholder(self.params.len() - 1)
2226
}
2327

2428
pub fn get_params(&self) -> &Vec<String> {
@@ -28,18 +32,20 @@ impl ParamsAllocator {
2832
pub fn build_sql_and_params(
2933
&self,
3034
sql: &str,
35+
native_allocated_params: Vec<String>,
3136
should_reuse_params: bool,
3237
) -> Result<(String, Vec<String>), CubeError> {
38+
let (sql, params) = self.add_native_allocated_params(sql, &native_allocated_params)?;
3339
let mut params_in_sql_order = Vec::new();
3440
let mut param_index_map: HashMap<usize, usize> = HashMap::new();
3541
let result_sql = if should_reuse_params {
3642
PARAMS_MATCH_RE
37-
.replace_all(sql, |caps: &Captures| {
43+
.replace_all(&sql, |caps: &Captures| {
3844
let ind: usize = caps[1].to_string().parse().unwrap();
3945
let new_index = if let Some(index) = param_index_map.get(&ind) {
4046
index.clone()
4147
} else {
42-
params_in_sql_order.push(self.params[ind].clone());
48+
params_in_sql_order.push(params[ind].clone());
4349
let index = params_in_sql_order.len();
4450
param_index_map.insert(ind, index);
4551
index
@@ -49,14 +55,39 @@ impl ParamsAllocator {
4955
.to_string()
5056
} else {
5157
PARAMS_MATCH_RE
52-
.replace_all(sql, |caps: &Captures| {
58+
.replace_all(&sql, |caps: &Captures| {
5359
let ind: usize = caps[1].to_string().parse().unwrap();
54-
params_in_sql_order.push(self.params[ind].clone());
60+
params_in_sql_order.push(params[ind].clone());
5561
let index = params_in_sql_order.len();
5662
format!("${}", index) //TODO get placeholder from js part
5763
})
5864
.to_string()
5965
};
6066
Ok((result_sql, params_in_sql_order))
6167
}
68+
69+
fn add_native_allocated_params(
70+
&self,
71+
sql: &str,
72+
native_allocated_params: &Vec<String>,
73+
) -> Result<(String, Vec<String>), CubeError> {
74+
lazy_static! {
75+
static ref NATIVE_PARAMS_MATCH_RE: Regex = Regex::new(r"\$(\d+)\$").unwrap();
76+
}
77+
78+
if native_allocated_params.is_empty() {
79+
Ok((sql.to_string(), self.params.clone()))
80+
} else {
81+
let mut result_params = self.params.clone();
82+
let sql = NATIVE_PARAMS_MATCH_RE
83+
.replace_all(sql, |caps: &Captures| {
84+
let ind: usize = caps[1].to_string().parse().unwrap();
85+
let param = native_allocated_params[ind].clone();
86+
result_params.push(param);
87+
self.make_placeholder(result_params.len() - 1)
88+
})
89+
.to_string();
90+
Ok((sql, result_params))
91+
}
92+
}
6293
}

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::CommonUtils;
2+
use crate::cube_bridge::join_definition::JoinDefinition;
23
use crate::cube_bridge::memeber_sql::MemberSql;
34
use crate::plan::{From, JoinBuilder, JoinCondition};
45
use crate::planner::query_tools::QueryTools;
@@ -25,6 +26,27 @@ impl JoinPlanner {
2526
alias_prefix: &Option<String>, /*TODO dimensions for subqueries*/
2627
) -> Result<From, CubeError> {
2728
let join = self.query_tools.cached_data().join()?.clone();
29+
self.make_join_node_impl(alias_prefix, join)
30+
}
31+
32+
pub fn make_join_node_with_prefix_and_join_hints(
33+
&self,
34+
alias_prefix: &Option<String>, /*TODO dimensions for subqueries*/
35+
join_hints: Vec<String>,
36+
) -> Result<From, CubeError> {
37+
let join = self.query_tools.join_graph().build_join(join_hints)?;
38+
self.make_join_node_impl(alias_prefix, join)
39+
}
40+
41+
pub fn make_join_node(&self) -> Result<From, CubeError> {
42+
self.make_join_node_with_prefix(&None)
43+
}
44+
45+
fn make_join_node_impl(
46+
&self,
47+
alias_prefix: &Option<String>,
48+
join: Rc<dyn JoinDefinition>,
49+
) -> Result<From, CubeError> {
2850
let root = self.utils.cube_from_path(join.static_data().root.clone())?;
2951
let joins = join.joins()?;
3052
if joins.items().is_empty() {
@@ -56,10 +78,6 @@ impl JoinPlanner {
5678
}
5779
}
5880

59-
pub fn make_join_node(&self) -> Result<From, CubeError> {
60-
self.make_join_node_with_prefix(&None)
61-
}
62-
6381
fn compile_join_condition(
6482
&self,
6583
cube_name: &String,

0 commit comments

Comments
 (0)