Skip to content

Commit

Permalink
fix(cubesql): Improve Thoughtspot WHERE IN support
Browse files Browse the repository at this point in the history
  • Loading branch information
MazterQyou committed Dec 23, 2022
1 parent e67e800 commit 6212efe
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 1 deletion.
170 changes: 170 additions & 0 deletions rust/cubesql/cubesql/src/compile/mod.rs
Expand Up @@ -15699,4 +15699,174 @@ ORDER BY \"COUNT(count)\" DESC"
}
)
}

#[tokio::test]
async fn test_thoughtspot_where_not_or() {
init_logger();

let logical_plan = convert_select_to_query_plan(
r#"
WITH "qt_0" AS (
SELECT "ta_1"."customer_gender" "ca_1"
FROM KibanaSampleDataEcommerce "ta_1"
WHERE NOT((
"ta_1"."customer_gender" IS NULL
OR LOWER("ta_1"."customer_gender") IN ('unknown')
))
GROUP BY "ca_1"
)
SELECT count(DISTINCT "ta_2"."ca_1") "ca_2"
FROM "qt_0" "ta_2"
"#
.to_string(),
DatabaseProtocol::PostgreSQL,
)
.await
.as_logical_plan();

assert_eq!(
logical_plan.find_cube_scan().request,
V1LoadRequestQuery {
measures: Some(vec![]),
dimensions: Some(vec!["KibanaSampleDataEcommerce.customer_gender".to_string()]),
segments: Some(vec![]),
time_dimensions: None,
order: None,
limit: None,
offset: None,
filters: Some(vec![
V1LoadRequestQueryFilterItem {
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
operator: Some("set".to_string()),
values: None,
or: None,
and: None,
},
V1LoadRequestQueryFilterItem {
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
operator: Some("notEquals".to_string()),
values: Some(vec!["unknown".to_string()]),
or: None,
and: None,
},
])
}
)
}

#[tokio::test]
async fn test_thoughtspot_where_binary_in_true_false() {
init_logger();

let logical_plan = convert_select_to_query_plan(
r#"
SELECT
((
LOWER("ta_1"."customer_gender") = 'female'
OR LOWER("ta_1"."customer_gender") = 'male'
)) "ca_1",
CASE
WHEN sum("ta_1"."count") IS NOT NULL THEN sum("ta_1"."count")
ELSE 0
END "ca_2"
FROM KibanaSampleDataEcommerce "ta_1"
WHERE ((
LOWER("ta_1"."customer_gender") = 'female'
OR LOWER("ta_1"."customer_gender") = 'male'
)) IN (
TRUE, FALSE
)
GROUP BY "ca_1"
ORDER BY
"ca_1" ASC,
"ca_2" ASC
"#
.to_string(),
DatabaseProtocol::PostgreSQL,
)
.await
.as_logical_plan();

assert_eq!(
logical_plan.find_cube_scan().request,
V1LoadRequestQuery {
measures: Some(vec!["KibanaSampleDataEcommerce.count".to_string()]),
dimensions: Some(vec!["KibanaSampleDataEcommerce.customer_gender".to_string()]),
segments: Some(vec![]),
time_dimensions: None,
order: None,
limit: None,
offset: None,
filters: Some(vec![
V1LoadRequestQueryFilterItem {
member: None,
operator: None,
values: None,
or: Some(vec![
json!(V1LoadRequestQueryFilterItem {
member: None,
operator: None,
values: None,
or: None,
and: Some(vec![
json!(V1LoadRequestQueryFilterItem {
member: Some(
"KibanaSampleDataEcommerce.customer_gender".to_string()
),
operator: Some("startsWith".to_string()),
values: Some(vec!["female".to_string()]),
or: None,
and: None,
}),
json!(V1LoadRequestQueryFilterItem {
member: Some(
"KibanaSampleDataEcommerce.customer_gender".to_string()
),
operator: Some("endsWith".to_string()),
values: Some(vec!["female".to_string()]),
or: None,
and: None,
}),
]),
}),
json!(V1LoadRequestQueryFilterItem {
member: None,
operator: None,
values: None,
or: None,
and: Some(vec![
json!(V1LoadRequestQueryFilterItem {
member: Some(
"KibanaSampleDataEcommerce.customer_gender".to_string()
),
operator: Some("startsWith".to_string()),
values: Some(vec!["male".to_string()]),
or: None,
and: None,
}),
json!(V1LoadRequestQueryFilterItem {
member: Some(
"KibanaSampleDataEcommerce.customer_gender".to_string()
),
operator: Some("endsWith".to_string()),
values: Some(vec!["male".to_string()]),
or: None,
and: None,
}),
]),
}),
]),
and: None,
},
V1LoadRequestQueryFilterItem {
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
operator: Some("set".to_string()),
values: None,
or: None,
and: None,
},
])
}
)
}
}
67 changes: 66 additions & 1 deletion rust/cubesql/cubesql/src/compile/rewrite/rules/filters.rs
Expand Up @@ -9,7 +9,7 @@ use crate::{
cube_scan_members, dimension_expr, expr_column_name, filter,
filter_cast_unwrap_replacer, filter_member, filter_op, filter_op_filters,
filter_replacer, fun_expr, fun_expr_var_arg, inlist_expr, is_not_null_expr,
is_null_expr, like_expr, limit, literal_bool, literal_expr, literal_int,
is_null_expr, like_expr, limit, list_expr, literal_bool, literal_expr, literal_int,
literal_string, measure_expr, member_name_by_alias, negative_expr, not_expr,
projection, rewrite,
rewriter::RewriteRules,
Expand Down Expand Up @@ -400,6 +400,21 @@ impl RewriteRules for FilterRules {
),
self.transform_negate_inlist("?negated", "?new_negated"),
),
rewrite(
"filter-replacer-not-or-to-not-and",
filter_replacer(
not_expr(binary_expr("?left", "OR", "?right")),
"?alias_to_cube",
"?members",
"?filter_aliases",
),
filter_replacer(
binary_expr(not_expr("?left"), "AND", not_expr("?right")),
"?alias_to_cube",
"?members",
"?filter_aliases",
),
),
transforming_rewrite(
"filter-replacer-is-null",
filter_replacer(
Expand Down Expand Up @@ -1465,6 +1480,56 @@ impl RewriteRules for FilterRules {
"?filter_aliases",
),
),
rewrite(
"filter-thoughtspot-lower-in-true-false",
filter_replacer(
inlist_expr(
binary_expr(
binary_expr(
fun_expr("Lower", vec![column_expr("?column")]),
"=",
literal_expr("?left_literal"),
),
"OR",
binary_expr(
fun_expr("Lower", vec![column_expr("?column")]),
"=",
literal_expr("?right_literal"),
),
),
list_expr(
"InListExprList",
vec![literal_bool(true), literal_bool(false)],
),
"InListExprNegated:false",
),
"?alias_to_cube",
"?members",
"?filter_aliases",
),
filter_replacer(
binary_expr(
binary_expr(
binary_expr(
fun_expr("Lower", vec![column_expr("?column")]),
"=",
literal_expr("?left_literal"),
),
"OR",
binary_expr(
fun_expr("Lower", vec![column_expr("?column")]),
"=",
literal_expr("?right_literal"),
),
),
"AND",
is_not_null_expr(column_expr("?column")),
),
"?alias_to_cube",
"?members",
"?filter_aliases",
),
),
transforming_rewrite(
"extract-year-equals",
filter_replacer(
Expand Down

0 comments on commit 6212efe

Please sign in to comment.