apache / apache/datafusion

ListingTable handling of missing partition values

Open
#18,083 6 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
9.3k
Forks
2.4k
Avg merge
3d 7h
Merged PRs (30d)
344

Description

This is broken out from https://github.com/apache/datafusion/pull/17958. See the other related discussion on that PR

Basically the question is what to do with a "bad" hive partitioned value

```
/table/year=2002/foo.parquet
/table/year=2003/bar.parquet
/table/baz.parquet # <-- what partition does this belong to?
/table/year=/baz.parquet # <-- likewise, what if the value is empty string?
```

For the filtering case, it looks like we do not infer the filter for ` IS NULL`, and the column is defined as [not nullable when the listing table is built](https://github.com/apache/datafusion/blob/main/datafusion/core/src/datasource/listing/table.rs#L996). We should probably fix this to support null columns, but we'll need to introduce some configuration for users to specify the null fallback value outside of the default `__HIVE_DEFAULT_PARTITION__`.

For the non-filtering case, this PR will indeed match null partition column values in the current implementation - but because we don't have any special treatment of them, it would return as the literal text `"__HIVE_DEFAULT_PARTITION__"` for example. If your partition column is then set as an `Int32` for example, the query will fail.

I think implementing proper support for the nulls will need more work outside of this PR. Because we already define the column as non-nullable, what do you think about manually excluding `__HIVE_DEFAULT_PARTITION__` values from the `parse_partitions_for_path` to prevent query errors like the one I describe above, until proper support for nulls is added? I can raise an issue and start working on it as well.

This won't help people with custom null fallback values, but would help for all default cases.

Yes, I should've been clearer that the `SELECT FROM blah` works but it returns the value as `__HIVE_DEFAULT_PARTITION__` for example - we don't convert them to `NULL` yet, which I think we probably ought to.

Hive itself seems to not convert the value at all, suggested by [this open issue](https://issues.apache.org/jira/browse/HIVE-1309). I struggled to find direct references to `HIVE_DEFAULT_PARTITION` in the Hive docs, I only came across [this ingestion guide](https://hive.apache.org/docs/latest/user/streaming-data-ingest-v2/#example) which explains how the Hive writer rewrites `NULL` into the `HIVE_DEFAULT_PARTITION` string.

I guess it is up to the implementer to decide what to do with that, because a text partition on a partition column you expect to be an integer could be annoying 😕 It looks like Impala decided to treat them as `NULL` values: [IMPALA-252](https://issues.apache.org/jira/browse/IMPALA-252).

I found the Impala ticket via [this Spark issue](https://issues.apache.org/jira/browse/SPARK-19887) and associated GitHub PR https://github.com/apache/spark/pull/17277 which also had an interesting discussion about this.

The side affect both of these tickets mention is that Hive does not differentiate between an empty string or a null value, so there is no way to tell which one a `HIVE_DEFAULT_PARTITION` is.

_Originally posted by @peasee in https://github.com/apache/datafusion/pull/17958#discussion_r2422243637_

Contributor guide

Open the contributing guide

Research direction

Read datafusion/core/src/datasource/listing/table.rs around the non-nullable partition-column definition at line 996, then trace parse_partitions_for_path and the related discussion in PR 17958. Define and document how missing, empty, default, and custom fallback partition values should behave, including filtering and typed partition columns; done requires agreed behavior implemented without query errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.