private static ASTNode replaceAlias(final ASTNode expr, final CubeQueryContext cubeql)
      throws SemanticException {
    ASTNode finalAST = HQLParser.copyAST(expr);
    HQLParser.bft(
        finalAST,
        new ASTNodeVisitor() {
          @Override
          public void visit(TreeNode visited) {
            ASTNode node = visited.getNode();
            ASTNode parent = null;
            if (visited.getParent() != null) {
              parent = visited.getParent().getNode();
            }

            if (node.getToken().getType() == TOK_TABLE_OR_COL
                && (parent != null && parent.getToken().getType() == DOT)) {
              ASTNode current = (ASTNode) node.getChild(0);
              if (current.getToken().getType() == Identifier) {
                String tableName = current.getToken().getText().toLowerCase();
                String alias = cubeql.getAliasForTableName(tableName);
                if (!alias.equalsIgnoreCase(tableName)) {
                  node.setChild(0, new ASTNode(new CommonToken(HiveParser.Identifier, alias)));
                }
              }
            }
          }
        });
    return finalAST;
  }
  private static void replaceColumnInAST(
      ASTNode expr, final String toReplace, final ASTNode columnAST) throws SemanticException {
    if (expr == null) {
      return;
    }
    // Traverse the tree and resolve expression columns
    HQLParser.bft(
        expr,
        new ASTNodeVisitor() {
          @Override
          public void visit(TreeNode visited) throws SemanticException {
            ASTNode node = visited.getNode();
            int childcount = node.getChildCount();
            for (int i = 0; i < childcount; i++) {
              ASTNode current = (ASTNode) node.getChild(i);
              if (current.getToken().getType() == TOK_TABLE_OR_COL
                  && (node != null && node.getToken().getType() != DOT)) {
                // Take child ident.totext
                ASTNode ident = (ASTNode) current.getChild(0);
                String column = ident.getText().toLowerCase();
                if (toReplace.equals(column)) {
                  node.setChild(i, HQLParser.copyAST(columnAST));
                }
              } else if (current.getToken().getType() == DOT) {
                // This is for the case where column name is prefixed by table name
                // or table alias
                // For example 'select fact.id, dim2.id ...'
                // Right child is the column name, left child.ident is table name
                ASTNode tabident = HQLParser.findNodeByPath(current, TOK_TABLE_OR_COL, Identifier);
                ASTNode colIdent = (ASTNode) current.getChild(1);

                String column = colIdent.getText().toLowerCase();

                if (toReplace.equals(column)) {
                  node.setChild(i, HQLParser.copyAST(columnAST));
                }
              }
            }
          }
        });
  }
    private void replaceAST(final CubeQueryContext cubeql, ASTNode node) throws SemanticException {
      if (node == null) {
        return;
      }
      // Traverse the tree and resolve expression columns
      HQLParser.bft(
          node,
          new ASTNodeVisitor() {
            @Override
            public void visit(TreeNode visited) throws SemanticException {
              ASTNode node = visited.getNode();
              int childcount = node.getChildCount();
              for (int i = 0; i < childcount; i++) {
                ASTNode current = (ASTNode) node.getChild(i);
                if (current.getToken().getType() == DOT) {
                  // This is for the case where column name is prefixed by table name
                  // or table alias
                  // For example 'select fact.id, dim2.id ...'
                  // Right child is the column name, left child.ident is table name
                  ASTNode tabident =
                      HQLParser.findNodeByPath(current, TOK_TABLE_OR_COL, Identifier);
                  ASTNode colIdent = (ASTNode) current.getChild(1);
                  String column = colIdent.getText().toLowerCase();

                  if (pickedExpressions.containsKey(column)) {
                    PickedExpression expr =
                        getPickedExpression(column, tabident.getText().toLowerCase());
                    if (expr != null) {
                      node.setChild(i, replaceAlias(expr.pickedCtx.finalAST, cubeql));
                    }
                  }
                }
              }
            }
          });
    }