{"record":{"id":"9635f879ac59145b","repo":"apache/iceberg","slug":"cannot-convert-to-parquet-filter-pred","errorCode":null,"errorMessage":"Cannot convert to Parquet filter: <pred>","messagePattern":"Cannot convert to Parquet filter: <pred>","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetFilters.java","lineNumber":127,"sourceCode":"    }\n\n    @Override\n    public <T> FilterPredicate predicate(BoundPredicate<T> pred) {\n      if (!(pred.term() instanceof BoundReference)) {\n        throw new UnsupportedOperationException(\n            \"Cannot convert non-reference to Parquet filter: \" + pred.term());\n      }\n\n      Operation op = pred.op();\n      BoundReference<T> ref = (BoundReference<T>) pred.term();\n      String path = schema.idToAlias(ref.fieldId());\n      Literal<T> lit;\n      if (pred.isUnaryPredicate()) {\n        lit = null;\n      } else if (pred.isLiteralPredicate()) {\n        lit = pred.asLiteralPredicate().literal();\n      } else {\n        throw new UnsupportedOperationException(\"Cannot convert to Parquet filter: \" + pred);\n      }\n\n      switch (ref.type().typeId()) {\n        case BOOLEAN:\n          Operators.BooleanColumn col = FilterApi.booleanColumn(path);\n          switch (op) {\n            case EQ:\n              return FilterApi.eq(col, getParquetPrimitive(lit));\n            case NOT_EQ:\n              return FilterApi.notEq(col, getParquetPrimitive(lit));\n          }\n          break;\n        case INTEGER:\n        case DATE:\n          return pred(op, FilterApi.intColumn(path), getParquetPrimitive(lit));\n        case LONG:\n        case TIME:\n        case TIMESTAMP:","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetFilters.java#L109-L145","documentation":"Thrown when a bound predicate is neither a unary predicate (no literal) nor a literal predicate, so the translator cannot extract a Parquet Literal to build the FilterPredicate. Only unary ops (is-null/not-null) and literal comparisons are convertible; other bound predicate kinds are not.","triggerScenarios":"Pushing predicates with complex/transformed terms or non-literal predicate kinds into this translator's predicate(BoundPredicate) method.","commonSituations":"Custom expression trees; engine versions generating new predicate kinds the translator predates; filters built programmatically with unusual ops.","solutions":["Restrict pushdown to simple literal/unary predicates on primitive columns; filter the expression tree before calling the translator.","Rewrite unsupported predicates into supported equivalents at planning time.","Upgrade Iceberg for broader predicate coverage."],"exampleFix":"// before\npushdown(customNonLiteralPredicate(\"col\")); // non-convertible\n// after\npushdown(Expressions.notNull(\"col\")); // unary predicate, convertible","handlingStrategy":"validation","validationCode":"if (!(pred.isUnaryPredicate() || pred.isLiteralPredicate())) {\n  // leave for record-level evaluation; do not push down\n}","typeGuard":"boolean convertible(BoundPredicate<?> pred) {\n  return pred.isUnaryPredicate() || pred.isLiteralPredicate();\n}","tryCatchPattern":"try {\n  FilterPredicate fp = parquetFilters.predicate(pred);\n} catch (UnsupportedOperationException e) {\n  LOG.debug(\"Skip pushdown: {}\", e.getMessage());\n  return null; // evaluate rows instead\n}","preventionTips":["Push only is-null/not-null and literal comparisons (eq, lt, lte, gt, gte, in, notIn, startsWith).","Avoid pushing user-supplied custom predicates blindly.","Update Iceberg when engines introduce new predicate kinds."],"tags":["parquet","pushdown","filter","predicate"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}