{"record":{"id":"99b9466e823bdbb8","repo":"apache/druid","slug":"cannot-translate-sqltypename-s-to-druid-type-for","errorCode":null,"errorMessage":"Cannot translate sqlTypeName[%s] to Druid type for field[%s]","messagePattern":"Cannot translate sqlTypeName\\[(.+?)\\] to Druid type for field\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/druid-exact-count-bitmap/src/main/java/org/apache/druid/query/aggregation/exact/count/bitmap64/sql/Bitmap64ExactCountSqlAggregator.java","lineNumber":158,"sourceCode":"      final RelDataType operandType = ((RexCall) columnRexNode).operands.get(0).getType();\n      final ColumnType operandDruidType = Calcites.getColumnTypeForRelDataType(operandType);\n      if (operandDruidType == null || !operandDruidType.isNumeric()) {\n        throw SimpleSqlAggregator.badTypeException(columnName, NAME, ColumnType.STRING);\n      }\n    }\n  }\n\n  private AggregatorFactory createBuildAggregatorFactory(\n      final RexNode columnRexNode,\n      final DruidExpression columnArg,\n      final VirtualColumnRegistry virtualColumnRegistry,\n      final String aggregatorName\n  )\n  {\n    final RelDataType dataType = columnRexNode.getType();\n    final ColumnType inputType = Calcites.getColumnTypeForRelDataType(dataType);\n    if (inputType == null) {\n      throw new ISE(\n          \"Cannot translate sqlTypeName[%s] to Druid type for field[%s]\",\n          dataType.getSqlTypeName(),\n          aggregatorName\n      );\n    }\n\n    final DimensionSpec dimensionSpec;\n\n    if (columnArg.isDirectColumnAccess()) {\n      dimensionSpec = columnArg.getSimpleExtraction().toDimensionSpec(null, inputType);\n    } else {\n      String virtualColumnName = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(columnArg, dataType);\n      dimensionSpec = new DefaultDimensionSpec(virtualColumnName, null, inputType);\n    }\n\n    return new Bitmap64ExactCountBuildAggregatorFactory(aggregatorName, dimensionSpec.getDimension());\n  }\n","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/druid-exact-count-bitmap/src/main/java/org/apache/druid/query/aggregation/exact/count/bitmap64/sql/Bitmap64ExactCountSqlAggregator.java#L140-L176","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nSELECT BITMAP64_EXACT_COUNT(tags) FROM t; -- tags is ARRAY<VARCHAR>\n// after\nSELECT BITMAP64_EXACT_COUNT(CAST(user_id AS BIGINT)) FROM t; -- scalar input only","handlingStrategy":"validation","validationCode":"// before running the query, check the argument's SQL type via EXPLAIN PLAN\n// or in planner code:\nColumnType t = Calcites.getColumnTypeForRelDataType(node.getType());\nif (t == null) {\n  throw new IllegalStateException(\"BITMAP64_EXACT_COUNT needs a scalar argument, got: \"\n      + node.getType().getSqlTypeName());\n}","typeGuard":null,"tryCatchPattern":"try {\n  runQuery(sql);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Cannot translate sqlTypeName\")) {\n    // rewrite the SQL with an explicit CAST on the aggregator argument and retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["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."],"tags":["sql","type-mapping","planner","druid"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}