void frame(Generator gen) { super.frame(gen); if (!gen.hasFrame(m_left) || !gen.hasFrame(m_right)) { return; } QFrame left = gen.getFrame(m_left); QFrame right = gen.getFrame(m_right); equate(gen, this, left, right); }
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); } }