private def collectFallbackNodes()

in gluten-substrait/src/main/scala/org/apache/spark/sql/execution/GlutenImplicits.scala [97:165]


  private def collectFallbackNodes(
      spark: SparkSession,
      plan: QueryPlan[_]): GlutenExplainUtils.FallbackInfo = {
    var numGlutenNodes = 0
    val fallbackNodeToReason = new mutable.HashMap[String, String]

    def collect(tmp: QueryPlan[_]): Unit = {
      tmp.foreachUp {
        case _: ExecutedCommandExec =>
        case _: CommandResultExec =>
        case _: V2CommandExec =>
        case _: DataWritingCommandExec =>
        case _: WholeStageCodegenExec =>
        case _: WholeStageTransformer =>
        case _: InputAdapter =>
        case _: ColumnarInputAdapter =>
        case _: InputIteratorTransformer =>
        case _: ColumnarToRowTransition =>
        case _: RowToColumnarTransition =>
        case p: ReusedExchangeExec =>
        case _: NoopLeaf =>
        case w: WriteFilesExec if w.child.isInstanceOf[NoopLeaf] =>
        case p: AdaptiveSparkPlanExec if isFinalAdaptivePlan(p) =>
          collect(p.executedPlan)
        case p: AdaptiveSparkPlanExec =>
          // if we are here that means we are inside table cache.
          val (innerNumGlutenNodes, innerFallbackNodeToReason) =
            withSQLConf(SQLConf.ADAPTIVE_EXECUTION_ENABLED.key -> "false") {
              // re-plan manually to skip cached data
              val newSparkPlan = QueryExecution.createSparkPlan(
                spark,
                spark.sessionState.planner,
                p.inputPlan.logicalLink.get)
              val newExecutedPlan = QueryExecution.prepareExecutedPlan(
                spark,
                newSparkPlan
              )
              GlutenExplainUtils.processPlan(
                newExecutedPlan,
                new PlanStringConcat().append,
                Some(plan => collectFallbackNodes(spark, plan)))
            }
          numGlutenNodes += innerNumGlutenNodes
          fallbackNodeToReason.++=(innerFallbackNodeToReason)
        case p: QueryStageExec => collect(p.plan)
        case p: GlutenPlan =>
          numGlutenNodes += 1
          p.innerChildren.foreach(collect)
        case i: InMemoryTableScanExec =>
          if (PlanUtil.isGlutenTableCache(i)) {
            numGlutenNodes += 1
          } else {
            GlutenExplainUtils.addFallbackNodeWithReason(
              i,
              "Columnar table cache is disabled",
              fallbackNodeToReason)
          }
          collect(i.relation.cachedPlan)
        case _: AQEShuffleReadExec => // Ignore
        case p: SparkPlan =>
          GlutenExplainUtils.handleVanillaSparkPlan(p, fallbackNodeToReason)
          p.innerChildren.foreach(collect)
        case _ =>
      }
    }

    collect(plan)
    (numGlutenNodes, fallbackNodeToReason.toMap)
  }