Source:
private static SymbolStatsEstimate subtractColumnStats( SymbolStatsEstimate leftStats, double leftRowCount, SymbolStatsEstimate rightStats, double rightRowCount, double newRowCount, RangeSubtractionStrategy strategy) { StatisticRange leftRange = StatisticRange.from(leftStats); StatisticRange rightRange = StatisticRange.from(rightStats); double nullsCountLeft = leftStats.getNullsFraction() * leftRowCount; double nullsCountRight = rightStats.getNullsFraction() * rightRowCount; double totalSizeLeft = (leftRowCount - nullsCountLeft) * leftStats.getAverageRowSize(); double totalSizeRight = (rightRowCount - nullsCountRight) * rightStats.getAverageRowSize(); double newNullsFraction = Math.max(nullsCountLeft - nullsCountRight, 0.0) / newRowCount; double newNonNullsRowCount = newRowCount * (1.0 - newNullsFraction); StatisticRange range = leftRange; double newDistinctValuesCount = leftStats.getDistinctValuesCount(); double leftValuesPerDistinctValue = leftRowCount * (1.0 - leftStats.getNullsFraction()) / leftStats.getDistinctValuesCount(); double rightValuesPerDistinctValue = rightRowCount * (1.0 - rightStats.getNullsFraction()) / rightStats.getDistinctValuesCount(); if (leftValuesPerDistinctValue < rightValuesPerDistinctValue) { range = strategy.range(leftRange, rightRange); newDistinctValuesCount = leftStats.getDistinctValuesCount() - rightStats.getDistinctValuesCount(); } return SymbolStatsEstimate.builder() .setDistinctValuesCount(newDistinctValuesCount) .setHighValue(range.getHigh()) .setLowValue(range.getLow()) .setAverageRowSize((totalSizeLeft - totalSizeRight) / newNonNullsRowCount) .setNullsFraction(newNullsFraction) .build(); }

Target:
private static SymbolStatsEstimate subtractColumnStats( SymbolStatsEstimate leftStats, double leftRowCount, SymbolStatsEstimate rightStats, double rightRowCount, double newRowCount, RangeSubtractionStrategy strategy) { StatisticRange leftRange = StatisticRange.from(leftStats); StatisticRange rightRange = StatisticRange.from(rightStats); double nullsCountLeft = leftStats.getNullsFraction() * leftRowCount; double nullsCountRight = rightStats.getNullsFraction() * rightRowCount; double totalSizeLeft = (leftRowCount - nullsCountLeft) * leftStats.getAverageRowSize(); double totalSizeRight = (rightRowCount - nullsCountRight) * rightStats.getAverageRowSize(); double newNullsFraction = Math.max(nullsCountLeft - nullsCountRight, 0.0) / newRowCount; double newNonNullsRowCount = newRowCount * (1.0 - newNullsFraction); StatisticRange range = leftRange; double newDistinctValuesCount = leftStats.getDistinctValuesCount(); double leftValuesPerDistinctValue = leftRowCount * (1.0 - leftStats.getNullsFraction()) / leftStats.getDistinctValuesCount(); double rightValuesPerDistinctValue = rightRowCount * (1.0 - rightStats.getNullsFraction()) / rightStats.getDistinctValuesCount(); if (leftValuesPerDistinctValue <= rightValuesPerDistinctValue) { range = strategy.range(leftRange, rightRange); newDistinctValuesCount = leftStats.getDistinctValuesCount() - rightStats.getDistinctValuesCount(); } return SymbolStatsEstimate.builder() .setDistinctValuesCount(newDistinctValuesCount) .setHighValue(range.getHigh()) .setLowValue(range.getLow()) .setAverageRowSize((totalSizeLeft - totalSizeRight) / newNonNullsRowCount) .setNullsFraction(newNullsFraction) .build(); }