consistent toString functions for expressions, parentasis are added if neccessary
This commit is contained in:
@@ -20,10 +20,15 @@ public class AndExpression implements Expression {
|
||||
return Type.AND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.LOGIC_AND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return exprs.stream().map(e -> {
|
||||
if (e instanceof OrExpression) {
|
||||
if (e.getPriority().getValue() < getPriority().getValue()) {
|
||||
return "(" + e + ")";
|
||||
} else {
|
||||
return e.toString();
|
||||
|
||||
@@ -17,9 +17,31 @@ public class BinaryExpression implements Expression {
|
||||
return Type.BINARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return switch (operator) {
|
||||
case EQ, NE, IS -> Priority.EQUALITY;
|
||||
case LT, LE, GT, GE -> Priority.RELATIONAL;
|
||||
case IN -> Priority.RELATIONAL; //or equality?
|
||||
default -> throw new IllegalStateException();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return left + " " + operator + " " + right;
|
||||
String ret = "";
|
||||
if (left.getPriority().getValue() < getPriority().getValue()) {
|
||||
ret += "(" + left + ")";
|
||||
} else {
|
||||
ret += left.toString();
|
||||
}
|
||||
ret += " " + operator + " ";
|
||||
if (right.getPriority().getValue() < getPriority().getValue()) {
|
||||
ret += "(" + right + ")";
|
||||
} else {
|
||||
ret += right.toString();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -30,8 +52,10 @@ public class BinaryExpression implements Expression {
|
||||
LE("<="),
|
||||
GT(">"),
|
||||
GE(">="),
|
||||
// OR("OR"),
|
||||
// AND("AND"),
|
||||
//
|
||||
// ADD("+"),
|
||||
// SUB("-"),
|
||||
|
||||
IN("IN"),
|
||||
IS("IS"),
|
||||
;
|
||||
@@ -48,7 +72,11 @@ public class BinaryExpression implements Expression {
|
||||
LT, GE,
|
||||
GE, LT,
|
||||
LE, GT,
|
||||
GT, LE);
|
||||
GT, LE
|
||||
|
||||
// ADD, SUB,
|
||||
// SUB, ADD
|
||||
);
|
||||
|
||||
public Operator invert() {
|
||||
return INVERSION.get(this);
|
||||
|
||||
@@ -20,6 +20,11 @@ public class ConstantExpression implements Expression {
|
||||
return Type.CONSTANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.CONSTANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package jef.expressions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
public interface Expression {
|
||||
Type getType();
|
||||
|
||||
Priority getPriority();
|
||||
|
||||
public enum Type {
|
||||
AND,
|
||||
BINARY,
|
||||
@@ -17,4 +22,28 @@ public interface Expression {
|
||||
UNARY,
|
||||
WHERE,
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum Priority {
|
||||
UNDEFINED(0),
|
||||
ASSIGNMENT(1), // =, +=, -=, *=, /=
|
||||
TERNARY(2), // ? :
|
||||
LOGIC_OR(3), // ||
|
||||
LOGIC_AND(4), // &&
|
||||
BITWISE_OR(5), // |
|
||||
BITWISE_XOR(6), // ^
|
||||
BITWISE_AND(7), // &
|
||||
EQUALITY(8), // ==, !=
|
||||
RELATIONAL(9), // <, <=, =>, >
|
||||
BIT_SHIFT(10), // <<, >>
|
||||
ADD_SUB(13), // +, -
|
||||
MUL_DIV_MOD(14), // *, /, %
|
||||
UNARY_PRE(15), // +, -, !, ~, --i, ++i
|
||||
UNARY_POST(16), // i++, i--
|
||||
CONSTANT(17), // constant values
|
||||
;
|
||||
|
||||
private final int value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,19 @@ public class OrExpression implements Expression {
|
||||
return Type.OR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.LOGIC_OR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return exprs.stream().map(Expression::toString).collect(Collectors.joining(" OR "));
|
||||
return exprs.stream().map(e -> {
|
||||
if (e.getPriority().getValue() < getPriority().getValue()) {
|
||||
return "(" + e + ")";
|
||||
} else {
|
||||
return e.toString();
|
||||
}
|
||||
}).collect(Collectors.joining(" OR "));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class ParameterExpression extends ConstantExpression implements Expressio
|
||||
} else if (this.value == null) {
|
||||
return "null";
|
||||
} else if (this.value instanceof Collection) {
|
||||
return "(" + ((Collection<?>) this.value).stream().map(Objects::toString).collect(Collectors.joining(", ")) + ")";
|
||||
return "(" + ((Collection<?>) this.value).stream().map(e -> e == null ? "NULL" : Objects.toString(e)).collect(Collectors.joining(", ")) + ")";
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@ public class SelectExpression implements Expression {
|
||||
return Type.SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SELECT " + fields.stream().map(e -> e.equals("*") ? e : "`" + e + "`").collect(Collectors.joining(", ")) + " FROM "
|
||||
|
||||
@@ -15,6 +15,11 @@ public class TernaryExpression implements Expression {
|
||||
return Type.TERNARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.TERNARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IF(" + cond + ", " + whenTrue + ", " + whenFalse + ")";
|
||||
|
||||
@@ -14,12 +14,17 @@ public class UnaryExpression implements Expression {
|
||||
return Type.UNARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.UNARY_PRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (expr instanceof ConstantExpression) {
|
||||
return operator + " " + expr;
|
||||
} else {
|
||||
if (expr.getPriority().getValue() < getPriority().getValue()) {
|
||||
return operator + " (" + expr + ")";
|
||||
} else {
|
||||
return operator + " " + expr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@ public class WhereExpression implements Expression {
|
||||
return Type.WHERE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return queryable + " WHERE " + where;
|
||||
|
||||
@@ -101,6 +101,11 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
|
||||
&& b.getOperator().isInvertible()) {
|
||||
//!(a < b) -> a >= b
|
||||
return new BinaryExpression(b.getLeft(), b.getRight(), b.getOperator().invert());
|
||||
} else if (inner instanceof BinaryExpression b
|
||||
&& expr.getOperator() == UnaryExpression.Operator.NOT
|
||||
&& b.getOperator() == BinaryExpression.Operator.IS) {
|
||||
//!(a < b) -> a >= b
|
||||
return new BinaryExpression(b.getLeft(), new UnaryExpression(b.getRight(), UnaryExpression.Operator.NOT), b.getOperator());
|
||||
} else {
|
||||
return super.modifyUnary(expr);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import jef.expressions.UnaryExpression;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ExpressionOptimizer extends ExpressionModifier {
|
||||
public class ExpressionOptimizerTopDown extends ExpressionModifier {
|
||||
@Override
|
||||
public Expression modifyAnd(AndExpression expr) {
|
||||
var ands = new ArrayList<Expression>(expr.getExprs().size() * 2);
|
||||
@@ -6,7 +6,6 @@ import jef.asm.PredicateParser;
|
||||
import jef.expressions.Expression;
|
||||
import jef.expressions.SelectExpression;
|
||||
import jef.expressions.WhereExpression;
|
||||
import jef.expressions.modifier.ExpressionOptimizer;
|
||||
import jef.expressions.modifier.ExpressionOptimizerBottomUp;
|
||||
import jef.expressions.modifier.TableAliasInjector;
|
||||
import jef.expressions.modifier.TernaryRewriter;
|
||||
|
||||
Reference in New Issue
Block a user