apache/beam · error · IllegalArgumentException
is a type constructor that takes parameters, not a type,so…
Error message
%s is a type constructor that takes parameters, not a type,so it cannot be converted to a %s
What it means
CalciteUtils.toFieldType(SqlTypeName) only converts atomic Calcite types. MAP, MULTISET, ARRAY and ROW are type constructors requiring parameter types, so converting one to a standalone Schema.FieldType is invalid and throws IllegalArgumentException. You must convert the element/row types and construct the composite FieldType yourself.
Solutions
- Branch on the SqlTypeName before calling: for ARRAY use FieldType.array(toFieldType(elementType)), for MAP use FieldType.map(k, v), for ROW use FieldType.row(toSchema(relDataType)).
- Use CalciteUtils.toFieldType(RelDataType) (the overload at line ~315) which handles parameterized types.
- Skip/composite-handle constructor types in schema conversion code.
Example fix
// before
FieldType ft = CalciteUtils.toFieldType(relDataType.getSqlTypeName()); // throws for ARRAY
// after
FieldType ft = relDataType.getSqlTypeName() == SqlTypeName.ARRAY
? FieldType.array(CalciteUtils.toFieldType(relDataType.getComponentType()))
: CalciteUtils.toFieldType(relDataType.getSqlTypeName()); Defensive patterns
Strategy: type-guard
Validate before calling
Set<SqlTypeName> constructors = Set.of(SqlTypeName.MAP, SqlTypeName.MULTISET, SqlTypeName.ARRAY, SqlTypeName.ROW);
if (constructors.contains(sqlTypeName)) { /* use composite conversion path */ } Type guard
boolean isTypeConstructor(SqlTypeName t) {
return t == SqlTypeName.MAP || t == SqlTypeName.MULTISET || t == SqlTypeName.ARRAY || t == SqlTypeName.ROW;
} Try / catch
try { ft = CalciteUtils.toFieldType(sqlTypeName); }
catch (IllegalArgumentException e) { /* branch to array/map/row construction using element types */ } Prevention
- Always handle ARRAY/MAP/ROW with their element-type-aware overloads
- Call toFieldType(RelDataType) instead of toFieldType(SqlTypeName) for column types
- Write a switch on SqlTypeName before schema conversion loops
When it happens
Trigger: Calling CalciteUtils.toFieldType with SqlTypeName.MAP, MULTISET, ARRAY or ROW, typically when a column's type is parameterized (e.g. an ARRAY<INT64> column whose SqlTypeName is ARRAY).
Common situations: Iterating RelDataType fields of a table containing array/map/struct columns and naively calling toFieldType per SqlTypeName; custom schema extraction from Calcite plans.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot find a matching Beam FieldType for Calcite type:
- Cannot find a matching Calcite SqlTypeName for Beam logical…
- Cannot find a matching Calcite SqlTypeName for Beam type
- Cannot infer types from
- columnsMapping ' ' does not fit to schema field names
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cb8bf206811b668a.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/utils/CalciteUtils.java:265
}
}
}
public static FieldType toFieldType(SqlTypeNameSpec sqlTypeName) {
return toFieldType(
Preconditions.checkArgumentNotNull(
SqlTypeName.get(sqlTypeName.getTypeName().getSimple()),
"Failed to find Calcite type with name '%s'",
sqlTypeName.getTypeName().getSimple()));
}
public static FieldType toFieldType(SqlTypeName sqlTypeName) {
switch (sqlTypeName) {
case MAP:
case MULTISET:
case ARRAY:
case ROW:
throw new IllegalArgumentException(
String.format(
"%s is a type constructor that takes parameters, not a type,"
+ "so it cannot be converted to a %s",
sqlTypeName, Schema.FieldType.class.getSimpleName()));
default:
FieldType fieldType = CALCITE_TO_BEAM_TYPE_MAPPING.get(sqlTypeName);
if (fieldType == null) {
throw new IllegalArgumentException(
"Cannot find a matching Beam FieldType for Calcite type: " + sqlTypeName);
}
return fieldType;
}
}
public static Schema.Field toField(RelDataTypeField calciteField) {
return toField(calciteField.getName(), calciteField.getType());
}
View on GitHub (pinned to 12126d8942)