Skip to content

Commit b8a5668

Browse files
author
Jeen Broekstra
authored
Merge pull request #797 from jamesrdf/issues/#695-join-projection
Fix #695: Don't treat path modifiers as subqueries
2 parents 0867d36 + 61007ee commit b8a5668

8 files changed

Lines changed: 54 additions & 7 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/QueryJoinOptimizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ protected List<TupleExpr> getSubSelects(List<TupleExpr> expressions) {
202202
List<TupleExpr> subselects = new ArrayList<TupleExpr>();
203203

204204
for (TupleExpr expr : expressions) {
205-
if (TupleExprs.containsProjection(expr)) {
205+
if (TupleExprs.containsSubquery(expr)) {
206206
subselects.add(expr);
207207
}
208208
}

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/StrictEvaluationStrategy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Join jo
911911
return new ServiceJoinIterator(leftIter, (Service)join.getRightArg(), bindings, this);
912912
}
913913

914-
if (TupleExprs.containsProjection(join.getRightArg())) {
914+
if (TupleExprs.containsSubquery(join.getRightArg())) {
915915
return new HashJoinIteration(this, join, bindings);
916916
}
917917
else {
@@ -923,7 +923,7 @@ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(LeftJoi
923923
final BindingSet bindings)
924924
throws QueryEvaluationException
925925
{
926-
if (TupleExprs.containsProjection(leftJoin.getRightArg())) {
926+
if (TupleExprs.containsSubquery(leftJoin.getRightArg())) {
927927
return new HashJoinIteration(this, leftJoin, bindings);
928928
}
929929

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/limited/LimitedSizeEvaluationStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Join jo
152152
return new ServiceJoinIterator(leftIter, (Service)join.getRightArg(), bindings, this);
153153
}
154154

155-
if (TupleExprs.containsProjection(join.getRightArg())) {
155+
if (TupleExprs.containsSubquery(join.getRightArg())) {
156156
return new LimitedSizeHashJoinIteration(this, join, bindings, used, maxSize);
157157
}
158158
else {

core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/Join.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public Join(TupleExpr leftArg, TupleExpr rightArg) {
4242
*/
4343
@Deprecated
4444
public boolean hasSubSelectInRightArg() {
45-
return TupleExprs.containsProjection(rightArg);
45+
return TupleExprs.containsSubquery(rightArg);
4646
}
4747

4848
public Set<String> getBindingNames() {

core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/Projection.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public class Projection extends UnaryTupleOperator {
2222

2323
private Var projectionContext = null;
2424

25+
private boolean subquery = true;
26+
2527
/*--------------*
2628
* Constructors *
2729
*--------------*/
@@ -38,6 +40,11 @@ public Projection(TupleExpr arg, ProjectionElemList elements) {
3840
setProjectionElemList(elements);
3941
}
4042

43+
public Projection(TupleExpr arg, ProjectionElemList elements, boolean subquery) {
44+
this(arg, elements);
45+
this.subquery = subquery;
46+
}
47+
4148
/*---------*
4249
* Methods *
4350
*---------*/
@@ -123,4 +130,12 @@ public void setProjectionContext(Var projectionContext) {
123130
this.projectionContext = projectionContext;
124131
}
125132

133+
public boolean isSubquery() {
134+
return subquery;
135+
}
136+
137+
public void setSubquery(boolean subquery) {
138+
this.subquery = subquery;
139+
}
140+
126141
}

core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/helpers/TupleExprs.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@
2828
*/
2929
public class TupleExprs {
3030

31+
/**
32+
* Verifies if the supplied {@link TupleExpr} contains a {@link Projection} with the subquery flag set to
33+
* true (default). If the supplied TupleExpr is a {@link Join} or contains a {@link Join}, projections
34+
* inside that Join's arguments will not be taken into account.
35+
*
36+
* @param t
37+
* a tuple expression.
38+
* @return <code>true</code> if the TupleExpr contains a subquery projection (outside of a Join),
39+
* <code>false</code> otherwise.
40+
*/
41+
public static boolean containsSubquery(TupleExpr t) {
42+
Deque<TupleExpr> queue = new ArrayDeque<>();
43+
queue.add(t);
44+
while (!queue.isEmpty()) {
45+
TupleExpr n = queue.removeFirst();
46+
if (n instanceof Projection && ((Projection)n).isSubquery()) {
47+
return true;
48+
}
49+
else if (n instanceof Join) {
50+
// projections already inside a Join need not be
51+
// taken into account
52+
return false;
53+
}
54+
else {
55+
queue.addAll(getChildren(n));
56+
}
57+
}
58+
return false;
59+
}
60+
3161
/**
3262
* Verifies if the supplied {@link TupleExpr} contains a {@link Projection}. If the supplied TupleExpr is
3363
* a {@link Join} or contains a {@link Join}, projections inside that Join's arguments will not be taken
@@ -37,7 +67,9 @@ public class TupleExprs {
3767
* a tuple expression.
3868
* @return <code>true</code> if the TupleExpr contains a projection (outside of a Join),
3969
* <code>false</code> otherwise.
70+
* @deprecated Since 2.3. Use {@link TupleExprs#containsSubQuery(TupleExpr)} instead.
4071
*/
72+
@Deprecated
4173
public static boolean containsProjection(TupleExpr t) {
4274
Deque<TupleExpr> queue = new ArrayDeque<>();
4375
queue.add(t);

core/queryparser/sparql/src/main/java/org/eclipse/rdf4j/query/parser/sparql/TupleExprBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ private TupleExpr handlePathModifiers(Scope scope, Var subjVar, TupleExpr te, Va
17001700
pelist.addElement(pe);
17011701
}
17021702

1703-
result = new Distinct(new Projection(union, pelist));
1703+
result = new Distinct(new Projection(union, pelist, false));
17041704
}
17051705
else {
17061706
// upperbound is abitrary-length

core/sail/federation/src/main/java/org/eclipse/rdf4j/sail/federation/evaluation/FederationStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(NaryJoi
9191
for (int i = 1, n = join.getNumberOfArguments(); i < n; i++) {
9292

9393
TupleExpr rightArg = join.getArg(i);
94-
if (TupleExprs.containsProjection(rightArg)
94+
if (TupleExprs.containsSubquery(rightArg)
9595
|| (rightArg instanceof OwnedTupleExpr && ((OwnedTupleExpr)rightArg).hasQuery()))
9696
{
9797
TupleExpr leftArg = join.getArg(i - 1);

0 commit comments

Comments
 (0)