{"record":{"id":"b0bd3727d13f1365","repo":"apache/iceberg","slug":"cannot-convert-term-to-sql-s","errorCode":null,"errorMessage":"Cannot convert term to SQL: %s","messagePattern":"Cannot convert term to SQL: (.+?)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java","lineNumber":693,"sourceCode":"        case NOT_STARTS_WITH:\n          return sqlString(pred.term()) + \" NOT LIKE '\" + pred.literal().value() + \"%'\";\n        case IN:\n          return sqlString(pred.term()) + \" IN (\" + sqlString(pred.literals()) + \")\";\n        case NOT_IN:\n          return sqlString(pred.term()) + \" NOT IN (\" + sqlString(pred.literals()) + \")\";\n        default:\n          throw new UnsupportedOperationException(\"Cannot convert predicate to SQL: \" + pred);\n      }\n    }\n\n    private static <T> String sqlString(UnboundTerm<T> term) {\n      if (term instanceof org.apache.iceberg.expressions.NamedReference) {\n        return term.ref().name();\n      } else if (term instanceof UnboundTransform) {\n        UnboundTransform<?, ?> transform = (UnboundTransform<?, ?>) term;\n        return transform.transform().toString() + \"(\" + transform.ref().name() + \")\";\n      } else {\n        throw new UnsupportedOperationException(\"Cannot convert term to SQL: \" + term);\n      }\n    }\n\n    private static <T> String sqlString(List<org.apache.iceberg.expressions.Literal<T>> literals) {\n      return literals.stream()\n          .map(DescribeExpressionVisitor::sqlString)\n          .collect(Collectors.joining(\", \"));\n    }\n\n    private static String sqlString(org.apache.iceberg.expressions.Literal<?> lit) {\n      if (lit.value() instanceof String) {\n        return \"'\" + lit.value() + \"'\";\n      } else if (lit.value() instanceof ByteBuffer) {\n        byte[] bytes = ByteBuffers.toByteArray((ByteBuffer) lit.value());\n        return \"X'\" + BaseEncoding.base16().encode(bytes) + \"'\";\n      } else {\n        return lit.value().toString();\n      }","sourceCodeStart":675,"sourceCodeEnd":711,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java#L675-L711","documentation":"sqlString in DescribeExpressionVisitor renders only NamedReference and UnboundTransform terms; any other UnboundTerm (e.g. a constant/extract term) throws UnsupportedOperationException because it has no direct SQL rendering.","triggerScenarios":"Calling Spark3Util.describe on a predicate whose term is neither a plain column reference nor a transform, e.g. predicates built over Literal references or other exotic terms.","commonSituations":"Programmatically constructed expressions with unusual terms being pretty-printed to SQL for catalog partition predicates or metadata filters.","solutions":["Restrict predicates to column or transform terms before describing","Catch UnsupportedOperationException and fall back to a generic string rendering of the expression","Extend the visitor (fork or newer version) to handle the specific term type"],"exampleFix":"// before\nthrow new UnsupportedOperationException(\"Cannot convert term to SQL: \" + term);\n// after\n} else if (term instanceof UnboundExtract) {\n  UnboundExtract<?> extract = (UnboundExtract<?>) term;\n  return \"extract(\" + extract.ref().name() + \")\";\n} else {\n  throw new UnsupportedOperationException(\"Cannot convert term to SQL: \" + term);\n}","handlingStrategy":"try-catch","validationCode":"boolean ok = term instanceof NamedReference || term instanceof UnboundTransform;","typeGuard":"boolean isRenderableTerm(UnboundTerm<?> t) { return t instanceof NamedReference || t instanceof UnboundTransform; }","tryCatchPattern":"try { return Spark3Util.describe(expr); } catch (UnsupportedOperationException e) { return expr.toString(); }","preventionTips":["Build filter predicates only on column references or transforms","Avoid literal/extract terms when SQL rendering is required","Write a custom ExpressionVisitor if richer term rendering is needed"],"tags":["spark","expressions","sql"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}