{"record":{"id":"ead618cfbd8d9e4f","repo":"apache/iceberg","slug":"unsupported-predicate-operation-op","errorCode":null,"errorMessage":"Unsupported predicate operation: <op>","messagePattern":"Unsupported predicate operation: <op>","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetFilters.java","lineNumber":214,"sourceCode":"        } else if (col.getColumnType().equals(Float.class)) {\n          return FilterApi.notEq(col, (C) (Float) Float.NaN);\n        } else {\n          return AlwaysTrue.INSTANCE;\n        }\n      case EQ:\n        return FilterApi.eq(col, value);\n      case NOT_EQ:\n        return FilterApi.notEq(col, value);\n      case GT:\n        return FilterApi.gt(col, value);\n      case GT_EQ:\n        return FilterApi.gtEq(col, value);\n      case LT:\n        return FilterApi.lt(col, value);\n      case LT_EQ:\n        return FilterApi.ltEq(col, value);\n      default:\n        throw new UnsupportedOperationException(\"Unsupported predicate operation: \" + op);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static <C extends Comparable<C>> C getParquetPrimitive(Literal<?> lit) {\n    if (lit == null) {\n      return null;\n    }\n\n    // TODO: this needs to convert to handle BigDecimal and UUID\n    Object value = lit.value();\n    if (value instanceof Number) {\n      return (C) lit.value();\n    } else if (value instanceof CharSequence) {\n      return (C) Binary.fromString(value.toString());\n    } else if (value instanceof ByteBuffer) {\n      return (C) Binary.fromReusedByteBuffer((ByteBuffer) value);\n    }","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetFilters.java#L196-L232","documentation":"The private pred() helper maps a bound predicate operation (EQ, NOT_EQ, GT, GT_EQ, LT, LT_EQ) to the corresponding Parquet FilterApi call. Any other operation reaching the default branch is rejected with this UnsupportedOperationException. It is a guard against operations the Parquet column-index filter API cannot express.","triggerScenarios":"Calling ParquetFilters.predicate() with a bound predicate whose operation is not one of EQ, NOT_EQ, GT, GT_EQ, LT, LT_EQ — e.g. STARTS_WITH, IN, or IS_NULL bound predicates that reach the pred() helper.","commonSituations":"Pushing down string startsWith filters, IN-list filters, or null checks on a Parquet scan; using expression types from a newer Iceberg version with an older converter.","solutions":["Use only comparison operators (==, !=, <, <=, >, >=) in expressions intended for Parquet pushdown","Rewrite IN as an OR of equalities, or handle the predicate client-side instead of pushdown","Catch UnsupportedOperationException and skip pushdown for that filter"],"exampleFix":"// before\nExpression e = Expressions.startsWith(\"name\", \"A\");\nFilterPredicate p = ParquetFilters.predicate(binder.bind(schema, e)); // throws\n// after\nExpression e = Expressions.equal(\"name\", \"Alice\");\nFilterPredicate p = ParquetFilters.predicate(binder.bind(schema, e));","handlingStrategy":"validation","validationCode":"switch (pred.op()) {\n  case EQ: case NOT_EQ: case GT: case GT_EQ: case LT: case LT_EQ: break;\n  default: throw new IllegalArgumentException(\"Not Parquet-pushdownable: \" + pred.op());\n}","typeGuard":null,"tryCatchPattern":"try {\n  FilterPredicate p = ParquetFilters.predicate(bound);\n} catch (UnsupportedOperationException e) {\n  logger.warn(\"Skipping pushdown: {}\", e.getMessage());\n}","preventionTips":["Use only =, !=, <, <=, >, >= for Parquet pushdown","Handle IN/startsWith/null checks outside pushdown"],"tags":["parquet","predicate-pushdown","unsupported-operation"],"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"}