This is an automated email from the ASF dual-hosted git repository.
cloud-fan pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.x by this push:
new 3028c1e481c4 [SPARK-58246][SQL] Read files from 7z archives
3028c1e481c4 is described below
commit 3028c1e481c447f03ef1119d0233df2fef5bd020
Author: akshatshenoi-db <[email protected]>
AuthorDate: Wed Jul 22 11:08:54 2026 +0800
[SPARK-58246][SQL] Read files from 7z archives
### What changes were proposed in this pull request?
This adds **7z** (`.7z`) as a third archive container to the archive-reader
feature (gated by
`spark.sql.files.archive.reader.enabled`, default off), alongside tar and
zip. It continues the
series: SPARK-57135/57321 CSV, SPARK-57419 JSON, SPARK-57478 text,
SPARK-57479 XML, SPARK-57481
Avro, SPARK-57705 zip container, SPARK-58110 the `SupportsArchiveFormat`
trait, SPARK-57590 Parquet.
The container engine is format-agnostic: data sources dispatch through the
trait's `isArchivePath`
+ `readArchiveEntries`, so CSV, JSON, text, XML, and Avro get 7z with no
per-data-source change.
Unlike tar and zip, 7z keeps its entry index at the *end* of the file and
can compress entries
together, so it cannot be read from a forward-only stream. The port:
- adds a read-only `HadoopSeekableByteChannel` over `FSDataInputStream` so
`SevenZFile` can seek to
the footer index in place (the archive is never copied to local disk);
- wraps `SevenZFile` in a `SevenZArchiveInputStream` adapter that fits the
existing
`ArchiveInputStream` cursor the engine already consumes, so
`openArchiveStream` gains a single
`.7z` case and the streaming engine itself is unchanged;
- adds `.7z` to `isArchivePath` and the unsupported-archive error message.
commons-compress reads 7z but treats its xz (LZMA/LZMA2) codec as an
optional dependency, so
`org.tukaani:xz` (already version-managed in the parent POM) is declared in
`sql/core/pom.xml`.
It also consolidates the per-container leaf test suites into each format's
`*ArchiveReadBase` (and
merges the CSV header/headerless bases), so adding a container no longer
multiplies suite files;
each format gains a `<Format>SevenZArchiveReadSuite` beside its existing
tar/zip suites.
### Why are the changes needed?
7z is a common archive format for shipping many small files compressed
together. Extending the
archive reader to 7z lets users read tarred/zipped/7z'd data without
unpacking first, and exercises
the seekable-container path (the previous containers were all forward-only
streams).
### Does this PR introduce _any_ user-facing change?
Yes, gated by `spark.sql.files.archive.reader.enabled` (default `false`).
When enabled, reading a
path ending in `.7z` returns the rows of its entries, the same as an
equivalent directory; when
disabled (the default), behavior is unchanged.
### How was this patch tested?
Added a `<Format>SevenZArchiveReadSuite` for CSV (header and headerless),
JSON, text, XML, and Avro
(each binding the format to the new
`SevenZArchiveReadBase`/`SevenZArchiveTestUtils`), so 7z runs the
full format-agnostic and format-specific archive test matrix. Added 7z
cases to
`SupportsArchiveFormatSuite` covering `.7z` dispatch, entry ordering, and
directory/dotfile/marker
skipping through the seek-based reader.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8)
Closes #57411 from akshatshenoi-db/archive-7z.
Authored-by: akshatshenoi-db <[email protected]>
Signed-off-by: Wenchen Fan <[email protected]>
(cherry picked from commit 0b1a92fa82bc574e77a58d3ed25f375d8cc9a7f2)
Signed-off-by: Wenchen Fan <[email protected]>
---
.../datasources/AvroArchiveReadBase.scala | 15 ++++
.../datasources/AvroTarArchiveReadSuite.scala | 28 -------
.../datasources/AvroZipArchiveReadSuite.scala | 28 -------
sql/core/pom.xml | 5 ++
.../datasources/SupportsArchiveFormat.scala | 98 +++++++++++++++++++++-
.../execution/datasources/CSVArchiveReadBase.scala | 89 ++++++++++++++++++++
.../datasources/CSVHeaderArchiveReadBase.scala | 52 ------------
.../datasources/CSVHeaderTarArchiveReadSuite.scala | 28 -------
.../datasources/CSVHeaderZipArchiveReadSuite.scala | 28 -------
.../datasources/CSVHeaderlessArchiveReadBase.scala | 43 ----------
.../CSVHeaderlessTarArchiveReadSuite.scala | 28 -------
.../CSVHeaderlessZipArchiveReadSuite.scala | 28 -------
.../datasources/JSONArchiveReadBase.scala | 15 ++++
.../datasources/JSONTarArchiveReadSuite.scala | 28 -------
.../datasources/JSONZipArchiveReadSuite.scala | 28 -------
.../datasources/SevenZArchiveReadBase.scala | 71 ++++++++++++++++
.../datasources/SupportsArchiveFormatSuite.scala | 73 ++++++++++++++++
.../datasources/TextArchiveReadBase.scala | 15 ++++
.../datasources/TextTarArchiveReadSuite.scala | 27 ------
.../datasources/TextZipArchiveReadSuite.scala | 27 ------
.../execution/datasources/XMLArchiveReadBase.scala | 15 ++++
.../datasources/XMLTarArchiveReadSuite.scala | 28 -------
.../datasources/XMLZipArchiveReadSuite.scala | 28 -------
23 files changed, 392 insertions(+), 433 deletions(-)
diff --git
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroArchiveReadBase.scala
b/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroArchiveReadBase.scala
index 0513cfe7db96..eb64fa2a6e5f 100644
---
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroArchiveReadBase.scala
+++
b/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroArchiveReadBase.scala
@@ -78,3 +78,18 @@ trait AvroArchiveReadBase extends ArchiveReadSuiteBase {
} finally stream.close()
}
}
+
+class AvroTarArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with AvroArchiveReadBase
+ with TarArchiveReadBase
+
+class AvroZipArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with AvroArchiveReadBase
+ with ZipArchiveReadBase
+
+class AvroSevenZArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with AvroArchiveReadBase
+ with SevenZArchiveReadBase
diff --git
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroTarArchiveReadSuite.scala
b/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroTarArchiveReadSuite.scala
deleted file mode 100644
index 00aa8396ed95..000000000000
---
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of Avro files packed in tar archives (`.tar`/`.tar.gz`/`.tgz`): the
shared archive tests
- * from [[ArchiveReadSuiteBase]] plus the Avro-specific ones from
[[AvroArchiveReadBase]], run over
- * tar containers via [[TarArchiveReadBase]].
- */
-class AvroTarArchiveReadSuite
- extends ArchiveReadSuiteBase
- with AvroArchiveReadBase
- with TarArchiveReadBase
diff --git
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroZipArchiveReadSuite.scala
b/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroZipArchiveReadSuite.scala
deleted file mode 100644
index 24281fb6637f..000000000000
---
a/connector/avro/src/test/scala/org/apache/spark/sql/execution/datasources/AvroZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of Avro files packed in zip archives (`.zip`): the shared archive
tests from
- * [[ArchiveReadSuiteBase]] plus the Avro-specific ones from
[[AvroArchiveReadBase]], run over zip
- * containers via [[ZipArchiveReadBase]].
- */
-class AvroZipArchiveReadSuite
- extends ArchiveReadSuiteBase
- with AvroArchiveReadBase
- with ZipArchiveReadBase
diff --git a/sql/core/pom.xml b/sql/core/pom.xml
index b545b516b05e..bce2e5e2d929 100644
--- a/sql/core/pom.xml
+++ b/sql/core/pom.xml
@@ -296,6 +296,11 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
+ <!-- commons-compress reads 7z archives but treats xz (LZMA/LZMA2) as an
optional dependency. -->
+ <dependency>
+ <groupId>org.tukaani</groupId>
+ <artifactId>xz</artifactId>
+ </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
diff --git
a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormat.scala
b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormat.scala
index 105bad108967..ffb38c52d9c5 100644
---
a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormat.scala
+++
b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormat.scala
@@ -18,6 +18,8 @@
package org.apache.spark.sql.execution.datasources
import java.io.{Closeable, InputStream}
+import java.nio.ByteBuffer
+import java.nio.channels.{NonWritableChannelException, SeekableByteChannel}
import java.util.Locale
import java.util.regex.Pattern
import java.util.zip.GZIPInputStream
@@ -25,12 +27,13 @@ import java.util.zip.GZIPInputStream
import scala.util.control.NonFatal
import org.apache.commons.compress.archivers.{ArchiveEntry, ArchiveInputStream}
+import org.apache.commons.compress.archivers.sevenz.{SevenZArchiveEntry,
SevenZFile}
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
import org.apache.commons.io.ByteOrderMark
import org.apache.commons.io.input.{BOMInputStream, CloseShieldInputStream}
import org.apache.hadoop.conf.Configuration
-import org.apache.hadoop.fs.Path
+import org.apache.hadoop.fs.{FSDataInputStream, Path}
import org.apache.hadoop.io.Text
import org.apache.hadoop.util.LineReader
@@ -39,7 +42,7 @@ import org.apache.spark.internal.Logging
import org.apache.spark.util.HadoopFSUtils
/**
- * Mixed into a file-based data source to let it read tar/zip archives of its
files, treating an
+ * Mixed into a file-based data source to let it read tar/zip/7z archives of
its files, treating an
* archive like a directory of the entries it contains. Schema inference is
left to each format.
*/
trait SupportsArchiveFormat extends Logging {
@@ -98,7 +101,7 @@ object SupportsArchiveFormat {
def isArchivePath(path: Path): Boolean = {
val name = path.getName.toLowerCase(Locale.ROOT)
name.endsWith(".tar") || name.endsWith(".tar.gz") || name.endsWith(".tgz")
||
- name.endsWith(".zip")
+ name.endsWith(".zip") || name.endsWith(".7z")
}
/**
@@ -123,9 +126,34 @@ object SupportsArchiveFormat {
}
case n if n.endsWith(".zip") =>
new
ZipArchiveInputStream(CodecStreams.createInputStreamWithCloseResource(conf,
path))
+ case n if n.endsWith(".7z") =>
+ openSevenZStream(path, conf)
case _ =>
throw new IllegalArgumentException(
- s"$path is not a supported archive (expected .tar, .tar.gz, .tgz, or
.zip)")
+ s"$path is not a supported archive (expected .tar, .tar.gz, .tgz,
.zip, or .7z)")
+ }
+ }
+
+ /**
+ * Opens a `.7z` archive by seeking.
+ *
+ * @param path the archive path
+ * @param conf Hadoop configuration used to open the archive
+ * @return the archive's entries as an [[ArchiveInputStream]] cursor
+ */
+ private def openSevenZStream(
+ path: Path,
+ conf: Configuration): ArchiveInputStream[_ <: ArchiveEntry] = {
+ val fs = path.getFileSystem(conf)
+ val in = fs.open(path)
+ try {
+ val channel = new HadoopSeekableByteChannel(in,
fs.getFileStatus(path).getLen)
+ new SevenZArchiveInputStream(
+ SevenZFile.builder().setSeekableByteChannel(channel).get(), channel)
+ } catch {
+ case NonFatal(e) =>
+ try in.close() catch { case NonFatal(_) => }
+ throw e
}
}
@@ -231,3 +259,65 @@ object SupportsArchiveFormat {
}
}
+
+/**
+ * Adapter for [[FSDataInputStream]] to [[SeekableByteChannel]].
+ *
+ * @param in the underlying seekable Hadoop stream
+ * @param length the file's size in bytes
+ */
+private class HadoopSeekableByteChannel(in: FSDataInputStream, length: Long)
+ extends SeekableByteChannel {
+
+ private var open = true
+
+ override def read(dst: ByteBuffer): Int = {
+ val len = dst.remaining()
+ if (len == 0) return 0
+ // Read straight into dst's backing array when it exposes one, avoiding a
per-call copy.
+ if (dst.hasArray) {
+ val n = in.read(dst.array(), dst.arrayOffset() + dst.position(), len)
+ if (n > 0) dst.position(dst.position() + n)
+ n
+ } else {
+ val buf = new Array[Byte](len)
+ val n = in.read(buf, 0, len)
+ if (n > 0) dst.put(buf, 0, n)
+ n
+ }
+ }
+
+ override def position(): Long = in.getPos
+ override def position(newPosition: Long): SeekableByteChannel = {
in.seek(newPosition); this }
+ override def size(): Long = length
+ override def isOpen: Boolean = open
+ override def close(): Unit = { open = false; in.close() }
+
+ override def write(src: ByteBuffer): Int = throw new
NonWritableChannelException
+ override def truncate(size: Long): SeekableByteChannel = throw new
NonWritableChannelException
+}
+
+/**
+ * Exposes the current [[SevenZFile]] entry's bytes as a plain forward
[[InputStream]].
+ *
+ * @param sevenZ the 7z file, positioned at the current entry
+ */
+private class SevenZEntryInputStream(sevenZ: SevenZFile) extends InputStream {
+ override def read(): Int = sevenZ.read()
+ override def read(b: Array[Byte], off: Int, len: Int): Int = sevenZ.read(b,
off, len)
+}
+
+/**
+ * Adapts a [[SevenZFile]] to the [[ArchiveInputStream]] cursor the engine
consumes. Closing it
+ * closes both the `SevenZFile` and the channel it reads from, which
`SevenZFile` does not own.
+ *
+ * @param sevenZ the 7z file to adapt
+ * @param channel the channel `sevenZ` reads from, closed alongside it
+ */
+private class SevenZArchiveInputStream(sevenZ: SevenZFile, channel:
SeekableByteChannel)
+ extends ArchiveInputStream[SevenZArchiveEntry](new
SevenZEntryInputStream(sevenZ), "UTF-8") {
+
+ override def getNextEntry(): SevenZArchiveEntry = sevenZ.getNextEntry
+
+ override def close(): Unit = try sevenZ.close() finally channel.close()
+}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVArchiveReadBase.scala
index 9ad49235b3fb..b3ab43fcd19c 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVArchiveReadBase.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVArchiveReadBase.scala
@@ -150,3 +150,92 @@ trait CSVArchiveReadBase extends ArchiveReadSuiteBase {
}
}
}
+
+/**
+ * [[CSVArchiveReadBase]] reading CSV files that carry a header row, plus
header-specific archive
+ * tests (mismatched headers, and delimiter/multiline cases whose first row is
a header).
+ */
+trait CSVHeaderArchiveReadBase extends CSVArchiveReadBase {
+
+ import testImplicits._
+
+ override protected def header: Boolean = true
+
+ test("CSV: entries with mismatched headers behave like standalone files") {
+ assertArchiveMatchesDir(
+ Seq(
+ entryName(0) -> encodeFile(sampleDf((1, "Alice"), (2, "Bob"))),
+ // A different second-column header: the schema's "name" column is
absent from this entry.
+ entryName(1) -> encodeFile(Seq((3, "Carol")).toDF("id", "nickname"))))
+ }
+
+ test("CSV: custom delimiter matches a directory read") {
+ assertArchiveMatchesDir(
+ Seq("a.csv" -> csvBytes("id;name\n1;Alice\n2;Bob\n")),
+ extraOptions = Map("delimiter" -> ";"))
+ }
+
+ test("CSV: multiline quoted fields with embedded newlines match a directory
read") {
+ assertArchiveMatchesDir(
+ Seq(
+ "a.csv" -> csvBytes("id,note\n1,\"line1\nline2\"\n2,\"plain\"\n"),
+ "b.csv" -> csvBytes("id,note\n3,\"a\nb\nc\"\n")),
+ extraOptions = Map("multiLine" -> "true"),
+ schema = "id INT, note STRING")
+ }
+}
+
+/**
+ * [[CSVArchiveReadBase]] reading headerless CSV files (columns are
positional), plus headerless
+ * delimiter/multiline archive tests. The shared archive tests from
[[ArchiveReadSuiteBase]] cover
+ * the common headerless read paths.
+ */
+trait CSVHeaderlessArchiveReadBase extends CSVArchiveReadBase {
+
+ override protected def header: Boolean = false
+
+ test("CSV: headerless custom delimiter matches a directory read") {
+ assertArchiveMatchesDir(
+ Seq("a.csv" -> csvBytes("1;Alice\n2;Bob\n"), "b.csv" ->
csvBytes("3;Carol\n")),
+ extraOptions = Map("delimiter" -> ";"))
+ }
+
+ test("CSV: headerless multiline quoted fields with embedded newlines match a
directory read") {
+ assertArchiveMatchesDir(
+ Seq(
+ "a.csv" -> csvBytes("1,\"line1\nline2\"\n2,\"plain\"\n"),
+ "b.csv" -> csvBytes("3,\"a\nb\nc\"\n")),
+ extraOptions = Map("multiLine" -> "true"),
+ schema = "id INT, note STRING")
+ }
+}
+
+class CSVHeaderTarArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderArchiveReadBase
+ with TarArchiveReadBase
+
+class CSVHeaderZipArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderArchiveReadBase
+ with ZipArchiveReadBase
+
+class CSVHeaderSevenZArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderArchiveReadBase
+ with SevenZArchiveReadBase
+
+class CSVHeaderlessTarArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderlessArchiveReadBase
+ with TarArchiveReadBase
+
+class CSVHeaderlessZipArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderlessArchiveReadBase
+ with ZipArchiveReadBase
+
+class CSVHeaderlessSevenZArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with CSVHeaderlessArchiveReadBase
+ with SevenZArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderArchiveReadBase.scala
deleted file mode 100644
index 32ad6e818076..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderArchiveReadBase.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * [[CSVArchiveReadBase]] reading CSV files that carry a header row, plus
header-specific archive
- * tests (mismatched headers, and delimiter/multiline cases whose first row is
a header).
- */
-trait CSVHeaderArchiveReadBase extends CSVArchiveReadBase {
-
- import testImplicits._
-
- override protected def header: Boolean = true
-
- test("CSV: entries with mismatched headers behave like standalone files") {
- assertArchiveMatchesDir(
- Seq(
- entryName(0) -> encodeFile(sampleDf((1, "Alice"), (2, "Bob"))),
- // A different second-column header: the schema's "name" column is
absent from this entry.
- entryName(1) -> encodeFile(Seq((3, "Carol")).toDF("id", "nickname"))))
- }
-
- test("CSV: custom delimiter matches a directory read") {
- assertArchiveMatchesDir(
- Seq("a.csv" -> csvBytes("id;name\n1;Alice\n2;Bob\n")),
- extraOptions = Map("delimiter" -> ";"))
- }
-
- test("CSV: multiline quoted fields with embedded newlines match a directory
read") {
- assertArchiveMatchesDir(
- Seq(
- "a.csv" -> csvBytes("id,note\n1,\"line1\nline2\"\n2,\"plain\"\n"),
- "b.csv" -> csvBytes("id,note\n3,\"a\nb\nc\"\n")),
- extraOptions = Map("multiLine" -> "true"),
- schema = "id INT, note STRING")
- }
-}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderTarArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderTarArchiveReadSuite.scala
deleted file mode 100644
index 7ac2ad4084aa..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of header-carrying CSV files packed in tar archives
(`.tar`/`.tar.gz`/`.tgz`): the shared
- * archive tests from [[ArchiveReadSuiteBase]] plus the header-mode CSV tests
from
- * [[CSVHeaderArchiveReadBase]], run over tar containers via
[[TarArchiveReadBase]].
- */
-class CSVHeaderTarArchiveReadSuite
- extends ArchiveReadSuiteBase
- with CSVHeaderArchiveReadBase
- with TarArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderZipArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderZipArchiveReadSuite.scala
deleted file mode 100644
index eb3bf1d78596..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of header-carrying CSV files packed in zip archives (`.zip`): the
shared archive tests from
- * [[ArchiveReadSuiteBase]] plus the header-mode CSV tests from
[[CSVHeaderArchiveReadBase]], run
- * over zip containers via [[ZipArchiveReadBase]].
- */
-class CSVHeaderZipArchiveReadSuite
- extends ArchiveReadSuiteBase
- with CSVHeaderArchiveReadBase
- with ZipArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessArchiveReadBase.scala
deleted file mode 100644
index ba4d7f63bb46..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessArchiveReadBase.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * [[CSVArchiveReadBase]] reading headerless CSV files (columns are
positional), plus headerless
- * delimiter/multiline archive tests. The shared archive tests from
[[ArchiveReadSuiteBase]] cover
- * the common headerless read paths.
- */
-trait CSVHeaderlessArchiveReadBase extends CSVArchiveReadBase {
-
- override protected def header: Boolean = false
-
- test("CSV: headerless custom delimiter matches a directory read") {
- assertArchiveMatchesDir(
- Seq("a.csv" -> csvBytes("1;Alice\n2;Bob\n"), "b.csv" ->
csvBytes("3;Carol\n")),
- extraOptions = Map("delimiter" -> ";"))
- }
-
- test("CSV: headerless multiline quoted fields with embedded newlines match a
directory read") {
- assertArchiveMatchesDir(
- Seq(
- "a.csv" -> csvBytes("1,\"line1\nline2\"\n2,\"plain\"\n"),
- "b.csv" -> csvBytes("3,\"a\nb\nc\"\n")),
- extraOptions = Map("multiLine" -> "true"),
- schema = "id INT, note STRING")
- }
-}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessTarArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessTarArchiveReadSuite.scala
deleted file mode 100644
index 28316c97ca8c..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of headerless CSV files packed in tar archives
(`.tar`/`.tar.gz`/`.tgz`): the shared
- * archive tests from [[ArchiveReadSuiteBase]] plus the headerless CSV tests
from
- * [[CSVHeaderlessArchiveReadBase]], run over tar containers via
[[TarArchiveReadBase]].
- */
-class CSVHeaderlessTarArchiveReadSuite
- extends ArchiveReadSuiteBase
- with CSVHeaderlessArchiveReadBase
- with TarArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessZipArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessZipArchiveReadSuite.scala
deleted file mode 100644
index b4bddb603725..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/CSVHeaderlessZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of headerless CSV files packed in zip archives (`.zip`): the shared
archive tests from
- * [[ArchiveReadSuiteBase]] plus the headerless CSV tests from
[[CSVHeaderlessArchiveReadBase]], run
- * over zip containers via [[ZipArchiveReadBase]].
- */
-class CSVHeaderlessZipArchiveReadSuite
- extends ArchiveReadSuiteBase
- with CSVHeaderlessArchiveReadBase
- with ZipArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONArchiveReadBase.scala
index 51e89832a4e5..24a187380535 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONArchiveReadBase.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONArchiveReadBase.scala
@@ -202,3 +202,18 @@ trait JSONArchiveReadBase extends ArchiveReadSuiteBase {
}
}
}
+
+class JSONTarArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with JSONArchiveReadBase
+ with TarArchiveReadBase
+
+class JSONZipArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with JSONArchiveReadBase
+ with ZipArchiveReadBase
+
+class JSONSevenZArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with JSONArchiveReadBase
+ with SevenZArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONTarArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONTarArchiveReadSuite.scala
deleted file mode 100644
index 5a703a321c59..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of JSON files packed in tar archives (`.tar`/`.tar.gz`/`.tgz`): the
shared archive tests
- * from [[ArchiveReadSuiteBase]] plus the JSON-specific ones from
[[JSONArchiveReadBase]], run over
- * tar containers via [[TarArchiveReadBase]].
- */
-class JSONTarArchiveReadSuite
- extends ArchiveReadSuiteBase
- with JSONArchiveReadBase
- with TarArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONZipArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONZipArchiveReadSuite.scala
deleted file mode 100644
index 76cee32238b3..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/JSONZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of JSON files packed in zip archives (`.zip`): the shared archive
tests from
- * [[ArchiveReadSuiteBase]] plus the JSON-specific ones from
[[JSONArchiveReadBase]], run over zip
- * containers via [[ZipArchiveReadBase]].
- */
-class JSONZipArchiveReadSuite
- extends ArchiveReadSuiteBase
- with JSONArchiveReadBase
- with ZipArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SevenZArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SevenZArchiveReadBase.scala
new file mode 100644
index 000000000000..efc6c280bfb6
--- /dev/null
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SevenZArchiveReadBase.scala
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.sql.execution.datasources
+
+import java.io.File
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+
+import org.apache.commons.compress.archivers.sevenz.{SevenZArchiveEntry,
SevenZOutputFile}
+
+/**
+ * Binds [[ArchiveReadSuiteBase]]'s archive-format hooks to 7z containers
(`.7z`). The
+ * container-writing helpers live in [[SevenZArchiveTestUtils]] (shared with
standalone suites that
+ * cannot extend `ArchiveReadSuiteBase`). Reusable across file formats -- a
+ * `<format>SevenZArchiveReadSuite` mixes this in alongside the file-format
trait.
+ */
+trait SevenZArchiveReadBase extends ArchiveReadSuiteBase with
SevenZArchiveTestUtils {
+
+ override protected def corruptArchiveExtension: String = "7z"
+}
+
+/**
+ * 7z container-writing helpers (`.7z`), independent of any read-test harness
-- the 7z peer of
+ * [[TarArchiveTestUtils]] and [[ZipArchiveTestUtils]].
[[SevenZArchiveReadBase]] mixes this into
+ * [[ArchiveReadSuiteBase]] for the format-agnostic suites, and standalone
suites that cannot extend
+ * `ArchiveReadSuiteBase` (e.g. `TextSevenZArchiveReadSuite`) mix it in
directly, so the container
+ * logic lives in one place.
+ */
+trait SevenZArchiveTestUtils {
+
+ /** 7z extensions to exercise; the head is the default. */
+ protected def archiveExtensions: Seq[String] = Seq("7z")
+
+ /** Writes `entries` (name -> bytes) into the 7z archive at `dest` (default
LZMA2 compression). */
+ protected def writeArchive(dest: File, entries: Seq[(String, Array[Byte])]):
Unit = {
+ val out = new SevenZOutputFile(dest)
+ try {
+ entries.foreach { case (entryName, bytes) =>
+ val entry = new SevenZArchiveEntry()
+ entry.setName(entryName)
+ out.putArchiveEntry(entry)
+ out.write(bytes)
+ out.closeArchiveEntry()
+ }
+ out.finish()
+ } finally out.close()
+ }
+
+ /**
+ * Writes bytes that are not a readable 7z archive to `dest`. The leading
bytes are not the 7z
+ * signature, so `SevenZFile` fails when the archive is opened (rather than
reporting it empty).
+ */
+ protected def writeCorruptArchive(dest: File): Unit =
+ Files.write(dest.toPath, "this is not a valid 7z archive, just some random
bytes"
+ .getBytes(StandardCharsets.UTF_8))
+}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormatSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormatSuite.scala
index 65547991c6b2..4247e82a1097 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormatSuite.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/SupportsArchiveFormatSuite.scala
@@ -25,6 +25,7 @@ import java.util.zip.GZIPOutputStream
import scala.collection.mutable.ArrayBuffer
+import org.apache.commons.compress.archivers.sevenz.{SevenZArchiveEntry,
SevenZOutputFile}
import org.apache.commons.compress.archivers.tar.{TarArchiveEntry,
TarArchiveOutputStream}
import org.apache.commons.compress.archivers.zip.{ZipArchiveEntry,
ZipArchiveOutputStream}
import org.apache.hadoop.conf.Configuration
@@ -122,6 +123,24 @@ class SupportsArchiveFormatSuite extends SparkFunSuite {
try fos.write(out.toByteArray) finally fos.close()
}
+ /** Write a 7z archive, used to verify the `.7z` archive path. */
+ private def writeSevenZ(file: File, entries: Seq[Entry]): Unit = {
+ val out = new SevenZOutputFile(file)
+ try {
+ entries.foreach { e =>
+ // 7z records an explicit directory flag rather than inferring it from
a trailing slash.
+ val sevenZEntry = new SevenZArchiveEntry()
+ sevenZEntry.setName(e.name)
+ sevenZEntry.setDirectory(e.isDir)
+ sevenZEntry.setHasStream(!e.isDir)
+ out.putArchiveEntry(sevenZEntry)
+ if (!e.isDir) out.write(e.data)
+ out.closeArchiveEntry()
+ }
+ out.finish()
+ } finally out.close()
+ }
+
private def textEntry(name: String, body: String): Entry =
Entry(name, body.getBytes(StandardCharsets.UTF_8))
@@ -445,4 +464,58 @@ class SupportsArchiveFormatSuite extends SparkFunSuite {
s"expected a clear unsupported-feature error, got $ex")
}
}
+
+ // ----- 7z -----------------------------------------------------------------
+ // 7z keeps its entry index at the end of the file, so the reader seeks
rather than streaming
+ // forward like tar and zip. These cases confirm the `.7z` dispatch and that
the seek-based
+ // container surfaces entries through the same engine.
+
+ test("readArchiveEntries: empty 7z yields empty iterator") {
+ withTempDir { dir =>
+ val sevenZ = new File(dir, "empty.7z")
+ writeSevenZ(sevenZ, Seq.empty)
+ assert(collect(sevenZ).isEmpty)
+ }
+ }
+
+ test("readArchiveEntries: 7z single entry exposes its name and bytes") {
+ withTempDir { dir =>
+ val sevenZ = new File(dir, "single.7z")
+ writeSevenZ(sevenZ, Seq(textEntry("only.csv", "hello\n")))
+ assert(collect(sevenZ) == Seq("only.csv" -> "hello\n"))
+ }
+ }
+
+ test("readArchiveEntries: 7z multiple entries chained in archive order") {
+ withTempDir { dir =>
+ val sevenZ = new File(dir, "multi.7z")
+ writeSevenZ(sevenZ,
+ Seq(textEntry("a.csv", "a"), textEntry("b.csv", "b"),
textEntry("c.csv", "c")))
+ assert(collect(sevenZ) == Seq("a.csv" -> "a", "b.csv" -> "b", "c.csv" ->
"c"))
+ }
+ }
+
+ test("readArchiveEntries: 7z directory entries are skipped") {
+ withTempDir { dir =>
+ val sevenZ = new File(dir, "dirs.7z")
+ writeSevenZ(sevenZ, Seq(
+ Entry("subdir", Array.emptyByteArray, isDir = true),
+ textEntry("subdir/data.csv", "x")))
+ assert(collect(sevenZ) == Seq("subdir/data.csv" -> "x"))
+ }
+ }
+
+ test("readArchiveEntries: 7z dotfile, underscore-marker, and prefixed-dir
entries are skipped") {
+ withTempDir { dir =>
+ val sevenZ = new File(dir, "skipped.7z")
+ writeSevenZ(sevenZ, Seq(
+ textEntry("._real.csv", "junk"), // macOS AppleDouble sidecar
+ textEntry(".hidden", "ignored"), // bare dotfile
+ textEntry("_SUCCESS", "marker"), // _-prefixed marker
(InMemoryFileIndex skips it)
+ textEntry("_temporary/part-0.csv", "tmp"), // entry under a _-prefixed
dir (skipped whole)
+ textEntry("real.csv", "kept"),
+ textEntry("nested/._sidecar", "junk2"))) // dotfile in a subdir
+ assert(collect(sevenZ) == Seq("real.csv" -> "kept"))
+ }
+ }
}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextArchiveReadBase.scala
index ba0cc64e1b35..1204c5a71b04 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextArchiveReadBase.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextArchiveReadBase.scala
@@ -189,3 +189,18 @@ trait TextArchiveReadBase extends QueryTest with
SharedSparkSession {
}
}
}
+
+class TextTarArchiveReadSuite extends TextArchiveReadBase with
TarArchiveTestUtils {
+
+ override protected def corruptArchiveExtension: String = "tar.gz"
+}
+
+class TextZipArchiveReadSuite extends TextArchiveReadBase with
ZipArchiveTestUtils {
+
+ override protected def corruptArchiveExtension: String = "zip"
+}
+
+class TextSevenZArchiveReadSuite extends TextArchiveReadBase with
SevenZArchiveTestUtils {
+
+ override protected def corruptArchiveExtension: String = "7z"
+}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextTarArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextTarArchiveReadSuite.scala
deleted file mode 100644
index 1764bfdefcfb..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of text files packed in tar archives (`.tar`/`.tar.gz`/`.tgz`): the
shared text archive
- * tests from [[TextArchiveReadBase]], run over tar containers via
[[TarArchiveTestUtils]].
- */
-class TextTarArchiveReadSuite extends TextArchiveReadBase with
TarArchiveTestUtils {
-
- override protected def corruptArchiveExtension: String = "tar.gz"
-}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextZipArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextZipArchiveReadSuite.scala
deleted file mode 100644
index a22951e8d5df..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/TextZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of text files packed in zip archives (`.zip`): the shared text
archive tests from
- * [[TextArchiveReadBase]], run over zip containers via
[[ZipArchiveTestUtils]].
- */
-class TextZipArchiveReadSuite extends TextArchiveReadBase with
ZipArchiveTestUtils {
-
- override protected def corruptArchiveExtension: String = "zip"
-}
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLArchiveReadBase.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLArchiveReadBase.scala
index 71f97dd32637..c5e956d4cd38 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLArchiveReadBase.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLArchiveReadBase.scala
@@ -133,3 +133,18 @@ trait XMLArchiveReadBase extends ArchiveReadSuiteBase {
schema = corruptSchema)
}
}
+
+class XMLTarArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with XMLArchiveReadBase
+ with TarArchiveReadBase
+
+class XMLZipArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with XMLArchiveReadBase
+ with ZipArchiveReadBase
+
+class XMLSevenZArchiveReadSuite
+ extends ArchiveReadSuiteBase
+ with XMLArchiveReadBase
+ with SevenZArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLTarArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLTarArchiveReadSuite.scala
deleted file mode 100644
index ec4a7047d600..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLTarArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of XML files packed in tar archives (`.tar`/`.tar.gz`/`.tgz`): the
shared archive tests
- * from [[ArchiveReadSuiteBase]] plus the XML-specific ones from
[[XMLArchiveReadBase]], run over
- * tar containers via [[TarArchiveReadBase]].
- */
-class XMLTarArchiveReadSuite
- extends ArchiveReadSuiteBase
- with XMLArchiveReadBase
- with TarArchiveReadBase
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLZipArchiveReadSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLZipArchiveReadSuite.scala
deleted file mode 100644
index 9721561b756f..000000000000
---
a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/XMLZipArchiveReadSuite.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.spark.sql.execution.datasources
-
-/**
- * Reads of XML files packed in zip archives (`.zip`): the shared archive
tests from
- * [[ArchiveReadSuiteBase]] plus the XML-specific ones from
[[XMLArchiveReadBase]], run over zip
- * containers via [[ZipArchiveReadBase]].
- */
-class XMLZipArchiveReadSuite
- extends ArchiveReadSuiteBase
- with XMLArchiveReadBase
- with ZipArchiveReadBase
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]