diff --git a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/AbstractQueryModelNode.java b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/AbstractQueryModelNode.java index 36f5541cd04..1575f839144 100644 --- a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/AbstractQueryModelNode.java +++ b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/AbstractQueryModelNode.java @@ -15,7 +15,7 @@ /** * Base implementation of {@link QueryModelNode}. */ -public abstract class AbstractQueryModelNode implements QueryModelNode { +public abstract class AbstractQueryModelNode implements QueryModelNode, GraphPatternGroupable { /*-----------* * Variables * @@ -25,6 +25,8 @@ public abstract class AbstractQueryModelNode implements QueryModelNode { private QueryModelNode parent; + private boolean isGraphPatternGroup; + /*---------* * Methods * *---------*/ @@ -39,6 +41,26 @@ public void setParentNode(QueryModelNode parent) { this.parent = parent; } + /* + * (non-Javadoc) + * + * @see org.eclipse.rdf4j.query.algebra.GraphPatternGroupable#isGraphPatternGroup() + */ + @Override + public boolean isGraphPatternGroup() { + return isGraphPatternGroup; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.rdf4j.query.algebra.GraphPatternGroupable#setGraphPatternGroup(boolean) + */ + @Override + public void setGraphPatternGroup(boolean isGraphPatternGroup) { + this.isGraphPatternGroup = isGraphPatternGroup; + } + /** * Dummy implementation of {@link QueryModelNode#visitChildren} that does nothing. Subclasses should override this * method when they have child nodes. diff --git a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/GraphPatternGroupable.java b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/GraphPatternGroupable.java new file mode 100644 index 00000000000..0b603fd84d9 --- /dev/null +++ b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/GraphPatternGroupable.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2019 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ +package org.eclipse.rdf4j.query.algebra; + +/** + * {@link QueryModelNode}s that can represent a full graph pattern group. + * + * Although the notion of a graph pattern group is strictly not relevant at the algebra level, it gives an indication to + * evaluation strategy implementations on how they can optimize join patterns wrt variable scope. + * + * @author Jeen Broekstra + * + */ +public interface GraphPatternGroupable { + + /** + * indicates if the node represents the root of a graph pattern group. + * + * @return true iff the node represents the node of a graph pattern group. + * + */ + public boolean isGraphPatternGroup(); + + /** + * Set the value of {@link #isGraphPatternGroup()} to true or false. + */ + public void setGraphPatternGroup(boolean isGraphPatternGroup); + +} diff --git a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/UnaryTupleOperator.java b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/UnaryTupleOperator.java index 7201599cd62..1cf6a01e427 100644 --- a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/UnaryTupleOperator.java +++ b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/UnaryTupleOperator.java @@ -12,7 +12,7 @@ /** * An abstract superclass for unary tuple operators which, by definition, has one argument. */ -public abstract class UnaryTupleOperator extends AbstractQueryModelNode implements TupleExpr { +public abstract class UnaryTupleOperator extends AbstractQueryModelNode implements TupleExpr, GraphPatternGroupable { /*-----------* * Variables * @@ -23,6 +23,8 @@ public abstract class UnaryTupleOperator extends AbstractQueryModelNode implemen */ protected TupleExpr arg; + private boolean isGraphPatternGroup; + /*--------------* * Constructors * *--------------*/ @@ -43,6 +45,16 @@ public UnaryTupleOperator(TupleExpr arg) { * Methods * *---------*/ + @Override + public boolean isGraphPatternGroup() { + return isGraphPatternGroup; + } + + @Override + public void setGraphPatternGroup(boolean isGraphPatternGroup) { + this.isGraphPatternGroup = isGraphPatternGroup; + } + /** * Gets the argument of this unary tuple operator. * diff --git a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/helpers/TupleExprs.java b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/helpers/TupleExprs.java index 55f0509cf01..4c71d5fbea5 100644 --- a/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/helpers/TupleExprs.java +++ b/queryalgebra-model/src/main/java/org/eclipse/rdf4j/query/algebra/helpers/TupleExprs.java @@ -15,6 +15,7 @@ import org.eclipse.rdf4j.model.BNode; import org.eclipse.rdf4j.model.Literal; import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.query.algebra.GraphPatternGroupable; import org.eclipse.rdf4j.query.algebra.Join; import org.eclipse.rdf4j.query.algebra.Projection; import org.eclipse.rdf4j.query.algebra.QueryModelNode; @@ -55,6 +56,20 @@ public static boolean containsSubquery(TupleExpr t) { return false; } + /** + * Verifies if the supplied {@link TupleExpr} represents a group graph pattern. + * + * @param expr a {@link TupleExpr} + * @return true if the {@link TupleExpr} is {@link GraphPatternGroupable} and has its graph pattern + * group flag set to true, false otherwise. + */ + public static boolean isGraphPatternGroup(TupleExpr expr) { + if (expr instanceof GraphPatternGroupable) { + return ((GraphPatternGroupable) expr).isGraphPatternGroup(); + } + return false; + } + /** * Verifies if the supplied {@link TupleExpr} contains a {@link Projection}. If the supplied TupleExpr is a * {@link Join} or contains a {@link Join}, projections inside that Join's arguments will not be taken into account. diff --git a/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/GraphPattern.java b/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/GraphPattern.java index 84a3a031be9..9795aa7a4d9 100644 --- a/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/GraphPattern.java +++ b/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/GraphPattern.java @@ -164,13 +164,7 @@ public TupleExpr buildTupleExpr() { for (int i = 1; i < requiredTEs.size(); i++) { TupleExpr te = requiredTEs.get(i); - // if (containsProjection(te) || containsProjection(result)) - // { - // result = new BottomUpJoin(result, te); - // } - // else { result = new Join(result, te); - // } } } diff --git a/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/TupleExprBuilder.java b/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/TupleExprBuilder.java index a9628adb274..68776119aaa 100644 --- a/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/TupleExprBuilder.java +++ b/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/TupleExprBuilder.java @@ -47,6 +47,7 @@ import org.eclipse.rdf4j.query.algebra.ExtensionElem; import org.eclipse.rdf4j.query.algebra.Filter; import org.eclipse.rdf4j.query.algebra.FunctionCall; +import org.eclipse.rdf4j.query.algebra.GraphPatternGroupable; import org.eclipse.rdf4j.query.algebra.Group; import org.eclipse.rdf4j.query.algebra.GroupConcat; import org.eclipse.rdf4j.query.algebra.GroupElem; @@ -1023,6 +1024,8 @@ public Object visit(ASTGraphPatternGroup node, Object data) throws VisitorExcept // bindings external to the group TupleExpr te = graphPattern.buildTupleExpr(); + ((GraphPatternGroupable) te).setGraphPatternGroup(true); + parentGP.addRequiredTE(te); graphPattern = parentGP;