This is an automated email from the ASF dual-hosted git repository. xxyu pushed a commit to branch kylin5 in repository https://gitbox.apache.org/repos/asf/kylin.git
commit 5c8bb0101796c48091a7e9faecea9e479c4ca6a9 Author: binbin.zheng <binbin.zh...@kyligence.io> AuthorDate: Thu Sep 29 18:44:26 2022 +0800 KYLIN-5323 fix segment matched to wrong model --- .../cube/realization/HybridRealization.java | 1 - .../metadata/realization/CapabilityResult.java | 6 ++- .../kylin/query/routing/CandidateSortTest.java | 59 ++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java index 0b3354bcf8..a40f4537d4 100644 --- a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java +++ b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java @@ -133,7 +133,6 @@ public class HybridRealization implements IRealization { public CapabilityResult isCapable(SQLDigest digest, List<NDataSegment> prunedSegments, List<NDataSegment> prunedStreamingSegments, Map<String, Set<Long>> secondStorageSegmentLayoutMap) { CapabilityResult result = new CapabilityResult(); - result.cost = Integer.MAX_VALUE; resolveSegmentsOverlap(prunedStreamingSegments); for (IRealization realization : getRealizations()) { diff --git a/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java b/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java index 2368812646..6cad1412b7 100644 --- a/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java +++ b/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java @@ -48,10 +48,14 @@ public class CapabilityResult { @Setter private IRealizationCandidate selectedStreamingCandidate; + @Getter + @Setter + private int layoutUnmatchedColsSize; + /** * The smaller the cost, the more capable the realization */ - public int cost; + public int cost = Integer.MAX_VALUE; /** * reason of incapable diff --git a/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java b/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java index f0d093addb..bdb79596e4 100644 --- a/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java +++ b/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java @@ -25,6 +25,7 @@ import java.util.Set; import org.apache.kylin.common.KylinConfig; import org.apache.kylin.common.QueryContext; +import org.apache.kylin.metadata.cube.cuboid.NLayoutCandidate; import org.apache.kylin.metadata.cube.model.NDataSegment; import org.apache.kylin.metadata.model.FunctionDesc; import org.apache.kylin.metadata.model.MeasureDesc; @@ -100,6 +101,31 @@ public class CandidateSortTest { val model3 = mockCandidate("model0003", "modelC", 4, 4); sort(model1, model2, model3).assertFirst(model1); } + + { + val model1 = mockCandidate("model0001", "modelA", 1, 1); + val model2 = mockEmptyCandidate("model0002", "modelB", 1); + sort(model1, model2).assertFirst(model1); + } + + { + val model1 = mockStreamingCandidate("model0001", "modelA", 1, 1); + val model2 = mockEmptyCandidate("model0002", "modelB", 1); + sort(model1, model2).assertFirst(model1); + } + + { + val model1 = mockHybridCandidate("model0001", "modelA", 1, 1, 2); + val model2 = mockEmptyCandidate("model0002", "modelB", 1); + sort(model1, model2).assertFirst(model1); + } + + { + val model1 = mockCandidate("model0001", "modelA", 1, 3); + val model2 = mockStreamingCandidate("model0002", "modelB", 1, 2); + val model3 = mockHybridCandidate("model0003", "modelC", 1, 4, 2); + sort(model1, model2, model3).assertFirst(model2); + } } private interface SortedCandidate { @@ -120,6 +146,39 @@ public class CandidateSortTest { candidate.realization = mockRealization(modelId, modelName, modelCost); val cap = new CapabilityResult(); cap.setSelectedCandidate(() -> candidateCost); + cap.cost = (int) cap.getSelectedCandidate().getCost(); + candidate.setCapability(cap); + return candidate; + } + + private Candidate mockStreamingCandidate(String modelId, String modelName, int modelCost, double candidateCost) { + val candidate = new Candidate(); + candidate.realization = mockRealization(modelId, modelName, modelCost); + val cap = new CapabilityResult(); + cap.setSelectedStreamingCandidate(() -> candidateCost); + cap.cost = (int) cap.getSelectedStreamingCandidate().getCost(); + candidate.setCapability(cap); + return candidate; + } + + private Candidate mockHybridCandidate(String modelId, String modelName, int modelCost, double candidateCost, + double streamingCandidateCost) { + val candidate = new Candidate(); + candidate.realization = mockRealization(modelId, modelName, modelCost); + val cap = new CapabilityResult(); + cap.setSelectedCandidate(() -> candidateCost); + cap.setSelectedStreamingCandidate(() -> streamingCandidateCost); + cap.cost = (int) Math.min(cap.getSelectedCandidate().getCost(), cap.getSelectedStreamingCandidate().getCost()); + candidate.setCapability(cap); + return candidate; + } + + private Candidate mockEmptyCandidate(String modelId, String modelName, int modelCost) { + val candidate = new Candidate(); + candidate.realization = mockRealization(modelId, modelName, modelCost); + val cap = new CapabilityResult(); + cap.setSelectedCandidate(NLayoutCandidate.EMPTY); + cap.setSelectedStreamingCandidate(NLayoutCandidate.EMPTY); candidate.setCapability(cap); return candidate; }