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;