ConstantOptimizer implements QueryOptimizer { @Override public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) { ConstantVisitor visitor = new ConstantVisitor(); tupleExpr.visit(visitor); Set<String> varsBefore = visitor.varNames; VarNameCollector varCollector = new VarNameCollector(); tupleExpr.visit(varCollector); Set<String> varsAfter = varCollector.varNames; if (varsAfter.size() < varsBefore.size()) { varsBefore.removeAll(varsAfter); for (ProjectionElemList projElems : visitor.projElemLists) { for (ProjectionElem projElem : projElems.getElements()) { String name = projElem.getSourceName(); if (varsBefore.contains(name)) { UnaryTupleOperator proj = (UnaryTupleOperator) projElems.getParentNode(); Extension ext = new Extension(proj.getArg()); proj.setArg(ext); Var lostVar = new Var(name); Value value = bindings.getValue(name); if (value != null) { lostVar.setValue(value); } ext.addElement(new ExtensionElem(lostVar, name)); } } } } } ConstantOptimizer(EvaluationStrategy strategy); @Override void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings);  }
@Test public void testAndOptimization() throws RDF4JException { String query = "prefix ex: <ex:>" + "select ?a ?b ?c\n" + "where {\n" + " bind((?a && ?b) as ?c) \n" + "}"; ParsedQuery pq = QueryParserUtil.parseQuery(QueryLanguage.SPARQL, query, null); TupleExpr original = pq.getTupleExpr(); final AlgebraFinder finder = new AlgebraFinder(); original.visit(finder); assertTrue(finder.logicalAndfound); finder.reset(); QueryBindingSet constants = new QueryBindingSet(); constants.addBinding("a", BooleanLiteral.TRUE); constants.addBinding("b", BooleanLiteral.FALSE); EvaluationStrategy strategy = new StrictEvaluationStrategy(new EmptyTripleSource(), null); TupleExpr optimized = optimize(pq.getTupleExpr().clone(), constants, strategy); optimized.visit(finder); assertFalse("optimized query should no longer contain && operator", finder.logicalAndfound); CloseableIteration<BindingSet, QueryEvaluationException> result = strategy.evaluate(optimized, new EmptyBindingSet()); assertNotNull(result); assertTrue(result.hasNext()); BindingSet bindings = result.next(); assertTrue(bindings.hasBinding("a")); assertTrue(bindings.hasBinding("b")); assertTrue(bindings.hasBinding("c")); }
@Test public void testFunctionOptimization() throws RDF4JException { String query = "prefix ex: <ex:>" + "select ?a ?b ?c \n " + "where {\n" + " bind(concat(?a, ?b) as ?c) \n" + "}"; ParsedQuery pq = QueryParserUtil.parseQuery(QueryLanguage.SPARQL, query, null); EvaluationStrategy strategy = new StrictEvaluationStrategy(new EmptyTripleSource(), null); TupleExpr original = pq.getTupleExpr(); final AlgebraFinder finder = new AlgebraFinder(); original.visit(finder); assertTrue(finder.functionCallFound); finder.reset(); QueryBindingSet constants = new QueryBindingSet(); constants.addBinding("a", ValueFactoryImpl.getInstance().createLiteral("foo")); constants.addBinding("b", ValueFactoryImpl.getInstance().createLiteral("bar")); TupleExpr optimized = optimize(pq.getTupleExpr().clone(), constants, strategy); optimized.visit(finder); assertFalse("optimized query should no longer contain function call", finder.functionCallFound); CloseableIteration<BindingSet, QueryEvaluationException> result = strategy.evaluate(optimized, new EmptyBindingSet()); assertNotNull(result); assertTrue(result.hasNext()); BindingSet bindings = result.next(); assertTrue(bindings.hasBinding("a")); assertTrue(bindings.hasBinding("b")); assertTrue(bindings.hasBinding("c")); }