Search in sources :

Example 56 with TupleExpr

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

the class AbstractQueryBuilder method query.

/**
 * @inheritDoc
 */
public T query() {
    UnaryTupleOperator aRoot = null;
    UnaryTupleOperator aCurr = null;
    if (mLimit != -1 || mOffset != -1) {
        Slice aSlice = new Slice();
        if (mLimit != -1) {
            aSlice.setLimit(mLimit);
        }
        if (mOffset != -1) {
            aSlice.setOffset(mOffset);
        }
        aRoot = aCurr = aSlice;
    }
    if (mOrderByElems != null && !mOrderByElems.isEmpty()) {
        Order aOrder = new Order();
        aOrder.addElements(mOrderByElems);
        if (aRoot == null) {
            aRoot = aCurr = aOrder;
        } else {
            aCurr.setArg(aOrder);
            aCurr = aOrder;
        }
    }
    if (mDistinct) {
        Distinct aDistinct = new Distinct();
        if (aRoot == null) {
            aRoot = aCurr = aDistinct;
        } else {
            aCurr.setArg(aDistinct);
            aCurr = aDistinct;
        }
    }
    if (mReduced) {
        Reduced aReduced = new Reduced();
        if (aRoot == null) {
            aRoot = aCurr = aReduced;
        } else {
            aCurr.setArg(aReduced);
            aCurr = aReduced;
        }
    }
    TupleExpr aJoin = join();
    if (mQuery instanceof ParsedTupleQuery && mProjectionVars.isEmpty()) {
        VarNameCollector aCollector = new VarNameCollector();
        aJoin.visit(aCollector);
        mProjectionVars.addAll(aCollector.getVarNames());
    } else if (mQuery instanceof ParsedGraphQuery && mProjectionPatterns.isEmpty()) {
        StatementPatternCollector aCollector = new StatementPatternCollector();
        aJoin.visit(aCollector);
        mProjectionPatterns.addAll(aCollector.getStatementPatterns());
    }
    UnaryTupleOperator aProjection = projection();
    if (aRoot == null) {
        aRoot = aCurr = aProjection;
    } else {
        aCurr.setArg(aProjection);
    }
    if (aProjection.getArg() == null) {
        aCurr = aProjection;
    } else {
        // I think this is always a safe cast
        aCurr = (UnaryTupleOperator) aProjection.getArg();
    }
    if (aJoin != null) {
        aCurr.setArg(aJoin);
    }
    mQuery.setTupleExpr(aRoot);
    if (!mFrom.isEmpty() || !mFromNamed.isEmpty()) {
        SimpleDataset aDataset = new SimpleDataset();
        for (IRI aFrom : mFrom) {
            aDataset.addDefaultGraph(aFrom);
        }
        for (IRI aFrom : mFromNamed) {
            aDataset.addNamedGraph(aFrom);
        }
        mQuery.setDataset(aDataset);
    }
    return mQuery;
}
Also used : Order(org.eclipse.rdf4j.query.algebra.Order) StatementPatternCollector(org.eclipse.rdf4j.query.algebra.helpers.StatementPatternCollector) IRI(org.eclipse.rdf4j.model.IRI) Distinct(org.eclipse.rdf4j.query.algebra.Distinct) UnaryTupleOperator(org.eclipse.rdf4j.query.algebra.UnaryTupleOperator) Slice(org.eclipse.rdf4j.query.algebra.Slice) ParsedGraphQuery(org.eclipse.rdf4j.query.parser.ParsedGraphQuery) VarNameCollector(org.eclipse.rdf4j.query.algebra.helpers.VarNameCollector) SimpleDataset(org.eclipse.rdf4j.query.impl.SimpleDataset) Reduced(org.eclipse.rdf4j.query.algebra.Reduced) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr) ParsedTupleQuery(org.eclipse.rdf4j.query.parser.ParsedTupleQuery)

Example 57 with TupleExpr

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

the class AbstractQueryBuilder method groupAsJoin.

private TupleExpr groupAsJoin(List<Group> theList) {
    BinaryTupleOperator aJoin = new Join();
    Filter aFilter = null;
    for (Group aGroup : theList) {
        TupleExpr aExpr = aGroup.expr();
        if (aExpr == null) {
            continue;
        }
        if (aExpr instanceof Filter && (((Filter) aExpr).getArg() == null || ((Filter) aExpr).getArg() instanceof EmptySet)) {
            if (aFilter == null) {
                aFilter = (Filter) aExpr;
            } else {
                // if we already have a filter w/ an empty arg, let's And the
                // conditions together.
                aFilter.setCondition(new And(aFilter.getCondition(), ((Filter) aExpr).getCondition()));
            }
            continue;
        }
        if (aFilter != null) {
            aFilter.setArg(aExpr);
            aExpr = aFilter;
            aFilter = null;
        }
        if (aGroup.isOptional()) {
            LeftJoin lj = new LeftJoin();
            TupleExpr aLeft = joinOrExpr(aJoin);
            if (aLeft != null) {
                lj.setLeftArg(aLeft);
                lj.setRightArg(aExpr);
                aJoin = lj;
                continue;
            }
        }
        if (aJoin.getLeftArg() == null) {
            aJoin.setLeftArg(aExpr);
        } else if (aJoin.getRightArg() == null) {
            aJoin.setRightArg(aExpr);
        } else {
            Join aNewJoin = new Join();
            aNewJoin.setLeftArg(aJoin);
            aNewJoin.setRightArg(aExpr);
            aJoin = aNewJoin;
        }
    }
    TupleExpr aExpr = joinOrExpr(aJoin);
    if (aFilter != null) {
        aFilter.setArg(aExpr);
        aExpr = aFilter;
    }
    return aExpr;
}
Also used : LeftJoin(org.eclipse.rdf4j.query.algebra.LeftJoin) Filter(org.eclipse.rdf4j.query.algebra.Filter) And(org.eclipse.rdf4j.query.algebra.And) BinaryTupleOperator(org.eclipse.rdf4j.query.algebra.BinaryTupleOperator) EmptySet(org.eclipse.rdf4j.query.algebra.EmptySet) LeftJoin(org.eclipse.rdf4j.query.algebra.LeftJoin) Join(org.eclipse.rdf4j.query.algebra.Join) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 58 with TupleExpr

use of org.eclipse.rdf4j.query.algebra.TupleExpr 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)

Example 59 with TupleExpr

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

the class TupleExprBuilder method visit.

@Override
public Object visit(ASTMinusGraphPattern node, Object data) throws VisitorException {
    GraphPattern parentGP = graphPattern;
    TupleExpr leftArg = graphPattern.buildTupleExpr();
    graphPattern = new GraphPattern(parentGP);
    node.jjtGetChild(0).jjtAccept(this, null);
    TupleExpr rightArg = graphPattern.buildTupleExpr();
    parentGP = new GraphPattern();
    parentGP.addRequiredTE(new Difference(leftArg, rightArg));
    graphPattern = parentGP;
    return null;
}
Also used : Difference(org.eclipse.rdf4j.query.algebra.Difference) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 60 with TupleExpr

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

the class TupleExprBuilder method visit.

@Override
public Object visit(ASTBind node, Object data) throws VisitorException {
    // bind expression
    ValueExpr ve = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, data);
    // name to bind the expression outcome to
    Node aliasNode = node.jjtGetChild(1);
    String alias = ((ASTVar) aliasNode).getName();
    Extension extension = new Extension();
    extension.addElement(new ExtensionElem(ve, alias));
    TupleExpr result = null;
    TupleExpr arg = graphPattern.buildTupleExpr();
    // check if alias is not previously used.
    if (arg.getBindingNames().contains(alias)) {
        // SES-2314 we need to doublecheck that the reused varname is not
        // just
        // for an anonymous var or a constant.
        VarCollector collector = new VarCollector();
        arg.visit(collector);
        for (Var v : collector.getCollectedVars()) {
            if (alias.equals(v.getName())) {
                if (!v.isConstant() && !v.isAnonymous()) {
                    throw new VisitorException(String.format("BIND clause alias '%s' was previously used", alias));
                }
                break;
            }
        }
    }
    if (arg instanceof Filter) {
        result = arg;
        // the BIND expression.
        while (((Filter) arg).getArg() instanceof Filter) {
            arg = ((Filter) arg).getArg();
        }
        extension.setArg(((Filter) arg).getArg());
        ((Filter) arg).setArg(extension);
    } else {
        extension.setArg(arg);
        result = extension;
    }
    GraphPattern replacementGP = new GraphPattern(graphPattern);
    replacementGP.addRequiredTE(result);
    graphPattern = replacementGP;
    return result;
}
Also used : Extension(org.eclipse.rdf4j.query.algebra.Extension) ValueExpr(org.eclipse.rdf4j.query.algebra.ValueExpr) Filter(org.eclipse.rdf4j.query.algebra.Filter) Var(org.eclipse.rdf4j.query.algebra.Var) QueryModelNode(org.eclipse.rdf4j.query.algebra.QueryModelNode) IsBNode(org.eclipse.rdf4j.query.algebra.IsBNode) ExtensionElem(org.eclipse.rdf4j.query.algebra.ExtensionElem) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Aggregations

TupleExpr (org.eclipse.rdf4j.query.algebra.TupleExpr)61 ValueExpr (org.eclipse.rdf4j.query.algebra.ValueExpr)19 Var (org.eclipse.rdf4j.query.algebra.Var)14 Projection (org.eclipse.rdf4j.query.algebra.Projection)13 Join (org.eclipse.rdf4j.query.algebra.Join)12 ProjectionElemList (org.eclipse.rdf4j.query.algebra.ProjectionElemList)11 Slice (org.eclipse.rdf4j.query.algebra.Slice)11 ArrayList (java.util.ArrayList)9 Extension (org.eclipse.rdf4j.query.algebra.Extension)9 StatementPattern (org.eclipse.rdf4j.query.algebra.StatementPattern)9 Test (org.junit.Test)9 Distinct (org.eclipse.rdf4j.query.algebra.Distinct)8 ExtensionElem (org.eclipse.rdf4j.query.algebra.ExtensionElem)8 ProjectionElem (org.eclipse.rdf4j.query.algebra.ProjectionElem)8 Filter (org.eclipse.rdf4j.query.algebra.Filter)7 Union (org.eclipse.rdf4j.query.algebra.Union)7 Group (org.eclipse.rdf4j.query.algebra.Group)6 MultiProjection (org.eclipse.rdf4j.query.algebra.MultiProjection)6 Order (org.eclipse.rdf4j.query.algebra.Order)6 Reduced (org.eclipse.rdf4j.query.algebra.Reduced)6