KYLIN-2514 reorder joinTable first Signed-off-by: Hongbin Ma <mahong...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/08600484 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/08600484 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/08600484 Branch: refs/heads/KYLIN-2501 Commit: 0860048484639aa07f745726a58c8544a911e5f6 Parents: 19c87e7 Author: Roger Shi <rogershijich...@hotmail.com> Authored: Sat Mar 18 14:58:25 2017 +0800 Committer: Hongbin Ma <mahong...@apache.org> Committed: Sat Mar 18 17:29:20 2017 +0800 ---------------------------------------------------------------------- .../kylin/metadata/model/DataModelDesc.java | 43 +++++++++++++++++++- .../apache/kylin/metadata/model/JoinsTree.java | 42 ++----------------- 2 files changed, 45 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/08600484/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java index 0a303ec..a26ccce 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java @@ -19,11 +19,13 @@ package org.apache.kylin.metadata.model; import java.io.Serializable; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.Set; import org.apache.commons.lang3.ArrayUtils; @@ -49,11 +51,11 @@ import com.google.common.collect.Sets; public class DataModelDesc extends RootPersistentEntity { private static final Logger logger = LoggerFactory.getLogger(DataModelDesc.class); - public static enum TableKind implements Serializable{ + public static enum TableKind implements Serializable { FACT, LOOKUP } - public static enum RealizationCapacity implements Serializable{ + public static enum RealizationCapacity implements Serializable { SMALL, MEDIUM, LARGE } @@ -295,6 +297,7 @@ public class DataModelDesc extends RootPersistentEntity { initJoinTablesForUpgrade(); initTableAlias(tables); initJoinColumns(); + reorderJoins(tables); initJoinsTree(); initDimensionsAndMetrics(); initPartitionDesc(); @@ -452,6 +455,42 @@ public class DataModelDesc extends RootPersistentEntity { joinsTree = new JoinsTree(rootFactTableRef, joins); } + private void reorderJoins(Map<String, TableDesc> tables) { + if (joinTables.length == 0) { + return; + } + + Map<String, List<JoinTableDesc>> fkMap = Maps.newHashMap(); + for (JoinTableDesc joinTable : joinTables) { + JoinDesc join = joinTable.getJoin(); + String fkSideName = join.getFKSide().getAlias(); + if (fkMap.containsKey(fkSideName)) { + fkMap.get(fkSideName).add(joinTable); + } else { + List<JoinTableDesc> joinTableList = Lists.newArrayList(); + joinTableList.add(joinTable); + fkMap.put(fkSideName, joinTableList); + } + } + + JoinTableDesc[] orderedJoinTables = new JoinTableDesc[joinTables.length]; + int orderedIndex = 0; + + Queue<JoinTableDesc> joinTableBuff = new ArrayDeque<JoinTableDesc>(); + TableDesc rootDesc = tables.get(rootFactTable); + joinTableBuff.addAll(fkMap.get(rootDesc.getName())); + while (!joinTableBuff.isEmpty()) { + JoinTableDesc head = joinTableBuff.poll(); + orderedJoinTables[orderedIndex++] = head; + String headAlias = head.getJoin().getPKSide().getAlias(); + if (fkMap.containsKey(headAlias)) { + joinTableBuff.addAll(fkMap.get(headAlias)); + } + } + + joinTables = orderedJoinTables; + } + private boolean validate() { // ensure no dup between dimensions/metrics http://git-wip-us.apache.org/repos/asf/kylin/blob/08600484/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java index c6df52e..8e2192f 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java @@ -19,17 +19,13 @@ package org.apache.kylin.metadata.model; import java.io.Serializable; -import java.util.ArrayDeque; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Queue; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; public class JoinsTree implements Serializable { private static final long serialVersionUID = 1L; @@ -44,41 +40,11 @@ public class JoinsTree implements Serializable { Preconditions.checkState(col.isQualified()); } - // Walk through joins to build FK table to joins mapping - HashMap<String, List<JoinDesc>> fkJoinMap = Maps.newHashMap(); - int joinCount = 0; + tableChains.put(rootTable.getAlias(), new Chain(rootTable, null, null)); for (JoinDesc join : joins) { - joinCount++; - String fkSideAlias = join.getFKSide().getAlias(); - if (fkJoinMap.containsKey(fkSideAlias)) { - fkJoinMap.get(fkSideAlias).add(join); - } else { - List<JoinDesc> joinDescList = Lists.newArrayList(join); - fkJoinMap.put(fkSideAlias, joinDescList); - } - } - - // Width-first build tree (tableChains) - Queue<Chain> chainBuff = new ArrayDeque<Chain>(); - chainBuff.add(new Chain(rootTable, null, null)); - int chainCount = 0; - while (!chainBuff.isEmpty()) { - Chain chain = chainBuff.poll(); - String pkSideAlias = chain.table.getAlias(); - chainCount++; - tableChains.put(pkSideAlias, chain); - - // this round pk side is next round's fk side - if (fkJoinMap.containsKey(pkSideAlias)) { - for (JoinDesc join : fkJoinMap.get(pkSideAlias)) { - chainBuff.add(new Chain(join.getPKSide(), join, chain)); - } - } - } - - // if join count not match (chain count - 1), there must be some join not take effect - if (joinCount != (chainCount - 1)) { - throw new IllegalArgumentException("There's some illegal Joins, please check your model"); + TableRef pkSide = join.getPKSide(); + Chain fkSide = tableChains.get(join.getFKSide().getAlias()); + tableChains.put(pkSide.getAlias(), new Chain(pkSide, join, fkSide)); } }