diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/AbstractPhysicalJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/AbstractPhysicalJoin.java index 9474aba3b5..84313a4535 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/AbstractPhysicalJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/AbstractPhysicalJoin.java @@ -53,6 +53,7 @@ public abstract class AbstractPhysicalJoin< protected final List otherJoinConjuncts; protected final JoinHint hint; protected final Optional markJoinSlotReference; + protected final List runtimeFilters = Lists.newArrayList(); // use for translate only protected final List filterConjuncts = Lists.newArrayList(); @@ -197,4 +198,12 @@ public abstract class AbstractPhysicalJoin< physicalJoin.put("Properties", properties); return physicalJoin; } + + public void addRuntimeFilter(RuntimeFilter rf) { + runtimeFilters.add(rf); + } + + public List getRuntimeFilters() { + return runtimeFilters; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java index b8528b1c37..013a8818a9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashJoin.java @@ -145,6 +145,10 @@ public class PhysicalHashJoin< args.add("hint"); args.add(hint); } + if (!runtimeFilters.isEmpty()) { + args.add("runtimeFilters"); + args.add(runtimeFilters.stream().map(rf -> rf.toString() + " ").collect(Collectors.toList())); + } return Utils.toSqlString("PhysicalHashJoin[" + id.asInt() + "]" + getGroupIdAsString(), args.toArray()); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/RuntimeFilter.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/RuntimeFilter.java index 12a545a22f..703a043b48 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/RuntimeFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/RuntimeFilter.java @@ -64,6 +64,7 @@ public class RuntimeFilter { this.builderNode = builderNode; this.bitmapFilterNotIn = bitmapFilterNotIn; this.buildSideNdv = buildSideNdv <= 0 ? -1L : buildSideNdv; + builderNode.addRuntimeFilter(this); } public Expression getSrcExpr() { @@ -101,4 +102,15 @@ public class RuntimeFilter { public long getBuildSideNdv() { return buildSideNdv; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("RF").append(id.asInt()) + .append("[").append(getSrcExpr()).append("->").append(targetSlot) + .append("(ndv/size = ").append(buildSideNdv).append("/") + .append(org.apache.doris.planner.RuntimeFilter.expectRuntimeFilterSize(buildSideNdv)) + .append(")"); + return sb.toString(); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java index 6b49b237c6..24aa57f34d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java @@ -1028,6 +1028,9 @@ public abstract class PlanNode extends TreeNode implements PlanStats { if (isBuildNode) { filterStr.append(" <- "); filterStr.append(filter.getSrcExpr().toSql()); + filterStr.append("(").append(filter.getEstimateNdv()).append("/") + .append(filter.getExpectFilterSizeBytes()).append("/") + .append(filter.getFilterSizeBytes()).append(")"); } else { filterStr.append(" -> "); filterStr.append(filter.getTargetExpr(getId()).toSql()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java b/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java index b606fedfcb..20cb993e7c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java @@ -33,6 +33,7 @@ import org.apache.doris.catalog.Type; import org.apache.doris.common.FeConstants; import org.apache.doris.common.IdGenerator; import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.SessionVariable; import org.apache.doris.thrift.TRuntimeFilterDesc; import org.apache.doris.thrift.TRuntimeFilterType; @@ -86,7 +87,8 @@ public final class RuntimeFilter { private long ndvEstimate = -1; // Size of the filter (in Bytes). Should be greater than zero for bloom filters. private long filterSizeBytes = 0; - public long expectFilterSizeBytes = 0; + + private long expectFilterSizeBytes = 0; // If true, the filter is produced by a broadcast join and there is at least one // destination scan node which is in the same fragment as the join; set in // DistributedPlanner.createHashJoinFragment(). @@ -546,19 +548,28 @@ public final class RuntimeFilter { * Considering that the `IN` filter may be converted to the `Bloom FIlter` when crossing fragments, * the bloom filter size is always calculated. */ - private void calculateFilterSize(RuntimeFilterGenerator.FilterSizeLimits filterSizeLimits) { + public void calculateFilterSize(RuntimeFilterGenerator.FilterSizeLimits filterSizeLimits) { if (ndvEstimate == -1) { filterSizeBytes = filterSizeLimits.defaultVal; return; } - double fpp = FeConstants.default_bloom_filter_fpp; - int logFilterSize = getMinLogSpaceForBloomFilter(ndvEstimate, fpp); - filterSizeBytes = 1L << logFilterSize; + SessionVariable sessionVariable = ConnectContext.get().getSessionVariable(); + if (sessionVariable.useRuntimeFilterDefaultSize) { + filterSizeBytes = filterSizeLimits.defaultVal; + return; + } + filterSizeBytes = expectRuntimeFilterSize(ndvEstimate); expectFilterSizeBytes = filterSizeBytes; filterSizeBytes = Math.max(filterSizeBytes, filterSizeLimits.minVal); filterSizeBytes = Math.min(filterSizeBytes, filterSizeLimits.maxVal); } + public static long expectRuntimeFilterSize(long ndv) { + double fpp = FeConstants.default_bloom_filter_fpp; + int logFilterSize = getMinLogSpaceForBloomFilter(ndv, fpp); + return 1L << logFilterSize; + } + /** * Returns the log (base 2) of the minimum number of bytes we need for a Bloom * filter with 'ndv' unique elements and a false positive probability of less @@ -620,4 +631,9 @@ public final class RuntimeFilter { + Joiner.on(", ").join(targets) + " " + "Selectivity: " + getSelectivity(); } + + + public long getExpectFilterSizeBytes() { + return expectFilterSizeBytes; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java index 2626997fd1..c0e31bf30c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java @@ -637,6 +637,9 @@ public class SessionVariable implements Serializable, Writable { @VariableMgr.VarAttr(name = RUNTIME_FILTER_MAX_IN_NUM) private int runtimeFilterMaxInNum = 102400; + @VariableMgr.VarAttr(name = USE_RF_DEFAULT) + public boolean useRuntimeFilterDefaultSize = false; + public int getBeNumberForTest() { return beNumberForTest; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java index 8f6976385a..70b7f2d66d 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -1408,98 +1408,131 @@ public class QueryPlanTest extends TestWithFeService { Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 1); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 2); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 3); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] <- `t1`.`k1`")); + + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 4); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[min_max] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[min_max] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 5); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[min_max] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 6); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] <- `t1`.`k1`, RF001[min_max] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] -> `t2`.`k1`, RF001[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 7); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[bloom] <- `t1`.`k1`," - + " RF002[min_max] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[bloom] -> `t2`.`k1`," - + " RF002[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[min_max] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 8); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 9); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 10); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] <- `t1`.`k1`, RF001[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] -> `t2`.`k1`, RF001[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 11); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[bloom] <- `t1`.`k1`, RF002[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[bloom] -> `t2`.`k1`, RF002[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 12); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[min_max] <- `t1`.`k1`, RF001[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[min_max] -> `t2`.`k1`, RF001[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 13); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[min_max] <- `t1`.`k1`, RF002[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[min_max] -> `t2`.`k1`, RF002[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 14); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] <- `t1`.`k1`, RF001[min_max] <- `t1`.`k1`, RF002[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[bloom] -> `t2`.`k1`, RF001[min_max] -> `t2`.`k1`, RF002[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[in_or_bloom] -> `t2`.`k1`")); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", 15); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`, RF001[bloom] <- `t1`.`k1`, RF002[min_max] <- `t1`.`k1`, RF003[in_or_bloom] <- `t1`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`, RF001[bloom] -> `t2`.`k1`, RF002[min_max] -> `t2`.`k1`, RF003[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[min_max] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF003[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF001[bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF002[min_max] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF003[in_or_bloom] -> `t2`.`k1`")); // support merge in filter, and forbidden implicit conversion to bloom filter queryStr = "explain select * from jointest t2 join [shuffle] jointest t1 where t1.k1 = t2.k1"; Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterMode", "GLOBAL"); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", TRuntimeFilterType.IN.getValue()); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] -> `t2`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in] <- `t1`.`k1`")); - Assert.assertFalse(explainString.contains("runtime filters: RF000[bloom] -> `t2`.`k1`")); - Assert.assertFalse(explainString.contains("runtime filters: RF000[bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in] <- `t1`.`k1`")); + Assert.assertFalse(explainString.contains("RF000[bloom] -> `t2`.`k1`")); + Assert.assertFalse(explainString.contains("RF000[bloom] <- `t1`.`k1`")); queryStr = "explain select * from jointest t2 join [shuffle] jointest t1 where t1.k1 = t2.k1"; Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterMode", "GLOBAL"); Deencapsulation.setField(connectContext.getSessionVariable(), "runtimeFilterType", TRuntimeFilterType.IN_OR_BLOOM.getValue()); explainString = getSQLPlanOrErrorMsg(queryStr); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in_or_bloom] -> `t2`.`k1`")); - Assert.assertTrue(explainString.contains("runtime filters: RF000[in_or_bloom] <- `t1`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in_or_bloom] -> `t2`.`k1`")); + Assert.assertTrue(explainString.contains("RF000[in_or_bloom] <- `t1`.`k1`")); } @Test diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/RuntimeFilterGeneratorTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/RuntimeFilterGeneratorTest.java index f8bdc7f3ac..2e5fb28cc0 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/RuntimeFilterGeneratorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/RuntimeFilterGeneratorTest.java @@ -155,16 +155,21 @@ public class RuntimeFilterGeneratorTest { Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 4); Assert.assertEquals(hashJoinNode.getRuntimeFilters().size(), 4); Assert.assertEquals(lhsScanNode.getRuntimeFilters().size(), 4); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + String rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains("RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains("RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains("RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains("RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); clearRuntimeFilterState(); new Expectations() { @@ -179,16 +184,23 @@ public class RuntimeFilterGeneratorTest { Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 4); Assert.assertEquals(hashJoinNode.getRuntimeFilters().size(), 4); Assert.assertEquals(lhsScanNode.getRuntimeFilters().size(), 4); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains("RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); clearRuntimeFilterState(); new Expectations() { @@ -248,7 +260,7 @@ public class RuntimeFilterGeneratorTest { }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`(-1/0/2097152)\n"); Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 1); @@ -266,7 +278,7 @@ public class RuntimeFilterGeneratorTest { }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); + "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`(-1/0/2097152)\n"); Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 1); @@ -283,12 +295,16 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + String rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -304,7 +320,7 @@ public class RuntimeFilterGeneratorTest { }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); + "RF000[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`(-1/0/2097152)\n"); Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), "RF000[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 1); @@ -321,12 +337,16 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -341,12 +361,17 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -361,14 +386,20 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 3); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 3); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 3); @@ -384,7 +415,7 @@ public class RuntimeFilterGeneratorTest { }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); + "RF000[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`(-1/0/2097152)\n"); Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), "RF000[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 1); @@ -401,12 +432,17 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -421,12 +457,16 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -441,14 +481,20 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 3); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 3); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 3); @@ -463,12 +509,16 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 2); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 2); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 2); @@ -483,14 +533,20 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 3); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 3); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 3); @@ -506,14 +562,20 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 3); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 3); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 3); @@ -528,16 +590,24 @@ public class RuntimeFilterGeneratorTest { } }; RuntimeFilterGenerator.generateRuntimeFilters(analyzer, hashJoinNode); - Assert.assertEquals(hashJoinNode.getRuntimeFilterExplainString(true), - "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`" - + ", RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`\n"); - Assert.assertEquals(lhsScanNode.getRuntimeFilterExplainString(false), - "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`" - + ", RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`\n"); + rfString = hashJoinNode.getRuntimeFilterExplainString(true); + Assert.assertTrue(rfString.contains( + "RF000[in] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] <- `default_cluster:test_db`.`test_rhs_tbl`.`test_rhs_col`")); + rfString = lhsScanNode.getRuntimeFilterExplainString(false); + Assert.assertTrue(rfString.contains( + "RF000[in] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF001[bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF002[min_max] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); + Assert.assertTrue(rfString.contains( + "RF003[in_or_bloom] -> `default_cluster:test_db`.`test_lhs_tbl`.`test_lhs_col`")); Assert.assertEquals(testPlanFragment.getTargetRuntimeFilterIds().size(), 4); Assert.assertEquals(testPlanFragment.getBuilderRuntimeFilterIds().size(), 4); Assert.assertEquals(analyzer.getAssignedRuntimeFilter().size(), 4);