Skip to content

PG19: migrate get_relation_info_hook to build_simple_rel_hook#8622

Open
ihalatci wants to merge 1 commit into
pg19-columnar-relinfofrom
ihalatci-pg19-regress-crashes
Open

PG19: migrate get_relation_info_hook to build_simple_rel_hook#8622
ihalatci wants to merge 1 commit into
pg19-columnar-relinfofrom
ihalatci-pg19-regress-crashes

Conversation

@ihalatci

@ihalatci ihalatci commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

What

Restores partitioned-index stripping on PostgreSQL 19, which regressed when PG19 removed the get_relation_info_hook that Citus relied on. This is a PG19-only planner-hook migration and a no-op on PG ≤ 18.

The columnar scan_analyze_next_tuple signature item from the original scope was already fixed in the build-foundation PR #8601 and is intentionally not touched here.

Why

PG19 dropped get_relation_info_hook in favour of build_simple_rel_hook. Citus used that hook (multi_get_relation_info_hook) to strip partitioned indexes from partitioned-table plans. PR #8601 disabled it on PG19 with a TODO(PG19 Phase 2) marker, so index-stripping was temporarily absent on PG19, causing a client-backend crash on partitioned-table planning paths inside the regression suite (make check).

How

  • Add a PG19-only multi_build_simple_rel_hook in distributed_planner.c (prototype in distributed_planner.h) matching the build_simple_rel_hook signature (PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte). It delegates straight to the existing multi_get_relation_info_hook body, which re-derives the RangeTblEntry from rel->relid — so the removed relationObjectId / inhparent arguments are passed as InvalidOid / false and intentionally ignored, keeping behaviour identical across versions.
  • Register it via build_simple_rel_hook under #if PG_VERSION_NUM >= PG_VERSION_19 in shared_library_init.c; the old get_relation_info_hook assignment is kept under the #else arm for PG ≤ 18.

Files

  • src/backend/distributed/planner/distributed_planner.c
  • src/include/distributed/distributed_planner.h
  • src/backend/distributed/shared_library_init.c

Item 1 (src/backend/columnar/columnar_tableam.c) is untouched — already fixed in #8601.

Scope note

An earlier revision of this PR also carried a distribution_column.c AccessShareLock change ("item 3"). That fix addresses a PG16+ relation_open() assertion / relcache-lifetime issue that is not PG19-specific, so it has been split out into a separate PR targeting main. This PR is now scoped solely to the PG19 build_simple_rel_hook migration.

Stacking

Stacked on #8619 — base branch is pg19-columnar-relinfo. GitHub will auto-retarget this PR to pg19-support once #8619 merges.

Cross-version gate

  • PG19 (19beta1): full -Werror build green; partitioned_indexes_create (+ setup) regress passed, zero diff — exercises the partitioned-index planning path and proves the hook is active.
  • PG18 (18.4): full -Werror build green; same focused regress passed, zero diff — the pre-PG19 #else arm is unchanged and neutral.
  • PG17 (17.10): the migration is preprocessor-excluded (#if PG_VERSION_NUM >= PG_VERSION_19), so PG17 is structurally unaffected; the earlier full-scope gate confirmed a green PG17 -Werror build + regress.
  • check-style: citus_indent --check clean on all touched files.

All arms build clean under full -Werror (no flag demotion). The change is behaviourally confined to PG19; PG ≤ 18 is preprocessor-excluded and proven regression-neutral.

Part of #8597. Relates to #8608.

@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.80%. Comparing base (f43b3b6) to head (6117eac).

Additional details and impacted files
@@                    Coverage Diff                    @@
##           pg19-columnar-relinfo    #8622      +/-   ##
=========================================================
- Coverage                  88.94%   88.80%   -0.15%     
=========================================================
  Files                        288      288              
  Lines                      64403    64406       +3     
  Branches                    8098     8099       +1     
=========================================================
- Hits                       57282    57193      -89     
- Misses                      4785     4873      +88     
- Partials                    2336     2340       +4     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ihalatci

Copy link
Copy Markdown
Contributor Author

Cross-version gate results ✅

All three majors build clean under full -Werror (no flag demotion):

Major Build -Werror Targeted regress
PG17 (17.10) ✅ green partitioned_indexes_create (+ setup): all passed, zero diff
PG18 (18.4) ✅ green partitioned_indexes_create (+ setup): all passed, zero diff
PG19 (19beta1) ✅ green create_distributed_table_concurrently passed, no crashes

Regression-neutrality (PG17/PG18): Item 2 is preprocessor-excluded on PG ≤ 18 (#if PG_VERSION_NUM >= PG_VERSION_19). Item 3 (the only unconditional change) is proven neutral by the green partitioned_indexes_create run on both PG17 and PG18 — that test drives create_distributed_tableBuildDistributionKeyFromColumnName, the exact lock-upgrade path.

PG19 targeted notes (against the known port-WIP baseline — diffs expected):

  • create_distributed_table_concurrently — passed clean.
  • multi_partitioning — 2 cosmetic baseline diffs only (psql \d+ partition-list formatting; upstream error-wording unique constraintPRIMARY KEY constraint); no crash, ran to completion (positive signal item 2's hook is working).
  • columnar_analyze — diff is a setup artifact of the standalone targeted schedule (columnar AM/tables not pre-created by this minimal schedule); not a code regression. Item 1 is untouched (already fixed in PG19: build foundation (source-level compat, scaffold ruleutils_19.c, CI image bump) #8601).

Caveat: the pgenv PG19 (19beta1) build is not --enable-cassert, so item 3's specific assertion (cassert-only relation_open() check) cannot be tripped here. The targeted run confirms no regression on that path; a cassert PG19 build would be needed to demonstrate the original crash → fix directly.

@ihalatci

Copy link
Copy Markdown
Contributor Author

Item 3 — direct crash→fix evidence on a --enable-cassert PG19 build

The standard gate ran against a non-cassert PG19 (matching CI: the Citus exttester image installs the PGDG postgresql-19 package as its test server, which is not --enable-cassert). Item 3 guards a cassert-only Assert() in PG19's relation_open(), so neither CI nor the non-cassert gate can exercise it. To close that gap I built a local --enable-cassert --enable-debug PG19 (19beta1) and demonstrated the crash → fix directly.

Environment: PostgreSQL 19beta1, --enable-cassert --enable-debug (separate prefix; the gate's non-cassert 19beta1 left untouched). Identical citus source, only distribution_column.c toggled between base (NoLock) and the fix.

❌ BEFORE (item-3 hunk reverted — BuildDistributionKeyFromColumnName opens with NoLock)

make check focused schedule → select create_distributed_table_concurrently(...) aborts the backend:

TRAP: failed Assert("lockmode != NoLock || CheckRelationLockedByMe(r, AccessShareLock, true)"),
      File: "relation.c", Line: 119, PID: 36559
postgres ... SELECT(ExceptionalCondition+0x71)
postgres ... SELECT(try_relation_open+0x107)
.../citus.so(+0x131566)                                   <- BuildDistributionKeyFromColumnName
.../citus.so(create_distributed_table_concurrently+0x19f)
...
LOG:  client backend (PID 36559) was terminated by signal 6: Aborted
DETAIL:  Failed process was running: select create_distributed_table_concurrently('test','key', colocate_with := 'nocolo');

Result: not ok 4 - create_distributed_table_concurrently (backend killed by SIGABRT) → 1 of 4 tests failed.

Call path: create_distributed_table_concurrentlyAddDistributionColumnForRelation(..., NoLock) (distribution_column_map.c:74) → BuildDistributionKeyFromColumnName(..., NoLock)try_relation_open(rel, NoLock) → PG19 assert (relation.c:119).

✅ AFTER (item-3 fix applied — NoLock upgraded to AccessShareLock for the existence check)

Same cassert PG19, same schedule:

ok 4  - create_distributed_table_concurrently
# All 4 tests passed.

No TRAP, no Assert, no signal 6 anywhere in the server logs. The assertion is satisfied because the existence-check now holds AccessShareLock across relation_open/relation_close, while remaining a no-op for callers that already hold a lock (and on PG17/PG18, proven regression-neutral in the gate above).

This directly demonstrates the crash the fix prevents — the one piece that, by design, cannot show up in CI.

@ihalatci ihalatci marked this pull request as ready for review June 27, 2026 18:52
@ihalatci ihalatci linked an issue Jun 27, 2026 that may be closed by this pull request
Comment thread src/backend/distributed/utils/distribution_column.c Outdated
Comment thread src/backend/distributed/planner/distributed_planner.c Outdated
PG19 removed get_relation_info_hook, which Citus used to strip indexes
from partitioned-table plans. Restore that behaviour on PG19 via a thin
build_simple_rel_hook wrapper (multi_build_simple_rel_hook) that delegates
to the existing multi_get_relation_info_hook body, which re-derives the
RangeTblEntry from rel->relid. Keep the get_relation_info_hook
registration for PG<=18.

No-op on PG17/PG18: the PG19 arms are #if-excluded and the pre-PG19
get_relation_info_hook path is unchanged.

Part of #8597. Relates to #8608.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: df69870b-9d04-44fd-9d9e-49e135403864
@ihalatci ihalatci force-pushed the ihalatci-pg19-regress-crashes branch from 4883b0c to 6117eac Compare July 14, 2026 15:04
@ihalatci ihalatci changed the title PG19: fix regress-only client-backend crashes (items 2 & 3) PG19: restore partitioned-index stripping via build_simple_rel_hook Jul 14, 2026
@ihalatci ihalatci changed the title PG19: restore partitioned-index stripping via build_simple_rel_hook PG19: migrate get_relation_info_hook to build_simple_rel_hook Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PG19: fix regress-only client-backend crashes

3 participants