{"record":{"id":"0b554323d4026a2e","repo":"apache/iceberg","slug":"day-transform-is-not-supported","errorCode":null,"errorMessage":"Day transform is not supported","messagePattern":"Day transform is not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java","lineNumber":73,"sourceCode":"\n  default T year(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Year transform is not supported\");\n  }\n\n  default T month(int fieldId, String sourceName, int sourceId) {\n    return month(sourceName, sourceId);\n  }\n\n  default T month(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Month transform is not supported\");\n  }\n\n  default T day(int fieldId, String sourceName, int sourceId) {\n    return day(sourceName, sourceId);\n  }\n\n  default T day(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Day transform is not supported\");\n  }\n\n  default T hour(int fieldId, String sourceName, int sourceId) {\n    return hour(sourceName, sourceId);\n  }\n\n  default T hour(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Hour transform is not supported\");\n  }\n\n  default T alwaysNull(int fieldId, String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Void transform is not supported\");\n  }\n\n  default T unknown(int fieldId, String sourceName, int sourceId, String transform) {\n    throw new UnsupportedOperationException(\n        String.format(\"Unknown transform %s is not supported\", transform));\n  }","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java#L55-L91","documentation":"PartitionSpecVisitor's default day() methods throw UnsupportedOperationException because the visitor implementation did not override the day-transform hook. PartitionSpecVisitor.visit detects day transforms (Dates.DAY, Timestamps.MICROS_TO_DAY/NANOS_TO_DAY, Days) and routes the field to day(); implementations covering only identity/bucket/truncate (or other subsets) hit this default and fail fast rather than producing an incorrect partition-field translation.","triggerScenarios":"PartitionSpecVisitor.visit on a table with a day(ts_col) or day(date_col) partition field where the concrete visitor has no day(int, String, int) or day(String, int) override.","commonSituations":"Very common in real deployments since day partitioning is one of the most widely used strategies: custom Hive/JDBC/Nessie catalog translators or metadata mappers that predate day-transform support, run against long-lived tables partitioned by day.","solutions":["Override day(int fieldId, String sourceName, int sourceId) in your visitor implementation to handle the day transform","Inspect table.spec().partitionType() before visiting to enumerate which transforms must be supported","If day partitioning is out of scope, override day() to fail with a domain-specific message naming the table/spec"],"exampleFix":"// before\nvisitor without day override -> UnsupportedOperationException\n// after\n@Override\npublic String day(int fieldId, String sourceName, int sourceId) {\n  return \"days(\" + sourceName + \")\";\n}","handlingStrategy":"validation","validationCode":"boolean hasDayTransform(PartitionSpec spec) {\n  return spec.fields().stream().anyMatch(f -> f.transform() instanceof Days\n      || f.transform() == Dates.DAY || f.transform() == Timestamps.MICROS_TO_DAY);\n}\n// gate PartitionSpecVisitor.visit on this check","typeGuard":"if (field.transform() instanceof Days) {\n  // handle day transform explicitly instead of falling through to the throwing default\n}","tryCatchPattern":"try {\n  PartitionSpecVisitor.visit(spec, visitor);\n} catch (UnsupportedOperationException e) {\n  throw new UnsupportedOperationException(\n      \"Table \" + table.name() + \" uses a day partition transform the visitor cannot map\", e);\n}","preventionTips":["Always implement day() — day partitioning is extremely common in production tables","Build visitor test fixtures for day(date), day(timestamp) specs","Validate partitionType() strings against the set of supported transforms before running translation"],"tags":["java","partitioning","visitor-pattern","unsupported-transform"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}