Repository: kylin Updated Branches: refs/heads/KYLIN-1875 dbbbae227 -> e9139f0c4
add JoinsTree, halfway Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/e9139f0c Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/e9139f0c Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/e9139f0c Branch: refs/heads/KYLIN-1875 Commit: e9139f0c4af71a85f67c50a9f4ba1c0454523bf0 Parents: dbbbae2 Author: Yang Li <liy...@apache.org> Authored: Mon Nov 28 07:49:11 2016 +0800 Committer: Yang Li <liy...@apache.org> Committed: Mon Nov 28 07:49:11 2016 +0800 ---------------------------------------------------------------------- .../apache/kylin/dict/DictionaryManager.java | 2 +- .../apache/kylin/metadata/model/JoinDesc.java | 11 ++ .../apache/kylin/metadata/model/JoinsTree.java | 113 +++++++++++++++++++ .../apache/kylin/metadata/model/TblColRef.java | 4 + 4 files changed, 129 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/e9139f0c/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java ---------------------------------------------------------------------- diff --git a/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java b/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java index 820299c..3c64e45 100644 --- a/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java +++ b/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java @@ -357,7 +357,7 @@ public class DictionaryManager { if (join.isInnerJoin() == false) return false; - TableRef table = join.getForeignKeyColumns()[0].getTableRef(); + TableRef table = join.getFKSide(); join = model.getPKSideJoinMap().get(table); } return true; http://git-wip-us.apache.org/repos/asf/kylin/blob/e9139f0c/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinDesc.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinDesc.java index d3c0745..6489244 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinDesc.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinDesc.java @@ -110,6 +110,14 @@ public class JoinDesc { Preconditions.checkState(tableRef == cols[i].getTableRef()); } + public TableRef getPKSide() { + return primaryKeyColumns[0].getTableRef(); + } + + public TableRef getFKSide() { + return foreignKeyColumns[0].getTableRef(); + } + public void sortByFK() { Preconditions.checkState(primaryKey.length == foreignKey.length && primaryKey.length == primaryKeyColumns.length && foreignKey.length == foreignKeyColumns.length); boolean cont = true; @@ -174,6 +182,9 @@ public class JoinDesc { // equals() without alias public boolean matches(JoinDesc other) { + if (other == null) + return false; + if (!this.type.equalsIgnoreCase(other.getType())) return false; http://git-wip-us.apache.org/repos/asf/kylin/blob/e9139f0c/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 new file mode 100644 index 0000000..0317a3d --- /dev/null +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/JoinsTree.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.apache.kylin.metadata.model; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.google.common.base.Preconditions; + +public class JoinsTree { + + final private Chain root; + final private Map<TableRef, Chain> tableChains = new LinkedHashMap<>(); + + public JoinsTree(TableRef rootTable, List<JoinDesc> joins) { + for (JoinDesc join : joins) { + for (TblColRef col : join.getForeignKeyColumns()) + Preconditions.checkState(col.isQualified()); + for (TblColRef col : join.getPrimaryKeyColumns()) + Preconditions.checkState(col.isQualified()); + } + + root = new Chain(rootTable, null, null); + tableChains.put(rootTable, root); + + for (JoinDesc join : joins) { + TableRef pkSide = join.getPKSide(); + Chain fkSide = tableChains.get(join.getFKSide()); + tableChains.put(pkSide, new Chain(pkSide, join, fkSide)); + } + } + + public Map<String, String> matches(JoinsTree another) { + Map<String, String> matchUp = new HashMap<>(); + + for (Chain chain : tableChains.values()) { + if (matchInTree(chain, another, matchUp) == false) + return null; + } + + return matchUp; + } + + private boolean matchInTree(Chain chain, JoinsTree another, Map<String, String> matchUp) { + String thisAlias = chain.table.getAlias(); + if (matchUp.containsKey(thisAlias)) + return true; + + for (Chain anotherChain : another.tableChains.values()) { + if (matchChain(chain, anotherChain, matchUp)) { + return true; + } + } + return false; + } + + private boolean matchChain(Chain chain, Chain anotherChain, Map<String, String> matchUp) { + String thisAlias = chain.table.getAlias(); + String anotherAlias = anotherChain.table.getAlias(); + + String curMatch = matchUp.get(thisAlias); + if (curMatch != null) + return curMatch.equals(anotherAlias); + if (curMatch == null && matchUp.values().contains(anotherAlias)) + return false; + + boolean matches = false; + if (chain.join == null) { + matches = anotherChain.join == null && chain.table.getTableDesc().equals(anotherChain.table.getTableDesc()); + } else { + matches = chain.join.matches(anotherChain.join) && matchChain(chain.fkSide, anotherChain.fkSide, matchUp); + } + + if (matches) { + matchUp.put(thisAlias, anotherAlias); + } + return matches; + } + + private static class Chain { + TableRef table; // pk side + JoinDesc join; + Chain fkSide; + + public Chain(TableRef table, JoinDesc join, Chain fkSide) { + this.table = table; + this.join = join; + this.fkSide = fkSide; + if (join != null) { + Preconditions.checkArgument(table == join.getPKSide()); + Preconditions.checkArgument(fkSide.table == join.getPKSide()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/kylin/blob/e9139f0c/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java index 2cfbafc..bf8d36b 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/TblColRef.java @@ -123,6 +123,10 @@ public class TblColRef implements Serializable { return table; } + public boolean isQualified() { + return table != null; + } + public String getTableAlias() { return table != null ? table.getAlias() : "UNKNOWN_ALIAS"; }