rdblue commented on code in PR #4938:
URL: https://github.com/apache/iceberg/pull/4938#discussion_r895214802


##########
api/src/main/java/org/apache/iceberg/expressions/Binder.java:
##########
@@ -96,7 +96,15 @@ public static Set<Integer> boundReferences(StructType 
struct, List<Expression> e
     }
     ReferenceVisitor visitor = new ReferenceVisitor();
     for (Expression expr : exprs) {
-      ExpressionVisitors.visit(bind(struct, expr, caseSensitive), visitor);
+      try {
+        ExpressionVisitors.visit(bind(struct, expr, caseSensitive), visitor);
+      } catch (IllegalStateException e) {
+        if (e.getMessage().contains("Found already bound predicate")) {

Review Comment:
   We shouldn't rely on exception messages like this.
   
   I think instead we should just add a utility to detect whether an expression 
is bound. Here's an implementation:
   
   ```java
     /**
      * Returns whether an expression is bound.
      * <p>
      * An expression is bound if all of its predicates are bound.
      *
      * @param expr an {@link Expression}
      * @return true if the expression is bound
      * @throws IllegalArgumentException if the expression has both bound and 
unbound predicates.
      */
     public static boolean isBound(Expression expr) {
       Boolean isBound = ExpressionVisitors.visit(expr, new IsBoundVisitor());
       return isBound != null ? isBound : false; // assume unbound if 
undetermined
     }
   
     private static class IsBoundVisitor extends 
ExpressionVisitors.ExpressionVisitor<Boolean> {
       @Override
       public Boolean not(Boolean result) {
         return result;
       }
   
       @Override
       public Boolean and(Boolean leftResult, Boolean rightResult) {
         return combineResults(leftResult, rightResult);
       }
   
       @Override
       public Boolean or(Boolean leftResult, Boolean rightResult) {
         return combineResults(leftResult, rightResult);
       }
   
       @Override
       public <T> Boolean predicate(BoundPredicate<T> pred) {
         return true;
       }
   
       @Override
       public <T> Boolean predicate(UnboundPredicate<T> pred) {
         return false;
       }
   
       private Boolean combineResults(Boolean isLeftBound, Boolean 
isRightBound) {
         if (isLeftBound != null) {
           Preconditions.checkArgument(isRightBound == null || 
isLeftBound.equals(isRightBound),
               "Found partially bound expression");
           return isLeftBound;
         } else {
           return isRightBound;
         }
       }
     }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to