@Override public ColumnExpressions<?> castValue(TypedValue.CastValue val, Void in) throws TypedValueVisitorException { // TODO: Check if cast is consistent with the reader // SQLColumnValues toReturn = val.operand.visit(this, in); // if (!toReturn.reader.isCastConsistent(val.getType().getInternalName())) // throw new TypedValueVisitorException("Attempting to cast to an inconsistent type"); return val.operand.visit(this, in); }
ColumnExpressions<?> transform(TypedValue val) throws TypedValueVisitorException { return val.visit(this, null); }
@Override public TypedValue defaultValue(TypedValue val, I in) throws E { // A subtree may be repeated in different parts of the tree, so here we // test whether we've seen the subtree before and return the new version // of the subtree if (remap.containsKey(val)) return remap.get(val); I param = val.visit(parameter, in); TypedValue newVal = val.visit(rewriter, param); remap.put(val, newVal); return newVal; }
@Override public TypedValue binaryOpValue(TypedValue.BinaryOperationValue val, I in) throws E { if (remap.containsKey(val)) return remap.get(val); I param = val.visit(parameter, in); TypedValue newLeft = val.left.visit(this, param); TypedValue newRight = val.right.visit(this, param); newLeft = newLeft.visit(rewriter, param); newRight = newRight.visit(rewriter, param); TypedValue newVal = val; if (newLeft != val.left || newRight != val.right) newVal = val.withNewChildren(newLeft, newRight); newVal = newVal.visit(rewriter, in); remap.put(val, newVal); return newVal; } // @Override public TypedValue comparisonOpValue(TypedValue.ComparisonValue val, I in) throws TypedValueVisitorException
@Override public TypedValue unaryOpValue(TypedValue.UnaryOperationValue val, I in) throws E { if (remap.containsKey(val)) return remap.get(val); I param = val.visit(parameter, in); TypedValue newOperand = val.operand.visit(this, param); newOperand = newOperand.visit(rewriter, param); TypedValue newVal = val; if (newOperand != val.operand) newVal = val.withNewChildren(newOperand); newVal = newVal.visit(rewriter, in); remap.put(val, newVal); return newVal; } // @Override public TypedValue getFieldValue(TypedValue.GetFieldValue val, I in) throws TypedValueVisitorException
@Override public O unaryOpValue(TypedValue.UnaryOperationValue val, I in) throws E { val.operand.visit(this, in); return defaultValue(val, in); }
@Override public O virtualMethodCallValue(MethodCallValue.VirtualMethodCallValue val, I in) throws E { val.base.visit(this, in); return methodCallValue(val, in); } }
@Override public O methodCallValue(MethodCallValue val, I in) throws E { for (TypedValue arg: val.args) arg.visit(this, in); return defaultValue(val, in); } @Override public O staticMethodCallValue(MethodCallValue.StaticMethodCallValue val, I in) throws E
private ColumnExpressions<?> handleMakeTupleMethodCall( MethodCallValue val, SymbExPassDown in, Function<RowReader<?>[], RowReader<?>> tupleReaderMaker) throws TypedValueVisitorException { ColumnExpressions<?> [] vals = new ColumnExpressions<?> [val.args.size()]; // TODO: This is a little wonky passing down isExpectingConditional, but I think it's right for those times you create a tuple with booleans and then extract the booleans later SymbExPassDown passdown = SymbExPassDown.with(val, in.isExpectingConditional); for (int n = 0; n < vals.length; n++) vals[n] = val.args.get(n).visit(this, passdown); RowReader<?> [] valReaders = new RowReader[vals.length]; for (int n = 0; n < vals.length; n++) valReaders[n] = vals[n].reader; ColumnExpressions<?> toReturn = new ColumnExpressions<>(tupleReaderMaker.apply(valReaders)); for (int n = 0; n < vals.length; n++) toReturn.columns.addAll(vals[n].columns); return toReturn; }
public static List<TypedValue> simplifyBooleans(List<TypedValue> conditions, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { List<TypedValue> newConditions = new ArrayList<TypedValue>(); for (TypedValue cond: conditions) { TypedValue simpcond = cond.visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simpcond = simpcond.visit(new SymbExBooleanRewriter(), true); newConditions.add(simpcond); } return newConditions; }
public static TypedValue simplifyBoolean(TypedValue value, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { TypedValue simplifiedBooleanReturnValue = value .visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simplifiedBooleanReturnValue = simplifiedBooleanReturnValue.visit(new SymbExBooleanRewriter(), true); return simplifiedBooleanReturnValue; } // public TypedValue getSimplifiedIsTrueReturnValue()
public static TypedValue simplify(TypedValue value, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { TypedValue simplifiedBooleanReturnValue = value .visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simplifiedBooleanReturnValue = simplifiedBooleanReturnValue.visit(new SymbExBooleanRewriter(), false); return simplifiedBooleanReturnValue; // return value.visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods)), null); } // public TypedValue getIsTrueReturnValue()
protected <U> ColumnExpressions<U> simplifyAndTranslatePathToColumns(LambdaAnalysis lambda, int pathIdx, SymbExToColumns translator, SymbExPassDown passdown) throws TypedValueVisitorException { return (ColumnExpressions<U>)PathAnalysisSimplifier .simplify(lambda.symbolicAnalysis.paths.get(pathIdx).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown); }
@Override public ColumnExpressions<?> castValue(TypedValue.CastValue val, SymbExPassDown in) throws TypedValueVisitorException { // We need to handle casts between primitive types carefully // because JPQL doesn't really support them directly if (val.isPrimitive()) { throw new TypedValueVisitorException("Casts of primitive values are not support in JPQL"); } // TODO: Check if cast is consistent with the reader // SQLColumnValues toReturn = val.operand.visit(this, in); // if (!toReturn.reader.isCastConsistent(val.getType().getInternalName())) // throw new TypedValueVisitorException("Attempting to cast to an inconsistent type"); return val.operand.visit(this, SymbExPassDown.with(val, in.isExpectingConditional)); }
@Override public ColumnExpressions<?> notOpValue(TypedValue.NotValue val, SymbExPassDown in) throws TypedValueVisitorException { SymbExPassDown passdown = SymbExPassDown.with(val, true); ColumnExpressions<?> left = val.operand.visit(this, passdown); return ColumnExpressions.singleColumn(left.reader, UnaryExpression.prefix("NOT", left.getOnlyColumn())); }
@Override public ColumnExpressions<?> mathOpValue(TypedValue.MathOpValue val, Void in) throws TypedValueVisitorException { ColumnExpressions<?> left = val.left.visit(this, in); ColumnExpressions<?> right = val.right.visit(this, in); Field leftField = (Field)left.getOnlyColumn(); Field rightField = (Field)right.getOnlyColumn(); Field resultField; switch(val.op) { case minus: resultField = leftField.minus(rightField); break; case plus: resultField = leftField.plus(rightField); break; case mul: resultField = leftField.mul(rightField); break; default: throw new TypedValueVisitorException("Unknown math operator"); } return ColumnExpressions.singleColumn(left.reader, resultField); }
@Override public ColumnExpressions<?> unaryMathOpValue(TypedValue.UnaryMathOpValue val, SymbExPassDown in) throws TypedValueVisitorException { SymbExPassDown passdown = SymbExPassDown.with(val, false); ColumnExpressions<?> left = val.operand.visit(this, passdown); return ColumnExpressions.singleColumn(left.reader, UnaryExpression.prefix(val.op.getOpString(), left.getOnlyColumn())); }
private <U> ColumnExpressions<U> binaryOpWithNull(String opString, TypedValue leftVal, TypedValue rightVal, SymbExPassDown passdown) throws TypedValueVisitorException { if (!("=".equals(opString) || "<>".equals(opString))) throw new TypedValueVisitorException("Unhandled operation involving NULL"); if (leftVal instanceof ConstantValue.NullConstant && rightVal instanceof ConstantValue.NullConstant) throw new TypedValueVisitorException("Cannot handle comparisons involving two NULLs"); TypedValue operandVal; if (leftVal instanceof ConstantValue.NullConstant) operandVal = rightVal; else operandVal = leftVal; ColumnExpressions<U> operand = (ColumnExpressions<U>)operandVal.visit(this, passdown); if ("=".equals(opString)) return ColumnExpressions.singleColumn(new SimpleRowReader<>(), UnaryExpression.postfix("IS NULL", operand.getOnlyColumn())); else return ColumnExpressions.singleColumn(new SimpleRowReader<>(), UnaryExpression.postfix("IS NOT NULL", operand.getOnlyColumn())); }
protected Expression pathConditionsToExpr(SymbExToColumns translator, PathAnalysis path) throws TypedValueVisitorException { Expression conditionExpr = null; for (TypedValue cmp: path.getConditions()) { SymbExPassDown passdown = SymbExPassDown.with(null, true); ColumnExpressions<?> col = cmp.visit(translator, passdown); if (!col.isSingleColumn()) throw new TypedValueVisitorException("Expecting a single column result for path condition"); Expression expr = col.getOnlyColumn(); if (conditionExpr != null) conditionExpr = new BinaryExpression("AND", conditionExpr, expr); else conditionExpr = expr; } return conditionExpr; }