@@ -282,7 +282,7 @@ def test_delta_empty_deletion_vector_read(spark_tmp_path, use_chunked_reader, us
282282 do_test_delta_deletion_vector_read (data_path , use_cdf , conf , f"SELECT * FROM delta.`{ data_path } `" )
283283
284284
285- def do_test_scan_split (spark_tmp_path , enable_deletion_vectors , expected_num_partitions , post_setup_table_func = None ):
285+ def do_test_scan_split (spark_tmp_path , enable_deletion_vectors , expected_num_partitions , post_setup_table_func = None , conf = None ):
286286 import os
287287 import math
288288
@@ -296,8 +296,8 @@ def setup_tables(spark):
296296 post_setup_table_func (spark , data_path )
297297 target_num_row_groups = 2
298298 row_group_size = int (num_rows * 4 / target_num_row_groups ) # num_rows * 4 bytes per int / target_num_row_groups
299- conf = {"parquet.block.size" : str (row_group_size )}
300- with_cpu_session (setup_tables , conf )
299+ table_setup_conf = {"parquet.block.size" : str (row_group_size )}
300+ with_cpu_session (setup_tables , table_setup_conf )
301301 # Verify that we have 1 file with 2 row groups
302302 def verify_files_and_row_groups ():
303303 # list files in data_path
@@ -314,12 +314,14 @@ def verify_files_and_row_groups():
314314 data_file = verify_files_and_row_groups ()
315315 file_size = os .path .getsize (data_file )
316316
317- conf = {"spark.sql.files.maxPartitionBytes" : str (math .ceil (file_size / 2.0 ))}
317+ read_conf = {"spark.sql.files.maxPartitionBytes" : str (math .ceil (file_size / 2.0 ))}
318+ if conf :
319+ read_conf = copy_and_update (read_conf , conf )
318320
319321 def get_num_partitions (spark ):
320322 df = spark .sql ("SELECT * from delta.`{}`" .format (data_path ))
321323 return df .rdd .getNumPartitions ()
322- num_partitions = with_gpu_session (get_num_partitions , conf = conf )
324+ num_partitions = with_gpu_session (get_num_partitions , conf = read_conf )
323325 assert num_partitions == expected_num_partitions , f"Expected { expected_num_partitions } partitions for split read"
324326
325327
@@ -343,30 +345,42 @@ def test_delta_scan_split_with_DV_enabled_with_no_DV(spark_tmp_path):
343345
344346@allow_non_gpu (* delta_meta_allow )
345347@delta_lake
348+ @pytest .mark .parametrize ("pushdown_dv_predicate" , [True , False ], ids = idfn )
346349@pytest .mark .skipif (is_databricks_runtime (),
347350 reason = "Deletion vector scan is not supported on Databricks" )
348351@pytest .mark .skipif (is_before_spark_353 (),
349352 reason = "Spark-RAPIDS supports scan with deletion vectors starting in Spark 3.5.3" )
350- def test_delta_scan_split_with_DV_enabled_with_DVs (spark_tmp_path ):
353+ def test_delta_scan_split_with_DV_enabled_with_DVs (spark_tmp_path , pushdown_dv_predicate ):
351354 def do_delete (spark , data_path ):
352355 num_deleted = spark .sql (f"DELETE FROM delta.`{ data_path } ` WHERE a = 0" ).collect ()[0 ][0 ]
353356 assert num_deleted > 0 , "Expected some rows to be deleted"
354- do_test_scan_split (spark_tmp_path , enable_deletion_vectors = True , expected_num_partitions = 1 , post_setup_table_func = do_delete )
357+ # The cuDF-based reader (GpuDeltaParquetFileFormat2), which is used when dv_predicate_pushdown is True, support the file split,
358+ # whereas the scala reader (GpuDeltaParquetFileFormat) does not support it.
359+ # So we expect 2 partitions when dv_predicate_pushdown is True, and 1 partition when it is False.
360+ expected_num_partitions = 2 if pushdown_dv_predicate else 1
361+ conf = {"spark.rapids.sql.delta.deletionVectors.predicatePushdown.enabled" : f"{ pushdown_dv_predicate } " }
362+ do_test_scan_split (spark_tmp_path , enable_deletion_vectors = True , expected_num_partitions = expected_num_partitions , post_setup_table_func = do_delete , conf = conf )
355363
356364
357365@allow_non_gpu (* delta_meta_allow )
358366@delta_lake
367+ @pytest .mark .parametrize ("pushdown_dv_predicate" , [True , False ], ids = idfn )
359368@pytest .mark .skipif (is_databricks_runtime (),
360369 reason = "Deletion vector scan is not supported on Databricks" )
361370@pytest .mark .skipif (is_before_spark_353 (),
362371 reason = "Spark-RAPIDS supports scan with deletion vectors starting in Spark 3.5.3" )
363- def test_delta_scan_split_with_DV_disabled_with_DVs (spark_tmp_path ):
372+ def test_delta_scan_split_with_DV_disabled_with_DVs (spark_tmp_path , pushdown_dv_predicate ):
364373 def do_delete_and_disable_DV (spark , data_path ):
365374 num_deleted = spark .sql (f"DELETE FROM delta.`{ data_path } ` WHERE a = 0" ).collect ()[0 ][0 ]
366375 assert num_deleted > 0 , "Expected some rows to be deleted"
367376 spark .sql (f"ALTER TABLE delta.`{ data_path } ` SET TBLPROPERTIES " +
368377 "('delta.enableDeletionVectors' = 'false')" )
369- do_test_scan_split (spark_tmp_path , enable_deletion_vectors = True , expected_num_partitions = 1 , post_setup_table_func = do_delete_and_disable_DV )
378+ # The cuDF-based reader (GpuDeltaParquetFileFormat2), which is used when dv_predicate_pushdown is True, support the file split,
379+ # whereas the scala reader (GpuDeltaParquetFileFormat) does not support it.
380+ # So we expect 2 partitions when dv_predicate_pushdown is True, and 1 partition when it is False.
381+ expected_num_partitions = 2 if pushdown_dv_predicate else 1
382+ conf = {"spark.rapids.sql.delta.deletionVectors.predicatePushdown.enabled" : f"{ pushdown_dv_predicate } " }
383+ do_test_scan_split (spark_tmp_path , enable_deletion_vectors = True , expected_num_partitions = expected_num_partitions , post_setup_table_func = do_delete_and_disable_DV , conf = conf )
370384
371385
372386@allow_non_gpu (* delta_meta_allow )
0 commit comments