From 6de480156ba00ea2b847d86f3127addb09209095 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 6 Jul 2026 12:12:41 -0400 Subject: [PATCH] Prevent satisfies_hash_partition from crashing with VARIADIC NULL. Commit f3b0897a1213f46b4d3a99a7f8ef3a4b32e03572 fixed some related problems, but overlooked this one. That commit first appeared in PostgreSQL 11, so back-patch to all supported branches. Backpatch-through: 14 Discussion: http://postgr.es/m/CA+TgmobsvQw3F+KRYT83=N3teh8D2t-oPR=U06QDZJE3viCJRg@mail.gmail.com Reviewed-by: Tender Wang Reviewed-by: Ewan Young --- src/backend/partitioning/partbounds.c | 14 +++++++++++++- src/test/regress/expected/hash_part.out | 7 +++++++ src/test/regress/sql/hash_part.sql | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 7c5d9110fb0..2aceec7dd06 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -4869,6 +4869,12 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) fcinfo->flinfo->fn_mcxt); } } + else if (PG_ARGISNULL(3)) + { + /* Special case for VARIADIC NULL::sometype[] */ + relation_close(parent, NoLock); + PG_RETURN_BOOL(false); + } else { ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); @@ -4939,12 +4945,18 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) } else { - ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); + ArrayType *variadic_array; int i; int nelems; Datum *datum; bool *isnull; + /* Special case for VARIADIC NULL::sometype[] */ + if (PG_ARGISNULL(3)) + PG_RETURN_BOOL(false); + + variadic_array = PG_GETARG_ARRAYTYPE_P(3); + deconstruct_array(variadic_array, my_extra->variadic_type, my_extra->variadic_typlen, diff --git a/src/test/regress/expected/hash_part.out b/src/test/regress/expected/hash_part.out index ac3aabee028..c54b74abf60 100644 --- a/src/test/regress/expected/hash_part.out +++ b/src/test/regress/expected/hash_part.out @@ -40,6 +40,13 @@ SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL); f (1 row) +-- variadic null +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, VARIADIC NULL::int[]); + satisfies_hash_partition +-------------------------- + f +(1 row) + -- too many arguments SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json); ERROR: number of partitioning columns (2) does not match number of partition keys provided (3) diff --git a/src/test/regress/sql/hash_part.sql b/src/test/regress/sql/hash_part.sql index e7eb36542cc..0eca58469a7 100644 --- a/src/test/regress/sql/hash_part.sql +++ b/src/test/regress/sql/hash_part.sql @@ -35,6 +35,9 @@ SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL); -- remainder is null SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL); +-- variadic null +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, VARIADIC NULL::int[]); + -- too many arguments SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json);