{"record":{"id":"fe0b55e4cc50aea2","repo":"apache/druid","slug":"column-s-has-conflicting-types-s-and-s","errorCode":null,"errorMessage":"Column[%s] has conflicting types [%s] and [%s]","messagePattern":"Column\\[(.+?)\\] has conflicting types \\[(.+?)\\] and \\[(.+?)\\]","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/column/RowSignature.java","lineNumber":78,"sourceCode":"   * {@link org.apache.druid.sql.calcite.schema.DruidSchema}\n   * Also helps in comparing the RowSignatures in equals method\n   */\n  private final int hashCode;\n\n  private RowSignature(final List<ColumnSignature> columnTypeList)\n  {\n    this.columnPositions.defaultReturnValue(-1);\n\n    final ImmutableList.Builder<String> columnNamesBuilder = ImmutableList.builder();\n\n    for (int i = 0; i < columnTypeList.size(); i++) {\n      final ColumnSignature sig = columnTypeList.get(i);\n      final ColumnType existingType = columnTypes.get(sig.name());\n\n      if (columnTypes.containsKey(sig.name()) && !Objects.equals(existingType, sig.type())) {\n        // It's ok to add the same column twice as long as the type is consistent.\n        // Note: we need the containsKey because the existingType might be present, but null.\n        throw new IAE(\"Column[%s] has conflicting types [%s] and [%s]\", sig.name(), existingType, sig.type());\n      }\n\n      columnTypes.put(sig.name(), sig.type());\n      columnPositions.put(sig.name(), i);\n      columnNamesBuilder.add(sig.name());\n    }\n\n    this.columnNames = columnNamesBuilder.build();\n    this.hashCode = computeHashCode();\n  }\n\n  @JsonCreator\n  static RowSignature fromColumnSignatures(final List<ColumnSignature> columnSignatures)\n  {\n    final Builder builder = builder();\n\n    for (final ColumnSignature columnSignature : columnSignatures) {\n      builder.add(columnSignature.name(), columnSignature.type());","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/column/RowSignature.java#L60-L96","documentation":"RowSignature's constructor validates that a column added multiple times carries a consistent type. When the same column name appears with two different (non-equal) ColumnTypes, Druid throws this IAE because a signature cannot resolve a single type per column. Note a null existing type is allowed; only genuinely conflicting non-null types fail.","triggerScenarios":"Building a RowSignature (or merging query signatures in join/union planning) where a column name is added twice with different ColumnTypes, e.g. via RowSignature.builder().add(\"col\", LONG).add(\"col\", STRING).build().","commonSituations":"SQL queries whose subqueries/joins produce a column with diverging inferred types; ingestion specs with timestampSpec/dataSchema referencing the same column with different types; combining signatures from heterogeneous segments.","solutions":["Rename one of the conflicting columns (or cast one side with CAST in SQL) so both occurrences have the same type","Inspect the signature-building code and ensure the column is only added once per type","Check ingestion spec fields (timestampSpec.column, metricsSpec) for accidental reuse of one column name with different types"],"exampleFix":"// before\nRowSignature.builder().add(\"v\", ColumnType.LONG).add(\"v\", ColumnType.STRING).build(); // IAE\n// after\nRowSignature.builder().add(\"v\", ColumnType.STRING).add(\"v_str\", ColumnType.STRING).build();","handlingStrategy":"validation","validationCode":"// before building, check duplicates:\nMap<String, ColumnType> seen = new HashMap<>();\nfor (ColumnSignature sig : signatures) {\n  ColumnType prev = seen.putIfAbsent(sig.name(), sig.type());\n  if (prev != null && !Objects.equals(prev, sig.type())) {\n    throw new IllegalArgumentException(\"Column \" + sig.name() + \" has conflicting types\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  RowSignature sig = RowSignature.builder()....build();\n} catch (IAE e) {\n  LOG.warn(e, \"Conflicting column types; casting one side\");\n  // rebuild signature with an explicit CAST applied to the offending column\n}","preventionTips":["In SQL, CAST mismatched columns so union/join branches agree on types","Avoid reusing one column name for different types in ingestion specs","Compare signatures of subqueries during query planning before combining"],"tags":["java","row-signature","type-conflict","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}