You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Parquet Predicate Pushdown Does Not Handle Type Coercion #7925
You have an explicit cast in there, the issue originates when the schema provided to the ParquetExec and used for planning doesn't match that of the underlying parquet file. The casts are internal to SchemaAdapter and will not show up in the plan
You have an explicit cast in there, the issue originates when the schema provided to the ParquetExec and used for planning doesn't match that of the underlying parquet file
@mhilton reminded me that we saw this in IOx when we tried to change from Timestamp(Nanos, None) to Timestamp(Nanos, UTF) -- I am writing this as a note mostly to myself
Now, when I create a table that requires type coercion (in this case defining column1 as Timestamp(Nanos, None)), any queries I run from the SQL layer show row groups are pruned as expected (row_groups_pruned_statistics=1 in the output of explain analyze)
❯ create external table utc_table(column1 timestamp) stored as parquet location '/tmp/example.parquet';
0 rows inset. Query took 0.001 seconds.
(note the predicate column1='2024-12-19'::timestamp compares column1 to a Timestamp(Nanos, None) so requires coercion)
@alamb I didnt, but here is the python script I was working on in case it helps anyone.
import datafusion
import pyarrow
ctx = datafusion.SessionContext()
# Ref https://github.com/apache/arrow-datafusion/blob/main/datafusion-examples/examples/to_timestamp.rs
ctx.sql(
"COPY (SELECT * FROM (VALUES (to_timestamp('2023-07-01 00:00:00-04:00', '%Y-%m-%d %H:%M:%S%#z'), to_timestamp('2023-07-01 00:00:00'))) AS data (tz_timestamp, timestamp)) TO 'timestamp.parquet'"
).collect()
ctx.register_parquet(
"data",
"timestamp.parquet",
schema=pyarrow.schema(
[
("tz_timestamp", pyarrow.timestamp("ns", "America/New_York")),
("timestamp", pyarrow.timestamp("ns")),
]
),
)
# Works without pushdown filters on timestamp without timezone
ctx.sql("SELECT * FROM data WHERE timestamp > '2023-01-01 00:00:00'").show()
ctx.sql("SELECT * FROM data WHERE timestamp > '2023-01-01 00:00:00-04:00'").show()
# Works with pushdown filter on timestamp without timezone
ctx.sql("SET datafusion.execution.parquet.pushdown_filters=true").collect()
ctx.sql("SELECT * FROM data WHERE timestamp > '2023-01-01 00:00:00'").show()
ctx.sql("SELECT * FROM data WHERE timestamp > '2023-01-01 00:00:00-04:00'").show()
# Works without pushdown filter on timestamp with timezone
ctx.sql("SET datafusion.execution.parquet.pushdown_filters=false").collect()
ctx.sql("SELECT * FROM data WHERE tz_timestamp > '2023-01-01 00:00:00'").show()
ctx.sql("SELECT * FROM data WHERE tz_timestamp > '2023-01-01 00:00:00-04:00'").show()
# Does NOT work with pushdown filter on timestamp with timezone
ctx.sql("SET datafusion.execution.parquet.pushdown_filters=true").collect()
# ctx.sql("SELECT * FROM data WHERE tz_timestamp > '2023-01-01 00:00:00'").show()
ctx.sql("SELECT * FROM data WHERE tz_timestamp > '2023-01-01 00:00:00-04:00'").show()
The case we're running into in InfluxDB when enabling timezones is slightly different. It is a parquet file with Timestamp without a timezone and then querying with either a timezone or in UTC. The odd part is that we have manually set the schema to be 'UTC', even though the backing parquet file is not.
the issue originates when the schema provided to the ParquetExec and used for planning doesn't match that of the underlying parquet file.
I agree with the suggestion that this is the cause of the issue we're encountering.
I have not been able to reproduce the issue natively in DataFusion using the datafusion-cli, as there is no way (that I can see) to change the schema. It does behave as I would expect when the schema matches the files.
This is the script I'm using to generate some parquet files.
> SET datafusion.execution.parquet.pushdown_filters=true;
0 row(s) fetched.
Elapsed 0.003 seconds.
> select * from './example_no_tz.parquet';
+---------------------+
| time |
+---------------------+
| 2024-01-01T00:00:00 |
| 2024-01-01T00:00:01 |
| 2024-01-01T00:00:02 |
| 2024-01-01T00:00:03 |
+---------------------+
4 row(s) fetched.
Elapsed 0.003 seconds.
> select * from './example_no_tz.parquet' where time >= '2024-01-01T00:00:02.000';
+---------------------+
| time |
+---------------------+
| 2024-01-01T00:00:02 |
| 2024-01-01T00:00:03 |
+---------------------+
2 row(s) fetched.
Elapsed 0.009 seconds.
> select * from './example_no_tz.parquet' where time >= ('2024-01-01T00:00:02.000' at time zone 'Europe/Brussels');
+---------------------+
| time |
+---------------------+
| 2024-01-01T00:00:00 |
| 2024-01-01T00:00:01 |
| 2024-01-01T00:00:02 |
| 2024-01-01T00:00:03 |
+---------------------+
4 row(s) fetched.
Elapsed 0.006 seconds.
If you perform any queries against the example with timezone, where the predicate is not in the same timezone, you get a type coercion error, which I believe makes sense.
> select * from './example_with_tz_utc.parquet';
+----------------------+
| time |
+----------------------+
| 2024-01-01T00:00:00Z |
| 2024-01-01T00:00:01Z |
| 2024-01-01T00:00:02Z |
| 2024-01-01T00:00:03Z |
+----------------------+
4 row(s) fetched.
Elapsed 0.004 seconds.
> select * from './example_with_tz_utc.parquet' where time >= '2024-01-01T00:00:02.000';
+----------------------+
| time |
+----------------------+
| 2024-01-01T00:00:02Z |
| 2024-01-01T00:00:03Z |
+----------------------+
2 row(s) fetched.
Elapsed 0.007 seconds.
> select * from './example_with_tz_utc.parquet' where time >= ('2024-01-01T00:00:02.000' at time zone 'Europe/Brussels');
Error during planning: Cannot infer common argument type for comparison operation Timestamp(Nanosecond, Some("UTC")) >= Timestamp(Nanosecond, Some("Europe/Brussels"))
Activity
alamb commentedon Oct 25, 2023
@tustvold do you have a reproducer for this one?
I tried a query like you described and it does not error:
tustvold commentedon Oct 25, 2023
You have an explicit cast in there, the issue originates when the schema provided to the ParquetExec and used for planning doesn't match that of the underlying parquet file. The casts are internal to SchemaAdapter and will not show up in the plan
alamb commentedon Oct 25, 2023
I see -- thank you.
alamb commentedon Feb 6, 2024
@mhilton reminded me that we saw this in IOx when we tried to change from
Timestamp(Nanos, None)toTimestamp(Nanos, UTF)-- I am writing this as a note mostly to myselfalamb commentedon Feb 8, 2024
I have been trying to make a reproducer for this issue, but I can not seem to.
This shows there are two row groups with UTC timestamp:
Now, when I create a table that requires type coercion (in this case defining
column1asTimestamp(Nanos, None)), any queries I run from the SQL layer show row groups are pruned as expected (row_groups_pruned_statistics=1in the output ofexplain analyze)(note the predicate
column1='2024-12-19'::timestampcomparescolumn1to aTimestamp(Nanos, None)so requires coercion)The same result comes from
Maybe the problem has something to do with constructing parquet exec directly as we do in InfluxDB
matthewmturner commentedon Mar 13, 2024
I can pick this up as I believe we are impacted by this as well. Going to work on creating reproducer first and will provide an update then.
matthewmturner commentedon Mar 22, 2024
As an update, this wasnt on our critical path so its been on the back burner. Unclear if ill be looking into this in the short term.
alamb commentedon Mar 22, 2024
@matthewmturner did you ever find a reproducer that shows the problem?
matthewmturner commentedon Mar 25, 2024
@alamb I didnt, but here is the python script I was working on in case it helps anyone.
jeffreyssmith2nd commentedon May 24, 2024
The case we're running into in InfluxDB when enabling timezones is slightly different. It is a parquet file with Timestamp without a timezone and then querying with either a timezone or in UTC. The odd part is that we have manually set the schema to be 'UTC', even though the backing parquet file is not.
I agree with the suggestion that this is the cause of the issue we're encountering.
I have not been able to reproduce the issue natively in DataFusion using the datafusion-cli, as there is no way (that I can see) to change the schema. It does behave as I would expect when the schema matches the files.
This is the script I'm using to generate some parquet files.
Some sample queries:
If you perform any queries against the example with timezone, where the predicate is not in the same timezone, you get a type coercion error, which I believe makes sense.
jeffreyssmith2nd commentedon May 29, 2024
take