@Override
  public void analyze(Analyzer analyzer) throws AnalysisException {
    if (isAnalyzed_) return;
    super.analyze(analyzer);
    analyzer.castAllToCompatibleType(originalChildren_);

    // TODO: improve with histograms
    selectivity_ = Expr.DEFAULT_SELECTIVITY;

    // Rewrite between predicate into a conjunctive/disjunctive compound predicate.
    if (isNotBetween_) {
      // Rewrite into disjunction.
      Predicate lower =
          new BinaryPredicate(
              BinaryPredicate.Operator.LT, originalChildren_.get(0), originalChildren_.get(1));
      Predicate upper =
          new BinaryPredicate(
              BinaryPredicate.Operator.GT, originalChildren_.get(0), originalChildren_.get(2));
      rewrittenPredicate_ = new CompoundPredicate(CompoundPredicate.Operator.OR, lower, upper);
    } else {
      // Rewrite into conjunction.
      Predicate lower =
          new BinaryPredicate(
              BinaryPredicate.Operator.GE, originalChildren_.get(0), originalChildren_.get(1));
      Predicate upper =
          new BinaryPredicate(
              BinaryPredicate.Operator.LE, originalChildren_.get(0), originalChildren_.get(2));
      rewrittenPredicate_ = new CompoundPredicate(CompoundPredicate.Operator.AND, lower, upper);
    }

    try {
      rewrittenPredicate_.analyze(analyzer);
      fn_ = rewrittenPredicate_.fn_;
    } catch (AnalysisException e) {
      // We should have already guaranteed that analysis will succeed.
      Preconditions.checkState(false, "Analysis failed in rewritten between predicate");
    }

    // Make sure toThrift() picks up the children of the rewritten predicate.
    children_ = rewrittenPredicate_.getChildren();
  }
 @Override
 protected void toThrift(TExprNode msg) {
   rewrittenPredicate_.toThrift(msg);
 }
 @Override
 public List<Expr> getConjuncts() {
   return rewrittenPredicate_.getConjuncts();
 }