diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/RelOptHiveTable.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/RelOptHiveTable.java index 50acf42..e699c87 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/RelOptHiveTable.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/RelOptHiveTable.java @@ -55,6 +55,7 @@ public class RelOptHiveTable extends RelOptAbstractTable { private final Table hiveTblMetadata; + private final String tblAlias; private final ImmutableList hiveNonPartitionCols; private final ImmutableMap hiveNonPartitionColsMap; private final ImmutableMap hivePartitionColsMap; @@ -71,11 +72,12 @@ .getLog(RelOptHiveTable.class .getName()); - public RelOptHiveTable(RelOptSchema optiqSchema, String name, RelDataType rowType, + public RelOptHiveTable(RelOptSchema optiqSchema, String qualifiedTblName, String tblAlias, RelDataType rowType, Table hiveTblMetadata, List hiveNonPartitionCols, List hivePartitionCols, HiveConf hconf, Map partitionCache, AtomicInteger noColsMissingStats) { - super(optiqSchema, name, rowType); + super(optiqSchema, qualifiedTblName, rowType); this.hiveTblMetadata = hiveTblMetadata; + this.tblAlias = tblAlias; this.hiveNonPartitionCols = ImmutableList.copyOf(hiveNonPartitionCols); this.hiveNonPartitionColsMap = getColInfoMap(hiveNonPartitionCols, 0); this.hivePartitionColsMap = getColInfoMap(hivePartitionCols, hiveNonPartitionColsMap.size()); @@ -141,6 +143,19 @@ public Table getHiveTableMD() { return hiveTblMetadata; } + public String getTableAlias() { + // NOTE: Optiq considers tbls to be equal if their names are the same. Hence + // we need to provide Optiq the fully qualified table name (dbname.tblname) + // and not the user provided aliases. + // However in HIVE DB name can not appear in select list; in case of join + // where table names differ only in DB name, Hive would require user + // introducing explicit aliases for tbl. + if (tblAlias == null) + return hiveTblMetadata.getTableName(); + else + return tblAlias; + } + private String getColNamesForLogging(Set colLst) { StringBuffer sb = new StringBuffer(); boolean firstEntry = true; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTBuilder.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTBuilder.java index 3762988..6da456d 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTBuilder.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTBuilder.java @@ -54,13 +54,18 @@ static ASTNode destNode() { static ASTNode table(TableAccessRelBase scan) { RelOptHiveTable hTbl = (RelOptHiveTable) scan.getTable(); - ASTBuilder b = ASTBuilder - .construct(HiveParser.TOK_TABREF, "TOK_TABREF") - .add( - ASTBuilder.construct(HiveParser.TOK_TABNAME, "TOK_TABNAME") - .add(HiveParser.Identifier, hTbl.getHiveTableMD().getDbName()) - .add(HiveParser.Identifier, hTbl.getHiveTableMD().getTableName())) - .add(HiveParser.Identifier, hTbl.getName()); + ASTBuilder b = ASTBuilder.construct(HiveParser.TOK_TABREF, "TOK_TABREF").add( + ASTBuilder.construct(HiveParser.TOK_TABNAME, "TOK_TABNAME") + .add(HiveParser.Identifier, hTbl.getHiveTableMD().getDbName()) + .add(HiveParser.Identifier, hTbl.getHiveTableMD().getTableName())); + + // NOTE: Optiq considers tbls to be equal if their names are the same. Hence + // we need to provide Optiq the fully qualified table name (dbname.tblname) + // and not the user provided aliases. + // However in HIVE DB name can not appear in select list; in case of join + // where table names differ only in DB name, Hive would require user + // introducing explicit aliases for tbl. + b.add(HiveParser.Identifier, hTbl.getTableAlias()); return b.node(); } @@ -154,11 +159,11 @@ static ASTNode literal(RexLiteral literal) { type = HiveParser.BigintLiteral; break; case DOUBLE: - val = literal.getValue3()+"D"; + val = literal.getValue3() + "D"; type = HiveParser.Number; break; case DECIMAL: - val = literal.getValue3()+"BD"; + val = literal.getValue3() + "BD"; type = HiveParser.DecimalLiteral; break; case FLOAT: diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java index 77427e8..a9eab4c 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java @@ -27,6 +27,7 @@ import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.ql.optimizer.optiq.OptiqSemanticException; +import org.apache.hadoop.hive.ql.optimizer.optiq.RelOptHiveTable; import org.apache.hadoop.hive.ql.optimizer.optiq.reloperators.HiveSortRel; import org.apache.hadoop.hive.ql.optimizer.optiq.translator.SqlFunctionConverter.HiveToken; import org.apache.hadoop.hive.ql.parse.ASTNode; @@ -479,7 +480,7 @@ public QueryBlockInfo(Schema schema, ASTNode ast) { private static final long serialVersionUID = 1L; Schema(TableAccessRelBase scan) { - String tabName = scan.getTable().getQualifiedName().get(0); + String tabName = ((RelOptHiveTable)scan.getTable()).getTableAlias(); for (RelDataTypeField field : scan.getRowType().getFieldList()) { add(new ColumnInfo(tabName, field.getName())); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index 3c24338..c4dacf9 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -12713,19 +12713,25 @@ private RelNode genTableLogicalPlan(String tableAlias, QB qb) throws SemanticExc RelDataType rowType = TypeConverter.getType(cluster, rr, null); // 4. Build RelOptAbstractTable - RelOptHiveTable optTable = new RelOptHiveTable(relOptSchema, tableAlias, rowType, tab, - nonPartitionColumns, partitionColumns, conf, partitionCache, noColsMissingStats); + String fullyQualifiedTabName = tab.getDbName(); + if (fullyQualifiedTabName != null && !fullyQualifiedTabName.isEmpty()) + fullyQualifiedTabName = fullyQualifiedTabName + "." + tab.getTableName(); + else + fullyQualifiedTabName = tab.getTableName(); + RelOptHiveTable optTable = new RelOptHiveTable(relOptSchema, fullyQualifiedTabName, + tableAlias, rowType, tab, nonPartitionColumns, partitionColumns, conf, partitionCache, + noColsMissingStats); // 5. Build Hive Table Scan Rel - tableRel = new HiveTableScanRel(cluster, cluster.traitSetOf(HiveRel.CONVENTION), - optTable, rowType); + tableRel = new HiveTableScanRel(cluster, cluster.traitSetOf(HiveRel.CONVENTION), optTable, + rowType); // 6. Add Schema(RR) to RelNode-Schema map ImmutableMap hiveToOptiqColMap = buildHiveToOptiqColumnMap(rr, tableRel); relToHiveRR.put(tableRel, rr); relToHiveColNameOptiqPosMap.put(tableRel, hiveToOptiqColMap); } catch (Exception e) { - if ( e instanceof SemanticException) { + if (e instanceof SemanticException) { throw (SemanticException) e; } else { throw (new RuntimeException(e));