package net.sourceforge.mayfly.evaluation.expression; import net.sourceforge.mayfly.datastore.Cell; import net.sourceforge.mayfly.datastore.NullCell; import net.sourceforge.mayfly.evaluation.Expression; import net.sourceforge.mayfly.evaluation.ResultRow; import net.sourceforge.mayfly.evaluation.ResultRows; import net.sourceforge.mayfly.evaluation.select.Evaluator; abstract public class BinaryOperator extends Expression { protected final Expression left; protected final Expression right; protected BinaryOperator(Expression left, Expression right) { super(left.location.combine(right.location)); this.left = left; this.right = right; } @Override public Cell evaluate(ResultRow row, Evaluator evaluator) { Cell leftCell = left.evaluate(row, evaluator); Cell rightCell = right.evaluate(row, evaluator); return combineCellsOrNulls(leftCell, rightCell); } @Override public Cell aggregate(ResultRows rows) { Cell leftCell = left.aggregate(rows); Cell rightCell = right.aggregate(rows); return combineCellsOrNulls(leftCell, rightCell); } private Cell combineCellsOrNulls(Cell leftCell, Cell rightCell) { if (leftCell instanceof NullCell) { return leftCell; } if (rightCell instanceof NullCell) { return rightCell; } return combine(leftCell, rightCell); } abstract protected Cell combine(Cell left, Cell right); @Override public String firstColumn() { String firstInLeft = left.firstColumn(); if (firstInLeft != null) { return firstInLeft; } return right.firstColumn(); } @Override public String firstAggregate() { return Expression.firstAggregate(left, right); } @Override public String displayName() { // Hard to get precedence and associativity right. // And we probably want to show the users's whitespace anyway(?). return "expression"; } @Override public boolean sameExpression(Expression other) { if (getClass().equals(other.getClass())) { BinaryOperator operator = (BinaryOperator) other; return left.sameExpression(operator.left) && right.sameExpression(operator.right); } else { return false; } } @Override public abstract Expression resolve(ResultRow row, Evaluator evaluator); @Override public void check(ResultRow row) { left.check(row); right.check(row); } public Expression left() { return left; } public Expression right() { return right; } }