Skip to content

Commit 5f78974

Browse files
committed
feat: Hour partition granularity support
1 parent 0508ffd commit 5f78974

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

packages/cubejs-schema-compiler/adapter/PreAggregations.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,17 @@ class PreAggregations {
134134
}
135135

136136
preAggregationTableName(cube, preAggregationName, preAggregation, skipSchema) {
137+
let partitionSuffix = '';
138+
if (preAggregation.partitionTimeDimensions) {
139+
const partitionTimeDimension = preAggregation.partitionTimeDimensions[0];
140+
partitionSuffix = partitionTimeDimension.dateRange[0].substring(
141+
0,
142+
preAggregation.partitionGranularity === 'hour' ? 13 : 10
143+
).replace(/[-T:]/g, '');
144+
}
137145
return this.query.preAggregationTableName(
138-
cube, preAggregationName + (
139-
preAggregation.partitionTimeDimensions ?
140-
preAggregation.partitionTimeDimensions[0].dateRange[0].replace('T00:00:00.000', '').replace(/-/g, '') :
141-
''
142-
),
146+
cube,
147+
preAggregationName + partitionSuffix,
143148
skipSchema
144149
);
145150
}

packages/cubejs-schema-compiler/compiler/CubeValidator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const BasePreAggregation = {
7474
),
7575
useOriginalSqlPreAggregations: Joi.boolean(),
7676
external: Joi.boolean(),
77-
partitionGranularity: Joi.any().valid('day', 'week', 'month', 'year'),
77+
partitionGranularity: Joi.any().valid('hour', 'day', 'week', 'month', 'year'),
7878
scheduledRefresh: Joi.boolean(),
7979
indexes: Joi.object().pattern(identifierRegex, Joi.alternatives().try(
8080
Joi.object().keys({

packages/cubejs-schema-compiler/parser/SqlParser.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,9 @@ class SqlParser {
7373
return sql.slice(start, stop + 1);
7474
}
7575
};
76-
const lexer = new GenericSqlLexer(chars);
77-
const tokens = new antlr4.CommonTokenStream(lexer);
78-
const parser = new GenericSqlParser(tokens);
79-
parser.buildParseTrees = true;
76+
8077
const errors = [];
8178
this.errors = errors;
82-
parser.removeErrorListeners();
8379

8480
class ExprErrorListener extends antlr4.error.ErrorListener {
8581
syntaxError(recognizer, offendingSymbol, line, column, msg, err) {
@@ -89,6 +85,13 @@ class SqlParser {
8985
}
9086
}
9187

88+
const lexer = new GenericSqlLexer(chars);
89+
lexer.removeErrorListeners();
90+
lexer.addErrorListener(new ExprErrorListener());
91+
const tokens = new antlr4.CommonTokenStream(lexer);
92+
const parser = new GenericSqlParser(tokens);
93+
parser.buildParseTrees = true;
94+
parser.removeErrorListeners();
9295
parser.addErrorListener(new ExprErrorListener());
9396

9497
return parser.statement();

packages/cubejs-schema-compiler/test/PreAggregationsTest.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/* eslint-disable quote-props */
2+
/* globals it, describe, after */
23
const R = require('ramda');
34

45
const PostgresQuery = require('../adapter/PostgresQuery');
56
const BigqueryQuery = require('../adapter/BigqueryQuery');
67
const PrepareCompiler = require('./PrepareCompiler');
78
require('should');
89

9-
const prepareCompiler = PrepareCompiler.prepareCompiler;
10+
const { prepareCompiler } = PrepareCompiler;
1011
const dbRunner = require('./DbRunner');
1112

1213
describe('PreAggregations', function test() {
@@ -128,6 +129,14 @@ describe('PreAggregations', function test() {
128129
granularity: 'day',
129130
partitionGranularity: 'month'
130131
},
132+
partitionedHourly: {
133+
type: 'rollup',
134+
measureReferences: [checkinsTotal],
135+
dimensionReferences: [source],
136+
timeDimensionReference: createdAt,
137+
granularity: 'hour',
138+
partitionGranularity: 'hour'
139+
},
131140
ratio: {
132141
type: 'rollup',
133142
measureReferences: [checkinsTotal, uniqueSourceCount],
@@ -749,6 +758,58 @@ describe('PreAggregations', function test() {
749758
});
750759
});
751760

761+
it('partitioned hourly', () => {
762+
return compiler.compile().then(() => {
763+
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
764+
measures: [
765+
'visitors.checkinsTotal'
766+
],
767+
dimensions: [
768+
'visitors.source'
769+
],
770+
timezone: 'UTC',
771+
preAggregationsSchema: '',
772+
timeDimensions: [{
773+
dimension: 'visitors.createdAt',
774+
granularity: 'hour',
775+
dateRange: ['2017-01-02', '2017-01-05']
776+
}],
777+
order: [{
778+
id: 'visitors.createdAt'
779+
}],
780+
});
781+
782+
const queryAndParams = query.buildSqlAndParams();
783+
console.log(queryAndParams);
784+
const preAggregationsDescription = query.preAggregations.preAggregationsDescription();
785+
console.log(preAggregationsDescription);
786+
787+
const queries = tempTablePreAggregations(preAggregationsDescription);
788+
789+
console.log(JSON.stringify(queries.concat(queryAndParams)));
790+
791+
return dbRunner.testQueries(
792+
queries.concat([queryAndParams]).map(q => replaceTableName(q, preAggregationsDescription, 242))
793+
).then(res => {
794+
console.log(JSON.stringify(res));
795+
res.should.be.deepEqual(
796+
[
797+
{
798+
"visitors__source": "some",
799+
"visitors__created_at_hour": "2017-01-03T00:00:00.000Z",
800+
"visitors__checkins_total": "3"
801+
},
802+
{
803+
"visitors__source": "some",
804+
"visitors__created_at_hour": "2017-01-05T00:00:00.000Z",
805+
"visitors__checkins_total": "2"
806+
}
807+
]
808+
);
809+
});
810+
});
811+
});
812+
752813
it('segment', () => {
753814
return compiler.compile().then(() => {
754815
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {

0 commit comments

Comments
 (0)