Skip to content

Columnar partitions get neither the custom scan nor the index-fetch penalty: set_rel_pathlist_hook returns early for non-baserels #436

Description

@ChronicallyJD

Found while verifying the external validation report behind #433 and #434.

src/columnar_customscan.c:957 returns early when rel->reloptkind != RELOPT_BASEREL:

if (rel->reloptkind != RELOPT_BASEREL)
    return;                     /* ... */

A partition of a partitioned table is RELOPT_OTHER_MEMBER_REL, so for a columnar
partition reached through its parent we install neither the custom scan path nor the
index-fetch penalty
(#355).

Measured

Same data, same index, one table partitioned and one not:

access plan time
through the parent Index Scan 484 ms
the same partition addressed directly Custom Scan (PgColumnarScan) 193 ms

Through the parent the cost is identical whether pgcolumnar.enable_index_fetch_penalty
is on or off
, which is the direct evidence that the hook never ran. And
enable_indexscan=off on the parent falls back to a Seq Scan, not to our scan, because
our path was never offered.

Why it matters more than the 2.5x

Partitioning is the standard advice for large fact tables, which is the shape this project
targets. A user who partitions a columnar table silently loses:

The last one compounds: a partitioned blob-heavy table is exactly the case where #433's
100 percent fetch-cache miss is most expensive, and it is also the case where nothing
prices it.

Worth asking the reporter

Their ledger fixture may have been partitioned. If it was, this rather than #434 is the
main explanation for the plan they got, and their 33-minute query would be explained
entirely by the custom scan never being offered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions