apache/beam · error · UnsupportedOperationException
Only INT64 is supported as the interval value for BigQuery.
Error message
Only INT64 is supported as the interval value for BigQuery.
What it means
BeamBigQuerySqlDialect.unparseSqlIntervalLiteral converts a SQL INTERVAL literal back into BigQuery-compatible syntax. BigQuery only accepts INT64 interval values in this dialect, so when the literal's value cannot be parsed as a Long the dialect throws UnsupportedOperationException instead of emitting invalid SQL.
Solutions
- Use whole-number INT64 interval values, e.g. INTERVAL 2 DAY instead of INTERVAL '1.5' DAY
- Compute fractional durations with arithmetic on integers (e.g. 1 DAY + 12 HOUR)
- Evaluate the interval expression in Beam instead of pushing it to BigQuery
Example fix
// before SELECT * FROM t WHERE ts > CURRENT_TIMESTAMP() - INTERVAL '1.5' DAY // after SELECT * FROM t WHERE ts > CURRENT_TIMESTAMP() - INTERVAL 1 DAY - INTERVAL 12 HOUR
Defensive patterns
Strategy: validation
Validate before calling
// validate interval literal before using it in a BigQuery-pushable query
Object v = literal.getValue();
Long.parseLong(String.valueOf(v)); // throws NumberFormatException early
if (!String.valueOf(v).matches("^-?\\d+$")) throw new IllegalArgumentException("BigQuery dialect requires INT64 interval values"); Type guard
boolean isInt64Interval(RexLiteral l) {
try { Long.parseLong(String.valueOf(l.getValue())); return true; }
catch (NumberFormatException e) { return false; }
} Try / catch
try {
runQuery(sql);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Only INT64")) { /* rewrite interval */ }
throw e;
} Prevention
- Use integer-valued INTERVAL literals only in queries targeting BigQuery
- Compose durations from whole units (DAY/HOUR/SECOND) instead of fractional literals
- Unit-test SQL unparse for every interval expression you generate
When it happens
Trigger: Unparsing (generating SQL for) an INTERVAL literal whose value string is not parseable by Long.parseLong — e.g. INTERVAL '1.5' DAY or non-numeric interval text — when serializing a Calcite plan for BigQuery.
Common situations: Using fractional or non-integer interval constants in queries pushed to BigQuery; passing interval literals created from string/decimal expressions; dialect differences between Calcite-standard intervals and BigQuery's limited interval support.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Predicate node ' ' should be a boolean expression, but was
- Bounded Source is not BigQueryStorageStreamSource, unable…
- Cannot convert BigQuery type '' to '' because the BigQuery…
- Conflicting field types for field
- custom_gcs_temp_location must be str or ValueProvider
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/87f9db341b361dbf.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigquery/BeamBigQuerySqlDialect.java:146
super.unparseCall(writer, call, leftPrec, rightPrec);
}
}
/** BigQuery interval syntax: INTERVAL int64 time_unit. */
@Override
public void unparseSqlIntervalLiteral(
SqlWriter writer, SqlIntervalLiteral literal, int leftPrec, int rightPrec) {
SqlIntervalLiteral.IntervalValue interval =
(SqlIntervalLiteral.IntervalValue) literal.getValue();
writer.keyword("INTERVAL");
if (interval.getSign() == -1) {
writer.print("-");
}
Long intervalValueInLong;
try {
intervalValueInLong = Long.parseLong(literal.getValue().toString());
} catch (NumberFormatException e) {
throw new UnsupportedOperationException(
"Only INT64 is supported as the interval value for BigQuery.");
}
writer.literal(intervalValueInLong.toString());
unparseSqlIntervalQualifier(writer, interval.getIntervalQualifier(), RelDataTypeSystem.DEFAULT);
}
private void unparseDoubleLiteralWrapperFunction(SqlWriter writer, String funName) {
writer.literal(DOUBLE_LITERAL_WRAPPERS.get(funName));
}
private void unparseNumericLiteralWrapperFunction(
SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
writer.literal("NUMERIC '");
call.operand(0).unparse(writer, leftPrec, rightPrec);
writer.literal("'");
}
/**View on GitHub (pinned to 12126d8942)