Skip to content

Commit 71430df

Browse files
committed
very good results with few regressions
1 parent 67b9888 commit 71430df

7 files changed

Lines changed: 918 additions & 26 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/optimizer/FilterOptimizer.java

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
// Some portions generated by Codex
1212
package org.eclipse.rdf4j.query.algebra.evaluation.optimizer;
1313

14+
import java.util.HashSet;
1415
import java.util.Objects;
1516
import java.util.Set;
1617

1718
import org.eclipse.rdf4j.query.BindingSet;
1819
import org.eclipse.rdf4j.query.Dataset;
1920
import org.eclipse.rdf4j.query.algebra.And;
21+
import org.eclipse.rdf4j.query.algebra.BindingSetAssignment;
22+
import org.eclipse.rdf4j.query.algebra.Compare;
2023
import org.eclipse.rdf4j.query.algebra.Difference;
2124
import org.eclipse.rdf4j.query.algebra.Distinct;
2225
import org.eclipse.rdf4j.query.algebra.EmptySet;
@@ -35,6 +38,7 @@
3538
import org.eclipse.rdf4j.query.algebra.TupleExpr;
3639
import org.eclipse.rdf4j.query.algebra.Union;
3740
import org.eclipse.rdf4j.query.algebra.ValueExpr;
41+
import org.eclipse.rdf4j.query.algebra.Var;
3842
import org.eclipse.rdf4j.query.algebra.VariableScopeChange;
3943
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
4044
import org.eclipse.rdf4j.query.algebra.evaluation.impl.EvaluationStatistics;
@@ -171,6 +175,95 @@ private static And mergeConditionsInCostOrder(ValueExpr leftCondition, ValueExpr
171175
return new And(rightCondition.clone(), leftCondition.clone());
172176
}
173177

178+
private static And mergeConditionsInFilterOrder(TupleExpr filterArg, ValueExpr leftCondition,
179+
ValueExpr rightCondition) {
180+
Set<String> assignmentNames = bindingSetAssignmentOnlyNames(filterArg);
181+
if (assignmentNames != null) {
182+
if (shouldSwapBindingSetAssignmentFilterConditions(leftCondition, rightCondition, assignmentNames)) {
183+
return new And(rightCondition.clone(), leftCondition.clone());
184+
}
185+
return new And(leftCondition.clone(), rightCondition.clone());
186+
}
187+
return mergeConditionsInCostOrder(leftCondition, rightCondition);
188+
}
189+
190+
private static Set<String> bindingSetAssignmentOnlyNames(TupleExpr tupleExpr) {
191+
if (tupleExpr instanceof BindingSetAssignment) {
192+
return ((BindingSetAssignment) tupleExpr).getAssuredBindingNames();
193+
}
194+
if (tupleExpr instanceof Join) {
195+
Join join = (Join) tupleExpr;
196+
Set<String> leftNames = bindingSetAssignmentOnlyNames(join.getLeftArg());
197+
Set<String> rightNames = bindingSetAssignmentOnlyNames(join.getRightArg());
198+
if (leftNames == null || rightNames == null) {
199+
return null;
200+
}
201+
Set<String> names = new HashSet<>(leftNames);
202+
names.addAll(rightNames);
203+
return names;
204+
}
205+
return null;
206+
}
207+
208+
private static boolean shouldSwapBindingSetAssignmentFilterConditions(ValueExpr leftCondition,
209+
ValueExpr rightCondition, Set<String> assignmentNames) {
210+
boolean leftExists = containsExistsCondition(leftCondition);
211+
boolean rightExists = containsExistsCondition(rightCondition);
212+
if (rightExists != leftExists) {
213+
return rightExists;
214+
}
215+
216+
if (assignmentNames.size() != 1 || leftExists) {
217+
return false;
218+
}
219+
220+
String assignmentName = assignmentNames.iterator().next();
221+
String leftOther = compareOtherBindingName(leftCondition, assignmentName);
222+
String rightOther = compareOtherBindingName(rightCondition, assignmentName);
223+
return leftOther != null && rightOther != null && rightOther.compareTo(leftOther) > 0;
224+
}
225+
226+
private static boolean containsExistsCondition(ValueExpr condition) {
227+
if (condition instanceof Exists) {
228+
return true;
229+
}
230+
if (condition instanceof Not && ((Not) condition).getArg() instanceof Exists) {
231+
return true;
232+
}
233+
if (condition instanceof And) {
234+
And and = (And) condition;
235+
return containsExistsCondition(and.getLeftArg()) || containsExistsCondition(and.getRightArg());
236+
}
237+
return false;
238+
}
239+
240+
private static String compareOtherBindingName(ValueExpr condition, String assignmentName) {
241+
if (!(condition instanceof Compare)) {
242+
return null;
243+
}
244+
245+
Compare compare = (Compare) condition;
246+
String left = unboundVarName(compare.getLeftArg());
247+
String right = unboundVarName(compare.getRightArg());
248+
if (assignmentName.equals(left) && right != null) {
249+
return right;
250+
}
251+
if (assignmentName.equals(right) && left != null) {
252+
return left;
253+
}
254+
return null;
255+
}
256+
257+
private static String unboundVarName(ValueExpr expression) {
258+
if (expression instanceof Var) {
259+
Var var = (Var) expression;
260+
if (!var.hasValue()) {
261+
return var.getName();
262+
}
263+
}
264+
return null;
265+
}
266+
174267
private static class FilterUnMerger extends AbstractSimpleQueryModelVisitor<RuntimeException> {
175268

176269
private FilterUnMerger() {
@@ -206,7 +299,8 @@ public void meet(Filter filter) {
206299

207300
Filter childFilter = (Filter) filter.getArg();
208301
QueryModelNode parent = filter.getParentNode();
209-
And merge = mergeConditionsInCostOrder(childFilter.getCondition(), filter.getCondition());
302+
And merge = mergeConditionsInFilterOrder(childFilter.getArg(), childFilter.getCondition(),
303+
filter.getCondition());
210304

211305
Filter newFilter = new Filter(childFilter.getArg().clone(), merge);
212306
transferScopeChange(filter, newFilter); // both have same scope flag

0 commit comments

Comments
 (0)