Skip to content

Commit b7821d4

Browse files
committed
wip
1 parent 5e4b1f5 commit b7821d4

1 file changed

Lines changed: 19 additions & 3 deletions

File tree

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
public class ExistsSemiJoinOptimizer implements QueryOptimizer {
5656

5757
private static final double MAX_RIGHT_TO_LEFT_RATIO = 8.0;
58+
private static final double MIN_LEFT_TO_RIGHT_RATIO_FOR_SINGLE_STATEMENT_PATTERN = 8.0;
5859

5960
private final EvaluationStatistics evaluationStatistics;
6061
private final boolean allowNonImprovingTransforms;
@@ -112,7 +113,7 @@ public void meet(Filter filter) {
112113
if (!hasStatementPatternCoveringVars(subQuery, shared)) {
113114
return;
114115
}
115-
if (shouldKeepExistsAsFilter(subQuery, shared)) {
116+
if (shouldKeepExistsAsFilter(arg, subQuery, shared)) {
116117
return;
117118
}
118119
TupleExpr right = buildDistinctProjection(subQuery.clone(), shared);
@@ -128,12 +129,27 @@ public void meet(Filter filter) {
128129
filter.setCondition(extraction.remainingCondition);
129130
}
130131

131-
private boolean shouldKeepExistsAsFilter(TupleExpr subQuery, Set<String> joinVars) {
132+
private boolean shouldKeepExistsAsFilter(TupleExpr leftArg, TupleExpr subQuery, Set<String> joinVars) {
132133
StatementPattern statementPattern = singleStatementPatternOrNull(subQuery);
133134
if (statementPattern == null) {
134135
return false;
135136
}
136-
return countUnboundNonJoinVars(statementPattern, joinVars) == 0;
137+
Map<String, String> aliases = collectAliasMap(leftArg);
138+
if (!aliases.isEmpty() && joinVars.stream().anyMatch(aliases::containsKey)) {
139+
return false;
140+
}
141+
142+
int localVarCount = countUnboundNonJoinVars(statementPattern, joinVars);
143+
if (localVarCount == 0) {
144+
return true;
145+
}
146+
147+
double leftCardinality = evaluationStatistics.getCardinality(leftArg);
148+
double rightCardinality = evaluationStatistics.getCardinality(subQuery);
149+
if (!Double.isFinite(leftCardinality) || !Double.isFinite(rightCardinality) || rightCardinality <= 0.0) {
150+
return true;
151+
}
152+
return leftCardinality < rightCardinality * MIN_LEFT_TO_RIGHT_RATIO_FOR_SINGLE_STATEMENT_PATTERN;
137153
}
138154

139155
private boolean shouldRewrite(TupleExpr left, TupleExpr right) {

0 commit comments

Comments
 (0)