apache/druid · error · IllegalStateException
Cannot translate sqlTypeName[%s] to Druid type for field[%s]
Error message
Cannot translate sqlTypeName[%s] to Druid type for field[%s]
What it means
Bitmap64ExactCountSqlAggregator.createBuildAggregatorFactory translates the SQL planner's RelDataType into a Druid ColumnType; when Calcites.getColumnTypeForRelDataType returns null (a SQL type Druid cannot represent), it throws IllegalStateException("Cannot translate sqlTypeName[%s] to Druid type for field[%s]"). This is an internal planner-level invariant failure: the aggregation input column has a SQL type with no Druid equivalent.
Source
Thrown at extensions-contrib/druid-exact-count-bitmap/src/main/java/org/apache/druid/query/aggregation/exact/count/bitmap64/sql/Bitmap64ExactCountSqlAggregator.java:158
final RelDataType operandType = ((RexCall) columnRexNode).operands.get(0).getType();
final ColumnType operandDruidType = Calcites.getColumnTypeForRelDataType(operandType);
if (operandDruidType == null || !operandDruidType.isNumeric()) {
throw SimpleSqlAggregator.badTypeException(columnName, NAME, ColumnType.STRING);
}
}
}
private AggregatorFactory createBuildAggregatorFactory(
final RexNode columnRexNode,
final DruidExpression columnArg,
final VirtualColumnRegistry virtualColumnRegistry,
final String aggregatorName
)
{
final RelDataType dataType = columnRexNode.getType();
final ColumnType inputType = Calcites.getColumnTypeForRelDataType(dataType);
if (inputType == null) {
throw new ISE(
"Cannot translate sqlTypeName[%s] to Druid type for field[%s]",
dataType.getSqlTypeName(),
aggregatorName
);
}
final DimensionSpec dimensionSpec;
if (columnArg.isDirectColumnAccess()) {
dimensionSpec = columnArg.getSimpleExtraction().toDimensionSpec(null, inputType);
} else {
String virtualColumnName = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(columnArg, dataType);
dimensionSpec = new DefaultDimensionSpec(virtualColumnName, null, inputType);
}
return new Bitmap64ExactCountBuildAggregatorFactory(aggregatorName, dimensionSpec.getDimension());
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Inspect the SQL type of the argument in the query plan (EXPLAIN PLAN FOR ...) and cast it to a supported scalar: e.g. BITMAP64_EXACT_COUNT(CAST(col AS BIGINT)).
- Ensure the argument is a scalar column (VARCHAR or numeric), not an ARRAY/MAP/STRUCT — extract the element first if it is nested.
- If the column comes from an ingestion spec, verify the Druid column's type metadata is correct (re-ingest or fix the dimension/metric spec so it is not reported as OTHER/NULL).
- If a specific expression (CASE, COALESCE with mixed types) produces the bad type, wrap it in an explicit CAST to normalize the type.
Example fix
// before SELECT BITMAP64_EXACT_COUNT(tags) FROM t; -- tags is ARRAY<VARCHAR> // after SELECT BITMAP64_EXACT_COUNT(CAST(user_id AS BIGINT)) FROM t; -- scalar input only
Defensive patterns
Strategy: validation
Validate before calling
// before running the query, check the argument's SQL type via EXPLAIN PLAN
// or in planner code:
ColumnType t = Calcites.getColumnTypeForRelDataType(node.getType());
if (t == null) {
throw new IllegalStateException("BITMAP64_EXACT_COUNT needs a scalar argument, got: "
+ node.getType().getSqlTypeName());
} Try / catch
try {
runQuery(sql);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Cannot translate sqlTypeName")) {
// rewrite the SQL with an explicit CAST on the aggregator argument and retry
} else {
throw e;
}
} Prevention
- Only pass scalar (VARCHAR or numeric) columns to BITMAP64_EXACT_COUNT; never ARRAY/MAP/STRUCT columns.
- Add explicit CASTs around computed expressions (CASE, COALESCE) inside the aggregator call.
- Run EXPLAIN PLAN FOR your SQL in CI to surface unmappable types before production.
- Keep the argument's ingested type metadata accurate so the planner does not infer NULL/OTHER types.
When it happens
Trigger: Calling BITMAP64_EXACT_COUNT (the bitmap64 exact-count SQL aggregator) on a column whose inferred SQL type is exotic or unsupported — e.g. ARRAY, MAP, STRUCT/ROW, NULL, or OTHER types produced by the Calcite planner — so getColumnTypeForRelDataType cannot map it.
Common situations: Aggregating over an ARRAY/MAP-typed column or a nested ROW field instead of a scalar; aliasing a NULL-typed expression (e.g. CAST(NULL AS ...)) into the aggregator; planner changes producing unusual RelDataTypes for expressions like CASE with mixed types; passing a subquery projection with an unmappable type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot translate sqlTypeName[%s] to Druid type for field[%s]
- Unknown
- Cannot return primitive float for Null Value
- Cannot return double for Null Value
- Cannot return long for Null Value
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/99b9466e823bdbb8.
Report an issue: GitHub.