From 6587fbbd64c64474485713e91caf71c12dde73ec Mon Sep 17 00:00:00 2001 From: shaofengshi Date: Thu, 4 Dec 2014 11:21:38 +0800 Subject: [PATCH] Add parse for dbname in DimensionDesc --- .../java/com/kylinolap/cube/model/CubeDesc.java | 29 ++++-- .../com/kylinolap/cube/model/DimensionDesc.java | 101 +++++++++++++++------ .../cube_desc/test_kylin_cube_with_slr_desc.json | 2 +- 3 files changed, 97 insertions(+), 35 deletions(-) diff --git a/cube/src/main/java/com/kylinolap/cube/model/CubeDesc.java b/cube/src/main/java/com/kylinolap/cube/model/CubeDesc.java index 688c605..511fa51 100644 --- a/cube/src/main/java/com/kylinolap/cube/model/CubeDesc.java +++ b/cube/src/main/java/com/kylinolap/cube/model/CubeDesc.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -467,23 +468,39 @@ public void init(KylinConfig config, Map tables) { this.addError("No data model found with name '" + modelName + "'."); } - Map> columnTableMap = new HashMap>(); + //key: column name; value: list of tables; + Map> columnTableMap = new HashMap>(); String colName; for(TableDesc table : tables.values()) { for(ColumnDesc col : table.getColumns()) { colName = col.getName(); - List tableNames = columnTableMap.get(colName); + List tableNames = columnTableMap.get(colName); if(tableNames == null) { - tableNames = new ArrayList(3); + tableNames = new LinkedList(); columnTableMap.put(colName, tableNames); } - tableNames.add(table.getName()); + tableNames.add(table); } } + + + // key: table name; value: list of databases; + Map> tableDatabaseMap = new HashMap>(); + + String tableName; + for(TableDesc table : tables.values()) { + tableName = table.getName(); + List dbNames = tableDatabaseMap.get(tableName); + if(dbNames == null) { + dbNames = new LinkedList(); + tableDatabaseMap.put(tableName, dbNames); + } + dbNames.add(table.getDatabase()); + } for (DimensionDesc dim : dimensions) { - dim.init(this, tables, columnTableMap); + dim.init(this, tables, columnTableMap, tableDatabaseMap); } sortDimAndMeasure(); @@ -511,7 +528,7 @@ public void init(KylinConfig config, Map tables) { private void initDimensionColumns(Map tables) { // fill back ColRefDesc for (DimensionDesc dim : dimensions) { - TableDesc dimTable = tables.get(dim.getTable()); + TableDesc dimTable = dim.getTableDesc(); JoinDesc join = dim.getJoin(); ArrayList dimColList = new ArrayList(); diff --git a/cube/src/main/java/com/kylinolap/cube/model/DimensionDesc.java b/cube/src/main/java/com/kylinolap/cube/model/DimensionDesc.java index 47d8361..1f24617 100644 --- a/cube/src/main/java/com/kylinolap/cube/model/DimensionDesc.java +++ b/cube/src/main/java/com/kylinolap/cube/model/DimensionDesc.java @@ -53,6 +53,8 @@ @JsonProperty("derived") private String[] derived; + private TableDesc tableDesc; + // computed private TblColRef[] columnRefs; private TblColRef[] derivedColRefs; @@ -68,6 +70,10 @@ public boolean isHierarchyColumn(TblColRef col) { return false; } + /** + * @deprecated use getTableDesc() to get accurate table info + * @return + */ public String getTable() { return table.toUpperCase(); } @@ -132,6 +138,10 @@ public void setDerivedColRefs(TblColRef[] derivedColRefs) { this.derivedColRefs = derivedColRefs; } + public TableDesc getTableDesc() { + return this.tableDesc; + } + @Override public boolean equals(Object o) { if (this == o) @@ -161,7 +171,54 @@ public String toString() { return "DimensionDesc [name=" + name + ", join=" + join + ", hierarchy=" + Arrays.toString(hierarchy) + ", table=" + table + ", column=" + Arrays.toString(column) + ", derived=" + Arrays.toString(derived) + "]"; } - public void init(CubeDesc cubeDesc, Map tables, Map> columnTableMap) { + /** + * parse column to get db name and table name + * @return an array carries db name + table name + * @throws IllegalStateException if the column name or name is incorrect or inaccurate + */ + private String[] parseTableDBName(String thisColumn, Map> columnTableMap, Map> tableDatabaseMap) { + String tableName = null, dbName = null; + String[] splits = StringSplitter.split(thisColumn, "."); + int length = splits.length; + if (length > 3 || length == 0) { + throw new IllegalStateException("The column name should be {db-name}.{table-name}.{column-name} (the {db-name} and {table-name} is optional); The given column value is: " + thisColumn); + } else if (length == 3) { + dbName = splits[0]; + tableName = splits[1]; + } else if (length == 2) { + tableName = splits[0]; + } + + if (tableName == null) { + List tables = columnTableMap.get(thisColumn); + if (tables == null) { + throw new IllegalStateException("The column '" + thisColumn + "' isn't appeared on any table."); + } else if (tables.size() > 1) { + throw new IllegalStateException("The column '" + thisColumn + "' is ambiguous; it appeared in more than one tables, please specify table name together with the column name."); + } else { + tableName = tables.get(0).getName(); + dbName = tables.get(0).getDatabase(); + } + } else if (dbName == null) { + List dbs = tableDatabaseMap.get(tableName); + if (dbs == null) { + throw new IllegalStateException("The table '" + tableName + "' isn't appeared on any database."); + } else if (dbs.size() > 1) { + throw new IllegalStateException("The table '" + tableName + "' is ambiguous; it appeared in more than one databases, please specify db name together with the table name."); + } else { + dbName = dbs.get(0); + } + } else { + List dbs = tableDatabaseMap.get(tableName); + if (!dbs.contains(dbName)) { + throw new IllegalStateException("The database '" + dbName + "' isn't appeared."); + } + } + + return new String[] { dbName, tableName }; + } + + public void init(CubeDesc cubeDesc, Map tables, Map> columnTableMap, Map> tableDatabaseMap) { if (name != null) name = name.toUpperCase(); @@ -170,36 +227,24 @@ public void init(CubeDesc cubeDesc, Map tables, Map 1) { - String thisTable = splits[splits.length - 2].toUpperCase(); - if (table == null) { - table = thisTable; - } else if (thisTable != null && !table.equalsIgnoreCase(thisTable)) { - throw new IllegalStateException("One dimension can only refer to the columns on the same table: '" + table + "' and '" + thisTable + "'."); - } - - if (database == null && splits.length > 2) { - database = splits[splits.length - 3].toUpperCase(); - } - - //this.column[i] = splits[splits.length - 1].toUpperCase(); - } else { - // if no table specified, seek the table among all tables - List tableNames = columnTableMap.get(thisColumn); - if (tableNames != null && tableNames.size() == 1) { - table = tableNames.get(0); - } else { - if (tableNames == null) - throw new IllegalStateException("The column '" + thisColumn + "' doesn't belong to any table."); - if (tableNames.size() > 1) - throw new IllegalStateException("The column '" + thisColumn + "' is ambiguous; the name appeared in more than one tables, please specify table name together with the column name."); - } + String thisColumn = this.column[i].toUpperCase(); + String[] dbTableNames = parseTableDBName(thisColumn, columnTableMap, tableDatabaseMap); + + if (database == null) { + database = dbTableNames[0]; + } else if (!database.equals(dbTableNames[0])) { + throw new IllegalStateException("One dimension can only refer to the tables in the same db: '" + database + "' and '" + dbTableNames[0] + "'."); + } + + if (table == null) { + table = dbTableNames[1]; + } else if (!table.equalsIgnoreCase(dbTableNames[1])) { + throw new IllegalStateException("One dimension can only refer to the columns on the same table: '" + table + "' and '" + dbTableNames[1] + "'."); } + } - TableDesc tableDesc = tables.get(table); + tableDesc = tables.get(database + "." + table); if (tableDesc == null) throw new IllegalStateException("Can't find table " + table + " on dimension " + name); diff --git a/examples/test_case_data/localmeta/cube_desc/test_kylin_cube_with_slr_desc.json b/examples/test_case_data/localmeta/cube_desc/test_kylin_cube_with_slr_desc.json index 148c315..3d6a6b2 100644 --- a/examples/test_case_data/localmeta/cube_desc/test_kylin_cube_with_slr_desc.json +++ b/examples/test_case_data/localmeta/cube_desc/test_kylin_cube_with_slr_desc.json @@ -31,7 +31,7 @@ }, { "name": "seller_type_cd", - "column": ["test_seller_type_dim.slr_segment_cd"], + "column": ["test_seller_type_dim.seller_type_cd"], "derived": ["seller_type_desc"] }, {