[PATCH] Fix disabled_nodes propagation for single-child Append paths

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: zengman(at)halodbtech(dot)com
Subject: [PATCH] Fix disabled_nodes propagation for single-child Append paths
Date: 2026-08-17 06:59:32
Message-ID: CAHewXNm_Zx5EDoaD7wo7bq6cfRroNznS+RBCzT_p2-CWQXpgSw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

A disabled IndexScan can still be chosen for a partitioned table even
when a non-disabled alternative is available.
This issue was originally reported to me by my colleague, Man Zeng.

For example:

```
CREATE TABLE dpart (a int, b int) PARTITION BY LIST (a);
CREATE TABLE dpart_1 PARTITION OF dpart FOR VALUES IN (1);
CREATE INDEX dpart_1_a_idx ON dpart_1(a);
INSERT INTO dpart VALUES (1,1), (1,2), (1,3);

SET enable_indexscan = off;

EXPLAIN (COSTS OFF)
SELECT * FROM dpart ORDER BY a;
```

This produces:

```
QUERY PLAN
-------------------------------------------------
Index Scan using dpart_1_a_idx on dpart_1 dpart
Disabled: true
(2 rows)
```

There is a non-disabled alternative using a SeqScan followed by a
Sort, so the disabled IndexScan should not be preferred.

The problem is in `create_append_path()`. When an Append has only one
child and both have the same parallel-awareness, it skips
`cost_append()` and copies the child's rows and costs directly:

```c
pathnode->path.rows = child->rows;
pathnode->path.startup_cost = child->startup_cost;
pathnode->path.total_cost = child->total_cost;
```

However, `child->disabled_nodes` is not copied. As a result, an
AppendPath whose child has `disabled_nodes = 1` can incorrectly have
`disabled_nodes = 0`, which affects subsequent path selection.

The attached patch propagates `disabled_nodes` in this single-child
case and adds a regression test.

With the patch, the example above produces:

```
QUERY PLAN
-------------------------------
Sort
Sort Key: dpart.a
-> Seq Scan on dpart_1 dpart
(3 rows)
```

Thoughts?

--
Thanks,
Tender Wang

Attachment Content-Type Size
0001-Fix-disabled_nodes-propagation-for-single-child-Appe.patch application/octet-stream 3.7 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Nikhil Sontakke 2026-08-17 07:03:24 Dropping a composite attribute causes data integrity violations
Previous Message Fujii Masao 2026-08-17 06:57:31 Re: Failing assertion while taking a restartpoint during crash recovery