Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/pages/reference/data-model/dimensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,14 @@ examples.

</ReferenceBox>

<WarningBox>

Custom granularities are supported for the following [data sources][ref-data-sources]:
Amazon Athena, Amazon Redshift, DuckDB, Databricks, Google BigQuery, ClickHouse, Microsoft SQL Server, MySQL, Postgres, and Snowflake.
Please [file an issue](https://github.com/cube-js/cube/issues) if you need support for another data source.

</WarningBox>

For each custom granularity, the `interval` parameter is required. It specifies
the duration of the time interval and has the following format:
`quantity unit [quantity unit...]`, e.g., `5 days` or `1 year 6 months`.
Expand Down Expand Up @@ -713,4 +721,5 @@ cube(`orders`, {
[ref-time-dimensions]: /reference/data-model/types-and-formats#time-1
[link-date-time-string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format
[ref-custom-granularity-recipe]: /guides/recipes/data-modeling/custom-granularity
[ref-ref-hierarchies]: /reference/data-model/hierarchies
[ref-ref-hierarchies]: /reference/data-model/hierarchies
[ref-data-sources]: /product/configuration/data-sources
2 changes: 1 addition & 1 deletion packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -3110,7 +3110,7 @@
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
dateBin(interval, source, origin) {
throw new Error('Date bin function is not implemented');
throw new Error('Date bin function, required for custom time dimension granularities, is not implemented for this data source');

Check warning on line 3113 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L3113 was not covered by tests
// Different syntax possible in different DBs
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export class PreAggregations {
const tableName = this.preAggregationTableName(cube, preAggregationName, preAggregation);
const invalidateKeyQueries = this.query.preAggregationInvalidateKeyQueries(cube, preAggregation, preAggregationName);
const queryForSqlEvaluation = this.query.preAggregationQueryForSqlEvaluation(cube, preAggregation);
const partitionInvalidateKeyQueries = queryForSqlEvaluation.partitionInvalidateKeyQueries && queryForSqlEvaluation.partitionInvalidateKeyQueries(cube, preAggregation);
const partitionInvalidateKeyQueries = queryForSqlEvaluation.partitionInvalidateKeyQueries?.(cube, preAggregation);

const allBackAliasMembers = this.query.allBackAliasMembers();

Expand Down
25 changes: 25 additions & 0 deletions packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parseSqlInterval } from '@cubejs-backend/shared';
import { BaseQuery } from './BaseQuery';
import { BaseFilter } from './BaseFilter';

Expand Down Expand Up @@ -55,6 +56,30 @@
field;
}

/**
* Returns sql for source expression floored to timestamps aligned with
* intervals relative to origin timestamp point.
* Athena doesn't support INTERVALs directly — using date_diff/date_add
*/
public dateBin(interval: string, source: string, origin: string): string {
const intervalParsed = parseSqlInterval(interval);
const intervalParts = Object.entries(intervalParsed);

Check warning on line 66 in packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts

View check run for this annotation

Codecov / codecov/patch

packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts#L64-L66

Added lines #L64 - L66 were not covered by tests

if (intervalParts.length > 1) {
throw new Error('Athena/Presto supports only simple intervals with one date part');

Check warning on line 69 in packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L69 was not covered by tests
}

const [unit, count] = intervalParts[0];
const originExpr = this.timeStampCast(`'${origin}'`);

Check warning on line 73 in packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts

View check run for this annotation

Codecov / codecov/patch

packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts#L72-L73

Added lines #L72 - L73 were not covered by tests

return `date_add('${unit}',

Check warning on line 75 in packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L75 was not covered by tests
floor(
date_diff('${unit}', ${originExpr}, ${source}) / ${count}
) * ${count},
${originExpr}
)`;
}

public timeGroupedColumn(granularity, dimension) {
return `date_trunc('${GRANULARITY_TO_INTERVAL[granularity]}', ${dimension})`;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/cubejs-server-core/src/core/DriverResolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ export const lookupDriverClass = (dbType): Constructor<BaseDriver> & {
*/
export const isDriver = (val: any): boolean => {
let isDriverInstance = val instanceof BaseDriver;
if (!isDriverInstance && val && val.constructor) {
if (!isDriverInstance && val?.constructor) {
let end = false;
let obj = val.constructor;
while (!isDriverInstance && !end) {
obj = Object.getPrototypeOf(obj);
end = !obj;
isDriverInstance = obj && obj.name ? obj.name === 'BaseDriver' : false;
isDriverInstance = obj?.name ? obj.name === 'BaseDriver' : false;
}
}
return isDriverInstance;
Expand All @@ -82,11 +82,11 @@ export const getDriverMaxPool = async (
const queryQueueOptions = await options
.queryCacheOptions
.queueOptions(context.dataSource);

const preAggregationsQueueOptions = await options
.preAggregationsOptions
.queueOptions(context.dataSource);

return 2 * (
queryQueueOptions.concurrency +
preAggregationsQueueOptions.concurrency
Expand Down
7 changes: 0 additions & 7 deletions packages/cubejs-testing-drivers/fixtures/athena.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,8 @@
"---------------------------------------",
"Custom Granularities ",
"---------------------------------------",
"querying custom granularities ECommerce: count by half_year + no dimension",
"querying custom granularities ECommerce: count by half_year_by_1st_april + no dimension",
"querying custom granularities ECommerce: count by three_months_by_march + no dimension",
"querying custom granularities ECommerce: count by half_year + dimension",
"querying custom granularities ECommerce: count by half_year_by_1st_april + dimension",
"querying custom granularities ECommerce: count by three_months_by_march + dimension",
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByUnbounded",
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByTrailing",
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading",

"SKIPPED SQL API (Need work)",
"---------------------------------------",
Expand Down
Loading
Loading