Skip to content

Commit 244c04b

Browse files
authored
chore(tesseract): Tests for segments in views (#10509)
1 parent 33a68a0 commit 244c04b

File tree

6 files changed

+255
-1
lines changed

6 files changed

+255
-1
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { PostgresQuery } from '../../../src/adapter/PostgresQuery';
2+
import { prepareJsCompiler } from '../../unit/PrepareCompiler';
3+
import { dbRunner } from './PostgresDBRunner';
4+
5+
describe('Segments in View with SubQuery Dimensions', () => {
6+
jest.setTimeout(200000);
7+
8+
const { compiler, joinGraph, cubeEvaluator } = prepareJsCompiler(`
9+
cube(\`Accounts\`, {
10+
sql: \`
11+
SELECT 1 AS id, 'US' AS region UNION ALL
12+
SELECT 2 AS id, 'US' AS region UNION ALL
13+
SELECT 3 AS id, 'EU' AS region UNION ALL
14+
SELECT 4 AS id, 'EU' AS region UNION ALL
15+
SELECT 5 AS id, 'AP' AS region
16+
\`,
17+
18+
joins: {
19+
Tickets: {
20+
relationship: \`one_to_many\`,
21+
sql: \`\${CUBE}.id = \${Tickets}.account_id\`,
22+
},
23+
},
24+
25+
dimensions: {
26+
id: {
27+
sql: \`id\`,
28+
type: \`number\`,
29+
primaryKey: true,
30+
public: true,
31+
},
32+
33+
region: {
34+
sql: \`\${CUBE}.region\`,
35+
type: \`string\`,
36+
},
37+
38+
ticketCount: {
39+
sql: \`\${Tickets.count}\`,
40+
type: \`number\`,
41+
subQuery: true,
42+
},
43+
},
44+
45+
segments: {
46+
hasNoTickets: {
47+
sql: \`(\${ticketCount} = 0)\`,
48+
},
49+
},
50+
51+
measures: {
52+
count: {
53+
type: \`count\`,
54+
},
55+
},
56+
});
57+
58+
cube(\`Tickets\`, {
59+
sql: \`
60+
SELECT 1 AS id, 1 AS account_id UNION ALL
61+
SELECT 2 AS id, 1 AS account_id UNION ALL
62+
SELECT 3 AS id, 3 AS account_id UNION ALL
63+
SELECT 4 AS id, 5 AS account_id
64+
\`,
65+
66+
dimensions: {
67+
id: {
68+
sql: \`id\`,
69+
type: \`number\`,
70+
primaryKey: true,
71+
},
72+
73+
accountId: {
74+
sql: \`\${CUBE}.account_id\`,
75+
type: \`number\`,
76+
},
77+
},
78+
79+
measures: {
80+
count: {
81+
type: \`count\`,
82+
},
83+
},
84+
});
85+
86+
view(\`accountOverview\`, {
87+
cubes: [
88+
{
89+
join_path: Accounts,
90+
includes: [
91+
\`hasNoTickets\`,
92+
\`count\`,
93+
\`region\`,
94+
],
95+
},
96+
],
97+
});
98+
`);
99+
100+
async function runQueryTest(q, expectedResult) {
101+
await compiler.compile();
102+
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, q);
103+
104+
console.log(query.buildSqlAndParams());
105+
106+
const res = await dbRunner.testQuery(query.buildSqlAndParams());
107+
console.log(JSON.stringify(res));
108+
109+
expect(res).toEqual(
110+
expectedResult
111+
);
112+
}
113+
114+
it('segment with subquery dimension in view', async () => runQueryTest({
115+
measures: ['accountOverview.count'],
116+
segments: ['accountOverview.hasNoTickets'],
117+
}, [{
118+
account_overview__count: '2',
119+
}]));
120+
121+
it('segment with subquery dimension in view with dimension', async () => runQueryTest({
122+
measures: ['accountOverview.count'],
123+
segments: ['accountOverview.hasNoTickets'],
124+
dimensions: ['accountOverview.region'],
125+
order: [{ id: 'accountOverview.region' }],
126+
}, [{
127+
account_overview__region: 'EU',
128+
account_overview__count: '1',
129+
}, {
130+
account_overview__region: 'US',
131+
account_overview__count: '1',
132+
}]));
133+
});

rust/cubesqlplanner/cubesqlplanner/src/test_fixtures/cube_bridge/mock_schema.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,11 +546,16 @@ impl MockViewBuilder {
546546
);
547547
}
548548

549+
let original_type = &measure.static_data().measure_type;
550+
let view_type = match original_type.as_str() {
551+
"number" | "string" | "time" | "boolean" => original_type.clone(),
552+
_ => "number".to_string(),
553+
};
549554
all_measures.insert(
550555
view_name,
551556
Rc::new(
552557
MockMeasureDefinition::builder()
553-
.measure_type(measure.static_data().measure_type.clone())
558+
.measure_type(view_type)
554559
.sql(view_member_sql)
555560
.build(),
556561
),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
cubes:
2+
- name: Accounts
3+
sql: "SELECT * FROM accounts"
4+
joins:
5+
- name: Tickets
6+
relationship: one_to_many
7+
sql: "{CUBE}.id = {Tickets.accountId}"
8+
dimensions:
9+
- name: id
10+
type: number
11+
sql: id
12+
primary_key: true
13+
- name: region
14+
type: string
15+
sql: "{CUBE}.region"
16+
- name: ticketCount
17+
type: number
18+
sql: "{Tickets.count}"
19+
sub_query: true
20+
segments:
21+
- name: hasNoTickets
22+
sql: "({ticketCount} = 0)"
23+
measures:
24+
- name: count
25+
type: count
26+
27+
- name: Tickets
28+
sql: "SELECT * FROM tickets"
29+
dimensions:
30+
- name: id
31+
type: number
32+
sql: id
33+
primary_key: true
34+
- name: accountId
35+
type: number
36+
sql: "{CUBE}.account_id"
37+
measures:
38+
- name: count
39+
type: count
40+
41+
views:
42+
- name: accountOverview
43+
cubes:
44+
- join_path: Accounts
45+
includes:
46+
- hasNoTickets
47+
- count
48+
- region

rust/cubesqlplanner/cubesqlplanner/src/tests/common_sql_generation.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,45 @@ fn test_query_level_join_hints() {
318318
"SQL should NOT use A->F join, got: {sql}"
319319
);
320320
}
321+
322+
#[test]
323+
fn test_segment_with_subquery_dimension_in_view() {
324+
let schema = MockSchema::from_yaml_file("common/segments_in_view.yaml");
325+
let test_context = TestContext::new(schema).unwrap();
326+
327+
let query_yaml = indoc! {"
328+
measures:
329+
- accountOverview.count
330+
segments:
331+
- accountOverview.hasNoTickets
332+
"};
333+
334+
let sql = test_context
335+
.build_sql(query_yaml)
336+
.expect("Should generate SQL for segment with subquery dimension in view");
337+
338+
insta::assert_snapshot!(sql);
339+
}
340+
341+
#[test]
342+
fn test_segment_with_subquery_dimension_in_view_with_dimension() {
343+
let schema = MockSchema::from_yaml_file("common/segments_in_view.yaml");
344+
let test_context = TestContext::new(schema).unwrap();
345+
346+
let query_yaml = indoc! {"
347+
measures:
348+
- accountOverview.count
349+
segments:
350+
- accountOverview.hasNoTickets
351+
dimensions:
352+
- accountOverview.region
353+
order:
354+
- id: accountOverview.region
355+
"};
356+
357+
let sql = test_context
358+
.build_sql(query_yaml)
359+
.expect("Should generate SQL for segment with subquery dimension in view with dimension");
360+
361+
insta::assert_snapshot!(sql);
362+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: cubesqlplanner/src/tests/common_sql_generation.rs
3+
expression: sql
4+
---
5+
SELECT count("accounts".id) "account_overview__count"
6+
FROM accounts AS "accounts"
7+
LEFT JOIN (SELECT "accounts".id "accounts__id", count("tickets".id) "ticket_count"
8+
FROM accounts AS "accounts"
9+
LEFT JOIN tickets AS "tickets" ON "accounts".id = "tickets".account_id
10+
GROUP BY 1
11+
ORDER BY 2 DESC) AS "Accounts_ticketCount_subquery" ON (("Accounts_ticketCount_subquery"."accounts__id" = "accounts".id))
12+
WHERE (("Accounts_ticketCount_subquery"."ticket_count" = 0))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
source: cubesqlplanner/src/tests/common_sql_generation.rs
3+
expression: sql
4+
---
5+
SELECT "accounts".region "account_overview__region", count("accounts".id) "account_overview__count"
6+
FROM accounts AS "accounts"
7+
LEFT JOIN (SELECT "accounts".id "accounts__id", count("tickets".id) "ticket_count"
8+
FROM accounts AS "accounts"
9+
LEFT JOIN tickets AS "tickets" ON "accounts".id = "tickets".account_id
10+
GROUP BY 1
11+
ORDER BY 2 DESC) AS "Accounts_ticketCount_subquery" ON (("Accounts_ticketCount_subquery"."accounts__id" = "accounts".id))
12+
WHERE (("Accounts_ticketCount_subquery"."ticket_count" = 0))
13+
GROUP BY 1
14+
ORDER BY 1 ASC

0 commit comments

Comments
 (0)