static ASTNode replaceAliases(ASTNode node, int nodePos, Map<String, String> colToTableAlias) { if (node == null) { return node; } int nodeType = node.getToken().getType(); if (nodeType == HiveParser.TOK_TABLE_OR_COL || nodeType == HiveParser.DOT) { String colName = HQLParser.getColName(node); String newAlias = colToTableAlias.get(colName.toLowerCase()); if (StringUtils.isBlank(newAlias)) { return node; } if (nodeType == HiveParser.DOT) { // No need to create a new node, just replace the table name ident ASTNode aliasNode = (ASTNode) node.getChild(0); ASTNode newAliasIdent = new ASTNode(new CommonToken(HiveParser.Identifier, newAlias)); aliasNode.setChild(0, newAliasIdent); } else { // Just a column ref, we need to make it alias.col // '.' will become the parent node ASTNode dot = new ASTNode(new CommonToken(HiveParser.DOT, ".")); ASTNode aliasIdentNode = new ASTNode(new CommonToken(HiveParser.Identifier, newAlias)); ASTNode tabRefNode = new ASTNode(new CommonToken(HiveParser.TOK_TABLE_OR_COL, "TOK_TABLE_OR_COL")); tabRefNode.addChild(aliasIdentNode); dot.addChild(tabRefNode); ASTNode colIdentNode = new ASTNode(new CommonToken(HiveParser.Identifier, colName)); dot.addChild(colIdentNode); ASTNode parent = (ASTNode) node.getParent(); if (parent != null) { parent.setChild(nodePos, dot); } else { return dot; } } } else { // recurse down for (int i = 0; i < node.getChildCount(); i++) { ASTNode child = (ASTNode) node.getChild(i); replaceAliases(child, i, colToTableAlias); } } return node; }
@Override public void rewriteContext(CubeQueryContext cubeql) throws LensException { Map<String, String> colToTableAlias = cubeql.getColToTableAlias(); extractTabAliasForCol(cubeql); findDimAttributesAndMeasures(cubeql); if (colToTableAlias.isEmpty()) { return; } // Rewrite the all the columns in the query with table alias prefixed. // If col1 of table tab1 is accessed, it would be changed as tab1.col1. // If tab1 is already aliased say with t1, col1 is changed as t1.col1 // replace the columns in select, groupby, having, orderby by // prepending the table alias to the col // sample select trees // 1: (TOK_SELECT (TOK_SELEXPR (TOK_TABLE_OR_COL key)) // (TOK_SELEXPR (TOK_FUNCTION count (TOK_TABLE_OR_COL value)))) // 2: (TOK_SELECT (TOK_SELEXPR (. (TOK_TABLE_OR_COL src) key)) // (TOK_SELEXPR (TOK_FUNCTION count (. (TOK_TABLE_OR_COL src) value)))) // 3: (TOK_SELECT (TOK_SELEXPR (. (TOK_TABLE_OR_COL src) key) srckey)))) replaceAliases(cubeql.getSelectAST(), 0, colToTableAlias); replaceAliases(cubeql.getHavingAST(), 0, colToTableAlias); replaceAliases(cubeql.getOrderByAST(), 0, colToTableAlias); replaceAliases(cubeql.getGroupByAST(), 0, colToTableAlias); replaceAliases(cubeql.getWhereAST(), 0, colToTableAlias); replaceAliases(cubeql.getJoinAST(), 0, colToTableAlias); // Update the aggregate expression set AggregateResolver.updateAggregates(cubeql.getSelectAST(), cubeql); AggregateResolver.updateAggregates(cubeql.getHavingAST(), cubeql); // Update alias map as well updateAliasMap(cubeql.getSelectAST(), cubeql); }
public void replaceAliasInAST(CubeQueryContext cubeql) throws SemanticException { AliasReplacer.extractTabAliasForCol(cubeql, this); AliasReplacer.replaceAliases(finalAST, 0, cubeql.getColToTableAlias()); }