apache/beam · error · IllegalArgumentException

Unsupported operands for expression: {call}

Error message

Unsupported operands for expression: {call}

What it means

convertFieldAndLiteral handles predicates whose operands are a field identifier and a literal (in either order). If both operands are neither a field-name-plus-literal combination (e.g., literal-literal, identifier-identifier, or nested calls), it throws this IllegalArgumentException.

Source

Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/FilterUtils.java:333

      Schema schema) {
    SqlNode left = getLeftChild(call);
    SqlNode right = getRightChild(call);
    if (left instanceof SqlIdentifier && right instanceof SqlLiteral) {
      String caseInsensitiveName = getFieldName((SqlIdentifier) left);
      Types.NestedField field = schema.caseInsensitiveFindField(caseInsensitiveName);
      String name = schema.findColumnName(field.fieldId());
      TypeID type = field.type().typeId();
      Object value = convertLiteral((SqlLiteral) right, name, type);
      return convertLR.apply(name, value);
    } else if (left instanceof SqlLiteral && right instanceof SqlIdentifier) {
      String caseInsensitiveName = getFieldName((SqlIdentifier) right);
      Types.NestedField field = schema.caseInsensitiveFindField(caseInsensitiveName);
      String name = schema.findColumnName(field.fieldId());
      TypeID type = field.type().typeId();
      Object value = convertLiteral((SqlLiteral) left, name, type);
      return convertRL.apply(name, value);
    } else {
      throw new IllegalArgumentException("Unsupported operands for expression: " + call);
    }
  }

  private static Object convertLiteral(SqlLiteral literal, String field, TypeID type) {
    SqlTypeName typeName = literal.getTypeName();
    switch (type) {
      case BOOLEAN:
        return literal.getValueAs(Boolean.class);
      case INTEGER:
        return literal.getValueAs(Integer.class);
      case LONG:
        return literal.getValueAs(Long.class);
      case FLOAT:
        return literal.getValueAs(Float.class);
      case DOUBLE:
        return literal.getValueAs(Double.class);
      case DECIMAL:
        return literal.getValueAs(BigDecimal.class);

View on GitHub (pinned to 12126d8942)

Solutions

  1. Rewrite the predicate so one side is a column name and the other is a literal, e.g. "col = 'value'".
  2. Quote intended string literals with single quotes so they parse as SqlLiteral, not identifiers.
  3. Remove tautological or column-to-column comparisons from pushdown filters.

Example fix

// before
Expression e = FilterUtils.convert("1 = 1", schema);
// after
Expression e = FilterUtils.convert("id = 1", schema);
Defensive patterns

Strategy: validation

Validate before calling

// ensure each predicate is of form column <op> literal, e.g.
checkArgument(fieldNames.size() >= 1 && literalCount == 1, "Predicate must compare one column to one literal");

Prevention

When it happens

Trigger: Calling FilterUtils.convert with a predicate like "1 = 1", "a = b", or any expression where the operands of a comparison are not (SqlIdentifier, SqlLiteral) or (SqlLiteral, SqlIdentifier).

Common situations: Tautological filters such as "1=1" auto-generated by query builders; comparing two columns (join-style predicates) in pushdown filters; literals written as identifiers by mistake (unquoted column names intended as strings).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/6287afc0b82096ae. Report an issue: GitHub.