Skip to content

Commit e684697

Browse files
mcheshkovmarianore-muttdata
authored andcommitted
fix(schema-compiler): Avoid mutating context on first occasion of TD with granularity (cube-js#9592)
1 parent 717e597 commit e684697

File tree

4 files changed

+76
-11
lines changed

4 files changed

+76
-11
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,8 +2918,10 @@ export class BaseQuery {
29182918
});
29192919
// for time dimension with granularity convertedToTz() is called internally in dimensionSql() flow,
29202920
// so we need to ignore convertTz later even if context convertTzForRawTimeDimension is set to true
2921-
this.safeEvaluateSymbolContext().ignoreConvertTzForTimeDimension = true;
2922-
return td.dimensionSql();
2921+
return this.evaluateSymbolSqlWithContext(
2922+
() => td.dimensionSql(),
2923+
{ ignoreConvertTzForTimeDimension: true },
2924+
);
29232925
} else {
29242926
let res = this.autoPrefixAndEvaluateSql(cubeName, symbol.sql, isMemberExpr);
29252927
const memPath = this.cubeEvaluator.pathFromArray([cubeName, name]);

packages/cubejs-testing/birdbox-fixtures/postgresql/schema/Orders.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
cube(`Orders`, {
22
sql: `
3-
select 1 as id, 100 as amount, 'new' status, '2024-01-01'::timestamptz created_at
3+
select 1 as id, 100 as amount, 'new' status, '2024-01-01'::timestamptz created_at, '2025-01-01'::timestamptz updated_at
44
UNION ALL
5-
select 2 as id, 200 as amount, 'new' status, '2024-01-02'::timestamptz created_at
5+
select 2 as id, 200 as amount, 'new' status, '2024-01-02'::timestamptz created_at, '2025-01-02'::timestamptz updated_at
66
UNION ALL
7-
select 3 as id, 300 as amount, 'processed' status, '2024-01-03'::timestamptz created_at
7+
select 3 as id, 300 as amount, 'processed' status, '2024-01-03'::timestamptz created_at, '2025-01-03'::timestamptz updated_at
88
UNION ALL
9-
select 4 as id, 500 as amount, 'processed' status, '2024-01-04'::timestamptz created_at
9+
select 4 as id, 500 as amount, 'processed' status, '2024-01-04'::timestamptz created_at, '2025-01-04'::timestamptz updated_at
1010
UNION ALL
11-
select 5 as id, 600 as amount, 'shipped' status, '2024-01-05'::timestamptz created_at
11+
select 5 as id, 600 as amount, 'shipped' status, '2024-01-05'::timestamptz created_at, '2025-01-05'::timestamptz updated_at
1212
`,
1313
joins: {
1414
OrderItems: {
@@ -122,6 +122,11 @@ cube(`Orders`, {
122122
createdAt: {
123123
sql: `created_at`,
124124
type: `time`
125+
},
126+
127+
updatedAt: {
128+
sql: `updated_at`,
129+
type: `time`
125130
}
126131
},
127132
});

packages/cubejs-testing/test/__snapshots__/smoke-cubesql.test.ts.snap

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ Object {
4242
"sql": Object {
4343
"query_type": "pushdown",
4444
"sql": Array [
45-
"SELECT \\"t\\".\\"avg_t_total_\\" \\"avg_t_total_\\"
45+
"SELECT \\"t\\".\\"avg_t_total_\\" \\"avg_t_total_\\"
4646
FROM (
47-
SELECT AVG(\\"t\\".\\"total\\") \\"avg_t_total_\\"
47+
SELECT AVG(\\"t\\".\\"total\\") \\"avg_t_total_\\"
4848
FROM (
4949
SELECT
5050
\\"orders\\".status \\"status\\", sum(\\"orders\\".amount) \\"total\\"
@@ -344,7 +344,7 @@ Object {
344344
"sql": Object {
345345
"query_type": "pushdown",
346346
"sql": Array [
347-
"SELECT \\"Orders\\".\\"sum_orders_total\\" \\"total\\"
347+
"SELECT \\"Orders\\".\\"sum_orders_total\\" \\"total\\"
348348
FROM (
349349
SELECT
350350
sum(\\"orders\\".amount) \\"sum_orders_total\\"
@@ -399,7 +399,7 @@ Object {
399399
"sql": Object {
400400
"query_type": "pushdown",
401401
"sql": Array [
402-
"SELECT \\"Orders\\".\\"sum_orders_total\\" \\"total\\"
402+
"SELECT \\"Orders\\".\\"sum_orders_total\\" \\"total\\"
403403
FROM (
404404
SELECT
405405
sum(\\"orders\\".amount) \\"sum_orders_total\\"
@@ -591,6 +591,36 @@ Array [
591591
]
592592
`;
593593

594+
exports[`SQL API Postgres (Data) member expression with granularity and raw time dimensions 1`] = `
595+
Array [
596+
Object {
597+
"quarter": 2024-01-01T00:00:00.000Z,
598+
"total": 100,
599+
"updatedAt": 2025-01-01T00:00:00.000Z,
600+
},
601+
Object {
602+
"quarter": 2024-01-01T00:00:00.000Z,
603+
"total": 300,
604+
"updatedAt": 2025-01-02T00:00:00.000Z,
605+
},
606+
Object {
607+
"quarter": 2024-01-01T00:00:00.000Z,
608+
"total": 600,
609+
"updatedAt": 2025-01-03T00:00:00.000Z,
610+
},
611+
Object {
612+
"quarter": 2024-01-01T00:00:00.000Z,
613+
"total": 1100,
614+
"updatedAt": 2025-01-04T00:00:00.000Z,
615+
},
616+
Object {
617+
"quarter": 2024-01-01T00:00:00.000Z,
618+
"total": 1700,
619+
"updatedAt": 2025-01-05T00:00:00.000Z,
620+
},
621+
]
622+
`;
623+
594624
exports[`SQL API Postgres (Data) metabase max number: metabase max number 1`] = `
595625
Array [
596626
Object {

packages/cubejs-testing/test/smoke-cubesql.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,5 +886,33 @@ filter_subq AS (
886886
const res = await connection.query(query);
887887
expect(res.rows).toMatchSnapshot('measure-with-ad-hoc-filters-and-original-measure');
888888
});
889+
890+
/// Query references `updatedAt` in three places: in outer projection, in grouping key and in window
891+
/// Incoming query is consistent: all three references same column
892+
/// This tests that generated SQL for pushdown remains consistent:
893+
/// whatever is present in grouping key should be present in window expression
894+
/// Interesting part here is that single column (and member expression) contains
895+
/// two different TD, one with granularity and one without, and both have to match grouping key
896+
test('member expression with granularity and raw time dimensions', async () => {
897+
const query = `
898+
SELECT
899+
DATE_TRUNC('qtr', createdAt) AS quarter,
900+
updatedAt,
901+
SUM(CASE
902+
WHEN sum(totalAmount) IS NOT NULL THEN sum(totalAmount)
903+
ELSE 0
904+
END) OVER (
905+
PARTITION BY DATE_TRUNC('qtr', createdAt)
906+
ORDER BY updatedAt
907+
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
908+
) AS total
909+
FROM Orders
910+
GROUP BY
911+
1, 2
912+
`;
913+
914+
const res = await connection.query(query);
915+
expect(res.rows).toMatchSnapshot();
916+
});
889917
});
890918
});

0 commit comments

Comments
 (0)