{"record":{"id":"8caf0e51834365a0","repo":"apache/iceberg","slug":"cannot-convert-type-to-sql","errorCode":null,"errorMessage":"Cannot convert type to SQL: ","messagePattern":"Cannot convert type to SQL: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java","lineNumber":614,"sourceCode":"        case DOUBLE:\n          return \"double\";\n        case DATE:\n          return \"date\";\n        case TIME:\n          return \"time\";\n        case TIMESTAMP:\n          return \"timestamp\";\n        case STRING:\n        case UUID:\n          return \"string\";\n        case FIXED:\n        case BINARY:\n          return \"binary\";\n        case DECIMAL:\n          Types.DecimalType decimal = (Types.DecimalType) primitive;\n          return \"decimal(\" + decimal.precision() + \",\" + decimal.scale() + \")\";\n      }\n      throw new UnsupportedOperationException(\"Cannot convert type to SQL: \" + primitive);\n    }\n  }\n\n  private static class DescribeExpressionVisitor\n      extends ExpressionVisitors.ExpressionVisitor<String> {\n    private static final DescribeExpressionVisitor INSTANCE = new DescribeExpressionVisitor();\n\n    private DescribeExpressionVisitor() {}\n\n    @Override\n    public String alwaysTrue() {\n      return \"true\";\n    }\n\n    @Override\n    public String alwaysFalse() {\n      return \"false\";\n    }","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java#L596-L632","documentation":"Spark3Util.DescribeExpressionVisitor.primitive maps Iceberg primitive types to SQL type strings for DESCRIBE output. The switch covers boolean, integer types, float/double, date, timestamp, string, uuid, fixed, binary and decimal; anything else (or an unexpected Type) throws UnsupportedOperationException 'Cannot convert type to SQL'.","triggerScenarios":"DESCRIBE TABLE on an Iceberg table whose schema contains a primitive type not handled by the visitor's switch — typically a newer Iceberg type added after this Spark v4.0 helper was written, or a nested/type dispatch bug passing a non-primitive into primitive().","commonSituations":"Schema written by a newer Iceberg version read by an older Spark connector; custom Type implementations; directly invoking Spark3Util.describeSchema on hand-built schemas.","solutions":["Check the schema type reported in the message; map it to a supported primitive (e.g. use string/uuid/fixed/binary/decimal equivalents)","Upgrade the Iceberg Spark module so its type-to-SQL mapping covers the type","Patch Spark3Util to add a case for the new type in the switch"],"exampleFix":"// before\nthrow new UnsupportedOperationException(\"Cannot convert type to SQL: \" + primitive);\n// after\ncase TIMESTAMP_NANO:\n  return \"timestamp_ntz\"; // add case before the throw\n// or\nreturn primitive.toString(); // degrade instead of throwing","handlingStrategy":"type-guard","validationCode":"Types.TypeID id = ((Types.PrimitiveType) type).typeId();\nSet<Types.TypeID> known = Set.of(BOOLEAN, INTEGER, LONG, FLOAT, DOUBLE, DATE,\n    TIMESTAMP, STRING, UUID, FIXED, BINARY, DECIMAL);\nif (!known.contains(id)) throw new IllegalArgumentException(\"Type not renderable as SQL: \" + type);","typeGuard":"boolean isRenderable(Types.Type t) {\n  return t instanceof Types.PrimitiveType && !t.equals(Types.TimestampNanoType.get());\n}","tryCatchPattern":"try {\n  String sql = primitive(type);\n} catch (UnsupportedOperationException e) {\n  return type.toString(); // degrade to Iceberg type name in DESCRIBE output\n}","preventionTips":["Keep the Iceberg Spark module at the same version as core to cover all primitive types","Handle nano-timestamps and new types explicitly in custom describe tooling","Test DESCRIBE output against schemas containing every primitive type you emit"],"tags":["spark","type-conversion","describe"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}