From 136077a9a97917a0653b1520356ac4b620c4e438 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Sun, 19 Jul 2026 19:25:49 +0200
Subject: [PATCH v6 4/9] Make sure Gather nodes don't have filters

We don't allow passing filters between the leader and workers, so make
sure to not create such Gather nodes.

We still can have filters in paralell query, but they have to be created
and consumed in the same process. For example, if a worker both builds
and consumes the filter, it's fine.

XXX Ultimately we'd want filters for parallel hash joins, and shared
between the leader and workers, but for now we don't have that.
---
 src/backend/optimizer/path/allpaths.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 6e750e69172..9ec34004697 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -3750,6 +3750,13 @@ generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
 						   NULL, rowsp);
 	add_path(rel, simple_gather_path);
 
+	/*
+	 * The cheapest partial path must not have any pushed-down filters. Maybe
+	 * in the future we'll be able to push those to parallel workers, but for
+	 * now that's not possible/allowed.
+	 */
+	Assert(cheapest_partial_path->expected_filters == NULL);
+
 	/*
 	 * For each useful ordering, we can consider an order-preserving Gather
 	 * Merge.
@@ -3762,6 +3769,10 @@ generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
 		if (subpath->pathkeys == NIL)
 			continue;
 
+		/* ignore paths with filters (not supported) */
+		if (subpath->expected_filters != NULL)
+			continue;
+
 		rows = compute_gather_rows(subpath);
 		path = create_gather_merge_path(root, rel, subpath, rel->reltarget,
 										subpath->pathkeys, NULL, rowsp);
-- 
2.55.0

