private void visit(ASTNode n) {
      if (n.getType() == HiveParser.Identifier) {
        if (visitedNodes.containsKey(n)) {
          /**
           * Since we are modifying the stream, it's not idempotent.  Ideally, the caller would take
           * care to only quote Identifiers in each subtree once, but this makes it safe
           */
          return;
        }
        visitedNodes.put(n, n);
        trs.insertBefore(n.getToken(), "`");
        trs.insertAfter(n.getToken(), "`");
      }
      if (n.getChildCount() <= 0) {
        return;
      }
      for (Node c : n.getChildren()) {
        visit((ASTNode)c);
      }
    }
This allows us to take an arbitrary ASTNode and turn it back into SQL that produced it.
Since HiveLexer.g is written such that it strips away any ` (back ticks) around
quoted identifiers we need to add those back to generated SQL.
Additionally, the parser only produces tokens of type Identifier and never
QuotedIdentifier (HIVE-6013).  So here we just quote all identifiers.
(') around String literals are retained w/o issues
ql/src/java/org/apache/hadoop/hive/ql/parse/MergeSemanticAnalyzer.java