Hive中会把TOK_ALLCOLREF替换成各个列名称,来看看代码中是如何做到的。
我以TOK_ALLCOLREF入手看代码,执行顺序不是这样的,这算是倒叙?=。=
来看SemanticAnalyzer.class这个类,这是查询中用得最多了。
首先看到genSelectPlan()方法
private Operator<?> genSelectPlan(ASTNode selExprList, QB qb,
Operator<?> input) throws SemanticException {
...
if (expr.getType() == HiveParser.TOK_ALLCOLREF) {
pos = genColListRegex(".*", expr.getChildCount() == 0 ? null
: getUnescapedName((ASTNode)expr.getChild(0)).toLowerCase(),
expr, col_list, inputRR, pos, out_rwsch, qb.getAliases());
selectStar = true;
}
...
}
咱们的列名称就在col_list存着,继续看genColListRegex()方法。可以发现它是由传入的inputRR字段获取的。
这inputRR是从调用这个方法就传过来了。。继续往上看。
genBodyPlan(QB qb, Operator input)
还是传过来的。。
Operator bodyOpInfo = genBodyPlan(qb, srcOpInfo);
srcOpInfo就是从这里来的,看一下genTablePlan
// Recurse over all the source tables
for (String alias : qb.getTabAliases()) {
Operator op = genTablePlan(alias, qb);
aliasToOpInfo.put(alias, op);
}
private Operator genTablePlan(String alias, QB qb) throws SemanticException {
String alias_id = (qb.getId() == null ? alias : qb.getId() + ":" + alias);
Table tab = qb.getMetaData().getSrcForAlias(alias);
RowResolver rwsch;
........................
rwsch = new RowResolver();
try {
// 先从Table中取到所有字段,加入RowResolver中
StructObjectInspector rowObjectInspector = (StructObjectInspector) tab
.getDeserializer().getObjectInspector();
List<? extends StructField> fields = rowObjectInspector
.getAllStructFieldRefs();
for (int i = 0; i < fields.size(); i++) {
rwsch.put(alias, fields.get(i).getFieldName(), new ColumnInfo(fields
.get(i).getFieldName(), TypeInfoUtils
.getTypeInfoFromObjectInspector(fields.get(i)
.getFieldObjectInspector()), alias, false));
}
} catch (SerDeException e) {
throw new RuntimeException(e);
}
// 这里再把Partition的字段给补上
// Hack!! - refactor once the metadata APIs with types are ready
// Finally add the partitioning columns
for (FieldSchema part_col : tab.getPartCols()) {
LOG.trace("Adding partition col: " + part_col);
// TODO: use the right type by calling part_col.getType() instead of
// String.class
rwsch.put(alias, part_col.getName(), new ColumnInfo(part_col.getName(),
TypeInfoFactory.stringTypeInfo, alias, true));
}
可以看到RowResolver存的值是列字段+分区字段。
最终select * 会得到这些值。。