Skip to content

Commit 09ed1f3

Browse files
authored
Fix test_parquet_interleaved_file_splits_partition_value_alignment on GCS again [databricks] (NVIDIA#15289)
Fixes NVIDIA#15256. ### Description `test_parquet_interleaved_file_splits_partition_value_alignment` fails on Dataproc when the Spark temporary directory uses HDFS. The test reads Parquet row-group metadata with PyArrow, whose HDFS filesystem implementation uses `libhdfs` and requires the `CLASSPATH` environment variable to contain the Hadoop JARs. Without that environment variable, the test fails with `OSError: HDFS connection failed`. This change replaces the PyArrow metadata reader with Spark's JVM-side `ParquetFileReader`. It uses the active Spark session's Hadoop configuration, allowing the helper to access files through the same filesystem implementation Spark uses. The row-group midpoint calculation now uses `BlockMetaData.getStartingPos()` and `BlockMetaData.getCompressedSize()`, which provide the same offsets and compressed-size information used by the previous PyArrow implementation. The Parquet reader is closed in a `finally` block. ### Checklists Documentation - [ ] Updated for new or modified user-facing features or behaviors - [x] No user-facing change Testing - [x] Added or modified tests to cover new code paths - [ ] Covered by existing tests (Please provide the names of the existing tests in the PR description.) - [ ] Not required Performance - [ ] Tests ran and results are added in the PR description - [ ] Issue filed with a link in the PR description - [x] Not required Signed-off-by: Jihoon Son <ghoonson@gmail.com>
1 parent 0ae4c23 commit 09ed1f3

3 files changed

Lines changed: 24 additions & 29 deletions

File tree

integration_tests/src/main/python/delta_lake_test.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,11 @@ def setup_table(spark):
693693
f"b={b_size}, max_split={max_split}")
694694

695695
a_tail_start = a_size - a_tail
696-
a_midpoints = parquet_row_group_midpoints(a_path)
697-
b_midpoints = parquet_row_group_midpoints(b_path)
696+
a_midpoints, b_midpoints = with_cpu_session(
697+
lambda spark: (
698+
parquet_row_group_midpoints(spark, a_path),
699+
parquet_row_group_midpoints(spark, b_path),
700+
))
698701
assert any(a_tail_start <= midpoint < a_size for midpoint in a_midpoints), (
699702
f"A tail split [{a_tail_start}, {a_size}) has no row-group midpoint; "
700703
f"midpoints={a_midpoints}")

integration_tests/src/main/python/parquet_test.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,8 +1020,11 @@ def parquet_file_info_by_part(spark):
10201020
f"b={b_size}, max_split={max_split}")
10211021

10221022
a_tail_start = a_size - a_tail
1023-
a_midpoints = parquet_row_group_midpoints(a_path)
1024-
b_midpoints = parquet_row_group_midpoints(b_path)
1023+
a_midpoints, b_midpoints = with_cpu_session(
1024+
lambda spark: (
1025+
parquet_row_group_midpoints(spark, a_path),
1026+
parquet_row_group_midpoints(spark, b_path),
1027+
))
10251028
assert any(a_tail_start <= midpoint < a_size for midpoint in a_midpoints), (
10261029
f"A tail split [{a_tail_start}, {a_size}) has no row-group midpoint; "
10271030
f"midpoints={a_midpoints}")

integration_tests/src/main/python/parquet_test_utils.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,18 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from urllib.parse import urlparse
16-
17-
import pyarrow.fs as pa_fs
18-
import pyarrow.parquet as pa_pq
19-
20-
21-
def parquet_row_group_midpoints(path):
15+
def parquet_row_group_midpoints(spark, path):
2216
"""Returns an approximate byte midpoint for each Parquet row group."""
23-
if urlparse(path).scheme:
24-
filesystem, path = pa_fs.FileSystem.from_uri(path)
25-
meta = pa_pq.read_metadata(path, filesystem=filesystem)
26-
else:
27-
meta = pa_pq.read_metadata(path)
28-
midpoints = []
29-
for rg_index in range(meta.num_row_groups):
30-
row_group = meta.row_group(rg_index)
31-
first_col = row_group.column(0)
32-
start = first_col.data_page_offset
33-
dict_offset = first_col.dictionary_page_offset
34-
if dict_offset is not None and dict_offset > 0:
35-
start = min(start, dict_offset)
36-
total_size = 0
37-
for col_index in range(row_group.num_columns):
38-
total_size += row_group.column(col_index).total_compressed_size
39-
midpoints.append(start + total_size // 2)
40-
return midpoints
17+
jvm = spark.sparkContext._jvm
18+
hadoop_conf = spark.sparkContext._jsc.hadoopConfiguration()
19+
hadoop_path = jvm.org.apache.hadoop.fs.Path(path)
20+
reader = jvm.org.apache.parquet.hadoop.ParquetFileReader.open(
21+
hadoop_conf, hadoop_path)
22+
try:
23+
blocks = reader.getFooter().getBlocks()
24+
return [
25+
block.getStartingPos() + block.getCompressedSize() // 2
26+
for block in blocks
27+
]
28+
finally:
29+
reader.close()

0 commit comments

Comments
 (0)