Repository: dask/dask

Issue:
Filters in read_parquet are not working in the latest dask version
While trying to reproduce code from [this answer](https://stackoverflow.com/a/72892141/10693596) with different dask versions I ran into inconsistent behavior.

Consider this snippet:

```python
from dask.dataframe import read_parquet
from dask.datasets import timeseries

df = timeseries(end="2000-01-03", seed=0).reset_index()
df["date"] = df["timestamp"].dt.date.astype("str")
df.to_parquet("test.pqt", partition_on=["id", "date"])
rare_id = df["id"].value_counts().compute().tail(1).index.values[0]

ddf = read_parquet("test.pqt", filters=[[("id", "==", rare_id)]], engine="pyarrow")
print(ddf.npartitions)  # 1 when using environment 2 defined below, but 491 when using environment 1 (latest dask)
```

Environment 1:

```yaml
name: dask
channels:
- conda-forge
dependencies:
- python=3.10
- ipykernel=6.4.1
- dask=2022.6.1
- pyarrow=8.0.0
- fastparquet=0.8.1
- pandas=1.4.3
```

Environment 2:

```yaml
name: dask2
channels:
- conda-forge
dependencies:
- python=3.10
- ipykernel=6.4.1
- dask=2022.1.0
- pyarrow=8.0.0
- fastparquet=0.8.1
- pandas=1.4.3
```

Just in case, here's the output of the fancy new `.show_versions()`:

```python
import dask

dask.utils.show_versions()
# {
#   "Python": "3.10.5",
#   "Platform": "Darwin",
#   "dask": "2022.6.1",
#   "distributed": "2022.6.1",
#   "numpy": "1.23.0",
#   "pandas": "1.4.3",
#   "cloudpickle": "2.1.0",
#   "fsspec": "2022.5.0",
#   "bokeh": "2.4.3",
#   "fastparquet": "0.8.1",
#   "pyarrow": "8.0.0",
#   "zarr": null
# }
```
Filters in read_parquet are not working in the latest dask version
While trying to reproduce code from [this answer](https://stackoverflow.com/a/72892141/10693596) with different dask versions I ran into inconsistent behavior.

Consider this snippet:

```python
from dask.dataframe import read_parquet
from dask.datasets import timeseries

df = timeseries(end="2000-01-03", seed=0).reset_index()
df["date"] = df["timestamp"].dt.date.astype("str")
df.to_parquet("test.pqt", partition_on=["id", "date"])
rare_id = df["id"].value_counts().compute().tail(1).index.values[0]

ddf = read_parquet("test.pqt", filters=[[("id", "==", rare_id)]], engine="pyarrow")
print(ddf.npartitions)  # 1 when using environment 2 defined below, but 491 when using environment 1 (latest dask)
```

Environment 1:

```yaml
name: dask
channels:
- conda-forge
dependencies:
- python=3.10
- ipykernel=6.4.1
- dask=2022.6.1
- pyarrow=8.0.0
- fastparquet=0.8.1
- pandas=1.4.3
```

Environment 2:

```yaml
name: dask2
channels:
- conda-forge
dependencies:
- python=3.10
- ipykernel=6.4.1
- dask=2022.1.0
- pyarrow=8.0.0
- fastparquet=0.8.1
- pandas=1.4.3
```

Just in case, here's the output of the fancy new `.show_versions()`:

```python
import dask

dask.utils.show_versions()
# {
#   "Python": "3.10.5",
#   "Platform": "Darwin",
#   "dask": "2022.6.1",
#   "distributed": "2022.6.1",
#   "numpy": "1.23.0",
#   "pandas": "1.4.3",
#   "cloudpickle": "2.1.0",
#   "fsspec": "2022.5.0",
#   "bokeh": "2.4.3",
#   "fastparquet": "0.8.1",
#   "pyarrow": "8.0.0",
#   "zarr": null
# }
```


Discussion:

Resolving patch:
diff --git a/dask/dataframe/io/parquet/arrow.py b/dask/dataframe/io/parquet/arrow.py
--- a/dask/dataframe/io/parquet/arrow.py
+++ b/dask/dataframe/io/parquet/arrow.py
@@ -1160,7 +1160,7 @@ def _construct_collection_plan(cls, dataset_info):
 
         # Check if this is a very simple case where we can just return
         # the path names
-        if gather_statistics is False and not split_row_groups:
+        if gather_statistics is False and not (split_row_groups or filters):
             return (
                 [
                     {"piece": (full_path, None, None)}


Test patch:
diff --git a/dask/dataframe/io/tests/test_parquet.py b/dask/dataframe/io/tests/test_parquet.py
--- a/dask/dataframe/io/tests/test_parquet.py
+++ b/dask/dataframe/io/tests/test_parquet.py
@@ -3424,6 +3424,36 @@ def test_pyarrow_dataset_filter_partitioned(tmpdir, split_row_groups):
     )
 
 
+def test_pyarrow_dataset_filter_on_partitioned(tmpdir, engine):
+    # See: https://github.com/dask/dask/issues/9246
+    df = pd.DataFrame({"val": range(7), "part": list("abcdefg")})
+    ddf = dd.from_map(
+        lambda i: df.iloc[i : i + 1],
+        range(7),
+    )
+    ddf.to_parquet(tmpdir, engine=engine, partition_on=["part"])
+
+    # Check that List[Tuple] filters are applied
+    read_ddf = dd.read_parquet(
+        tmpdir,
+        engine=engine,
+        filters=[("part", "==", "c")],
+    )
+    read_ddf["part"] = read_ddf["part"].astype("object")
+    assert_eq(df.iloc[2:3], read_ddf)
+
+    # Check that List[List[Tuple]] filters are aplied.
+    # (fastparquet doesn't support this format)
+    if engine == "pyarrow":
+        read_ddf = dd.read_parquet(
+            tmpdir,
+            engine=engine,
+            filters=[[("part", "==", "c")]],
+        )
+        read_ddf["part"] = read_ddf["part"].astype("object")
+        assert_eq(df.iloc[2:3], read_ddf)
+
+
 @PYARROW_MARK
 def test_parquet_pyarrow_write_empty_metadata(tmpdir):
     # https://github.com/dask/dask/issues/6600