Search in sources :

Example 1 with ExprList

use of org.apache.jena.sparql.expr.ExprList in project jena by apache.

the class TransformFilterDisjunction method transform.

@Override
public Op transform(OpFilter opFilter, final Op subOp) {
    ExprList exprList = opFilter.getExprs();
    // First pass - any disjunctions at all?
    boolean processDisjunction = false;
    for (Expr expr : exprList) {
        if (isDisjunction(expr)) {
            processDisjunction = true;
            break;
        }
    }
    // Still may be a disjunction in a form we don't optimize. 
    if (!processDisjunction)
        return super.transform(opFilter, subOp);
    ExprList exprList2 = new ExprList();
    Op newOp = subOp;
    // remember what's been seen so that FILTER(?x = <x> || ?x = <x> ) does not result in two transforms. 
    Set<Expr> doneSoFar = new HashSet<>();
    for (Expr expr : exprList) {
        if (!isDisjunction(expr)) {
            // Assignment there?
            exprList2.add(expr);
            continue;
        }
        //            // Relies on expression equality.
        //            if ( doneSoFar.contains(expr) )
        //                continue ;
        //            // Must be canonical: ?x = <x> is the same as <x> = ?x
        //            doneSoFar.add(expr) ;
        Op op2 = expandDisjunction(expr, newOp);
        if (op2 != null)
            newOp = op2;
    }
    if (exprList2.isEmpty())
        return newOp;
    // There should have been at least on disjunction.
    if (newOp == subOp) {
        Log.warn(this, "FilterDisjunction assumption failure: didn't find a disjunction after all");
        return super.transform(opFilter, subOp);
    }
    // Failed.  These a was one or more expressions we couldn't handle.
    // So the full pattern is going to be executed anyway. 
    //return super.transform(super.transform(opFilter, subOp)) ;
    // Put the non-disjunctions outside the disjunction and the pattern rewrite. 
    Op opOther = OpFilter.filterBy(exprList2, newOp);
    if (opOther instanceof OpFilter) {
        return opOther;
    }
    // opOther is not a filter any more - should not happen but to isolate from future changes ...
    Log.warn(this, "FilterDisjunction assumption failure: not a filter after processing disjunction/other mix");
    return super.transform(opFilter, subOp);
}
Also used : Op(org.apache.jena.sparql.algebra.Op) Expr(org.apache.jena.sparql.expr.Expr) ExprList(org.apache.jena.sparql.expr.ExprList) OpFilter(org.apache.jena.sparql.algebra.op.OpFilter) HashSet(java.util.HashSet)

Example 2 with ExprList

use of org.apache.jena.sparql.expr.ExprList in project jena by apache.

the class TransformFilterPlacement method placeJoin.

private Placement placeJoin(ExprList exprs, OpJoin opJoin) {
    Op left = opJoin.getLeft();
    Op right = opJoin.getRight();
    Collection<Var> leftVars = fixedVars(left);
    Collection<Var> rightVars = fixedVars(right);
    // More sophisticated - consider optionl variables as well.
    // This code check the two ways to get fixed vars yields the same
    // and it does for the test suite. 
    //        //---
    //        VarFinder vfLeft = VarFinder.process(left) ;
    //        VarFinder vfRight = VarFinder.process(right) ;
    //        if ( ! CollectionUtils.sameElts(leftVars, vfLeft.getFixed() ) )
    //            System.err.println("Left: "+leftVars+" : "+vfLeft.getFixed() ) ;
    //        if ( ! CollectionUtils.sameElts(rightVars, vfRight.getFixed() ) )
    //            System.err.println("Right: "+rightVars+" : "+vfRight.getFixed() ) ;
    //        //---
    ExprList unpushed = new ExprList();
    ExprList pushLeft = new ExprList();
    ExprList pushRight = new ExprList();
    for (Expr expr : exprs) {
        Set<Var> vars = expr.getVarsMentioned();
        boolean pushed = false;
        if (leftVars.containsAll(vars)) {
            pushLeft.add(expr);
            pushed = true;
        }
        if (pushed && !pushRightAsWellAsLeft)
            continue;
        // If left only, make this "else if" of left test, remove "continue" 
        if (rightVars.containsAll(vars)) {
            // Push right
            pushRight.add(expr);
            pushed = true;
        }
        if (!pushed)
            unpushed.add(expr);
    }
    if (pushLeft.isEmpty() && pushRight.isEmpty())
        return null;
    Op opLeftNew = left;
    if (!pushLeft.isEmpty())
        opLeftNew = transformOpAlways(pushLeft, opLeftNew);
    Op opRightNew = right;
    if (!pushRight.isEmpty())
        opRightNew = transformOpAlways(pushRight, opRightNew);
    Op op = OpJoin.create(opLeftNew, opRightNew);
    return result(op, unpushed);
}
Also used : Op(org.apache.jena.sparql.algebra.Op) Expr(org.apache.jena.sparql.expr.Expr) ExprList(org.apache.jena.sparql.expr.ExprList) Var(org.apache.jena.sparql.core.Var)

Example 3 with ExprList

use of org.apache.jena.sparql.expr.ExprList in project jena by apache.

the class TransformFilterPlacement method placeSequence.

/*
     * A Sequence is a number of joins where scoping means the LHS can be
     * substituted into the right, i.e. there are no scoping issues. Assuming a
     * substitution join is going to be done, filtering once as soon as the
     * accumulated variables cover the filter is a good thing to do. It is
     * effectively pusing on the left side only - the right side, by
     * substitution, will never see the variables. The variable can not be
     * reintroduced (it will have been renamed away if it's the same name,
     * different scope, which is a different variable with the same name in the
     * orginal query).
     */
private Placement placeSequence(ExprList exprsIn, OpSequence opSequence) {
    ExprList exprs = ExprList.copy(exprsIn);
    Set<Var> varScope = new HashSet<>();
    List<Op> ops = opSequence.getElements();
    Op op = null;
    for (Op op1 : ops) {
        op = insertAnyFilter$(exprs, varScope, op);
        Op seqElt = op1;
        Placement p = transform(exprs, seqElt);
        if (isChange(p)) {
            exprs = p.unplaced;
            seqElt = p.op;
        }
        varScope.addAll(fixedVars(seqElt));
        op = OpSequence.create(op, seqElt);
    }
    return result(op, exprs);
}
Also used : Op(org.apache.jena.sparql.algebra.Op) ExprList(org.apache.jena.sparql.expr.ExprList) Var(org.apache.jena.sparql.core.Var)

Example 4 with ExprList

use of org.apache.jena.sparql.expr.ExprList in project jena by apache.

the class TransformFilterPlacement method transform.

@Override
public Op transform(OpFilter opFilter, Op x) {
    ExprList exprs = opFilter.getExprs();
    // Extract any expressions with "nasty" cases (RAND, UUID, STRUUID and BNODE)
    // which are not true functions (they return a different value every call so
    // number of calls matters.  NOW is safe (returns a fixed time point for the whole
    // query.
    // Phase one - check to see if work needed. 
    ExprList exprs2 = null;
    for (Expr expr : exprs) {
        if (!ExprLib.isStable(expr)) {
            if (exprs2 == null)
                exprs2 = new ExprList();
            exprs2.add(expr);
        }
    }
    // Phase 2 - if needed, split.
    if (exprs2 != null) {
        ExprList exprs1 = new ExprList();
        for (Expr expr : exprs) {
            // We are assuming fixup is rare. 
            if (ExprLib.isStable(expr))
                exprs1.add(expr);
        }
        exprs = exprs1;
    }
    Placement placement = transform(exprs, x);
    if (isNoChange(placement))
        // Didn't do anything.
        return super.transform(opFilter, x);
    Op op = buildFilter(placement);
    if (exprs2 != null)
        // Add back the non-deterministic expressions
        op = OpFilter.filterBy(exprs2, op);
    return op;
}
Also used : Op(org.apache.jena.sparql.algebra.Op) Expr(org.apache.jena.sparql.expr.Expr) ExprList(org.apache.jena.sparql.expr.ExprList)

Example 5 with ExprList

use of org.apache.jena.sparql.expr.ExprList in project jena by apache.

the class TransformFilterPlacement method placeBGP.

// See also placeQuadPattern.
// 
// An improvement might be to put any filters that apply to exactly one triple
// directly on the triple pattern.  At the moment, the filter is put over
// the block leading up to the triple pattern.
private static Placement placeBGP(ExprList exprsIn, 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);
    for (Triple triple : pattern) {
        OpBGP opBGP = getBGP(op);
        if (opBGP == null) {
            // Last thing was not a BGP (so it likely to be a filter)
            // Need to pass the results from that into the next triple.
            opBGP = new OpBGP();
            op = OpSequence.create(op, opBGP);
        }
        opBGP.getPattern().add(triple);
        // Update variables in scope.
        VarUtils.addVarsFromTriple(patternVarsScope, triple);
        op = insertAnyFilter$(exprs, patternVarsScope, op);
    }
    return result(op, exprs);
}
Also used : Triple(org.apache.jena.graph.Triple) Op(org.apache.jena.sparql.algebra.Op) ExprList(org.apache.jena.sparql.expr.ExprList) Var(org.apache.jena.sparql.core.Var)

Aggregations

ExprList (org.apache.jena.sparql.expr.ExprList)27 Op (org.apache.jena.sparql.algebra.Op)17 Expr (org.apache.jena.sparql.expr.Expr)15 Var (org.apache.jena.sparql.core.Var)11 Node (org.apache.jena.graph.Node)3 Triple (org.apache.jena.graph.Triple)3 HashSet (java.util.HashSet)2 OpFilter (org.apache.jena.sparql.algebra.op.OpFilter)2 BasicPattern (org.apache.jena.sparql.core.BasicPattern)2 Test (org.junit.Test)2 ExprRewriter (org.apache.jena.arq.querybuilder.rewriters.ExprRewriter)1 MockSecurityEvaluator (org.apache.jena.permissions.MockSecurityEvaluator)1 SecurityEvaluator (org.apache.jena.permissions.SecurityEvaluator)1 OpRewriter (org.apache.jena.permissions.query.rewriter.OpRewriter)1 SecuredFunction (org.apache.jena.permissions.query.rewriter.SecuredFunction)1 SortCondition (org.apache.jena.query.SortCondition)1 OpBGP (org.apache.jena.sparql.algebra.op.OpBGP)1 VarExprList (org.apache.jena.sparql.core.VarExprList)1 QueryIterator (org.apache.jena.sparql.engine.QueryIterator)1 NodeValue (org.apache.jena.sparql.expr.NodeValue)1