protected static void pathConditionsToClauses(PathAnalysis path, List<TypedValue> clauses) throws TypedValueVisitorException { for (TypedValue cmp: path.getConditions()) { clauses.add(cmp); } }
public <U> ColumnExpressions<U> apply(List<Table<?>> fromTables) { try { SymbExToColumns translator = new SymbExToColumns(metamodel, new SelectFromWhereLambdaArgumentHandler(lambda, fromTables)); // TODO: Handle this case by translating things to use SELECT CASE if (lambda.symbolicAnalysis.paths.size() > 1) return null; ColumnExpressions<U> returnExpr = (ColumnExpressions<U>)translator.transform(PathAnalysisSimplifier.simplify(lambda.symbolicAnalysis.paths.get(0).getReturnValue(), Collections.emptyMap(), Collections.emptyMap(), false)); return returnExpr; } catch (TypedValueVisitorException e) { e.printStackTrace(); throw new IllegalArgumentException("Could not create query from lambda", e); } }
public void checkLambdaSideEffects(LambdaAnalysis lambda) throws QueryTransformException { for (PathAnalysis path: lambda.symbolicAnalysis.paths) { if (!path.getSideEffects().isEmpty()) throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); } }
TypedValue returnVal = PathAnalysisSimplifier.simplifyBoolean(path.getReturnValue(), Collections.emptyMap(), Collections.emptyMap(), false); ColumnExpressions<?> returnColumns = translator.transform(returnVal); if (!returnColumns.isSingleColumn()) throw new IllegalArgumentException("Where lambda should only return a single column of data"); for (TypedValue cmp: path.getConditions())
public void addPath(List<MethodSideEffect> sideEffects, TypedValue returnValue, List<? extends TypedValue> conditions) { PathAnalysis pathAnalysis = new PathAnalysis(sideEffects, returnValue, conditions); paths.add(pathAnalysis); } }
PathAnalysis path = where.symbolicAnalysis.paths.get(n); TypedValue returnVal = PathAnalysisSimplifier.simplifyBoolean(path.getReturnValue(), Collections.emptyMap(), Collections.emptyMap(), false); ColumnExpressions<?> returnColumns = translator.transform(returnVal); if (!returnColumns.isSingleColumn()) { for (TypedValue cmp : path.getConditions()) { ColumnExpressions<?> col = translator.transform(cmp); if (!col.isSingleColumn()) {
List<TypedValue.ComparisonValue> conditions = pathConditions.conditions; PathAnalysis toReturn = new PathAnalysis(interpreter.sideEffects, returnValue, conditions); return toReturn;
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); }
for (TypedValue val: PathAnalysisSimplifier.simplifyBooleans(path.getConditions(), comparisonMethods, comparisonStaticMethods, isAllEqualsConverted))
private void analyzeConstructor(MethodAnalysisResults analysis) throws QueryTransformException { if (analysis == null) throw new QueryTransformException("Symbolic execution of constructor failed"); if (analysis.paths.size() != 1) throw new QueryTransformException("Symbolic execution of constructor failed"); for (MethodSideEffect effect: analysis.paths.get(0).getSideEffects()) { if (effect instanceof MethodSideEffectCall) { MethodSideEffectCall call = (MethodSideEffectCall) effect; if (call.m.equals(abstractFunction1Constructor)) continue; } else if (effect instanceof MethodSideEffectFieldAssign) { // Assigning to local fields is safe as long as the constructed object doesn't escape the lambda. continue; } else throw new QueryTransformException("Lambda calls a constructor with unknown side-effects"); } }
.simplify(lambda.symbolicAnalysis.paths.get(0).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown);
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; }
if (analysis == null) throw new QueryTransformException("Symbolic execution of constructor failed"); if (analysis.paths.size() != 1) throw new QueryTransformException("Symbolic execution of constructor failed"); for (MethodSideEffect effect: analysis.paths.get(0).getSideEffects())
.simplifyBoolean(path.getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe); if (returnVal instanceof ConstantValue.BooleanConstant)
@Override public void checkLambdaSideEffects(LambdaAnalysis lambda) throws QueryTransformException { for (PathAnalysis path: lambda.symbolicAnalysis.paths) { for (MethodSideEffect effect: path.getSideEffects()) { if (effect instanceof MethodSideEffectCall) { MethodSideEffectCall call = (MethodSideEffectCall)effect; if (!call.m.name.equals("<init>")) throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); try { TransformationClassAnalyzer classAnalyzer = new TransformationClassAnalyzer(call.m.owner, alternateClassLoader); PathAnalysisFactory pathAnalysisFactory = new PathAnalysisFactory( metamodel.getMethodChecker(isObjectEqualsSafe, isAllEqualsSafe, isCollectionContainsSafe)); MethodAnalysisResults analysis = classAnalyzer.analyzeLambdaMethod(call.m.name, call.m.desc, pathAnalysisFactory); analyzeConstructor(analysis); continue; } catch (AnalyzerException | IOException e) { throw new QueryTransformException("Could not analyze the side-effects of the lambda to check for safety", e); } } throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); } } } }
.simplify(joinLambda.symbolicAnalysis.paths.get(0).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown);
.simplify(lambda.symbolicAnalysis.paths.get(0).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown);
.simplify(lambda.symbolicAnalysis.paths.get(0).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown);
public <U> ColumnExpressions<U> apply(List<Table<?>> fromTables) { try { SymbExToColumns translator = new SymbExToColumns(metamodel, new SelectFromWhereLambdaArgumentHandler(lambda, fromTables)); // TODO: Handle this case by translating things to use SELECT CASE if (lambda.symbolicAnalysis.paths.size() > 1) return null; ColumnExpressions<U> returnExpr = (ColumnExpressions<U>)translator.transform(PathAnalysisSimplifier.simplify(lambda.symbolicAnalysis.paths.get(0).getReturnValue(), Collections.emptyMap(), Collections.emptyMap(), false)); return returnExpr; } catch (TypedValueVisitorException e) { e.printStackTrace(); throw new IllegalArgumentException("Could not create query from lambda", e); } }