You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2017/03/31 06:59:58 UTC

[08/21] kylin git commit: KYLIN-2514 handle disordered joins in data model

KYLIN-2514 handle disordered joins in data model

Signed-off-by: Hongbin Ma <ma...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/14b96a86
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/14b96a86
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/14b96a86

Branch: refs/heads/KYLIN-2501
Commit: 14b96a86dc4cf6da78f2137838ca9827848f52be
Parents: 40249fe
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Mar 17 19:27:18 2017 +0800
Committer: Hongbin Ma <ma...@apache.org>
Committed: Fri Mar 17 19:55:27 2017 +0800

----------------------------------------------------------------------
 .../apache/kylin/metadata/model/JoinsTree.java  | 43 +++++++++++++++++---
 .../model_desc/ci_left_join_model.json          | 28 ++++++-------
 2 files changed, 52 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/14b96a86/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 c7666cb..3c876a0 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
@@ -24,8 +24,12 @@ 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;
+import com.google.common.collect.Queues;
 
 public class JoinsTree  implements Serializable {
     private static final long serialVersionUID = 1L;
@@ -40,12 +44,41 @@ public class JoinsTree  implements Serializable {
                 Preconditions.checkState(col.isQualified());
         }
 
-        tableChains.put(rootTable.getAlias(), new Chain(rootTable, null, null));
+        // Walk through joins to build FK table to joins mapping
+        HashMap<String, List<JoinDesc>> fkJoinMap = Maps.newHashMap();
+        int joinCount = 0;
+        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);
+            }
+        }
 
-        for (JoinDesc join : joins) {
-            TableRef pkSide = join.getPKSide();
-            Chain fkSide = tableChains.get(join.getFKSide().getAlias());
-            tableChains.put(pkSide.getAlias(), new Chain(pkSide, join, fkSide));
+        // Width-first build tree (tableChains)
+        Queue<Chain> chainBuff = Queues.newArrayDeque();
+        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");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/14b96a86/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json b/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
index 1b08aaf..bc5b444 100644
--- a/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
+++ b/examples/test_case_data/localmeta/model_desc/ci_left_join_model.json
@@ -31,20 +31,6 @@
       }
     },
     {
-      "table": "DEFAULT.TEST_ACCOUNT",
-      "alias": "SELLER_ACCOUNT",
-      "kind": "FACT",
-      "join": {
-        "type": "LEFT",
-        "primary_key": [
-          "SELLER_ACCOUNT.ACCOUNT_ID"
-        ],
-        "foreign_key": [
-          "TEST_KYLIN_FACT.SELLER_ID"
-        ]
-      }
-    },
-    {
       "table": "EDW.TEST_CAL_DT",
       "join": {
         "type": "LEFT",
@@ -119,6 +105,20 @@
           "SELLER_ACCOUNT.ACCOUNT_COUNTRY"
         ]
       }
+    },
+    {
+      "table": "DEFAULT.TEST_ACCOUNT",
+      "alias": "SELLER_ACCOUNT",
+      "kind": "FACT",
+      "join": {
+        "type": "LEFT",
+        "primary_key": [
+          "SELLER_ACCOUNT.ACCOUNT_ID"
+        ],
+        "foreign_key": [
+          "TEST_KYLIN_FACT.SELLER_ID"
+        ]
+      }
     }
   ],
   "dimensions": [