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

  1. 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)).
  2. Ensure the argument is a scalar column (VARCHAR or numeric), not an ARRAY/MAP/STRUCT — extract the element first if it is nested.
  3. 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).
  4. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/99b9466e823bdbb8. Report an issue: GitHub.