From 2203fe36eae478c4a97c2c98b3d70320452b8f77 Mon Sep 17 00:00:00 2001 From: Mehmet YILMAZ Date: Thu, 18 Dec 2025 14:36:38 +0300 Subject: [PATCH] =?UTF-8?q?PG18:=20Add=20regression=20coverage=20for=20EXP?= =?UTF-8?q?LAIN=20(WAL)=20=E2=80=9CWAL=20Buffers=20Full=E2=80=9D=20(#8383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PostgreSQL 18 extends `EXPLAIN (ANALYZE, WAL)` to report how many times WAL buffers became full (`WAL Buffers Full`). https://github.com/postgres/postgres/commit/320545bfc This PR adds regression coverage to ensure Citus preserves the new PG18 field through the distributed EXPLAIN aggregation path: * Creates a distributed table and forces per-task EXPLAIN output via `citus.explain_all_tasks`. * Captures `EXPLAIN (ANALYZE true, WAL true, FORMAT JSON)` into `jsonb`. * Asserts the plan is distributed by checking for `"Task Count"`. * Asserts the new PG18 `"WAL Buffers Full"` property exists, and extracts its value. #### Why we don’t assert `wal_buffers_full > 0` Getting `wal_buffers_full > 0` reliably requires either shrinking `wal_buffers` (postmaster restart) or generating enough WAL to exhaust the buffer before a flush, which isn’t deterministic in this regression harness across coordinators/workers. As-is we’re verifying Citus carries the new field through EXPLAIN; pushing for non-zero would likely be flaky. --- src/test/regress/expected/pg18.out | 53 ++++++++++++++++++++++++++++++ src/test/regress/sql/pg18.sql | 42 +++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/src/test/regress/expected/pg18.out b/src/test/regress/expected/pg18.out index 9ac592479..94c4b198c 100644 --- a/src/test/regress/expected/pg18.out +++ b/src/test/regress/expected/pg18.out @@ -2957,6 +2957,59 @@ SELECT result FROM run_command_on_all_nodes( DROP TABLESPACE (3 rows) +-- PG18 Feature: EXPLAIN (WAL) reports WAL buffers becoming full. +-- PG18 commit: https://github.com/postgres/postgres/commit/320545bfc +SET search_path TO pg18_nn; +SET citus.explain_all_tasks TO true; +CREATE TABLE wal_explain_dist(id int, payload text); +SELECT create_distributed_table('wal_explain_dist', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO wal_explain_dist VALUES + (1, 'one'), (2, 'two'), (3, 'three'); +-- Helper to capture distributed EXPLAIN ANALYZE (WAL) as JSON +CREATE OR REPLACE FUNCTION explain_analyze_wal_json(query text) +RETURNS jsonb +AS $$ +DECLARE + result jsonb; +BEGIN + EXECUTE format('EXPLAIN (ANALYZE true, WAL true, FORMAT JSON) %s', query) + INTO result; + RETURN result; +END; +$$ LANGUAGE plpgsql; +CREATE TEMP TABLE wal_explain_plan(plan jsonb); +INSERT INTO wal_explain_plan(plan) +SELECT explain_analyze_wal_json($$SELECT count(*) FROM wal_explain_dist$$); +-- Ensure Citus keeps distributed-task context in the WAL-aware EXPLAIN output +SELECT jsonb_path_exists(plan, '$.**."Task Count"') AS wal_explain_distributed_plan +FROM wal_explain_plan; + wal_explain_distributed_plan +--------------------------------------------------------------------- + t +(1 row) + +-- New PG18 field: wal_buffers_full must survive the distributed EXPLAIN path +SELECT jsonb_path_exists(plan, '$.**."WAL Buffers Full"') AS wal_buffers_full_present +FROM wal_explain_plan; + wal_buffers_full_present +--------------------------------------------------------------------- + t +(1 row) + +SELECT jsonb_path_query_first(plan, '$.**."WAL Buffers Full"') AS wal_buffers_full_value +FROM wal_explain_plan; + wal_buffers_full_value +--------------------------------------------------------------------- + 0 +(1 row) + +DROP TABLE wal_explain_plan; +SET citus.explain_all_tasks TO default; -- cleanup with minimum verbosity SET client_min_messages TO ERROR; RESET search_path; diff --git a/src/test/regress/sql/pg18.sql b/src/test/regress/sql/pg18.sql index a3954f628..01b81bce2 100644 --- a/src/test/regress/sql/pg18.sql +++ b/src/test/regress/sql/pg18.sql @@ -1849,6 +1849,48 @@ SELECT result FROM run_command_on_all_nodes( $$ ); +-- PG18 Feature: EXPLAIN (WAL) reports WAL buffers becoming full. +-- PG18 commit: https://github.com/postgres/postgres/commit/320545bfc +SET search_path TO pg18_nn; +SET citus.explain_all_tasks TO true; + +CREATE TABLE wal_explain_dist(id int, payload text); +SELECT create_distributed_table('wal_explain_dist', 'id'); + +INSERT INTO wal_explain_dist VALUES + (1, 'one'), (2, 'two'), (3, 'three'); + +-- Helper to capture distributed EXPLAIN ANALYZE (WAL) as JSON +CREATE OR REPLACE FUNCTION explain_analyze_wal_json(query text) +RETURNS jsonb +AS $$ +DECLARE + result jsonb; +BEGIN + EXECUTE format('EXPLAIN (ANALYZE true, WAL true, FORMAT JSON) %s', query) + INTO result; + RETURN result; +END; +$$ LANGUAGE plpgsql; + +CREATE TEMP TABLE wal_explain_plan(plan jsonb); +INSERT INTO wal_explain_plan(plan) +SELECT explain_analyze_wal_json($$SELECT count(*) FROM wal_explain_dist$$); + +-- Ensure Citus keeps distributed-task context in the WAL-aware EXPLAIN output +SELECT jsonb_path_exists(plan, '$.**."Task Count"') AS wal_explain_distributed_plan +FROM wal_explain_plan; + +-- New PG18 field: wal_buffers_full must survive the distributed EXPLAIN path +SELECT jsonb_path_exists(plan, '$.**."WAL Buffers Full"') AS wal_buffers_full_present +FROM wal_explain_plan; + +SELECT jsonb_path_query_first(plan, '$.**."WAL Buffers Full"') AS wal_buffers_full_value +FROM wal_explain_plan; + +DROP TABLE wal_explain_plan; +SET citus.explain_all_tasks TO default; + -- cleanup with minimum verbosity SET client_min_messages TO ERROR; RESET search_path;