private boolean genSubQueryRelNode(QB qb, ASTNode node, RelNode srcRel, boolean forHavingClause,
                                       Map<ASTNode, QBSubQueryParseInfo> subQueryToRelNode)
            throws CalciteSubquerySemanticException {

      boolean isSubQuery = false;
      boolean enableJoinReordering = false;
      try {
        Deque<ASTNode> stack = new ArrayDeque<ASTNode>();
        stack.push(node);

        while (!stack.isEmpty()) {
          ASTNode next = stack.pop();

          switch (next.getType()) {
          case HiveParser.TOK_SUBQUERY_EXPR:

            QBSubQueryParseInfo parseInfo = QBSubQueryParseInfo.parse(next);
            if (parseInfo.hasFullAggregate() && (
                    parseInfo.getOperator().getType() == QBSubQuery.SubQueryType.EXISTS ||
                            parseInfo.getOperator().getType() == QBSubQuery.SubQueryType.NOT_EXISTS)) {
              subQueryToRelNode.put(next, parseInfo);
              isSubQuery = true;
              break;
            }

            //disallow subqueries which HIVE doesn't currently support
            SubQueryUtils.subqueryRestrictionCheck(qb, next, srcRel, forHavingClause,
                ctx, this.relToHiveRR);

            String sbQueryAlias = "sq_" + qb.incrNumSubQueryPredicates();
            QB qbSQ = new QB(qb.getId(), sbQueryAlias, true);
            qbSQ.setInsideView(qb.isInsideView());
            Phase1Ctx ctx1 = initPhase1Ctx();
            ASTNode subQueryRoot = (ASTNode) next.getChild(1);
            doPhase1(subQueryRoot, qbSQ, ctx1, null);
            getMetaData(qbSQ);
            this.subqueryId++;
            RelNode subQueryRelNode =
                genLogicalPlan(qbSQ, false, relToHiveColNameCalcitePosMap.get(srcRel), relToHiveRR.get(srcRel));

            if (subQueryRelNode instanceof HiveProject) {
              subQueryMap.put(subQueryRelNode, subQueryRoot);
            }

            subQueryToRelNode.put(next, parseInfo.setSubQueryRelNode(subQueryRelNode));
            isSubQuery = true;
            enableJoinReordering = true;
            break;
          default:
            int childCount = next.getChildCount();
            for (int i = childCount - 1; i >= 0; i--) {
              stack.push((ASTNode) next.getChild(i));
            }
          }
        }
      } catch (SemanticException e) {
        throw new CalciteSubquerySemanticException(e.getMessage());
      }
      if (enableJoinReordering) {
        // since subqueries will later be rewritten into JOINs we want join reordering logic to trigger
        profilesCBO.add(ExtendedCBOProfile.JOIN_REORDERING);
      }
      return isSubQuery;
    }
Shuttle that replaces certain references with correlation variables
if needed.
ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java