Skip to content

Commit

Permalink
some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
waralexrom committed Dec 5, 2024
1 parent d22c327 commit 764da0f
Show file tree
Hide file tree
Showing 30 changed files with 681 additions and 143 deletions.
47 changes: 41 additions & 6 deletions packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,38 @@ export class BaseQuery {
}
}

buildSqlAndParamsTest(exportAnnotatedSql) {
if (!this.options.preAggregationQuery && !this.options.disableExternalPreAggregations && this.externalQueryClass) {
if (this.externalPreAggregationQuery()) { // TODO performance
return this.externalQuery().buildSqlAndParams(exportAnnotatedSql);
}
}
const js_res = this.compilers.compiler.withQuery(

Check failure on line 614 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Identifier 'js_res' is not in camel case
this,
() => this.cacheValue(
['buildSqlAndParams', exportAnnotatedSql],
() => this.paramAllocator.buildSqlAndParams(
this.buildParamAnnotatedSql(),
exportAnnotatedSql,
this.shouldReuseParams
),
{ cache: this.queryCache }
)
);
console.log('js result: ', js_res[0]);

Check failure on line 626 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Identifier 'js_res' is not in camel case
const rust = this.buildSqlAndParamsRust(exportAnnotatedSql);
console.log('rust result: ', rust[0]);
return js_res;

Check failure on line 629 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Identifier 'js_res' is not in camel case
}

buildSqlAndParamsRust(exportAnnotatedSql) {

Check failure on line 632 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines


Check failure on line 634 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

More than 1 blank line not allowed
const order = this.options.order && R.pipe(
R.map((hash) => (!hash || !hash.id) ? null : hash),

Check failure on line 636 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Arrow function used ambiguously with a conditional expression

Check failure on line 636 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Multiple spaces found before '?'
R.reject(R.isNil),
)(this.options.order);

const queryParams = {
measures: this.options.measures,
dimensions: this.options.dimensions,
Expand All @@ -614,12 +645,13 @@ export class BaseQuery {
joinRoot: this.join.root,
joinGraph: this.joinGraph,
cubeEvaluator: this.cubeEvaluator,
order: this.options.order,
order: order,

Check failure on line 648 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Expected property shorthand
filters: this.options.filters,
limit: this.options.limit ? this.options.limit.toString() : null,
rowLimit: this.options.rowLimit ? this.options.rowLimit.toString() : null,
offset: this.options.offset ? this.options.offset.toString() : null,
baseTools: this,
ungrouped: this.options.ungrouped

};
const res = nativeBuildSqlAndParams(queryParams);
Expand All @@ -628,6 +660,10 @@ export class BaseQuery {
return res;
}

getAllocatedParams() {
return this.paramAllocator.getParams()

Check failure on line 664 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Missing semicolon
}

// FIXME helper for native generator, maybe should be moved entire to rust
generateTimeSeries(granularity, dateRange) {
return timeSeriesBase(granularity, dateRange);
Expand Down Expand Up @@ -806,6 +842,7 @@ export class BaseQuery {
} = this.fullKeyQueryAggregateMeasures();

if (!multipliedMeasures.length && !cumulativeMeasures.length && !multiStageMembers.length) {
console.log("!!!!! LLLOOOO!!!!");

Check failure on line 845 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 6 spaces but found 4
return this.simpleQuery();
}

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

console.log("!!! measure to her ", measureToHierarchy);

const hasMultiStageMembers = (m) => {
if (memberToIsMultiStage[m]) {
return true;
Expand All @@ -1036,10 +1075,8 @@ export class BaseQuery {
R.uniq,
R.map(m => this.newMeasure(m))
);
console.log("!!!! meas hierarchy", measureToHierarchy);

const multipliedMeasures = measuresToRender(true, false)(measureToHierarchy);
console.log("!!! mul meas", multipliedMeasures);
const regularMeasures = measuresToRender(false, false)(measureToHierarchy);

const cumulativeMeasures =
Expand Down Expand Up @@ -1777,7 +1814,6 @@ export class BaseQuery {
return measures.map(measure => {
const cubes = this.collectFrom([measure], this.collectCubeNamesFor.bind(this), 'collectCubeNamesFor');
const joinHints = this.collectFrom([measure], this.collectJoinHintsFor.bind(this), 'collectJoinHintsFor');
console.log("!!! cubes: ", cubes, " ", joinHints);
if (R.any(cubeName => keyCubeName !== cubeName, cubes)) {
const measuresJoin = this.joinGraph.buildJoin(joinHints);
if (measuresJoin.multiplicationFactor[keyCubeName]) {
Expand Down Expand Up @@ -2484,7 +2520,6 @@ export class BaseQuery {
fn,
renderContext
);
console.log("!!!!! renderContext.measuresToRender.length ", renderContext.measuresToRender.length);
return renderContext.measuresToRender.length ?
R.uniq(renderContext.measuresToRender) :
[renderContext.rootMeasure.value];
Expand Down Expand Up @@ -3293,7 +3328,7 @@ export class BaseQuery {
lt: '{{ column }} < {{ param }}',
lte: '{{ column }} <= {{ param }}',
like_pattern: '{% if start_wild %}\'%\' || {% endif %}{{ value }}{% if end_wild %}|| \'%\'{% endif %}',
always_true: '1 == 1'
always_true: '1 = 1'

},
quotes: {
Expand Down
4 changes: 4 additions & 0 deletions packages/cubejs-schema-compiler/src/adapter/ParamAllocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export class ParamAllocator {
return `$${paramIndex}$`;
}

public getParams() {
return this.params;
}

// eslint-disable-next-line no-unused-vars
protected paramPlaceHolder(paramIndex) {
return '?';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ describe('SQL Generation', () => {
}
});

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

const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
Expand Down Expand Up @@ -486,7 +486,7 @@ describe('SQL Generation', () => {
}]
});

console.log(query.buildSqlAndParams());
console.log(query.buildSqlAndParamsTest());

return dbRunner.testQuery(query.buildSqlAndParams()).then(res => {
console.log(JSON.stringify(res));
Expand Down Expand Up @@ -648,7 +648,7 @@ describe('SQL Generation', () => {
});
});

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

const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub struct BaseQueryOptionsStatic {
#[serde(rename = "rowLimit")]
pub row_limit: Option<String>,
pub offset: Option<String>,
pub ungrouped: Option<bool>,
}

#[nativebridge::native_bridge(BaseQueryOptionsStatic)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ pub trait BaseTools {
granularity: String,
date_range: Vec<String>,
) -> Result<Vec<Vec<String>>, CubeError>;
fn get_allocated_params(&self) -> Result<Vec<String>, CubeError>;
}
15 changes: 9 additions & 6 deletions rust/cubesqlplanner/cubesqlplanner/src/plan/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,16 @@ impl FilterItem {
.items
.iter()
.map(|itm| itm.to_sql(templates, context.clone(), schema.clone()))
.collect::<Result<Vec<_>, _>>()?;
let result = if items_sql.is_empty() {
templates.always_true()?
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.filter(|itm| !itm.is_empty())
.collect::<Vec<_>>();
if items_sql.is_empty() {
"".to_string()
} else {
items_sql.join(&operator)
};
format!("({})", result)
let result = items_sql.join(&operator);
format!("({})", result)
}
}
FilterItem::Item(item) => {
let sql = item.to_sql(context.clone(), schema)?;
Expand Down
13 changes: 9 additions & 4 deletions rust/cubesqlplanner/cubesqlplanner/src/planner/base_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,29 @@ impl<IT: InnerTypes> BaseQuery<IT> {
}

fn build_sql_and_params_impl(&self) -> Result<Select, CubeError> {
let nodes_factory = if self.request.ungrouped() {
SqlNodesFactory::new_ungroupped()
} else {
SqlNodesFactory::new()
};

if self.request.is_simple_query()? {
println!("!!!! IS SIMPLE");
let planner = SimpleQueryPlanner::new(
self.query_tools.clone(),
self.request.clone(),
SqlNodesFactory::new(),
nodes_factory.clone(),
);
planner.plan()
} else {
let multiplied_measures_query_planner = MultipliedMeasuresQueryPlanner::new(
self.query_tools.clone(),
self.request.clone(),
SqlNodesFactory::new(),
nodes_factory.clone(),
);
let multi_stage_query_planner =
MultiStageQueryPlanner::new(self.query_tools.clone(), self.request.clone());
let full_key_aggregate_planner =
FullKeyAggregateQueryPlanner::new(self.request.clone(), SqlNodesFactory::new());
FullKeyAggregateQueryPlanner::new(self.request.clone(), nodes_factory.clone());
let mut subqueries = multiplied_measures_query_planner.plan_queries()?;
let (multi_stage_ctes, multi_stage_subqueries) =
multi_stage_query_planner.plan_queries()?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,12 @@ impl BaseFilter {
}

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

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

fn first_param(&self) -> Result<String, CubeError> {
Expand Down
45 changes: 38 additions & 7 deletions rust/cubesqlplanner/cubesqlplanner/src/planner/params_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::collections::HashMap;

//const PARAMS_MATCH_REGEXP = /\$(\d+)\$/g;
lazy_static! {
static ref PARAMS_MATCH_RE: Regex = Regex::new(r"\$(\d+)\$").unwrap();
static ref PARAMS_MATCH_RE: Regex = Regex::new(r"\$_(\d+)_\$").unwrap();
}
pub struct ParamsAllocator {
params: Vec<String>,
Expand All @@ -16,9 +16,13 @@ impl ParamsAllocator {
ParamsAllocator { params: Vec::new() }
}

pub fn allocate_param(&mut self, name: &str) -> usize {
pub fn make_placeholder(&self, index: usize) -> String {
format!("$_{}_$", index)
}

pub fn allocate_param(&mut self, name: &str) -> String {
self.params.push(name.to_string());
self.params.len() - 1
self.make_placeholder(self.params.len() - 1)
}

pub fn get_params(&self) -> &Vec<String> {
Expand All @@ -28,18 +32,20 @@ impl ParamsAllocator {
pub fn build_sql_and_params(
&self,
sql: &str,
native_allocated_params: Vec<String>,
should_reuse_params: bool,
) -> Result<(String, Vec<String>), CubeError> {
let (sql, params) = self.add_native_allocated_params(sql, &native_allocated_params)?;
let mut params_in_sql_order = Vec::new();
let mut param_index_map: HashMap<usize, usize> = HashMap::new();
let result_sql = if should_reuse_params {
PARAMS_MATCH_RE
.replace_all(sql, |caps: &Captures| {
.replace_all(&sql, |caps: &Captures| {
let ind: usize = caps[1].to_string().parse().unwrap();
let new_index = if let Some(index) = param_index_map.get(&ind) {
index.clone()
} else {
params_in_sql_order.push(self.params[ind].clone());
params_in_sql_order.push(params[ind].clone());
let index = params_in_sql_order.len();
param_index_map.insert(ind, index);
index
Expand All @@ -49,14 +55,39 @@ impl ParamsAllocator {
.to_string()
} else {
PARAMS_MATCH_RE
.replace_all(sql, |caps: &Captures| {
.replace_all(&sql, |caps: &Captures| {
let ind: usize = caps[1].to_string().parse().unwrap();
params_in_sql_order.push(self.params[ind].clone());
params_in_sql_order.push(params[ind].clone());
let index = params_in_sql_order.len();
format!("${}", index) //TODO get placeholder from js part
})
.to_string()
};
Ok((result_sql, params_in_sql_order))
}

fn add_native_allocated_params(
&self,
sql: &str,
native_allocated_params: &Vec<String>,
) -> Result<(String, Vec<String>), CubeError> {
lazy_static! {
static ref NATIVE_PARAMS_MATCH_RE: Regex = Regex::new(r"\$(\d+)\$").unwrap();
}

if native_allocated_params.is_empty() {
Ok((sql.to_string(), self.params.clone()))
} else {
let mut result_params = self.params.clone();
let sql = NATIVE_PARAMS_MATCH_RE
.replace_all(sql, |caps: &Captures| {
let ind: usize = caps[1].to_string().parse().unwrap();
let param = native_allocated_params[ind].clone();
result_params.push(param);
self.make_placeholder(result_params.len() - 1)
})
.to_string();
Ok((sql, result_params))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::CommonUtils;
use crate::cube_bridge::join_definition::JoinDefinition;
use crate::cube_bridge::memeber_sql::MemberSql;
use crate::plan::{From, JoinBuilder, JoinCondition};
use crate::planner::query_tools::QueryTools;
Expand All @@ -25,6 +26,27 @@ impl JoinPlanner {
alias_prefix: &Option<String>, /*TODO dimensions for subqueries*/
) -> Result<From, CubeError> {
let join = self.query_tools.cached_data().join()?.clone();
self.make_join_node_impl(alias_prefix, join)
}

pub fn make_join_node_with_prefix_and_join_hints(
&self,
alias_prefix: &Option<String>, /*TODO dimensions for subqueries*/
join_hints: Vec<String>,
) -> Result<From, CubeError> {
let join = self.query_tools.join_graph().build_join(join_hints)?;
self.make_join_node_impl(alias_prefix, join)
}

pub fn make_join_node(&self) -> Result<From, CubeError> {
self.make_join_node_with_prefix(&None)
}

fn make_join_node_impl(
&self,
alias_prefix: &Option<String>,
join: Rc<dyn JoinDefinition>,
) -> Result<From, CubeError> {
let root = self.utils.cube_from_path(join.static_data().root.clone())?;
let joins = join.joins()?;
if joins.items().is_empty() {
Expand Down Expand Up @@ -56,10 +78,6 @@ impl JoinPlanner {
}
}

pub fn make_join_node(&self) -> Result<From, CubeError> {
self.make_join_node_with_prefix(&None)
}

fn compile_join_condition(
&self,
cube_name: &String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ impl MultiStageMemberQueryPlanner {
None,
None,
true,
false,
)?;

let node_factory = if self.description.state().time_shifts().is_empty() {
Expand Down
Loading

0 comments on commit 764da0f

Please sign in to comment.