This is an automated email from the ASF dual-hosted git repository.

LuciferYang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 55e386d05dcf [SPARK-58223][SQL] Fix SparkSession.Builder.classic() 
building a Connect session
55e386d05dcf is described below

commit 55e386d05dcf4b1d004bc52a7ae5d40d8746d963
Author: YangJie <[email protected]>
AuthorDate: Tue Jul 21 10:38:05 2026 +0800

    [SPARK-58223][SQL] Fix SparkSession.Builder.classic() building a Connect 
session
    
    ### What changes were proposed in this pull request?
    
    `SparkSession.Builder.classic()` passed `CONNECT_COMPANION` to `mode(...)`, 
identical to `connect()`:
    
    ```scala
    def classic(): this.type = mode(CONNECT_COMPANION)
    def connect(): this.type = mode(CONNECT_COMPANION)
    ```
    
    `companion` drives `builder()` (`companion.builder()`), so on a classpath 
with both implementations `SparkSession.builder().classic().getOrCreate()` 
built a Connect session rather than a Classic one. This changes `classic()` to 
pass `CLASSIC_COMPANION` (which is already defined and used by the config-key 
path `API_MODE_CLASSIC => CLASSIC_COMPANION`).
    
    It also adds regression coverage: 
`SparkSessionBuilderImplementationBindingSuite` gains a shared 
`implementationSpecificBuilder` hook and a test asserting the built session is 
in the expected package, exercised by both the Classic (`.classic()`) and 
Connect (`.connect()`) concrete suites -- the mode selectors previously had no 
coverage.
    
    ### Why are the changes needed?
    
    `builder().classic()` does not honor its contract: it returns a Connect 
session (or fails, if only the classic implementation is available), 
contradicting the method name and scaladoc. Introduced by SPARK-49700; present 
since 4.1.0.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes. `SparkSession.builder().classic().getOrCreate()` now builds a Classic 
session as documented, instead of a Connect session. This is a bug fix relative 
to released 4.1.x.
    
    ### How was this patch tested?
    
    New shared test `SPARK-58223: mode selector binds to the correct 
implementation` in `SparkSessionBuilderImplementationBindingSuite`, run by both 
the Classic and Connect suites. Verified reproduce-then-fix: the Classic case 
fails on the unfixed tree (the built session is not in 
`org.apache.spark.sql.classic`) and passes after the fix; the classic suite 
passes.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #57379 from LuciferYang/SPARK-classic-builder.
    
    Authored-by: YangJie <[email protected]>
    Signed-off-by: yangjie01 <[email protected]>
---
 .../src/main/scala/org/apache/spark/sql/SparkSession.scala   |  2 +-
 .../sql/SparkSessionBuilderImplementationBindingSuite.scala  | 12 ++++++++++++
 .../SparkSessionBuilderImplementationBindingSuite.scala      |  3 +++
 .../SparkSessionBuilderImplementationBindingSuite.scala      |  8 ++++++--
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/sql/api/src/main/scala/org/apache/spark/sql/SparkSession.scala 
b/sql/api/src/main/scala/org/apache/spark/sql/SparkSession.scala
index 37d5d85e6344..a17a5dcac9e8 100644
--- a/sql/api/src/main/scala/org/apache/spark/sql/SparkSession.scala
+++ b/sql/api/src/main/scala/org/apache/spark/sql/SparkSession.scala
@@ -913,7 +913,7 @@ object SparkSession extends SparkSessionCompanion {
     /**
      * Make the builder create a Classic SparkSession.
      */
-    def classic(): this.type = mode(CONNECT_COMPANION)
+    def classic(): this.type = mode(CLASSIC_COMPANION)
 
     /**
      * Make the builder create a Connect SparkSession.
diff --git 
a/sql/api/src/test/scala/org/apache/spark/sql/SparkSessionBuilderImplementationBindingSuite.scala
 
b/sql/api/src/test/scala/org/apache/spark/sql/SparkSessionBuilderImplementationBindingSuite.scala
index 95c82cbdbdb6..5c9746736e7c 100644
--- 
a/sql/api/src/test/scala/org/apache/spark/sql/SparkSessionBuilderImplementationBindingSuite.scala
+++ 
b/sql/api/src/test/scala/org/apache/spark/sql/SparkSessionBuilderImplementationBindingSuite.scala
@@ -36,6 +36,13 @@ trait SparkSessionBuilderImplementationBindingSuite
   protected def sparkContext: SparkContext
   protected def implementationPackageName: String = getClass.getPackageName
 
+  /**
+   * A builder whose implementation mode is pinned via the mode selector 
(`classic()` /
+   * `connect()`). Each concrete suite overrides this so we verify the 
selector binds to the
+   * matching implementation.
+   */
+  protected def implementationSpecificBuilder: SparkSession.Builder
+
   private def assertInCorrectPackage[T](obj: T): Unit = {
     assert(obj.getClass.getPackageName == implementationPackageName)
   }
@@ -72,6 +79,11 @@ trait SparkSessionBuilderImplementationBindingSuite
     assert(df.head() == 11)
   }
 
+  test("SPARK-58223: mode selector binds to the correct implementation") {
+    val session = implementationSpecificBuilder.getOrCreate()
+    assertInCorrectPackage(session)
+  }
+
   test("emptyDataFrame with Schema") {
     val session = SparkSession.builder().getOrCreate()
     val schema =
diff --git 
a/sql/connect/client/jvm/src/test/scala/org/apache/spark/sql/connect/SparkSessionBuilderImplementationBindingSuite.scala
 
b/sql/connect/client/jvm/src/test/scala/org/apache/spark/sql/connect/SparkSessionBuilderImplementationBindingSuite.scala
index 06eb06299f4c..ba47a413cd67 100644
--- 
a/sql/connect/client/jvm/src/test/scala/org/apache/spark/sql/connect/SparkSessionBuilderImplementationBindingSuite.scala
+++ 
b/sql/connect/client/jvm/src/test/scala/org/apache/spark/sql/connect/SparkSessionBuilderImplementationBindingSuite.scala
@@ -33,4 +33,7 @@ class SparkSessionBuilderImplementationBindingSuite
   }
 
   override protected def sparkContext: SparkContext = null
+
+  override protected def implementationSpecificBuilder: 
sql.SparkSession.Builder =
+    sql.SparkSession.builder().connect()
 }
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/classic/SparkSessionBuilderImplementationBindingSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/classic/SparkSessionBuilderImplementationBindingSuite.scala
index 5bfc60bef2bf..bbdd429b6d61 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/classic/SparkSessionBuilderImplementationBindingSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/classic/SparkSessionBuilderImplementationBindingSuite.scala
@@ -16,7 +16,7 @@
  */
 package org.apache.spark.sql.classic
 
-import org.apache.spark.sql
+import org.apache.spark.sql.{SparkSession => BaseSparkSession}
 import org.apache.spark.sql.test.SharedSparkSession
 
 /**
@@ -24,4 +24,8 @@ import org.apache.spark.sql.test.SharedSparkSession
  */
 class SparkSessionBuilderImplementationBindingSuite
   extends SharedSparkSession
-  with sql.SparkSessionBuilderImplementationBindingSuite
+  with org.apache.spark.sql.SparkSessionBuilderImplementationBindingSuite {
+
+  override protected def implementationSpecificBuilder: 
BaseSparkSession.Builder =
+    BaseSparkSession.builder().classic()
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to