cube-js/cube · error
Athena/Presto supports only simple intervals with one date p
Error message
Athena/Presto supports only simple intervals with one date part
What it means
PrestoDB/Athena only supports date_bin-style shifting with a single-unit interval (e.g. '1 day', '5 minute'). parseSqlInterval() returns an object of date parts; if more than one part is present (e.g. '1 month 3 days'), the query cannot be translated, so Cube throws immediately in dateBin.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts:95
const timestampField = this.promoteDateToTimestamp(field);
const atTimezone = `${timestampField} AT TIME ZONE '${this.timezone}'`;
return `CAST(date_add('minute', timezone_minute(${atTimezone}), date_add('hour', timezone_hour(${atTimezone}), ${timestampField})) AS TIMESTAMP)`;
}
/**
* 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.
* Origin is wrapped in `CAST(... AS TIMESTAMP)` so that `date_add` returns
* a plain TIMESTAMP rather than `timestamp with time zone` — Hive cannot
* write the TZ-aware type into an export bucket.
*/
public dateBin(interval: string, source: string, origin: string): string {
const intervalParsed = parseSqlInterval(interval);
const intervalParts = Object.entries(intervalParsed);
if (intervalParts.length > 1) {
throw new Error('Athena/Presto supports only simple intervals with one date part');
}
const [unit, count] = intervalParts[0];
const originExpr = `CAST(${this.timeStampCast(`'${origin}'`)} AS TIMESTAMP)`;
return `date_add('${unit}',
floor(
date_diff('${unit}', ${originExpr}, ${source}) / ${count}
) * ${count},
${originExpr}
)`;
}
public timeGroupedColumn(granularity, dimension) {
return `date_trunc('${GRANULARITY_TO_INTERVAL[granularity]}', ${dimension})`;
}
public intervalString(interval: string): string {View on GitHub (pinned to 7d981676b3)
Solutions
- Use an interval with exactly one date part, e.g. change '1 month 3 days' to '1 month' or '3 days'
- If a compound interval is required, compute the equivalent single unit (e.g. 6 months) or split the logic into multiple granularities/pre-aggregations
- Check that the query is not accidentally routed to Presto/Athena (wrong driver/dbType) if your interval was valid on another database
Example fix
// before const interval = '1 month 7 days'; queryBuilder.dateBin(interval, src, origin); // after const interval = '1 month'; // or '7 days' — one date part only
Defensive patterns
Strategy: validation
Validate before calling
const parts = parseSqlInterval(interval);
if (Object.values(parts).filter(v => v).length > 1) throw new Error('Use a single date-part interval for Athena/Presto'); Try / catch
try { return qb.dateBin(interval, src, origin); } catch (e) { if (e.message.includes('simple intervals')) { /* fall back to single-unit interval or rethrow with guidance */ } throw e; } Prevention
- Keep granularity intervals to one unit for Athena/Presto sources
- Centralize interval constants per dialect
- Add schema-level tests that compile time dimensions against the target dialect
When it happens
Trigger: Calling dateBin(interval, source, origin) (directly or via time-dimension dateBin/granularity derivation) with a compound interval string like '1 month 2 days' or '1 year 6 months' against a Presto/Athena data source.
Common situations: Defining a named granularity or pre-aggregation with a multi-part interval; a time dimension granularity configured for another dialect (e.g. Postgres supports compound intervals) being reused against Athena.
Related errors
- Complex intervals like "${interval}" are not supported. Plea
- Query was cancelled
- Unload is not configured. Please define CUBEJS_AWS_S3_OUTPUT
- Export bucket is not configured.
- ${queryExecution.QueryExecution?.Status?.StateChangeReason}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/89091ac36f153930.
Report an issue: GitHub.