All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliyun.odps.table.optimizer.predicate.CompoundPredicate Maven / Gradle / Ivy

The newest version!
package com.aliyun.odps.table.optimizer.predicate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableList;

/**
 * @author dingxin ([email protected])
 */
public class CompoundPredicate extends Predicate {

  public enum Operator {
    /**
     * 复合谓词运算符
     */
    AND("and"),
    OR("or"),
    NOT("not");
    private final String description;

    Operator(String description) {
      this.description = description;
    }

    public String getDescription() {
      return description;
    }
  }

  private final Operator logicalOperator;
  private final List predicates;

  public CompoundPredicate(Operator logicalOperator) {
    this(logicalOperator, new ArrayList<>());
  }

  public CompoundPredicate(Operator logicalOperator, List predicates) {
    super(PredicateType.COMPOUND);
    this.logicalOperator = logicalOperator;
    this.predicates = predicates;
    if (logicalOperator == Operator.NOT && predicates.size() > 1) {
      throw new IllegalArgumentException("NOT operator should only have one operand");
    }
  }

  public static CompoundPredicate and(Predicate... predicates) {
    return new CompoundPredicate(Operator.AND,
                                 Arrays.stream(predicates).collect(Collectors.toList()));
  }

  public static CompoundPredicate or(Predicate... predicates) {
    return new CompoundPredicate(Operator.OR,
                                 Arrays.stream(predicates).collect(Collectors.toList()));
  }

  public static CompoundPredicate not(Predicate predicates) {
    return new CompoundPredicate(Operator.NOT, ImmutableList.of(predicates));
  }

  public void addPredicate(Predicate predicate) {
    predicates.add(predicate);
  }

  @Override
  public String toString() {
    if (predicates.isEmpty()) {
      return Predicate.NO_PREDICATE.toString();
    }

    String opStr = logicalOperator.getDescription();
    StringBuilder sb = new StringBuilder();

    // 对于 NOT 运算符,我们确保只有一个操作数
    if (logicalOperator == Operator.NOT) {
      Predicate predicate = predicates.get(0);
      if (!validatePredicate(predicate)) {
        return Predicate.NO_PREDICATE.toString();
      }
      sb.append(opStr).append(" ");
      if (predicate instanceof CompoundPredicate) {
        sb.append('(').append(predicate).append(')');
      } else {
        sb.append(predicate.toString());
      }
      return sb.toString();
    }

    for (int i = 0; i < predicates.size(); i++) {
      Predicate currentPredicate = predicates.get(i);
      if (!validatePredicate(currentPredicate)) {
        if (logicalOperator == Operator.OR) {
          // A or true = true
          // 对于 or 谓词,如果有任意谓词是 true,则结果为 true
          return Predicate.NO_PREDICATE.toString();
        } else {
          // A and true = A
          // 对于 and 谓词,跳过子谓词为 true 的谓词
          continue;
        }
      }
      if (sb.length() != 0) {
        sb.append(" ").append(opStr).append(" ");
      }
      if (currentPredicate instanceof CompoundPredicate
          && ((CompoundPredicate) currentPredicate).logicalOperator != this.logicalOperator) {
        sb.append('(').append(currentPredicate).append(')');
      } else {
        sb.append(currentPredicate.toString());
      }
    }
    return sb.toString();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy