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

  1. 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)).
  2. Use CalciteUtils.toFieldType(RelDataType) (the overload at line ~315) which handles parameterized types.
  3. 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

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


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)