apache/iceberg · error · UnsupportedOperationException

Cannot convert term to SQL:

Error message

Cannot convert term to SQL: 

What it means

DescribeExpressionVisitor.sqlString(UnboundTerm) renders a predicate term as SQL: a NamedReference renders as its column name and an UnboundTransform as transform(col). Any other term (e.g. AccessorReference or bound terms) throws UnsupportedOperationException 'Cannot convert term to SQL'.

Solutions

  1. Use predicates over top-level columns or unbound transforms so terms render as ref or transform(col)
  2. Extend the visitor (or write a custom ExpressionVisitor) if nested/marshalled term rendering is required
  3. Flatten nested-field predicates into a supported form before rendering

Example fix

// before
sqlString(customTerm) // throws
// after
if (term instanceof NamedReference || term instanceof UnboundTransform) {
  sqlString(term);
} else {
  throw new IllegalArgumentException("Unsupported term: " + term);
}
Defensive patterns

Strategy: type-guard

Validate before calling

boolean ok = term instanceof org.apache.iceberg.expressions.NamedReference
    || term instanceof org.apache.iceberg.expressions.UnboundTransform;
if (!ok) throw new IllegalArgumentException("Term not renderable as SQL: " + term);

Type guard

boolean isRenderableTerm(org.apache.iceberg.expressions.Term t) {
  return t instanceof org.apache.iceberg.expressions.NamedReference
      || t instanceof org.apache.iceberg.expressions.UnboundTransform;
}

Try / catch

try {
  return sqlString(term);
} catch (UnsupportedOperationException e) {
  return term.toString();
}

Prevention

When it happens

Trigger: Rendering an Iceberg predicate whose term is not a plain column reference or unbound transform — e.g. terms built over struct accessors or custom term implementations passed into the describe visitor.

Common situations: DESCRIBE output for filters on nested fields or exotic terms; tooling that feeds arbitrary UnboundTerm objects into Spark3Util's describe path.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/c08f2c534c4256c4. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:697

        case NOT_STARTS_WITH:
          return sqlString(pred.term()) + " NOT LIKE '" + pred.literal().value() + "%'";
        case IN:
          return sqlString(pred.term()) + " IN (" + sqlString(pred.literals()) + ")";
        case NOT_IN:
          return sqlString(pred.term()) + " NOT IN (" + sqlString(pred.literals()) + ")";
        default:
          throw new UnsupportedOperationException("Cannot convert predicate to SQL: " + pred);
      }
    }

    private static <T> String sqlString(UnboundTerm<T> term) {
      if (term instanceof org.apache.iceberg.expressions.NamedReference) {
        return term.ref().name();
      } else if (term instanceof UnboundTransform) {
        UnboundTransform<?, ?> transform = (UnboundTransform<?, ?>) term;
        return transform.transform().toString() + "(" + transform.ref().name() + ")";
      } else {
        throw new UnsupportedOperationException("Cannot convert term to SQL: " + term);
      }
    }

    private static <T> String sqlString(List<org.apache.iceberg.expressions.Literal<T>> literals) {
      return literals.stream()
          .map(DescribeExpressionVisitor::sqlString)
          .collect(Collectors.joining(", "));
    }

    private static String sqlString(org.apache.iceberg.expressions.Literal<?> lit) {
      if (lit.value() instanceof String) {
        return "'" + lit.value() + "'";
      } else if (lit.value() instanceof ByteBuffer) {
        byte[] bytes = ByteBuffers.toByteArray((ByteBuffer) lit.value());
        return "X'" + BaseEncoding.base16().encode(bytes) + "'";
      } else {
        return lit.value().toString();
      }

View on GitHub (pinned to 86d9c8fc54)