@Override
  public RelNode visit(HiveProject project) {
    if (!subQueryMap.containsKey(project)) {
      // No AST found for this subtree
      return super.visit(project);
    }

    // The AST associated to the RelNode is part of the original AST, but we need the expanded one
    // 1. Collect the path elements of this node in the original AST
    ArrayDeque<Integer> path = new ArrayDeque<>();
    ASTNode curr = subQueryMap.get(project);
    while (curr != null && curr != originalAST) {
      path.push(curr.getType());
      curr = (ASTNode) curr.getParent();
    }

    // 2. Search for the node in the expanded tree
    ASTNode expandedSubqAST = new CalcitePlanner.ASTSearcher().simpleBreadthFirstSearch(expandedAST, path);
    if (expandedSubqAST == null) {
      return super.visit(project);
    }

    // 3. Lookup MV in the registry by AST subtree coming from the expanded tree.
    // Deal only with MVs which are not supported by the Calcite based rewrite algorithm since that algorithm
    // also makes cost based decisions and can produce better plans.
    RelNode match = getMaterializedViewByAST(
        expandedSubqAST, relBuilder.getCluster(), NON_CALCITE, db, tablesUsedByOriginalPlan,
        validTxnsList, txnManager);
    if (match != null) {
      return match;
    }

    return super.visit(project);
  }
Traverse the plan and tries to rewrite subtrees of the plan to materialized view scans.

The rewrite depends on whether the subtree's corresponding AST match with any materialized view
definitions AST.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveMaterializedViewASTSubQueryRewriteShuttle.java