use of org.apache.jena.sparql.expr.ExprList in project jena by apache.
the class TransformFilterPlacement method processExtendAssign.
/** Try to optimize (filter (extend ...)) , (filter (let ...)) */
private Placement processExtendAssign(ExprList exprs, OpExtendAssign input) {
// We assume that each (extend) and (assign) is usually in simple form -
// always one assignment. We cope with the general form (multiple
// assignments) but do not attempt reordering of assignments.
// There are three cases:
// 1 - expressions that can be pushed into the subop.
// 2 - expressions that are covered when the extend/assign has applied. [wrapping]
// 3 - expressions that are not covered even at the outermost level. [unplaced]
List<Var> vars1 = input.getVarExprList().getVars();
Op subOp = input.getSubOp();
// Case 1 : Do as much inner placement as possible.
ExprList remaining = exprs;
Placement p = transform(exprs, input.getSubOp());
if (isChange(p)) {
subOp = p.op;
remaining = p.unplaced;
}
// Case 2 : wrapping
// Case 3 : unplaced
// Variables in subop and introduced by (extend)/(assign)
Set<Var> subVars = OpVars.fixedVars(subOp);
subVars.addAll(input.getVarExprList().getVars());
ExprList wrapping = new ExprList();
ExprList unplaced = new ExprList();
for (Expr expr : remaining) {
Set<Var> exprVars = expr.getVarsMentioned();
if (subVars.containsAll(exprVars))
wrapping.add(expr);
else
unplaced.add(expr);
}
Op result = input.copy(subOp);
if (!wrapping.isEmpty())
result = OpFilter.filterBy(wrapping, result);
return result(result, unplaced);
}
use of org.apache.jena.sparql.expr.ExprList in project jena by apache.
the class TransformFilterPlacement method placeFilter.
private Placement placeFilter(ExprList exprs, OpFilter input) {
// If input.getSubOp is itself a filter, it has already been
// processed because the Transform is applied bottom-up.
// We must not let the filter's expressions go back as "unplaced"
// as they are scoped to the input and if "unplaced" are available
// out of that scope.
Op op = input.getSubOp();
ExprList exprsInner = input.getExprs();
ExprList exprsOuter = exprs;
// Outer
Placement p = transform(exprsOuter, input.getSubOp());
if (isChange(p)) {
op = p.op;
exprsOuter = p.unplaced;
}
// Put inner round the modified Op.
// If op is also a filter, a single filter is created with
// exprsInner now after placed filters.
// ("after" means later in the exprList of the filter).
Op f = OpFilter.filterBy(exprsInner, op);
return new Placement(f, exprsOuter);
}
use of org.apache.jena.sparql.expr.ExprList in project jena by apache.
the class TransformFilterPlacement method placeQuadPattern.
private static Placement placeQuadPattern(ExprList exprsIn, Node graphNode, BasicPattern pattern) {
ExprList exprs = ExprList.copy(exprsIn);
Set<Var> patternVarsScope = new HashSet<>();
// Any filters that depend on no variables.
Op op = insertAnyFilter$(exprs, patternVarsScope, null);
if (Var.isVar(graphNode)) {
// Add in the graph node of the quad block.
VarUtils.addVar(patternVarsScope, Var.alloc(graphNode));
}
for (Triple triple : pattern) {
OpQuadPattern opQuad = getQuads(op);
if (opQuad == null) {
opQuad = new OpQuadPattern(graphNode, new BasicPattern());
op = OpSequence.create(op, opQuad);
}
opQuad.getBasicPattern().add(triple);
// Update variables in scope.
VarUtils.addVarsFromTriple(patternVarsScope, triple);
op = insertAnyFilter$(exprs, patternVarsScope, op);
}
return result(op, exprs);
}
use of org.apache.jena.sparql.expr.ExprList in project jena by apache.
the class TransformFilterPlacement method placeDisjunction.
private Placement placeDisjunction(ExprList exprs, OpDisjunction input) {
if (false) {
// Push everything, always
// Left as a safty fall back.
List<Op> x = new ArrayList<>();
input.getElements().forEach(op -> {
Placement p = transform(exprs, op);
if (isNoChange(p)) {
x.add(buildFilter(exprs, op));
} else {
Op op1 = buildFilter(p);
x.add(op1);
}
});
return result(input.copy(x), emptyList);
}
// Don't push any expressions that aren't used in any of the arms of the disjunction.
// This is more about being tidy.
List<Expr> unplaced = new ArrayList<>(exprs.getList());
//List<Placement> x = input.getElements().stream().map(op->transform(exprs, op)).collect(Collectors.toList()) ;
List<Placement> placements = new ArrayList<>(exprs.size());
Boolean someChange = Boolean.FALSE;
for (Op op : input.getElements()) {
Placement p = transform(exprs, op);
if (isChange(p)) {
unplaced.retainAll(p.unplaced.getList());
someChange = Boolean.TRUE;
} else
p = result(op, exprs);
placements.add(p);
}
;
if (!someChange)
return noChangePlacement;
List<Expr> retained = new ArrayList<>(exprs.getList());
retained.removeAll(unplaced);
// Mutate placements to remove the expres going outside.
List<Op> ops = new ArrayList<>(input.size());
for (Placement p : placements) {
// No "noChange" at this point.
p.unplaced.getListRaw().removeAll(unplaced);
ops.add(buildFilter(p));
}
;
return result(input.copy(ops), new ExprList(unplaced));
}
use of org.apache.jena.sparql.expr.ExprList in project jena by apache.
the class TransformFilterPlacement method wrapQuadPattern.
/** Wrap the Graph node, Basic Pattern with any applicable expressions from the ExprList
* but do not break up the BasicPattern in any way.
*/
private static Placement wrapQuadPattern(ExprList exprsIn, Node graphNode, BasicPattern pattern) {
Set<Var> vs = new HashSet<>();
VarUtils.addVars(vs, pattern);
if (Var.isVar(graphNode))
vs.add(Var.alloc(graphNode));
ExprList pushed = new ExprList();
ExprList unpushed = new ExprList();
for (Expr e : exprsIn) {
Set<Var> eVars = e.getVarsMentioned();
if (vs.containsAll(eVars)) {
pushed.add(e);
} else {
unpushed.add(e);
}
}
// Can't push anything into a filter around this quadpattern
if (pushed.size() == 0)
return null;
// Safe to place some conditions around the quadpattern
return new Placement(OpFilter.filterBy(pushed, new OpQuadPattern(graphNode, pattern)), unpushed);
}
Aggregations