@@ -766,17 +766,22 @@ private long candidatesMask(long mask) {
766766 private long computeCandidatesMask (long mask ) {
767767 long preferred = 0L ;
768768 long disconnected = 0L ;
769+ long disconnectedSmallBindingAssignments = 0L ;
769770 for (int i = 0 ; i < factors .size (); i ++) {
770771 if (contains (mask , i )) {
771772 continue ;
772773 }
773774 if (hasConnection (mask , i )) {
774775 preferred |= bit (i );
775776 } else {
776- disconnected |= bit (i );
777+ long bit = bit (i );
778+ disconnected |= bit ;
779+ if (isSmallBindingSetAssignment (i )) {
780+ disconnectedSmallBindingAssignments |= bit ;
781+ }
777782 }
778783 }
779- return preferred != 0L ? preferred : disconnected ;
784+ return preferred != 0L ? preferred | disconnectedSmallBindingAssignments : disconnected ;
780785 }
781786
782787 private SketchBasedJoinEstimator .JoinStepEstimate estimateTransition (long mask ,
@@ -1380,6 +1385,7 @@ private int compareBridgeUnlockOrder(StatePlan left, StatePlan right) {
13801385 int size = Math .min (left .order ().size (), right .order ().size ());
13811386 long leftMask = 0L ;
13821387 long rightMask = 0L ;
1388+ long lastIntroducedVars = 0L ;
13831389 for (int i = 0 ; i < size ; i ++) {
13841390 int leftIndex = left .order ().get (i ).intValue ();
13851391 int rightIndex = right .order ().get (i ).intValue ();
@@ -1391,20 +1397,78 @@ private int compareBridgeUnlockOrder(StatePlan left, StatePlan right) {
13911397 }
13921398 boolean leftLeaf = isLeafUnlock (leftIndex , leftMask );
13931399 boolean rightLeaf = isLeafUnlock (rightIndex , rightMask );
1400+ boolean leftOlderBoundLeaf = isOlderBoundRuntimeJoin (leftIndex , leftMask , lastIntroducedVars );
1401+ boolean rightOlderBoundLeaf = isOlderBoundRuntimeJoin (rightIndex , rightMask , lastIntroducedVars );
13941402 if (leftBridge && rightLeaf
1403+ && !rightOlderBoundLeaf
13951404 && bridgeUnlockStepComparable (left .physicalStepRanks ().get (i ),
13961405 right .physicalStepRanks ().get (i ))) {
13971406 return -1 ;
13981407 }
13991408 if (rightBridge && leftLeaf
1409+ && !leftOlderBoundLeaf
14001410 && bridgeUnlockStepComparable (right .physicalStepRanks ().get (i ),
14011411 left .physicalStepRanks ().get (i ))) {
14021412 return 1 ;
14031413 }
14041414 return 0 ;
14051415 }
1416+ long boundBeforeStep = boundVariableMask (leftMask );
14061417 leftMask |= bit (leftIndex );
14071418 rightMask |= bit (rightIndex );
1419+ lastIntroducedVars = bindingVarMasks [leftIndex ] & ~boundBeforeStep ;
1420+ }
1421+ return 0 ;
1422+ }
1423+
1424+ private boolean isOlderBoundLeaf (int factorIndex , long previousMask , long lastIntroducedVars ) {
1425+ return lastIntroducedVars != 0L
1426+ && isLeafUnlock (factorIndex , previousMask )
1427+ && joinStepRole (factorIndex , previousMask , lastIntroducedVars ) == JoinStepRole .OLDER_BOUND_JOIN ;
1428+ }
1429+
1430+ private boolean isOlderBoundRuntimeJoin (int factorIndex , long previousMask , long lastIntroducedVars ) {
1431+ if (lastIntroducedVars == 0L ) {
1432+ return false ;
1433+ }
1434+ long runtimeVars = runtimeVarMasks [factorIndex ];
1435+ if (runtimeVars == 0L || (runtimeVars & lastIntroducedVars ) != 0L ) {
1436+ return false ;
1437+ }
1438+ long olderBoundVars = runtimeBoundVariableMask (previousMask ) & ~lastIntroducedVars ;
1439+ return (runtimeVars & olderBoundVars ) != 0L ;
1440+ }
1441+
1442+ private int compareOlderBoundLeafOrder (StatePlan left , StatePlan right ) {
1443+ int size = Math .min (left .order ().size (), right .order ().size ());
1444+ long leftMask = 0L ;
1445+ long rightMask = 0L ;
1446+ long lastIntroducedVars = 0L ;
1447+ for (int i = 0 ; i < size ; i ++) {
1448+ int leftIndex = left .order ().get (i ).intValue ();
1449+ int rightIndex = right .order ().get (i ).intValue ();
1450+ if (leftIndex != rightIndex ) {
1451+ boolean leftOlderBoundLeaf = isOlderBoundRuntimeJoin (leftIndex , leftMask , lastIntroducedVars );
1452+ boolean rightOlderBoundLeaf = isOlderBoundRuntimeJoin (rightIndex , rightMask , lastIntroducedVars );
1453+ if (leftOlderBoundLeaf == rightOlderBoundLeaf ) {
1454+ return 0 ;
1455+ }
1456+ PhysicalStepRank leftStep = left .physicalStepRanks ().get (i );
1457+ PhysicalStepRank rightStep = right .physicalStepRanks ().get (i );
1458+ if (leftOlderBoundLeaf && stepWorkComparable (leftStep .workRows (), rightStep .workRows (),
1459+ BRIDGE_CONTINUATION_MAX_STEP_WORK_RATIO )) {
1460+ return -1 ;
1461+ }
1462+ if (rightOlderBoundLeaf && stepWorkComparable (rightStep .workRows (), leftStep .workRows (),
1463+ BRIDGE_CONTINUATION_MAX_STEP_WORK_RATIO )) {
1464+ return 1 ;
1465+ }
1466+ return 0 ;
1467+ }
1468+ long boundBeforeStep = boundVariableMask (leftMask );
1469+ leftMask |= bit (leftIndex );
1470+ rightMask |= bit (rightIndex );
1471+ lastIntroducedVars = bindingVarMasks [leftIndex ] & ~boundBeforeStep ;
14081472 }
14091473 return 0 ;
14101474 }
@@ -1830,19 +1894,25 @@ private boolean isBetter(StatePlan candidate, StatePlan incumbent) {
18301894 if (incumbent == null ) {
18311895 return true ;
18321896 }
1833- boolean structurallyComparableWork = structurallyComparableWork (candidate .totalWork (), incumbent .totalWork ());
1834- if (structurallyComparableWork && candidate .mask () == incumbent .mask ()) {
1897+ if (candidate .mask () == incumbent .mask ()) {
18351898 int deferredFilterComparison = compareDeferredFilterOrder (candidate .order (), incumbent .order ());
18361899 if (deferredFilterComparison != 0 ) {
18371900 return deferredFilterComparison < 0 ;
18381901 }
1902+ int guardedBindingComparison = compareGuardedBindingAssignmentOrder (candidate , incumbent );
1903+ if (guardedBindingComparison != 0 ) {
1904+ return guardedBindingComparison < 0 ;
1905+ }
1906+ }
1907+ boolean structurallyComparableWork = structurallyComparableWork (candidate .totalWork (), incumbent .totalWork ());
1908+ if (structurallyComparableWork && candidate .mask () == incumbent .mask ()) {
18391909 int boundGuardComparison = compareBoundGuardOrder (candidate .order (), incumbent .order ());
18401910 if (boundGuardComparison != 0 ) {
18411911 return boundGuardComparison < 0 ;
18421912 }
1843- int guardedBindingComparison = compareGuardedBindingAssignmentOrder (candidate , incumbent );
1844- if (guardedBindingComparison != 0 ) {
1845- return guardedBindingComparison < 0 ;
1913+ int narrowAnchorComparison = compareNarrowAnchorOrder (candidate , incumbent );
1914+ if (narrowAnchorComparison != 0 ) {
1915+ return narrowAnchorComparison < 0 ;
18461916 }
18471917 }
18481918 if (structurallyComparableWork && candidate .mask () == incumbent .mask ()) {
@@ -1851,9 +1921,15 @@ private boolean isBetter(StatePlan candidate, StatePlan incumbent) {
18511921 return bridgeUnlockComparison < 0 ;
18521922 }
18531923 }
1854- int connectivityComparison = compareOrderConnectivity (candidate .order (), incumbent .order ());
1855- if (connectivityComparison != 0 && structurallyComparableWork ) {
1856- return connectivityComparison < 0 ;
1924+ if (!structurallyComparableWork && candidate .mask () == incumbent .mask ()) {
1925+ int narrowAnchorComparison = compareNarrowAnchorOrder (candidate , incumbent );
1926+ if (narrowAnchorComparison != 0 ) {
1927+ return narrowAnchorComparison < 0 ;
1928+ }
1929+ }
1930+ int olderBoundLeafComparison = compareOlderBoundLeafOrder (candidate , incumbent );
1931+ if (olderBoundLeafComparison != 0 ) {
1932+ return olderBoundLeafComparison < 0 ;
18571933 }
18581934 int guardExpansionComparison = compareBoundGuardExpansionOrder (candidate , incumbent );
18591935 if (guardExpansionComparison != 0 ) {
@@ -1867,6 +1943,10 @@ private boolean isBetter(StatePlan candidate, StatePlan incumbent) {
18671943 if (continuationComparison != 0 ) {
18681944 return continuationComparison < 0 ;
18691945 }
1946+ int connectivityComparison = compareOrderConnectivity (candidate .order (), incumbent .order ());
1947+ if (connectivityComparison != 0 && structurallyComparableWork ) {
1948+ return connectivityComparison < 0 ;
1949+ }
18701950 int workComparison = Double .compare (candidate .totalWork (), incumbent .totalWork ());
18711951 if (workComparison != 0 ) {
18721952 return workComparison < 0 ;
@@ -1885,6 +1965,41 @@ private boolean isBetter(StatePlan candidate, StatePlan incumbent) {
18851965 return compareOrder (candidate .order (), incumbent .order ()) < 0 ;
18861966 }
18871967
1968+ private int compareNarrowAnchorOrder (StatePlan left , StatePlan right ) {
1969+ int size = Math .min (left .order ().size (), right .order ().size ());
1970+ long leftMask = 0L ;
1971+ long rightMask = 0L ;
1972+ for (int i = 0 ; i < size ; i ++) {
1973+ int leftIndex = left .order ().get (i ).intValue ();
1974+ int rightIndex = right .order ().get (i ).intValue ();
1975+ if (leftIndex != rightIndex ) {
1976+ if ((runtimeVarMasks [leftIndex ] & runtimeVarMasks [rightIndex ]) == 0L ) {
1977+ return 0 ;
1978+ }
1979+ long leftIntroduced = bindingVarMasks [leftIndex ] & ~boundVariableMask (leftMask );
1980+ long rightIntroduced = bindingVarMasks [rightIndex ] & ~boundVariableMask (rightMask );
1981+ if (isStrictSubset (leftIntroduced , rightIntroduced )
1982+ && stepWorkComparable (left .physicalStepRanks ().get (i ).workRows (),
1983+ right .physicalStepRanks ().get (i ).workRows (), ANCHOR_BRIDGE_MAX_STEP_WORK_RATIO )) {
1984+ return -1 ;
1985+ }
1986+ if (isStrictSubset (rightIntroduced , leftIntroduced )
1987+ && stepWorkComparable (right .physicalStepRanks ().get (i ).workRows (),
1988+ left .physicalStepRanks ().get (i ).workRows (), ANCHOR_BRIDGE_MAX_STEP_WORK_RATIO )) {
1989+ return 1 ;
1990+ }
1991+ return 0 ;
1992+ }
1993+ leftMask |= bit (leftIndex );
1994+ rightMask |= bit (rightIndex );
1995+ }
1996+ return 0 ;
1997+ }
1998+
1999+ private static boolean isStrictSubset (long subset , long superset ) {
2000+ return subset != 0L && subset != superset && (subset & superset ) == subset ;
2001+ }
2002+
18882003 private boolean structurallyComparableWork (double leftWorkRows , double rightWorkRows ) {
18892004 if (!isFiniteNonNegative (leftWorkRows ) || !isFiniteNonNegative (rightWorkRows )) {
18902005 return false ;
@@ -1958,6 +2073,9 @@ private double deferredFilterOrderingWeight(JoinOrderPlanner.FilterConstraint fi
19582073 && passRatio <= DEFERRED_FILTER_ORDERING_MAX_PASS_RATIO ) {
19592074 return 1.0d + (DEFERRED_FILTER_ORDERING_MAX_PASS_RATIO - passRatio );
19602075 }
2076+ if (filter .getConditionCost () > JoinOrderPlanner .FILTER_COST_CHEAP ) {
2077+ return 1.0d ;
2078+ }
19612079 return 0.0d ;
19622080 }
19632081
0 commit comments