Hive ASTNodeOrigin 的用法

ASTNodeOrigin类用于保存SQL解析中AST节点的来源信息,如视图定义或子查询上下文。在处理如类型检查错误时,它帮助精确地指出错误发生在哪个定义的位置,而不是笼统地指向顶层查询。在视图替换和子查询构建过程中,ASTNodeOrigin被用来记录和设置源信息,以便于错误报告和查询分析。
摘要由CSDN通过智能技术生成

ASTNodeOrigin 包含关于生成特定 ASTNode 对象的上下文信息。
例如,我们定义视图 create view v as select x+1 as y from t,我们要处理查询 select v1.y from v as v1。如果在执行查询前,执行了 ALTER TABLE t 改变了 x 的类型,导致查询语句的类型检查错误。当出现错误时,我们希望提供关于 v 的定义语句中出错的位置,而不是上层查询的错误位置。

/**
 * ASTNodeOrigin contains contextual information about the object from whose
 * definition a particular ASTNode originated. For example, suppose a view v is
 * defined as <code>select x+1 as y from t</code>, and we're processing a query
 * <code>select v1.y from v as v1</code>, and there's a type-checking problem
 * with the expression <code>x+1</code> due to an ALTER TABLE on t subsequent to
 * the creation of v. Then, when reporting the error, we want to provide the
 * parser location with respect to the definition of v (rather than with respect
 * to the top-level query, since that represents a completely different
 * "parser coordinate system").
 * 
 *<p>
 * 
 * So, when expanding the definition of v while analyzing the top-level query,
 * we tag each ASTNode with a reference to an ASTNodeOrign describing v and its
 * usage within the query.
 */
public class ASTNodeOrigin {
  private final String objectType;
  private final String objectName;
  private final String objectDefinition;
  private final String usageAlias;
  private final ASTNode usageNode;
}

ASTNodeOrigin 有两种应用,第一种是子查询,第二种是视图。

视图

当SQL 解析时,SemanticAnalyzer 发现用到的表是一个视图,调用replaceViewReferenceWithDefinition(qb, tab, tabName, alias);

  private void replaceViewReferenceWithDefinition(QB qb, Table tab,
                                                  String tab_name, String alias) throws SemanticException {
	
	ASTNode viewTree;
	    final ASTNodeOrigin viewOrigin = new ASTNodeOrigin("VIEW", tab.getTableName(),
	        tab.getViewExpandedText(), alias, qb.getParseInfo().getSrcForAlias(
	        alias));
	    try {
	      // Reparse text, passing null for context to avoid clobbering
	      // the top-level token stream.
	      String viewFullyQualifiedName = tab.getCompleteName();
	      String viewText = tab.getViewExpandedText();
	      TableMask viewMask = new TableMask(this, conf, false);
	      viewTree = ParseUtils.parse(viewText, ctx, tab.getCompleteName());
	      // viewTree 和子节点调用setOrigin(viewOrigin)
	      }
}

子查询

子查询构建的时候生成 originalSQASTOrigin

public QBSubQuery(String outerQueryId,
      int sqIdx,
      ASTNode subQueryAST,
      ASTNode parentQueryExpression,
      SubQueryTypeDef operator,
      ASTNode originalSQAST,
      Context ctx) {
    super();
    this.subQueryAST = subQueryAST;
    this.parentQueryExpression = parentQueryExpression;
    this.operator = operator;
    this.outerQueryId = outerQueryId;
    this.sqIdx = sqIdx;
    this.alias = "sq_" + this.sqIdx;
    this.numCorrExprsinSQ = 0;
    this.numOuterCorrExprsForHaving = 0;
    String s = ctx.getTokenRewriteStream().toString(
        originalSQAST.getTokenStartIndex(), originalSQAST.getTokenStopIndex());
    originalSQASTOrigin = new ASTNodeOrigin("SubQuery", alias, s, alias, originalSQAST);
    numOfCorrelationExprsAddedToSQSelect = 0;
    groupbyAddedToSQ = false;

    if ( operator.getType() == SubQueryType.NOT_IN ) {
      notInCheck = new NotInCheck();
    }

    subQueryDiagnostic = SubQueryDiagnostic.getRewrite(this, ctx.getTokenRewriteStream(), ctx);
  }

在 subqueryRestrictionsCheck 方法里,调用 subQueryAST.setOrigin(originalSQASTOrigin);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值