Skip to content

Commit 59834e7

Browse files
authored
fix: Mismatched input '10000'. Expecting: '?', 'ALL', <integer> for post-aggregate members in Athena (#8262)
* fix: Mismatched input '10000'. Expecting: '?', 'ALL', <integer> for post-aggregate members in Athena * Missing connection definition * Remove credentials duplication * Fix precision * Fix presto offset test
1 parent e559114 commit 59834e7

File tree

14 files changed

+336
-15
lines changed

14 files changed

+336
-15
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,15 +1981,27 @@ export class BaseQuery {
19811981
}
19821982

19831983
groupByDimensionLimit() {
1984-
let limitClause = '';
1984+
let limit = null;
19851985
if (this.rowLimit !== null) {
19861986
if (this.rowLimit === MAX_SOURCE_ROW_LIMIT) {
1987-
limitClause = ` LIMIT ${this.paramAllocator.allocateParam(MAX_SOURCE_ROW_LIMIT)}`;
1987+
limit = this.paramAllocator.allocateParam(MAX_SOURCE_ROW_LIMIT);
19881988
} else if (typeof this.rowLimit === 'number') {
1989-
limitClause = ` LIMIT ${this.rowLimit}`;
1989+
limit = this.rowLimit;
19901990
}
19911991
}
1992-
const offsetClause = this.offset ? ` OFFSET ${parseInt(this.offset, 10)}` : '';
1992+
const offset = this.offset ? parseInt(this.offset, 10) : null;
1993+
return this.limitOffsetClause(limit, offset);
1994+
}
1995+
1996+
/**
1997+
* @protected
1998+
* @param limit
1999+
* @param offset
2000+
* @returns {string}
2001+
*/
2002+
limitOffsetClause(limit, offset) {
2003+
const limitClause = limit != null ? ` LIMIT ${limit}` : '';
2004+
const offsetClause = offset != null ? ` OFFSET ${offset}` : '';
19932005
return `${limitClause}${offsetClause}`;
19942006
}
19952007

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export class MssqlQuery extends BaseQuery {
7878
return new MssqlParamAllocator(expressionParams);
7979
}
8080

81+
// TODO replace with limitOffsetClause override
8182
public groupByDimensionLimit() {
8283
if (this.rowLimit) {
8384
return this.offset ? ` OFFSET ${parseInt(this.offset, 10)} ROWS FETCH NEXT ${parseInt(this.rowLimit, 10)} ROWS ONLY` : '';

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class OracleFilter extends BaseFilter {
3131
export class OracleQuery extends BaseQuery {
3232
/**
3333
* "LIMIT" on Oracle it's illegal
34+
* TODO replace with limitOffsetClause override
3435
*/
3536
public groupByDimensionLimit() {
3637
const limitClause = this.rowLimit === null ? '' : ` FETCH NEXT ${this.rowLimit && parseInt(this.rowLimit, 10) || 10000} ROWS ONLY`;

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,9 @@ export class PrestodbQuery extends BaseQuery {
102102
return `approx_distinct(${sql})`;
103103
}
104104

105-
public groupByDimensionLimit() {
106-
const limitClause = this.rowLimit === null ? '' : ` LIMIT ${this.rowLimit && parseInt(this.rowLimit, 10) || 10000}`;
107-
const offsetClause = this.offset ? ` OFFSET ${parseInt(this.offset, 10)}` : '';
108-
105+
protected limitOffsetClause(limit, offset) {
106+
const limitClause = limit != null ? ` LIMIT ${limit}` : '';
107+
const offsetClause = offset != null ? ` OFFSET ${offset}` : '';
109108
return `${offsetClause}${limitClause}`;
110109
}
111110

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ describe('SQL Generation', () => {
285285
view('visitors_post_aggregate', {
286286
cubes: [{
287287
join_path: 'visitors',
288-
includes: ['adjusted_rank_sum', 'source', 'updated_at', 'visitor_revenue']
288+
includes: '*'
289289
}]
290290
})
291291
@@ -957,6 +957,7 @@ describe('SQL Generation', () => {
957957
}],
958958
timezone: 'America/Los_Angeles',
959959
offset: 5,
960+
rowLimit: 5,
960961
});
961962

962963
console.log(query.buildSqlAndParams());
@@ -2596,6 +2597,32 @@ describe('SQL Generation', () => {
25962597
}]
25972598
));
25982599

2600+
it('post aggregate percentage of total with limit', async () => runQueryTest(
2601+
{
2602+
measures: ['visitors_post_aggregate.percentage_of_total'],
2603+
dimensions: ['visitors_post_aggregate.source'],
2604+
order: [{
2605+
id: 'visitors_post_aggregate.source'
2606+
}],
2607+
rowLimit: 1,
2608+
limit: 1
2609+
},
2610+
[{
2611+
visitors_post_aggregate__percentage_of_total: 15,
2612+
visitors_post_aggregate__source: 'google'
2613+
}]
2614+
));
2615+
2616+
it('post aggregate percentage of total with limit totals', async () => runQueryTest(
2617+
{
2618+
measures: ['visitors_post_aggregate.percentage_of_total'],
2619+
rowLimit: 1
2620+
},
2621+
[{
2622+
visitors_post_aggregate__percentage_of_total: 100
2623+
}]
2624+
));
2625+
25992626
it('post aggregate percentage of total filtered', async () => runQueryTest(
26002627
{
26012628
measures: ['visitors.revenue', 'visitors.percentage_of_total'],

packages/cubejs-testing-drivers/fixtures/_schemas.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,19 @@
290290
"type": "prior"
291291
}]
292292
},
293+
{
294+
"name": "totalProfitForStatus",
295+
"type": "sum",
296+
"sql": "{totalProfit}",
297+
"post_aggregate": true,
298+
"reduce_by": ["category"]
299+
},
300+
{
301+
"name": "percentageOfTotalForStatus",
302+
"type": "number",
303+
"sql": "ROUND(100 * {totalProfit} / NULLIF({totalProfitForStatus}, 0))",
304+
"post_aggregate": true
305+
},
293306
{
294307
"name": "hiddenSum",
295308
"sql": "profit",

packages/cubejs-testing-drivers/fixtures/athena.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
"CUBEJS_AWS_SECRET": "${DRIVERS_TESTS_ATHENA_CUBEJS_AWS_SECRET}",
1212
"CUBEJS_AWS_REGION": "us-east-1",
1313
"CUBEJS_AWS_ATHENA_WORKGROUP": "primary",
14-
"CUBEJS_AWS_S3_OUTPUT_LOCATION": "s3://athena-drivers-tests-preaggs/output"
14+
"CUBEJS_AWS_S3_OUTPUT_LOCATION": "s3://athena-drivers-tests-preaggs/output",
15+
"CUBEJS_PG_SQL_PORT": "5656",
16+
"CUBEJS_SQL_USER": "admin",
17+
"CUBEJS_SQL_PASSWORD": "admin_password",
18+
"CUBESQL_SQL_PUSH_DOWN": "true"
1519
},
16-
"ports" : ["4000"]
20+
"ports" : ["4000", "5656"]
1721
},
1822
"cast": {
1923
"SELECT_PREFIX": "",

packages/cubejs-testing-drivers/src/tests/testQueries.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function testQueries(type: string, { includeIncrementalSchemaSuite, exten
3232

3333
let connectionId = 0;
3434

35-
async function createPostgresClient(user: string, password: string, pgPort: number | undefined) {
35+
async function createPostgresClient(user: string = 'admin', password: string = 'admin_password', pgPort: number | undefined = env.cube.pgPort) {
3636
if (!pgPort) {
3737
throw new Error('port must be defined');
3838
}
@@ -1513,7 +1513,7 @@ export function testQueries(type: string, { includeIncrementalSchemaSuite, exten
15131513
}
15141514

15151515
executePg('SQL API: powerbi min max push down', async () => {
1516-
const connection = await createPostgresClient('admin', 'admin_password', env.cube.pgPort);
1516+
const connection = await createPostgresClient();
15171517
const res = await connection.query(`
15181518
select
15191519
max("rows"."orderDate") as "a0",
@@ -1530,7 +1530,7 @@ from
15301530
});
15311531

15321532
executePg('SQL API: powerbi min max ungrouped flag', async () => {
1533-
const connection = await createPostgresClient('admin', 'admin_password', env.cube.pgPort);
1533+
const connection = await createPostgresClient();
15341534
const res = await connection.query(`
15351535
select
15361536
count(distinct("rows"."totalSales")) + max(
@@ -1553,7 +1553,7 @@ from
15531553
});
15541554

15551555
executePg('SQL API: ungrouped pre-agg', async () => {
1556-
const connection = await createPostgresClient('admin', 'admin_password', env.cube.pgPort);
1556+
const connection = await createPostgresClient();
15571557
const res = await connection.query(`
15581558
select
15591559
"productName",
@@ -1564,5 +1564,16 @@ from
15641564
`);
15651565
expect(res.rows).toMatchSnapshot('ungrouped_pre_agg');
15661566
});
1567+
1568+
executePg('SQL API: post-aggregate percentage of total', async () => {
1569+
const connection = await createPostgresClient();
1570+
const res = await connection.query(`
1571+
select
1572+
sum("BigECommerce"."percentageOfTotalForStatus")
1573+
from
1574+
"public"."BigECommerce" "BigECommerce"
1575+
`);
1576+
expect(res.rows).toMatchSnapshot('post_aggregate_percentage_of_total');
1577+
});
15671578
});
15681579
}

0 commit comments

Comments
 (0)