mirror of https://github.com/citusdata/citus.git
PG18: Add _plan_json() test helper and switch columnar index tests to JSON plan checks (#8299)
fixes #8263 * Introduces `columnar_test_helpers._plan_json(q text) -> jsonb`, which runs `EXPLAIN (FORMAT JSON, COSTS OFF, ANALYZE OFF)` and returns the plan as `jsonb`. This lets us assert on plan structure instead of text matching. * Updates `columnar_indexes.sql` tests to detect whether any index-based scan is used by searching the JSON plan’s `"Node Type"` (e.g., `Index Scan`, `Index Only Scan`, `Bitmap Index Scan`). ## Notable changes * New helper in `src/test/regress/sql/columnar_test_helpers.sql`: * `EXECUTE format('EXPLAIN (FORMAT JSON, COSTS OFF, ANALYZE OFF) %s', q) INTO j;` * Returns the `jsonb` plan for downstream assertions. ```sql SELECT NOT jsonb_path_exists( columnar_test_helpers._plan_json('SELECT b FROM columnar_table WHERE b = 30000'), '$[*].Plan.** ? (@."Node Type" like_regex "^(Index|Bitmap Index).*Scan$")' ) AS uses_no_index_scan; ``` to verify no index scan occurs at the partial index boundary (`b = 30000`) and that an index scan is used where expected (`b = 30001`). --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>pull/8292/head
parent
6251eab9b7
commit
61b491f0f4
|
|
@ -176,12 +176,15 @@ SELECT pg_total_relation_size('columnar_table_b_idx') * 5 <
|
|||
(1 row)
|
||||
|
||||
-- can't use index scan due to partial index boundaries
|
||||
EXPLAIN (COSTS OFF) SELECT b FROM columnar_table WHERE b = 30000;
|
||||
QUERY PLAN
|
||||
SELECT NOT jsonb_path_exists(
|
||||
columnar_test_helpers._plan_json('SELECT b FROM columnar_table WHERE b = 30000'),
|
||||
-- Regex matches any index-based scan: "Index Scan", "Index Only Scan", "Bitmap Index Scan".
|
||||
'$[*].Plan.** ? (@."Node Type" like_regex "^(Index|Bitmap Index).*Scan$")'
|
||||
) AS uses_no_index_scan; -- expect: t
|
||||
uses_no_index_scan
|
||||
---------------------------------------------------------------------
|
||||
Seq Scan on columnar_table
|
||||
Filter: (b = 30000)
|
||||
(2 rows)
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- can use index scan
|
||||
EXPLAIN (COSTS OFF) SELECT b FROM columnar_table WHERE b = 30001;
|
||||
|
|
|
|||
|
|
@ -146,3 +146,11 @@ BEGIN
|
|||
RETURN NEXT;
|
||||
END LOOP;
|
||||
END; $$ language plpgsql;
|
||||
CREATE OR REPLACE FUNCTION _plan_json(q text)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE j jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON, COSTS OFF, ANALYZE OFF) %s', q) INTO j;
|
||||
RETURN j;
|
||||
END $$;
|
||||
|
|
|
|||
|
|
@ -114,7 +114,11 @@ SELECT pg_total_relation_size('columnar_table_b_idx') * 5 <
|
|||
pg_total_relation_size('columnar_table_a_idx');
|
||||
|
||||
-- can't use index scan due to partial index boundaries
|
||||
EXPLAIN (COSTS OFF) SELECT b FROM columnar_table WHERE b = 30000;
|
||||
SELECT NOT jsonb_path_exists(
|
||||
columnar_test_helpers._plan_json('SELECT b FROM columnar_table WHERE b = 30000'),
|
||||
-- Regex matches any index-based scan: "Index Scan", "Index Only Scan", "Bitmap Index Scan".
|
||||
'$[*].Plan.** ? (@."Node Type" like_regex "^(Index|Bitmap Index).*Scan$")'
|
||||
) AS uses_no_index_scan; -- expect: t
|
||||
-- can use index scan
|
||||
EXPLAIN (COSTS OFF) SELECT b FROM columnar_table WHERE b = 30001;
|
||||
|
||||
|
|
|
|||
|
|
@ -158,3 +158,12 @@ BEGIN
|
|||
RETURN NEXT;
|
||||
END LOOP;
|
||||
END; $$ language plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _plan_json(q text)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE j jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON, COSTS OFF, ANALYZE OFF) %s', q) INTO j;
|
||||
RETURN j;
|
||||
END $$;
|
||||
|
|
|
|||
Loading…
Reference in New Issue