Drop PG16 support - #8757
Merged
Merged
Drop PG16 support#8757
Conversation
Makes PG17 the minimum supported PostgreSQL version, so the supported set becomes PG17 and PG18. This is the first of two PRs; a follow-up will clean up test outputs and helpers (see #8750). - configure/configure.ac: reject PG16 - remove PG_VERSION_16 and the pre-PG17 half of pg_version_compat.h - delete ruleutils_16.c and rename pg_get_object_address_16_17_18.c - strip PG_VERSION_17 version guards that are now always true/dead - CI: drop the pg16 matrix entries, devcontainer stage and 16->17/16->18 pg-upgrade jobs; pg-upgrade now only covers 17->18 citus.enable_outer_joins_with_pseudoconstant_quals_pre_pg17 only ever applied to PG16. It is kept defined-but-inert so existing configurations keep loading, and now raises a deprecation warning when set explicitly. It is scheduled for removal in 15.1 (see #8751). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
Temporary pin to the dev images built by citusdata/the-process#240. Revert to the stable -v<sha> suffix once that PR merges and the release images are published. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (57.14%) is below the target coverage (75.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #8757 +/- ##
=======================================
Coverage 88.72% 88.73%
=======================================
Files 289 289
Lines 65073 64992 -81
Branches 8203 8200 -3
=======================================
- Hits 57739 57673 -66
+ Misses 4967 4953 -14
+ Partials 2367 2366 -1 🚀 New features to boost your workflow:
|
Addresses the two real CI failures on the PG16 drop. check-style: restore the blank line that citus-style requires between a variable declaration and a following comment block (merge_planner.c, citus_depended_object.c), and collapse the four blank lines left behind by the removed pre-PG17 helper in recursive_planning.c down to two. pg17: the three citus.enable_outer_joins_with_pseudoconstant_quals_pre_pg17 SET/RESET pairs now emit the new deprecation warning, which is not in the expected output. The GUC was already inert on PG17, so each "wrong result pre-pg17" query was a verbatim duplicate of the query immediately above it and the comment was no longer true. Remove the whole scaffold (SET, comment, duplicate query, RESET) rather than only silencing the warning. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
Removing the PG_VERSION_16 guards left three declaration/assignment splits that only existed so the value could be set inside an #if block, and made pg_version_constants.h unused in extension.c. - merge_planner.c: inline the initializers in GetMergeJoinTree and GetMergeJoinCondition - citus_depended_object.c: inline the mergeJoinCondition initializer - extension.c: drop the now-unused pg_version_constants.h include Verified locally by running the full check-style job: all 7 mutating ci/*.sh scripts produce no diff, all 7 validators exit 0, and uncrustify leaves the changed files byte-identical. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
ibrahim halatci (ihalatci)
marked this pull request as ready for review
August 14, 2026 09:12
Onur Tirtir (onurctirtir)
approved these changes
Aug 21, 2026
Onur Tirtir (onurctirtir)
left a comment
Member
There was a problem hiding this comment.
Do we have any alternative test outputs we can drop while dropping support for PG < 17?
Contributor
Author
yes, in #8764 as a follow after this PR merges |
…pport # Conflicts: # .github/workflows/build_and_test.yml # configure # configure.ac
the-process #240 has merged as 609733ff2, so the release images are now published and the temporary dev pin is no longer needed. This supersedes the earlier "TEMP: point CI at the-process dev images" commit; since this PR is squash-merged, that commit does not reach main and only the final value here matters. Verified every tag referenced through image_suffix exists at -v609733f: extbuilder, exttester and failtester for 17.10/18.4/19beta3, stylechecker:0.8.33, pgupgradetester:17.10-18.4-19beta3, and citusupgradetester:17.10 (the only version that job's matrix uses). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
ibrahim halatci (ihalatci)
pushed a commit
that referenced
this pull request
Sep 1, 2026
Should have been part of #8757 This commit deletes some redundant alternative test outputs which were created for PG16, and collapses the now-always-true `server_version_ge_17` gates. Since the minimum supported version is PG17, `server_version_ge_17` is always true, so the `\else` branches guarded by it were dead code. Also: - removes the dead `15_16` arm from the `version_category` CASE in merge_unsupported - removes an always-true `PG_MAJOR_VERSION >= 16` branch in common.py - fixes a stale `#endif` comment in ruleutils_18.c which claimed the band was `>= 17 && < 18` while the `#if` actually guards `>= 18 && < 19` Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
ibrahim halatci (ihalatci)
added a commit
that referenced
this pull request
Sep 1, 2026
Part 2 of 2 for [#8750](#8750). Stacked on [#8757](#8757) — **this PR targets that branch, not `main`.** Please merge [#8757](#8757) first. Mirrors the equivalent PG14 cleanup commit [`529b303b6`](529b303b6) that followed the PG15 drop. ## What this does Now that PG17 is the minimum supported version, `server_version_ge_17` is always true. This removes the resulting dead code. ### Deleted 6 dead alternative expected outputs (-4000 lines) | File | Why it is dead | |---|---| | `expected/pg17_0.out` | PG16-only "cannot push down this subquery" errors | | `expected/pg17_json_0.out` | pure truncation after `\q` | | `expected/subquery_in_where_0.out` | contains the PG16 pseudoconstant-quals ERROR | | `expected/grant_on_table_propagation_0.out` | prints `f` for `server_version_ge_17` | | `expected/merge_unsupported_0.out` | `version_category` = `15_16` | | `expected/multi_alter_table_add_constraints_1.out` | the `ge_17` block produced no output | ### Collapsed 8 `server_version_ge_17` gates `merge_unsupported`, `grant_on_table_propagation`, `multi_alter_table_add_constraints`, `multi_mx_create_table`, `multi_mx_hide_shard_names`, `multi_schema_support`, `pg15`, `pg17`, `pg17_json` — `.sql` and `.out` edited in lockstep. ### Other - `merge_unsupported`: dropped the dead `WHEN ... IN (15, 16) THEN '15_16'` arm (the 17/18 arms stay) - `citus_tests/common.py`: removed an always-true `if PG_MAJOR_VERSION >= 16:` - `ruleutils_18.c`: fixed a stale `#endif` comment that said `>= 17 && < 18` while the `#if` guards `>= 18 && < 19` ## Deliberately NOT changed - `sql/pg16.sql` / `expected/pg16.out` — ungated feature test, same as `pg15.sql` was kept after the PG15 drop - `multi_test_helpers.sql` `pg_ge_16_options` — catalog introspection (`attname = 'daticurules'`), not a version gate - `expected/multi_mx_hide_shard_names_0.out` and `expected/pg18_0.out` — still-live alternatives (plan shape / `<18` branch) ## Verification - All 14 `ci/*.sh` style scripts pass; `black` / `isort` / `flake8` clean - Clean build against PG17.10, zero warnings - All 10 affected regression tests pass locally: `subquery_in_where`, `pg15`, `pg17`, `pg17_json`, `merge_unsupported`, `grant_on_table_propagation`, `multi_alter_table_add_constraints`, `multi_schema_support`, `multi_mx_create_table`, `multi_mx_hide_shard_names` --------- Co-authored-by: Ibrahim Halatci <ihalatci@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b92da71-e0c2-4baf-b47d-c81ec58da88b
Closed
ibrahim halatci (ihalatci)
added a commit
that referenced
this pull request
Sep 2, 2026
DESCRIPTION: Quote EXTRACT fields and support latest PostgreSQL minors Fixes #8803. ## Changes - quote EXTRACT field identifiers in the copied PG17 and PG18 ruleutils implementations; `ruleutils_19.c` already carries the equivalent fix from #8753; - run one discriminating, repeat-safe regression across supported PostgreSQL versions from the N-1-excluded create-Citus schedule; PG19 retains its dedicated #8753 coverage; - bump CI coverage from 17.10 / 18.4 to 17.11 / 18.6; - forward-port the already-landed release-14 fallout for the new PostgreSQL security minors, including `output_plugin_libraries` handling and modern psql COPY behavior; - add PG18 to the `test-citus-upgrade` matrix. ### PG18 citus upgrade coverage `citusupgradetester` is built and published for PG18 (`CITUS_UPGRADE_VERSIONS_18=v14.2.0`), but the matrix listed only PG17, so that image was built and never exercised. This adds it, matching the convention on `release-14.0`, which lists every supported major except the newest. PG19 stays out deliberately. The image compiles released Citus from source, and no released Citus supports PG19 yet, which is why the-process filters it out of `CITUS_UPGRADE_PG_VERSIONS`. PG19 upgrade paths are still covered by `test-pg-upgrade`, whose matrix already includes 17→18, 18→19, and 17→19. ## Cross-repo dependency The test images are built by [the-process#244](citusdata/the-process#244), stacked above [the-process#240](citusdata/the-process#240). Both have merged, along with #8757 and #8764, so this PR is last in that sequence and now pins the released `-vdba9cbb` suffix. ## Validation - `-Werror` builds: PostgreSQL 17.11, 18.6, and 19beta3 - shared `extract_deparse`: 8/8 repetitions on each of PostgreSQL 17.11, 18.6, and 19beta3 - focused PG17, PG18, and PG19 version regressions - focused `split_output_plugin_denied` regression on PG18.6 - `citus_indent --check` - SQL snapshot and test-schedule checks - `pg_regress_multi.pl` syntax check - all 13 image tags referenced by the workflow resolved against GHCR at the `-vdba9cbb` suffix before pinning ## Known limitation carried over from the release branches The `output_plugin_libraries` preflight splits the GUC on commas, so a plugin name containing a comma inside a quoted element (`"a,b"`) is not parsed the way PostgreSQL's `SplitGUCList` would parse it. This is unreachable for the name `citus` and matches what already shipped on release-14.0, release-13.2, and release-12.1. --------- Co-authored-by: Ibrahim Halatci <ihalatci@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ihalatci <10450368+ihalatci@users.noreply.github.com> Co-authored-by: ihalatci <ihalatci@users.noreply.github.com> Copilot-Session: 7c6370b2-06fd-4491-bf92-ecb811d34518
8 tasks
ibrahim halatci (ihalatci)
added a commit
that referenced
this pull request
Sep 8, 2026
## Problem Branch protection today enumerates every individual CI leg as a required status check. Almost all of those names embed the Postgres major, e.g. `Test Citus / PG18 - check-multi`. That makes the required-check list a function of each branch's PG matrix, so it can never be homogeneous across `main` and the release branches, and it silently rots whenever the matrix changes. Two concrete symptoms: - `release-14.0` had **no protection at all** until it was added manually this week. Nothing detects that state. - `Drop PG16 support (#8757)` just invalidated every `PG16 - *` required context on `main`. Required checks that no longer exist are simply never reported, so the gap is invisible rather than loud. Counts as of today: `main` 111 required contexts, `release-13.2` 89, `release-12.1` 108 — all different, all hand-maintained. ## Change Adds one aggregate gate job per workflow whose **name is constant** and does not mention any Postgres version: | Job | Display name | Workflow | |---|---|---| | `ci-gate` | `CI` | `build_and_test.yml` | | `packaging-gate` | `Packaging` | `packaging-test-pipelines.yml` | Each gate is `if: always()`, `needs:` the blocking jobs, and fails if any of them reports `failure`, `cancelled`, or `skipped`. Branch protection can then require just `CI` + `Packaging` and never be touched again when the matrix moves. This is additive only — no existing line is modified, and no job's behavior changes. +54 lines total. ### Gated (blocking) `build_and_test.yml`: `params`, `check-sql-snapshots`, `check-style`, `build`, `test-citus`, `test-citus-failure`, `test-citus-cdc`, `test-arbitrary-configs`, `test-pg-upgrade`, `test-citus-upgrade`. `packaging-test-pipelines.yml`: `get_postgres_versions_from_file`, `rpm_build_tests`, `deb_build_tests`. ### Not gated (advisory — still run, still visible) `test-flakyness-pre`, `test-flakyness`, `ch_benchmark`, `tpcc_benchmark`, `prepare_parallelization_matrix_32`, and the N-1 suites. These are deliberately non-blocking. ## Notes for reviewers - Every job in `needs` is unconditional, which is what makes treating `skipped` as a failure safe. The conditional jobs (benchmarks, flakyness) are exactly the ones left out. **If a conditional job is ever added to `needs`, that logic must be revisited.** - Trade-off: if a job is deleted from the workflow, the gate goes green without it. A `CODEOWNERS` entry for `/.github/workflows/` is the intended mitigation and will follow separately. - The required-check list must be derived from a **pull request**, not a push: `license/cla`, `get_postgres_versions_from_file` and all 21 `deb_build_tests`/`rpm_build_tests` legs only run on `pull_request`. ## Rollout 1. This PR — confirm `CI` and `Packaging` appear and go green. 2. Backport to `release-14.0` and `release-13.2` (job IDs are identical to `main`, so it applies verbatim). 3. Add repository rulesets covering `main` + maintained release branches, using numeric ref patterns so future branches such as `release-15.0` are protected automatically instead of starting out unprotected. 4. Run rulesets in `evaluate`, then switch to `active` and retire the per-branch classic protections. `release-12.1` keeps its existing classic protection and is intentionally out of scope here. Backporting to `release-13.2` will newly enforce `check-style` there, since that branch currently requires only `check-sql-snapshots` among the generic checks. That is an intended homogenization, called out here so it is not a surprise. Co-authored-by: Ibrahim Halatci <ihalatci@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: efb25be2-5642-4485-ad0c-fe162a1e4410
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 1 of 2 for #8750 — drops PostgreSQL 16 support. Supported set becomes PG17 + PG18.
This mirrors the PG15 drop (
62a919066): PR 1 covers build plumbing, source, and CI; PR 2 covers test output / helper cleanup.This PR depends on citusdata/the-process#240, which removes PG16 from the test image definitions.
image_suffixis temporarily pinned to the dev images from that PR (-dev-ef6cc68) in a separate, clearly labelled commit. Once CI is green here,the-process#240is merged and the release images are published, that commit gets replaced with the new stable-v<sha>suffix and this PR moves out of draft.What changed
Build plumbing
configure.ac/configure— PG16 no longer accepted; configure now fails withCitus is not compatible with the detected PostgreSQL version 16.src/include/pg_version_constants.h— droppedPG_VERSION_16.gitattributes— dropped theruleutils_16.centryFiles
src/backend/distributed/deparser/ruleutils_16.c(9235 lines)pg_get_object_address_16_17_18.c→pg_get_object_address_17_18.cSources
src/include/pg_version_compat.h— 480 → 437 lines; the pre-PG17 compat half is gonePG_VERSION_17guard blocks removed across 19 files, plus the now-deadhasPseudoconstantQualshelper and the PG16makeStringConstfallbackDeprecated GUC
citus.enable_outer_joins_with_pseudoconstant_quals_pre_pg17is left defined but inert rather than removed, so existing configs don't fail to start. It now carries a deprecation description and a check hook that warns whenever it is set from any non-default source (sessionSET,ALTER SYSTEM,ALTER DATABASE/ROLE ... SET,postgresql.conf):A clean install that never touches the GUC stays silent, and a value persisted across a restart does not produce per-backend log spam. Removal is tracked in #8751 for 15.1.
CI / devcontainer
build_and_test.yml— dropped thepg16_versionparam and every matrix entry that used it;upgrade_pg_versions→17.10-18.4;test-pg-upgradereduced to just 17→18flaky_test_debugging.yml—vars.pg16_version→vars.pg17_version.devcontainer/Dockerfile— removed thepg16build stage.github/actions/setup_cassert_pg/action.yml— doc-string example updatedVerification
ALTER SYSTEM/ restart)banned.h.sh,check_gucs_are_alphabetically_sorted.sh,editorconfig.shFollow-ups (deliberately not in this PR)
SET/RESETpairs inpg17.sqlthat would otherwise pull the new warning into expected outputtest-citus-upgradeis missing PG18sql/udfs/