{"record":{"id":"fa8e4c60f482a26d","repo":"apache/beam","slug":"unknown-datetime-type-logicalid","errorCode":null,"errorMessage":"Unknown DateTime type ${logicalId}","messagePattern":"Unknown DateTime type (.+?)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamEnumerableConverter.java","lineNumber":340,"sourceCode":"        LogicalType<?, ?> logicalType = type.getLogicalType();\n        assert logicalType != null;\n        String logicalId = logicalType.getIdentifier();\n        if (SqlTypes.TIME.getIdentifier().equals(logicalId)) {\n          if (beamValue instanceof Long) { // base type\n            return (Long) beamValue;\n          } else { // input type\n            return ((LocalTime) beamValue).toNanoOfDay();\n          }\n        } else if (SqlTypes.DATE.getIdentifier().equals(logicalId)) {\n          if (beamValue instanceof Long) { // base type\n            return ((Long) beamValue).intValue();\n          } else { // input type\n            return (int) ((LocalDate) beamValue).toEpochDay();\n          }\n        } else if (logicalType instanceof PassThroughLogicalType) {\n          return beamValue;\n        } else {\n          throw new UnsupportedOperationException(\"Unknown DateTime type \" + logicalId);\n        }\n      case DATETIME:\n        return ((ReadableInstant) beamValue).getMillis();\n      case BYTE:\n      case INT16:\n      case INT32:\n      case INT64:\n      case DECIMAL:\n      case FLOAT:\n      case DOUBLE:\n      case STRING:\n      case BOOLEAN:\n      case BYTES:\n        return beamValue;\n      case ARRAY:\n        return ((List<?>) beamValue)\n            .stream()\n                .map(elem -> fieldToAvatica(type.getCollectionElementType(), elem))","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamEnumerableConverter.java#L322-L358","documentation":"fieldToAvatica converts Beam Row field values into Avatica (Calcite JDBC) typed values. In the DATE branch, if the field's logical type is neither the recognized DATE logical type nor a PassThroughLogicalType, the converter cannot map it and throws UnsupportedOperationException(\"Unknown DateTime type \" + logicalId). It is a schema/type-support limitation, not a data error.","triggerScenarios":"Executing a Beam SQL SELECT whose schema contains a DATE/timestamp logical type column with a custom or unrecognized LogicalType identifier (logicalId) that BeamEnumerableConverter does not know how to convert to Avatica's java.sql.Date representation.","commonSituations":"Using custom logical types registered in the schema (e.g. via Schema.builder().addLogicalType or custom FieldType with logical type), or Beam version mismatches where a new built-in logical type isn't yet handled by the Avatica converter.","solutions":["Use standard Beam DATE/TIME logical types instead of a custom logical type for the column","Make the logical type implement PassThroughLogicalType so the value is returned as-is","Convert the column to a primitive DATE (FieldType of TypeName.DATETIME) before querying","Patch BeamEnumerableConverter.fieldToAvatica to handle the logicalId","Check Beam version — upgrade if the logical type support was added later"],"exampleFix":"// before\nFieldType dateField = FieldType.logicalType(new MyDateLogicalType());\n// after: use a supported logical type or pass-through\nFieldType dateField = FieldType.logicalType(new MyDateLogicalType() implements PassThroughLogicalType);","handlingStrategy":"validation","validationCode":"FieldType ft = schema.getField(i).getType();\nif (ft.getTypeName() == TypeName.DATETIME && ft.getLogicalType() != null\n    && !(ft.getLogicalType() instanceof Dates.LogicalDate)\n    && !(ft.getLogicalType() instanceof PassThroughLogicalType)) {\n  throw new IllegalArgumentException(\"Unsupported logical type: \" + ft.getLogicalType().getIdentifier());\n}","typeGuard":"boolean isSupportedDateField(FieldType ft) {\n  return ft.getTypeName() != TypeName.DATETIME || ft.getLogicalType() == null\n      || ft.getLogicalType() instanceof PassThroughLogicalType;\n}","tryCatchPattern":"try {\n  Object v = fieldToAvatica(fieldType, value);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Unknown DateTime type\")) {\n    // fall back to raw value or coerce to java.sql.Date\n  } else throw e;\n}","preventionTips":["Use standard Beam logical types for DATE/TIME columns queried via Beam SQL","Implement PassThroughLogicalType for custom logical types","Normalize schemas to primitive types before exposing them to Beam SQL","Test SELECT round-trips on all schema columns in CI","Check Beam release notes for newly supported logical types"],"tags":["java","beam","sql","avatica","unsupported-type","logical-type"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}