Skip to content

Commit 442321b

Browse files
committed
initial implementation
1 parent 78c2bee commit 442321b

24 files changed

Lines changed: 2257 additions & 30 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public DefaultEvaluationStrategy(TripleSource tripleSource, Dataset dataset,
285285
this.dataset = dataset;
286286
this.serviceResolver = serviceResolver;
287287
this.iterationCacheSyncThreshold = iterationCacheSyncTreshold;
288-
this.pipeline = new org.eclipse.rdf4j.query.algebra.evaluation.optimizer.StandardQueryOptimizerPipeline(this,
288+
this.pipeline = new org.eclipse.rdf4j.query.algebra.evaluation.optimizer.SparqlUoQueryOptimizerPipeline(this,
289289
tripleSource, evaluationStatistics);
290290
this.trackResultSize = trackResultSize;
291291
this.tupleFuncRegistry = tupleFunctionRegistry;
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.optimizer;
13+
14+
import org.eclipse.rdf4j.query.BindingSet;
15+
import org.eclipse.rdf4j.query.Dataset;
16+
import org.eclipse.rdf4j.query.algebra.Exists;
17+
import org.eclipse.rdf4j.query.algebra.Join;
18+
import org.eclipse.rdf4j.query.algebra.LeftJoin;
19+
import org.eclipse.rdf4j.query.algebra.Not;
20+
import org.eclipse.rdf4j.query.algebra.Projection;
21+
import org.eclipse.rdf4j.query.algebra.QueryRoot;
22+
import org.eclipse.rdf4j.query.algebra.Service;
23+
import org.eclipse.rdf4j.query.algebra.StatementPattern;
24+
import org.eclipse.rdf4j.query.algebra.TupleExpr;
25+
import org.eclipse.rdf4j.query.algebra.Union;
26+
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
27+
import org.eclipse.rdf4j.query.algebra.evaluation.impl.EvaluationStatistics;
28+
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo.BeCostEstimator;
29+
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo.BeGroupNode;
30+
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo.BeTreeBuilder;
31+
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo.BeTreeSerializer;
32+
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo.BeTreeTransformer;
33+
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
34+
35+
public class SparqlUoOptimizer implements QueryOptimizer {
36+
37+
private static final ParentReferenceCleaner PARENT_REFERENCE_CLEANER = new ParentReferenceCleaner();
38+
39+
private final BeTreeBuilder builder = new BeTreeBuilder();
40+
private final BeTreeSerializer serializer = new BeTreeSerializer();
41+
private final BeTreeTransformer transformer;
42+
43+
public SparqlUoOptimizer(EvaluationStatistics evaluationStatistics) {
44+
this(evaluationStatistics, false);
45+
}
46+
47+
public SparqlUoOptimizer(EvaluationStatistics evaluationStatistics, boolean allowNonImprovingTransforms) {
48+
this.transformer = new BeTreeTransformer(new BeCostEstimator(evaluationStatistics),
49+
allowNonImprovingTransforms);
50+
}
51+
52+
@Override
53+
public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
54+
PARENT_REFERENCE_CLEANER.optimize(tupleExpr, dataset, bindings);
55+
tupleExpr.visit(new SparqlUoVisitor());
56+
}
57+
58+
private class SparqlUoVisitor extends AbstractQueryModelVisitor<RuntimeException> {
59+
60+
@Override
61+
public void meet(Join node) {
62+
if (isGroupRoot(node)) {
63+
rewrite(node);
64+
return;
65+
}
66+
super.meet(node);
67+
}
68+
69+
@Override
70+
public void meet(LeftJoin node) {
71+
if (node.getCondition() == null && isGroupRoot(node)) {
72+
rewrite(node);
73+
return;
74+
}
75+
super.meet(node);
76+
}
77+
78+
@Override
79+
public void meet(Union node) {
80+
if (isGroupRoot(node)) {
81+
rewrite(node);
82+
return;
83+
}
84+
super.meet(node);
85+
}
86+
87+
@Override
88+
public void meet(StatementPattern node) {
89+
if (isGroupRoot(node)) {
90+
rewrite(node);
91+
}
92+
}
93+
94+
@Override
95+
public void meet(Service node) {
96+
// Skip SERVICE subtrees to avoid changing remote semantics.
97+
}
98+
99+
@Override
100+
public void meet(Projection node) {
101+
if (node.isSubquery() && !(node.getParentNode() instanceof QueryRoot)) {
102+
return;
103+
}
104+
super.meet(node);
105+
}
106+
107+
@Override
108+
public void meet(Exists node) {
109+
// Skip EXISTS subqueries.
110+
}
111+
112+
@Override
113+
public void meet(Not node) {
114+
// Skip NOT EXISTS subqueries.
115+
}
116+
117+
private boolean isGroupRoot(TupleExpr node) {
118+
if (node.getParentNode() == null) {
119+
return false;
120+
}
121+
return !(node.getParentNode() instanceof Join
122+
|| node.getParentNode() instanceof LeftJoin
123+
|| node.getParentNode() instanceof Union);
124+
}
125+
126+
private void rewrite(TupleExpr node) {
127+
BeGroupNode group = builder.build(node);
128+
transformer.transform(group);
129+
TupleExpr replacement = serializer.serialize(group);
130+
node.replaceWith(replacement);
131+
}
132+
}
133+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.optimizer;
13+
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
17+
import org.eclipse.rdf4j.query.algebra.evaluation.EvaluationStrategy;
18+
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
19+
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizerPipeline;
20+
import org.eclipse.rdf4j.query.algebra.evaluation.TripleSource;
21+
import org.eclipse.rdf4j.query.algebra.evaluation.impl.EvaluationStatistics;
22+
23+
public class SparqlUoQueryOptimizerPipeline implements QueryOptimizerPipeline {
24+
25+
private final QueryOptimizerPipeline delegate;
26+
private final SparqlUoOptimizer sparqlUoOptimizer;
27+
28+
public SparqlUoQueryOptimizerPipeline(EvaluationStrategy strategy, TripleSource tripleSource,
29+
EvaluationStatistics evaluationStatistics) {
30+
this.delegate = new StandardQueryOptimizerPipeline(strategy, tripleSource, evaluationStatistics);
31+
this.sparqlUoOptimizer = new SparqlUoOptimizer(evaluationStatistics);
32+
}
33+
34+
@Override
35+
public Iterable<QueryOptimizer> getOptimizers() {
36+
List<QueryOptimizer> optimizers = new ArrayList<>();
37+
boolean inserted = false;
38+
for (QueryOptimizer optimizer : delegate.getOptimizers()) {
39+
if (!inserted && optimizer instanceof QueryJoinOptimizer) {
40+
optimizers.add(sparqlUoOptimizer);
41+
inserted = true;
42+
}
43+
optimizers.add(optimizer);
44+
}
45+
if (!inserted) {
46+
optimizers.add(sparqlUoOptimizer);
47+
}
48+
return optimizers;
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo;
13+
14+
public abstract class AbstractBeNode implements BeNode {
15+
private BeNode parent;
16+
17+
@Override
18+
public BeNode getParent() {
19+
return parent;
20+
}
21+
22+
@Override
23+
public void setParent(BeNode parent) {
24+
this.parent = parent;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.optimizer.sparqluo;
13+
14+
import java.util.Objects;
15+
16+
import org.eclipse.rdf4j.query.algebra.TupleExpr;
17+
18+
public class BeBarrierNode extends AbstractBeNode {
19+
private final TupleExpr tupleExpr;
20+
21+
BeBarrierNode(TupleExpr tupleExpr) {
22+
this.tupleExpr = Objects.requireNonNull(tupleExpr, "tupleExpr");
23+
}
24+
25+
@Override
26+
public BeNodeType getType() {
27+
return BeNodeType.BARRIER;
28+
}
29+
30+
TupleExpr getTupleExpr() {
31+
return tupleExpr;
32+
}
33+
}

0 commit comments

Comments
 (0)