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

dongjoon-hyun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/spark-connect-swift.git


The following commit(s) were added to refs/heads/main by this push:
     new 6a1e37a  [SPARK-60064] Fix DataFrameReader and DataStreamReader to not 
send empty format when format is not specified
6a1e37a is described below

commit 6a1e37a9b19401413b4815aadfd02e6600e2f94b
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Wed Oct 7 16:16:19 2026 -0700

    [SPARK-60064] Fix DataFrameReader and DataStreamReader to not send empty 
format when format is not specified
    
    ### What changes were proposed in this pull request?
    
    This PR aims to fix `DataFrameReader.load` and `DataStreamReader.load` to 
set `DataSource.format` only when a format is specified.
    
    ### Why are the changes needed?
    
    `DataSource.format` is a proto3 `optional` field. Previously, `load` always 
assigned `self.source` (initialized to `""`) to it, so the server saw 
`hasFormat == true` and called `reader.format("")` instead of falling back to 
`spark.sql.sources.default`. As a result, `spark.read.load(path)` and 
`spark.readStream.schema(...).load(path)` without `format(...)` failed.
    
    ```
    [DATA_SOURCE_NOT_FOUND] Failed to find the data source: . Make sure the 
provider name is correct and the package is properly registered and compatible 
with your Spark version. SQLSTATE: 42K02
    ```
    
    This is consistent with the PySpark Connect client, which sets 
`data_source.format` only when `format` is not `None`.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes. `load` without `format(...)` now uses the default data source 
(`spark.sql.sources.default`) instead of failing.
    
    ### How was this patch tested?
    
    Pass the CIs with the newly added test cases 
(`DataFrameReaderTests.loadWithoutFormat` and 
`DataStreamTests.loadWithoutFormat`). Without this fix, the newly added tests 
fail with the `DATA_SOURCE_NOT_FOUND` error against Apache Spark 4.2.0 Connect 
server.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Opus 5.5
    
    Closes #590 from dongjoon-hyun/SPARK-60064.
    
    Authored-by: Dongjoon Hyun <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 Sources/SparkConnect/DataFrameReader.swift         |  4 +++-
 Sources/SparkConnect/DataStreamReader.swift        |  4 +++-
 Tests/SparkConnectTests/DataFrameReaderTests.swift |  8 ++++++++
 Tests/SparkConnectTests/DataStreamTests.swift      | 12 ++++++++++++
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Sources/SparkConnect/DataFrameReader.swift 
b/Sources/SparkConnect/DataFrameReader.swift
index 245ae2e..1439513 100644
--- a/Sources/SparkConnect/DataFrameReader.swift
+++ b/Sources/SparkConnect/DataFrameReader.swift
@@ -165,7 +165,9 @@ public actor DataFrameReader: Sendable {
     self.paths = paths
 
     var dataSource = DataSource()
-    dataSource.format = self.source
+    if !self.source.isEmpty {
+      dataSource.format = self.source
+    }
     dataSource.paths = self.paths
     dataSource.options = self.extraOptions.toStringDictionary()
     if let userSpecifiedSchemaDDL = self.userSpecifiedSchemaDDL {
diff --git a/Sources/SparkConnect/DataStreamReader.swift 
b/Sources/SparkConnect/DataStreamReader.swift
index 931ce99..c0a0405 100644
--- a/Sources/SparkConnect/DataStreamReader.swift
+++ b/Sources/SparkConnect/DataStreamReader.swift
@@ -144,7 +144,9 @@ public actor DataStreamReader: Sendable {
     self.paths = paths
 
     var dataSource = DataSource()
-    dataSource.format = self.source
+    if !self.source.isEmpty {
+      dataSource.format = self.source
+    }
     dataSource.paths = self.paths
     dataSource.options = self.extraOptions.toStringDictionary()
     if let userSpecifiedSchemaDDL = self.userSpecifiedSchemaDDL {
diff --git a/Tests/SparkConnectTests/DataFrameReaderTests.swift 
b/Tests/SparkConnectTests/DataFrameReaderTests.swift
index 5843758..f9d76a7 100644
--- a/Tests/SparkConnectTests/DataFrameReaderTests.swift
+++ b/Tests/SparkConnectTests/DataFrameReaderTests.swift
@@ -123,6 +123,14 @@ struct DataFrameReaderTests {
     await spark.stop()
   }
 
+  @Test
+  func loadWithoutFormat() async throws {
+    let spark = try await SparkSession.builder.getOrCreate()
+    let path = "../examples/src/main/resources/users.parquet"
+    #expect(try await spark.read.load(path).count() == 2)
+    await spark.stop()
+  }
+
   @Test
   func table() async throws {
     let tableName = "TABLE_" + UUID().uuidString.replacingOccurrences(of: "-", 
with: "")
diff --git a/Tests/SparkConnectTests/DataStreamTests.swift 
b/Tests/SparkConnectTests/DataStreamTests.swift
index 7f1ad99..d844a04 100644
--- a/Tests/SparkConnectTests/DataStreamTests.swift
+++ b/Tests/SparkConnectTests/DataStreamTests.swift
@@ -85,6 +85,18 @@ struct DataStreamTests {
     await spark.stop()
   }
 
+  @Test
+  func loadWithoutFormat() async throws {
+    let spark = try await SparkSession.builder.getOrCreate()
+    let input = "/tmp/input-" + UUID().uuidString
+    try await spark.range(1).write.parquet(input)
+
+    let df = try await spark.readStream.schema("id LONG").load(input)
+    #expect(try await df.isStreaming())
+    #expect(try await df.columns == ["id"])
+    await spark.stop()
+  }
+
   @Test
   func startConcurrently() async throws {
     let spark = try await SparkSession.builder.getOrCreate()


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

Reply via email to