{"record":{"id":"d52059f7a77c5016","repo":"apache/iceberg","slug":"notin-expression-is-not-supported-by-the-visitor","errorCode":null,"errorMessage":"notIn expression is not supported by the visitor","messagePattern":"notIn expression is not supported by the visitor","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/ExpressionVisitors.java","lineNumber":116,"sourceCode":"\n    public <T> R gtEq(BoundReference<T> ref, Literal<T> lit) {\n      return null;\n    }\n\n    public <T> R eq(BoundReference<T> ref, Literal<T> lit) {\n      return null;\n    }\n\n    public <T> R notEq(BoundReference<T> ref, Literal<T> lit) {\n      return null;\n    }\n\n    public <T> R in(BoundReference<T> ref, Set<T> literalSet) {\n      throw new UnsupportedOperationException(\"In expression is not supported by the visitor\");\n    }\n\n    public <T> R notIn(BoundReference<T> ref, Set<T> literalSet) {\n      throw new UnsupportedOperationException(\"notIn expression is not supported by the visitor\");\n    }\n\n    public <T> R startsWith(BoundReference<T> ref, Literal<T> lit) {\n      throw new UnsupportedOperationException(\n          \"startsWith expression is not supported by the visitor\");\n    }\n\n    public <T> R notStartsWith(BoundReference<T> ref, Literal<T> lit) {\n      throw new UnsupportedOperationException(\n          \"notStartsWith expression is not supported by the visitor\");\n    }\n\n    /**\n     * Handle a non-reference value in this visitor.\n     *\n     * <p>Visitors that require {@link BoundReference references} and not {@link Bound terms} can\n     * use this method to return a default value for expressions with non-references. The default\n     * implementation will throw a validation exception because the non-reference is not supported.","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/ExpressionVisitors.java#L98-L134","documentation":"The base visitor's default notIn(BoundReference, Set) throws UnsupportedOperationException, marking NOT IN predicates as unsupported unless the visitor opts in. Thrown when visiting an expression containing notIn without an override.","triggerScenarios":"Visiting an expression containing notIn(col, values) (e.g. filter \"col NOT IN (...)\") with a visitor that does not override notIn(BoundReference<T>, Set<T>).","commonSituations":"Custom predicate translators or evaluators built before notIn was added to the visitor API encountering newer filters from engines.","solutions":["Override notIn(BoundReference<T>, Set<T>) in the visitor (typically as NOT of the in() result)","Rewrite the expression (e.g. via Expressions.rewriteNot) so notIn is decomposed into supported predicates","Upgrade the evaluator implementation to one supporting notIn"],"exampleFix":"// before\n// no override -> default throws\n// after\n@Override\npublic <T> R notIn(BoundReference<T> ref, Set<T> literalSet) {\n  return not(inResult(ref, literalSet));\n}","handlingStrategy":"try-catch","validationCode":"boolean hasNotIn = exprOpScan(expr, op -> op == Expression.Operation.NOT_IN);","typeGuard":"static boolean isNotInPredicate(Predicate p) { return p.op() == Expression.Operation.NOT_IN; }","tryCatchPattern":"try {\n  return visitor.notIn(ref, literalSet);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"notIn expression is not supported\")) {\n    return not(visitor.in(ref, literalSet));\n  }\n  throw e;\n}","preventionTips":["Override notIn() whenever you override in()","Apply Expressions.rewriteNot to push NOT operators down before visiting","Test custom visitors with NOT IN filters from engine pushdown"],"tags":["java","expressions","visitor","notin-predicate"],"backgroundTag":"method-not-implemented","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"}