Hive Select * 替换回列字段

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 * 会得到这些值。。




fatkun

44条评论

兄弟,把图片批量下载的取大图规则做成在选项页可动态添加的行不?自己每添加一个网站的取大图规则太麻烦了,还要整什么url编码,不大方便啊。还有就是默认添加国内的一些知名图片站的图片吧,比如poco.cn,太平洋摄影部落等

请教一个问题,如果是select col1,col2,这些列是怎么得到的;我没找到地方

在genSelectPlan这个方法里,往下看多几行,关注col_list这个变量就可以了,这是把列找出来的。 } else { // Case when this is an expression ExprNodeDesc exp = genExprNodeDesc(expr, inputRR); col_list.add(exp);

发表评论

电子邮件地址不会被公开。