fix queries with 'WHERE field == 0' so that they are not represented as 'WHERE NOT field'

This commit is contained in:
wea_ondara
2022-07-14 18:06:39 +02:00
parent eee94e9c45
commit 4bee1e28e4
6 changed files with 42 additions and 17 deletions

View File

@@ -61,15 +61,12 @@ class FilterMethodVisitor extends MethodVisitor {
System.out.println("field insn: " + ops.getOrDefault(opcode, "" + opcode) + ", " + owner + ", " + name + ", " + descriptor);
if (opcode == Opcodes.GETFIELD) {
var v = varStack.pop();
if (v instanceof ParameterExpression) {
// if (((Expression.ParameterExpression) v).isInput()) {
// varStack.push(new Expression.ConstantExpression(name));
// } else {
System.out.println("womp womp " + v);
throw new RuntimeException("field insn: unsupported GETFIELD op");
// }
} else if (v instanceof ConstantExpression) {
varStack.push(new FieldExpression(name));
if (v instanceof ParameterExpression p) {
if (p.isInput()) {
varStack.push(new FieldExpression(name, descriptor));
} else {
throw new RuntimeException("field insn: unsupported GETFIELD expression");
}
} else {
throw new RuntimeException("field insn: unsupported GETFIELD op");
}
@@ -117,11 +114,8 @@ class FilterMethodVisitor extends MethodVisitor {
public void visitVarInsn(int opcode, int varIndex) {
System.out.println("var insn: " + ops.getOrDefault(opcode, "" + opcode) + ", " + varIndex);
if (opcode == Opcodes.ALOAD) {
if (varIndex == parameterClasses.length - 1) {
varStack.push(new ConstantExpression("predicate param"));
} else {
varStack.push(new ParameterExpression(varIndex, args[varIndex], varIndex == parameterClasses.length - 1));
}
var value = varIndex == parameterClasses.length - 1 ? null : args[varIndex];
varStack.push(new ParameterExpression(varIndex, value, varIndex == parameterClasses.length - 1, parameterClasses[varIndex]));
} else {
throw new RuntimeException("var insn: unsupported opcode " + ops.getOrDefault(opcode, "" + opcode));
}

View File

@@ -5,10 +5,12 @@ import lombok.Getter;
@Getter
public class FieldExpression extends ConstantExpression implements Expression {
private final String name;
private final String classDescriptor;
public FieldExpression(String name) {
public FieldExpression(String name, String classDescriptor) {
super(name);
this.name = name;
this.classDescriptor = classDescriptor;
}
@Override

View File

@@ -10,11 +10,13 @@ import java.util.stream.Collectors;
public class ParameterExpression extends ConstantExpression implements Expression {
private final int index;
private final boolean isInput;
private final String classDescriptor;
public ParameterExpression(int index, Object value, boolean isInput) {
public ParameterExpression(int index, Object value, boolean isInput, String classDescriptor) {
super(value);
this.index = index;
this.isInput = isInput;
this.classDescriptor = classDescriptor;
}
@Override

View File

@@ -0,0 +1,24 @@
package jef.expressions.modifier;
import jef.expressions.BinaryExpression;
import jef.expressions.ConstantExpression;
import jef.expressions.Expression;
import jef.expressions.FieldExpression;
import jef.expressions.UnaryExpression;
import java.util.Set;
public class IConst0Fixer extends ExpressionModifier {
private static final Set<String> DESCRIPTORS = Set.of("I", "F", "D", "L",
"Ljava/lang/Integer;", "Ljava/lang/Float;", "Ljava/lang/Double;", "Ljava/lang/Long;");
@Override
public Expression modifyUnary(UnaryExpression expr) {
if (expr.getOperator() == UnaryExpression.Operator.NOT
&& expr.getExpr().getType() == Expression.Type.FIELD
&& DESCRIPTORS.contains(((FieldExpression) expr.getExpr()).getClassDescriptor())) {
return modify(new BinaryExpression(expr.getExpr(), ConstantExpression.V0, BinaryExpression.Operator.EQ));
}
return super.modifyUnary(expr);
}
}

View File

@@ -14,6 +14,6 @@ public class TableAliasInjector extends ExpressionModifier {
@Override
public Expression modifyField(FieldExpression expr) {
return new FieldExpression(prefix + expr.getName());
return new FieldExpression(prefix + expr.getName(), expr.getClassDescriptor());
}
}

View File

@@ -7,6 +7,7 @@ import jef.expressions.Expression;
import jef.expressions.SelectExpression;
import jef.expressions.WhereExpression;
import jef.expressions.modifier.ExpressionOptimizerBottomUp;
import jef.expressions.modifier.IConst0Fixer;
import jef.expressions.modifier.TableAliasInjector;
import jef.expressions.modifier.TernaryRewriter;
import jef.serializable.SerializablePredicate;
@@ -34,6 +35,8 @@ public class FilterOp<T extends Serializable> implements Queryable<T>, Operation
System.out.println(expr);
expr = new TernaryRewriter().modify(expr);
System.out.println(expr);
expr = new IConst0Fixer().modify(expr);
System.out.println(expr);
// expr = new ExpressionOptimizer().modify(expr);
expr = new ExpressionOptimizerBottomUp().modify(expr);
expr = new TableAliasInjector(getTableAlias()).modify(expr);