Пример #1
0
  static void equate(Generator gen, Expression expr, QFrame left, QFrame right) {
    Expression lexpr = left.getExpression();
    Expression rexpr = right.getExpression();

    List lvals = left.getValues();
    List rvals = right.getValues();

    List lnull = gen.getNull(lexpr);
    List rnull = gen.getNull(rexpr);

    if (lvals.size() != rvals.size()) {
      if (lvals.size() == 1 && lnull.containsAll(lvals)) {
        lvals = repeat(lvals.get(0), rvals.size());
      } else if (rvals.size() == 1 && rnull.containsAll(rvals)) {
        rvals = repeat(rvals.get(0), lvals.size());
      } else {
        throw new IllegalStateException(
            "cardinality mismatch\nlvals: "
                + lvals
                + "\nrvals: "
                + rvals
                + "\nleft: "
                + lexpr
                + "\nright: "
                + rexpr);
      }
    }

    List lnonnull = gen.getNonNull(lexpr);
    List rnonnull = gen.getNonNull(rexpr);

    for (int i = 0; i < lvals.size(); i++) {
      QValue lval = (QValue) lvals.get(i);
      QValue rval = (QValue) rvals.get(i);
      gen.addEquality(expr, lval, rval);
      if (lnull.contains(lval)) {
        gen.addNull(expr, rval);
      }
      if (lnonnull.contains(lval)) {
        gen.addNonNull(expr, rval);
      }
      if (rnull.contains(rval)) {
        gen.addNull(expr, lval);
      }
      if (rnonnull.contains(rval)) {
        gen.addNonNull(expr, lval);
      }
    }

    gen.addSufficient(expr);
  }
Пример #2
0
  static Code emit(Generator gen, Expression lexpr, Expression rexpr) {
    if (gen.hasFrame(lexpr) && gen.hasFrame(rexpr)) {
      QFrame lframe = gen.getFrame(lexpr);
      QFrame rframe = gen.getFrame(rexpr);
      if (!lframe.isSelect() && !rframe.isSelect()) {
        List lvals = lframe.getValues();
        List rvals = rframe.getValues();
        List lnull = gen.getNull(lexpr);
        List rnull = gen.getNull(rexpr);
        if (lvals.size() != rvals.size()) {
          if (lvals.size() == 1 && lnull.containsAll(lvals)) {
            lvals = repeat(lvals.get(0), rvals.size());
          } else if (rvals.size() == 1 && rnull.containsAll(rvals)) {
            rvals = repeat(rvals.get(0), lvals.size());
          } else {
            throw new IllegalStateException("signature missmatch: " + lvals + ", " + rvals);
          }
        }
        List conds = new ArrayList();
        for (int i = 0; i < lvals.size(); i++) {
          QValue l = (QValue) lvals.get(i);
          QValue r = (QValue) rvals.get(i);
          Code lsql = l.emit();
          Code rsql = r.emit();
          if (lsql.isNull()) {
            if (!r.isNullable()) {
              return Code.FALSE;
            }
          } else if (rsql.isNull()) {
            if (!l.isNullable()) {
              return Code.FALSE;
            }
          }

          if (!lsql.equals(rsql)) {
            conds.add(emit(lsql, null, rsql, null));
          }
        }
        if (conds.isEmpty()) {
          return Code.TRUE;
        } else {
          return Code.join(conds, " and ");
        }
      }
    }

    // XXX: we can to do something smarter than this for
    // multi column selects
    Code lsql = lexpr.emit(gen);
    Code rsql = rexpr.emit(gen);

    // we need the isEmpty test because we don't want to eliminate
    // redundent bind var comparison the first time a query is
    // cached since the sql may not be redundent for subsequent
    // query executions

    if (lsql.getBindings().isEmpty() && lsql.equals(rsql)) {
      return Code.TRUE;
    } else {
      return emit(lsql, lexpr, rsql, rexpr);
    }
  }