From 4bee1e28e468dd029fa20902abda5f3d36ef4f60 Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Thu, 14 Jul 2022 18:06:39 +0200 Subject: [PATCH] fix queries with 'WHERE field == 0' so that they are not represented as 'WHERE NOT field' --- .../java/jef/asm/FilterMethodVisitor.java | 22 +++++++---------- .../java/jef/expressions/FieldExpression.java | 4 +++- .../jef/expressions/ParameterExpression.java | 4 +++- .../expressions/modifier/IConst0Fixer.java | 24 +++++++++++++++++++ .../modifier/TableAliasInjector.java | 2 +- src/main/java/jef/operations/FilterOp.java | 3 +++ 6 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 src/main/java/jef/expressions/modifier/IConst0Fixer.java diff --git a/src/main/java/jef/asm/FilterMethodVisitor.java b/src/main/java/jef/asm/FilterMethodVisitor.java index 1acac71..ed294bf 100644 --- a/src/main/java/jef/asm/FilterMethodVisitor.java +++ b/src/main/java/jef/asm/FilterMethodVisitor.java @@ -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)); } diff --git a/src/main/java/jef/expressions/FieldExpression.java b/src/main/java/jef/expressions/FieldExpression.java index edd0172..4e5acce 100644 --- a/src/main/java/jef/expressions/FieldExpression.java +++ b/src/main/java/jef/expressions/FieldExpression.java @@ -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 diff --git a/src/main/java/jef/expressions/ParameterExpression.java b/src/main/java/jef/expressions/ParameterExpression.java index 9bef83b..59cf68c 100644 --- a/src/main/java/jef/expressions/ParameterExpression.java +++ b/src/main/java/jef/expressions/ParameterExpression.java @@ -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 diff --git a/src/main/java/jef/expressions/modifier/IConst0Fixer.java b/src/main/java/jef/expressions/modifier/IConst0Fixer.java new file mode 100644 index 0000000..2020a01 --- /dev/null +++ b/src/main/java/jef/expressions/modifier/IConst0Fixer.java @@ -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 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); + } +} diff --git a/src/main/java/jef/expressions/modifier/TableAliasInjector.java b/src/main/java/jef/expressions/modifier/TableAliasInjector.java index 90da0ae..482efc8 100644 --- a/src/main/java/jef/expressions/modifier/TableAliasInjector.java +++ b/src/main/java/jef/expressions/modifier/TableAliasInjector.java @@ -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()); } } diff --git a/src/main/java/jef/operations/FilterOp.java b/src/main/java/jef/operations/FilterOp.java index 98f41be..57c23e5 100644 --- a/src/main/java/jef/operations/FilterOp.java +++ b/src/main/java/jef/operations/FilterOp.java @@ -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 implements Queryable, 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);