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: 0001-Fix-disabled_nodes-propagation-for-single-child-Appe.patch
Description: Binary data

Reply via email to