mbutrovich commented on code in PR #26310:
URL: https://github.com/apache/datafusion/pull/26310#discussion_r4482770280


##########
datafusion/sqllogictest/test_files/listing_table_partitions.slt:
##########
@@ -127,3 +127,118 @@ select year, count(*) from root_file_test group by year 
order by year;
 ----
 2024 2
 2025 1
+
+# Test: a null partition value, which Hive compliant writers spell with a
+# `__HIVE_DEFAULT_PARTITION__` directory, is read as NULL.
+
+query I
+copy (values(1, 'alice'))
+to 
'test_files/scratch/listing_table_partitions/null_part/d=2024-01-01/data.parquet';
+----
+1
+
+query I
+copy (values(2, 'bob'))
+to 
'test_files/scratch/listing_table_partitions/null_part/d=__HIVE_DEFAULT_PARTITION__/data.parquet';
+----
+1
+
+statement count 0
+create external table null_part (column1 int, column2 varchar, d date)
+stored as parquet
+partitioned by (d)
+location 'test_files/scratch/listing_table_partitions/null_part/';
+
+query ITD
+select column1, column2, d from null_part order by column1;
+----
+1 alice 2024-01-01
+2 bob NULL
+
+query ITD
+select column1, column2, d from null_part where d is null;
+----
+2 bob NULL
+
+# The null partition does not match an equality filter.
+query ITD
+select column1, column2, d from null_part where d = '2024-01-01';
+----
+1 alice 2024-01-01
+
+# ... nor an inequality filter.
+query ITD
+select column1, column2, d from null_part where d <> '2024-01-01';
+----
+
+query ITD
+select column1, column2, d from null_part where d not in ('2024-01-01');
+----
+
+# Statistics for the null partition count its rows as nulls.
+query I
+select count(d) from null_part;
+----
+1
+
+query DD
+select min(d), max(d) from null_part;
+----
+2024-01-01 2024-01-01

Review Comment:
   Could we add a case for a table that infers its partition columns? Without a 
declared schema, `CREATE EXTERNAL TABLE` infers `d` as `Dictionary(UInt16, 
Utf8)`, which is the usual way to read a Hive-written table. The new tests only 
reach `ScalarValue::try_new_null` with `Date32`, `Int32`, and `Utf8`. Something 
like this, after the `min`/`max` query:
   
   ```
   # Partition columns inferred from the directories are dictionary encoded.
   statement count 0
   create external table null_part_inferred
   stored as parquet
   location 'test_files/scratch/listing_table_partitions/null_part/';
   
   query TT
   select arrow_typeof(d), d from null_part_inferred where d is null;
   ----
   Dictionary(UInt16, Utf8) NULL
   
   query I
   select column1 from null_part_inferred where d <> '2024-01-01';
   ----
   ```



##########
datafusion/datasource/src/file_groups.rs:
##########
@@ -360,7 +360,7 @@ impl FileGroupPartitioner {
 /// Partition column statistics are derived from the individual file partition 
values:
 /// - `min` = minimum partition value across all files in the group
 /// - `max` = maximum partition value across all files in the group

Review Comment:
   Could we update the `min` and `max` lines too, now that this block covers 
null partitions? A file with a null partition value gets absent `min`/`max` 
from 
[`with_statistics`](https://github.com/apache/datafusion/blob/bdc97394c1c0ce26fa0a29ccab954503cb5d4b70/datafusion/datasource/src/mod.rs#L347-L355).
 When the group's statistics are merged, 
[`precision_min`](https://github.com/apache/datafusion/blob/b6b2e0e5d5f119f46b7fb6288827aee7041ab00d/datafusion/common/src/stats.rs#L887-L910)
 returns `Precision::Absent` if either side is absent. So a group with one null 
partition has no bounds for that column, and these two lines say it does. 
#26748 tracks the merge fix, and the doc can point there until it lands.
   
   ```suggestion
   /// - `min` = minimum partition value across all files in the group, or 
absent if any
   ///   file in the group has a null partition value (see #26748)
   /// - `max` = maximum partition value across all files in the group, or 
absent if any
   ///   file in the group has a null partition value
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to