5555public 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