Search in sources :

Example 16 with StatementPattern

use of org.eclipse.rdf4j.query.algebra.StatementPattern in project rdf4j by eclipse.

the class TupleExprBuilder method getConstructVars.

/**
 * Gets the set of variables that are relevant for the constructor. This method accumulates all subject,
 * predicate and object variables from the supplied statement patterns, but ignores any context variables.
 */
private Set<Var> getConstructVars(Collection<StatementPattern> statementPatterns) {
    Set<Var> vars = new LinkedHashSet<Var>(statementPatterns.size() * 2);
    for (StatementPattern sp : statementPatterns) {
        vars.add(sp.getSubjectVar());
        vars.add(sp.getPredicateVar());
        vars.add(sp.getObjectVar());
    }
    return vars;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) StatementPattern(org.eclipse.rdf4j.query.algebra.StatementPattern) Var(org.eclipse.rdf4j.query.algebra.Var)

Example 17 with StatementPattern

use of org.eclipse.rdf4j.query.algebra.StatementPattern in project rdf4j by eclipse.

the class TupleExprBuilder method createPath.

private TupleExpr createPath(Scope scope, Var subjVar, TupleExpr pathExpression, Var endVar, Var contextVar, long length) throws VisitorException {
    if (pathExpression instanceof StatementPattern) {
        Var predVar = ((StatementPattern) pathExpression).getPredicateVar();
        if (length == 0L) {
            return new ZeroLengthPath(scope, subjVar, endVar, contextVar);
        } else {
            GraphPattern gp = new GraphPattern();
            gp.setContextVar(contextVar);
            gp.setStatementPatternScope(scope);
            Var nextVar = null;
            for (long i = 0L; i < length; i++) {
                if (i < length - 1) {
                    nextVar = createAnonVar();
                } else {
                    nextVar = endVar;
                }
                gp.addRequiredSP(subjVar, predVar, nextVar);
                subjVar = nextVar;
            }
            return gp.buildTupleExpr();
        }
    } else {
        if (length == 0L) {
            return new ZeroLengthPath(scope, subjVar, endVar, contextVar);
        } else {
            GraphPattern gp = new GraphPattern();
            gp.setContextVar(contextVar);
            gp.setStatementPatternScope(scope);
            Var nextVar = null;
            for (long i = 0L; i < length; i++) {
                if (i < length - 1L) {
                    nextVar = createAnonVar();
                } else {
                    nextVar = endVar;
                }
                // create a clone of the path expression.
                TupleExpr clone = pathExpression.clone();
                VarReplacer replacer = new VarReplacer(endVar, nextVar);
                clone.visit(replacer);
                gp.addRequiredTE(clone);
                subjVar = nextVar;
            }
            return gp.buildTupleExpr();
        }
    }
}
Also used : StatementPattern(org.eclipse.rdf4j.query.algebra.StatementPattern) ZeroLengthPath(org.eclipse.rdf4j.query.algebra.ZeroLengthPath) Var(org.eclipse.rdf4j.query.algebra.Var) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 18 with StatementPattern

use of org.eclipse.rdf4j.query.algebra.StatementPattern in project rdf4j by eclipse.

the class TupleExprBuilder method replaceSameTermVars.

private List<StatementPattern> replaceSameTermVars(List<StatementPattern> statementPatterns, Set<SameTerm> sameTermConstraints) {
    if (sameTermConstraints != null) {
        for (SameTerm st : sameTermConstraints) {
            Var left = (Var) st.getLeftArg();
            Var right = (Var) st.getRightArg();
            for (StatementPattern sp : statementPatterns) {
                Var subj = sp.getSubjectVar();
                Var obj = sp.getObjectVar();
                if (subj.equals(left) || subj.equals(right)) {
                    if (obj.equals(left) || obj.equals(right)) {
                        sp.setObjectVar(subj);
                    }
                }
            }
        }
    }
    return statementPatterns;
}
Also used : StatementPattern(org.eclipse.rdf4j.query.algebra.StatementPattern) Var(org.eclipse.rdf4j.query.algebra.Var) SameTerm(org.eclipse.rdf4j.query.algebra.SameTerm)

Example 19 with StatementPattern

use of org.eclipse.rdf4j.query.algebra.StatementPattern in project rdf4j by eclipse.

the class TupleExprBuilder method visit.

@Override
public Object visit(ASTPathSequence pathSeqNode, Object data) throws VisitorException {
    ValueExpr subject = (ValueExpr) data;
    Var subjVar = mapValueExprToVar(subject);
    // check if we should invert subject and object.
    boolean invertSequence = checkInverse(pathSeqNode);
    @SuppressWarnings("unchecked") List<ValueExpr> objectList = (List<ValueExpr>) getObjectList(pathSeqNode).jjtAccept(this, null);
    List<ASTPathElt> pathElements = pathSeqNode.getPathElements();
    int pathLength = pathElements.size();
    GraphPattern pathSequencePattern = new GraphPattern(graphPattern);
    Scope scope = pathSequencePattern.getStatementPatternScope();
    Var contextVar = pathSequencePattern.getContextVar();
    Var startVar = subjVar;
    for (int i = 0; i < pathLength; i++) {
        ASTPathElt pathElement = pathElements.get(i);
        ASTPathMod pathMod = pathElement.getPathMod();
        long lowerBound = Long.MIN_VALUE;
        long upperBound = Long.MIN_VALUE;
        if (pathMod != null) {
            lowerBound = pathMod.getLowerBound();
            upperBound = pathMod.getUpperBound();
            if (upperBound == Long.MIN_VALUE) {
                upperBound = lowerBound;
            } else if (lowerBound == Long.MIN_VALUE) {
                lowerBound = upperBound;
            }
        }
        if (pathElement.isNegatedPropertySet()) {
            // create a temporary negated property set object and set the
            // correct subject and object vars to continue
            // the path sequence.
            NegatedPropertySet nps = new NegatedPropertySet();
            nps.setScope(scope);
            nps.setSubjectVar(startVar);
            nps.setContextVar(contextVar);
            for (Node child : pathElement.jjtGetChildren()) {
                if (child instanceof ASTPathMod) {
                    // skip the modifier
                    continue;
                }
                nps.addPropertySetElem((PropertySetElem) child.jjtAccept(this, data));
            }
            Var[] objVarReplacement = null;
            if (i == pathLength - 1) {
                if (objectList.contains(subjVar)) {
                    // See SES-1685
                    Var objVar = mapValueExprToVar(objectList.get(objectList.indexOf(subjVar)));
                    objVarReplacement = new Var[] { objVar, createAnonVar() };
                    objectList.remove(objVar);
                    objectList.add(objVarReplacement[1]);
                } else {
                    nps.setObjectList(objectList);
                }
            } else {
                // not last element in path.
                Var nextVar = createAnonVar();
                List<ValueExpr> nextVarList = new ArrayList<ValueExpr>();
                nextVarList.add(nextVar);
                nps.setObjectList(nextVarList);
                startVar = nextVar;
            }
            // convert the NegatedPropertySet to a proper TupleExpr
            TupleExpr te = createTupleExprForNegatedPropertySet(nps, i);
            if (objVarReplacement != null) {
                SameTerm condition = new SameTerm(objVarReplacement[0], objVarReplacement[1]);
                pathSequencePattern.addConstraint(condition);
            }
            for (ValueExpr object : objectList) {
                Var objVar = mapValueExprToVar(object);
                te = handlePathModifiers(scope, subjVar, te, objVar, contextVar, lowerBound, upperBound);
            }
            pathSequencePattern.addRequiredTE(te);
        } else if (pathElement.isNestedPath()) {
            GraphPattern parentGP = graphPattern;
            graphPattern = new GraphPattern(parentGP);
            if (i == pathLength - 1) {
                // last element in the path
                pathElement.jjtGetChild(0).jjtAccept(this, startVar);
                TupleExpr te = graphPattern.buildTupleExpr();
                for (ValueExpr object : objectList) {
                    Var objVar = mapValueExprToVar(object);
                    if (objVar.equals(subjVar)) {
                        // see SES-1685
                        Var objVarReplacement = createAnonVar();
                        te = handlePathModifiers(scope, startVar, te, objVarReplacement, contextVar, lowerBound, upperBound);
                        SameTerm condition = new SameTerm(objVar, objVarReplacement);
                        pathSequencePattern.addConstraint(condition);
                    } else {
                        te = handlePathModifiers(scope, startVar, te, objVar, contextVar, lowerBound, upperBound);
                    }
                    pathSequencePattern.addRequiredTE(te);
                }
            } else {
                // not the last element in the path, introduce an anonymous
                // var
                // to connect.
                Var nextVar = createAnonVar();
                pathElement.jjtGetChild(0).jjtAccept(this, startVar);
                TupleExpr te = graphPattern.buildTupleExpr();
                // replace all object list occurrences with the intermediate
                // var.
                te = replaceVarOccurrence(te, objectList, nextVar);
                te = handlePathModifiers(scope, startVar, te, nextVar, contextVar, lowerBound, upperBound);
                pathSequencePattern.addRequiredTE(te);
                startVar = nextVar;
            }
            graphPattern = parentGP;
        } else {
            ValueExpr pred = (ValueExpr) pathElement.jjtAccept(this, data);
            Var predVar = mapValueExprToVar(pred);
            TupleExpr te;
            if (i == pathLength - 1) {
                // objects
                for (ValueExpr object : objectList) {
                    Var objVar = mapValueExprToVar(object);
                    boolean replaced = false;
                    // to avoid problems in cyclic paths
                    if (objVar.equals(subjVar)) {
                        objVar = createAnonVar();
                        replaced = true;
                    }
                    Var endVar = objVar;
                    if (invertSequence) {
                        endVar = subjVar;
                        if (startVar.equals(subjVar)) {
                            // inverted path sequence of length 1.
                            startVar = objVar;
                        }
                    }
                    if (pathElement.isInverse()) {
                        te = new StatementPattern(scope, endVar, predVar, startVar, contextVar);
                        te = handlePathModifiers(scope, endVar, te, startVar, contextVar, lowerBound, upperBound);
                    } else {
                        te = new StatementPattern(scope, startVar, predVar, endVar, contextVar);
                        te = handlePathModifiers(scope, startVar, te, endVar, contextVar, lowerBound, upperBound);
                    }
                    if (replaced) {
                        SameTerm condition = new SameTerm(objVar, mapValueExprToVar(object));
                        pathSequencePattern.addConstraint(condition);
                    }
                    pathSequencePattern.addRequiredTE(te);
                }
            } else {
                // not the last element in the path, introduce an anonymous
                // var
                // to connect.
                Var nextVar = createAnonVar();
                if (invertSequence && startVar.equals(subjVar)) {
                    // sequence
                    for (ValueExpr object : objectList) {
                        Var objVar = mapValueExprToVar(object);
                        startVar = objVar;
                        if (pathElement.isInverse()) {
                            Var temp = startVar;
                            startVar = nextVar;
                            nextVar = temp;
                        }
                        te = new StatementPattern(scope, startVar, predVar, nextVar, contextVar);
                        te = handlePathModifiers(scope, startVar, te, nextVar, contextVar, lowerBound, upperBound);
                        pathSequencePattern.addRequiredTE(te);
                    }
                } else {
                    if (pathElement.isInverse()) {
                        final Var oldStartVar = startVar;
                        startVar = nextVar;
                        nextVar = oldStartVar;
                    }
                    te = new StatementPattern(scope, startVar, predVar, nextVar, contextVar);
                    te = handlePathModifiers(scope, startVar, te, nextVar, contextVar, lowerBound, upperBound);
                    pathSequencePattern.addRequiredTE(te);
                }
                // set the subject for the next element in the path.
                startVar = (pathElement.isInverse() ? startVar : nextVar);
            }
        }
    }
    // add the created path sequence to the graph pattern.
    for (TupleExpr te : pathSequencePattern.getRequiredTEs()) {
        graphPattern.addRequiredTE(te);
    }
    if (pathSequencePattern.getConstraints() != null) {
        for (ValueExpr constraint : pathSequencePattern.getConstraints()) {
            graphPattern.addConstraint(constraint);
        }
    }
    return null;
}
Also used : ValueExpr(org.eclipse.rdf4j.query.algebra.ValueExpr) Var(org.eclipse.rdf4j.query.algebra.Var) QueryModelNode(org.eclipse.rdf4j.query.algebra.QueryModelNode) IsBNode(org.eclipse.rdf4j.query.algebra.IsBNode) SameTerm(org.eclipse.rdf4j.query.algebra.SameTerm) ArrayList(java.util.ArrayList) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr) StatementPattern(org.eclipse.rdf4j.query.algebra.StatementPattern) Scope(org.eclipse.rdf4j.query.algebra.StatementPattern.Scope) List(java.util.List) ArrayList(java.util.ArrayList) ProjectionElemList(org.eclipse.rdf4j.query.algebra.ProjectionElemList)

Aggregations

StatementPattern (org.eclipse.rdf4j.query.algebra.StatementPattern)19 Var (org.eclipse.rdf4j.query.algebra.Var)14 TupleExpr (org.eclipse.rdf4j.query.algebra.TupleExpr)9 ProjectionElemList (org.eclipse.rdf4j.query.algebra.ProjectionElemList)6 ArrayList (java.util.ArrayList)5 ProjectionElem (org.eclipse.rdf4j.query.algebra.ProjectionElem)5 ValueConstant (org.eclipse.rdf4j.query.algebra.ValueConstant)5 ValueExpr (org.eclipse.rdf4j.query.algebra.ValueExpr)5 LinkedHashSet (java.util.LinkedHashSet)4 Extension (org.eclipse.rdf4j.query.algebra.Extension)4 ExtensionElem (org.eclipse.rdf4j.query.algebra.ExtensionElem)4 Join (org.eclipse.rdf4j.query.algebra.Join)4 MultiProjection (org.eclipse.rdf4j.query.algebra.MultiProjection)4 BNodeGenerator (org.eclipse.rdf4j.query.algebra.BNodeGenerator)3 EmptySet (org.eclipse.rdf4j.query.algebra.EmptySet)3 Projection (org.eclipse.rdf4j.query.algebra.Projection)3 Reduced (org.eclipse.rdf4j.query.algebra.Reduced)3 SameTerm (org.eclipse.rdf4j.query.algebra.SameTerm)3 Slice (org.eclipse.rdf4j.query.algebra.Slice)3 ParsedQuery (org.eclipse.rdf4j.query.parser.ParsedQuery)3