KuduPredicate merge()

in java/kudu-client/src/main/java/org/apache/kudu/client/KuduPredicate.java [721:813]


  KuduPredicate merge(KuduPredicate other) {
    Preconditions.checkArgument(column.equals(other.column),
                                "predicates from different columns may not be merged");

    // First, consider other.type == NONE, IS_NOT_NULL, or IS_NULL
    // NONE predicates dominate.
    if (other.type == PredicateType.NONE) {
      return other;
    }

    // NOT NULL is dominated by all other predicates,
    // except IS NULL, for which the merge is NONE.
    if (other.type == PredicateType.IS_NOT_NULL) {
      return type == PredicateType.IS_NULL ? none(column) : this;
    }

    // NULL merged with any predicate type besides itself is NONE.
    if (other.type == PredicateType.IS_NULL) {
      return type == PredicateType.IS_NULL ? this : none(column);
    }

    // Now other.type == EQUALITY, RANGE, or IN_LIST.
    switch (type) {
      case NONE: return this;
      case IS_NOT_NULL: return other;
      case IS_NULL: return none(column);
      case EQUALITY: {
        if (other.type == PredicateType.EQUALITY) {
          if (compare(column, lower, other.lower) != 0) {
            return none(this.column);
          } else {
            return this;
          }
        } else if (other.type == PredicateType.RANGE) {
          if (other.rangeContains(lower)) {
            return this;
          } else {
            return none(this.column);
          }
        } else {
          Preconditions.checkState(other.type == PredicateType.IN_LIST);
          return other.merge(this);
        }
      }
      case RANGE: {
        if (other.type == PredicateType.EQUALITY || other.type == PredicateType.IN_LIST) {
          return other.merge(this);
        } else {
          Preconditions.checkState(other.type == PredicateType.RANGE);
          byte[] newLower = other.lower == null ||
              (lower != null && compare(column, lower, other.lower) >= 0) ? lower : other.lower;
          byte[] newUpper = other.upper == null ||
              (upper != null && compare(column, upper, other.upper) <= 0) ? upper : other.upper;
          if (newLower != null && newUpper != null && compare(column, newLower, newUpper) >= 0) {
            return none(column);
          } else {
            if (newLower != null && newUpper != null && areConsecutive(newLower, newUpper)) {
              return new KuduPredicate(PredicateType.EQUALITY, column, newLower, null);
            } else {
              return new KuduPredicate(PredicateType.RANGE, column, newLower, newUpper);
            }
          }
        }
      }
      case IN_LIST: {
        if (other.type == PredicateType.EQUALITY) {
          if (this.inListContains(other.lower)) {
            return other;
          } else {
            return none(column);
          }
        } else if (other.type == PredicateType.RANGE) {
          List<byte[]> values = new ArrayList<>();
          for (byte[] value : inListValues) {
            if (other.rangeContains(value)) {
              values.add(value);
            }
          }
          return buildInList(column, values);
        } else {
          Preconditions.checkState(other.type == PredicateType.IN_LIST);
          List<byte[]> values = new ArrayList<>();
          for (byte[] value : inListValues) {
            if (other.inListContains(value)) {
              values.add(value);
            }
          }
          return buildInList(column, values);
        }
      }
      default: throw new IllegalStateException(String.format("unknown predicate type %s", this));
    }
  }