diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/InlineCTE.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/InlineCTE.scala index 50828b945bb40..8cc25328ce70b 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/InlineCTE.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/InlineCTE.scala @@ -140,7 +140,8 @@ case class InlineCTE( cteMap: mutable.Map[Long, CTEReferenceInfo]): LogicalPlan = { plan match { case WithCTE(child, cteDefs) => - val remainingDefs = cteDefs.filter { cteDef => + val notInlined = mutable.ArrayBuffer.empty[CTERelationDef] + cteDefs.foreach { cteDef => val refInfo = cteMap(cteDef.id) if (refInfo.refCount > 0) { val newDef = refInfo.cteDef.copy(child = inlineCTE(refInfo.cteDef.child, cteMap)) @@ -148,17 +149,17 @@ case class InlineCTE( cteMap(cteDef.id) = cteMap(cteDef.id).copy( cteDef = newDef, shouldInline = inlineDecision ) - // Retain the not-inlined CTE relations in place. - !inlineDecision - } else { - keepDanglingRelations + if (!inlineDecision) notInlined += newDef + } else if (keepDanglingRelations) { + notInlined += refInfo.cteDef } } val inlined = inlineCTE(child, cteMap) - if (remainingDefs.isEmpty) { + if (notInlined.isEmpty) { inlined } else { - WithCTE(inlined, remainingDefs) + // Retain the not-inlined CTE relations in place. + WithCTE(inlined, notInlined.toSeq) } case ref: CTERelationRef => diff --git a/sql/core/src/test/scala/org/apache/spark/sql/CTEInlineSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/CTEInlineSuite.scala index a06b50d175f90..7b608b7438c29 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/CTEInlineSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/CTEInlineSuite.scala @@ -703,6 +703,17 @@ abstract class CTEInlineSuiteBase checkErrorTableNotFound(e, "`tab_non_exists`", ExpectedContext("tab_non_exists", 83, 96)) } } + + test("SPARK-48307: not-inlined CTE references sibling") { + val df = sql( + """ + |WITH + |v1 AS (SELECT 1 col), + |v2 AS (SELECT col, rand() FROM v1) + |SELECT l.col FROM v2 l JOIN v2 r ON l.col = r.col + |""".stripMargin) + checkAnswer(df, Row(1)) + } } class CTEInlineSuiteAEOff extends CTEInlineSuiteBase with DisableAdaptiveExecutionSuite