From c21c762a7182bc49626a58b68370d281dec10c18 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 17 Aug 2026 16:50:54 +0900 Subject: [PATCH] Fix handling of NULL input in opclass option functions Nine opclass option functions exist in the tree, and are not marked as STRICT while they are unable to handle NULL inputs: 1) Backend core: brin_bloom_options brin_minmax_multi_options gtsvector_options 2) Contrib modules: ghstore_options gtrgm_options g_int_options g_intbig_options _ltree_gist_options ltree_gist_options The backend core functions have their proisstrict switched to true. The contrib module functions do nothing if given a NULL input. Oversights originating from 911e70207703, with a coding pattern that has spread across more places of the tree. --- src/include/catalog/pg_proc.dat | 6 +++--- contrib/hstore/hstore_gist.c | 7 ++++++- contrib/intarray/_int_gist.c | 7 ++++++- contrib/intarray/_intbig_gist.c | 7 ++++++- contrib/ltree/_ltree_gist.c | 7 ++++++- contrib/ltree/ltree_gist.c | 7 ++++++- contrib/pg_trgm/trgm_gist.c | 7 ++++++- 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 66c3c9a04cfb..5e998183bdb1 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -9131,7 +9131,7 @@ proargtypes => 'internal internal internal', prosrc => 'brin_minmax_multi_union' }, { oid => '4620', descr => 'BRIN multi minmax support', - proname => 'brin_minmax_multi_options', proisstrict => 'f', + proname => 'brin_minmax_multi_options', proisstrict => 't', prorettype => 'void', proargtypes => 'internal', prosrc => 'brin_minmax_multi_options' }, @@ -9237,7 +9237,7 @@ proname => 'brin_bloom_union', prorettype => 'bool', proargtypes => 'internal internal internal', prosrc => 'brin_bloom_union' }, { oid => '4595', descr => 'BRIN bloom support', - proname => 'brin_bloom_options', proisstrict => 'f', prorettype => 'void', + proname => 'brin_bloom_options', proisstrict => 't', prorettype => 'void', proargtypes => 'internal', prosrc => 'brin_bloom_options' }, # userlock replacements @@ -10008,7 +10008,7 @@ proargtypes => 'internal gtsvector int4 oid internal', prosrc => 'gtsvector_consistent_oldsig' }, { oid => '3434', descr => 'GiST tsvector support', - proname => 'gtsvector_options', proisstrict => 'f', prorettype => 'void', + proname => 'gtsvector_options', proisstrict => 't', prorettype => 'void', proargtypes => 'internal', prosrc => 'gtsvector_options' }, { oid => '3656', descr => 'GIN tsvector support', diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c index 832a268e0d2f..9bb29a6ed111 100644 --- a/contrib/hstore/hstore_gist.c +++ b/contrib/hstore/hstore_gist.c @@ -614,7 +614,12 @@ ghstore_consistent(PG_FUNCTION_ARGS) Datum ghstore_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(GistHstoreOptions)); add_local_int_reloption(relopts, "siglen", diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c index 98711ac54e2f..d602a5ac8067 100644 --- a/contrib/intarray/_int_gist.c +++ b/contrib/intarray/_int_gist.c @@ -626,7 +626,12 @@ g_int_picksplit(PG_FUNCTION_ARGS) Datum g_int_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(GISTIntArrayOptions)); add_local_int_reloption(relopts, "numranges", diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c index 396da703438e..5f570f263ff8 100644 --- a/contrib/intarray/_intbig_gist.c +++ b/contrib/intarray/_intbig_gist.c @@ -585,7 +585,12 @@ g_intbig_consistent(PG_FUNCTION_ARGS) Datum g_intbig_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(GISTIntArrayBigOptions)); add_local_int_reloption(relopts, "siglen", diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c index 07d668235924..77e5aa852343 100644 --- a/contrib/ltree/_ltree_gist.c +++ b/contrib/ltree/_ltree_gist.c @@ -546,7 +546,12 @@ _ltree_consistent(PG_FUNCTION_ARGS) Datum _ltree_gist_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(LtreeGistOptions)); add_local_int_reloption(relopts, "siglen", "signature length", diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c index e8451171c729..bb39b4cb973d 100644 --- a/contrib/ltree/ltree_gist.c +++ b/contrib/ltree/ltree_gist.c @@ -735,7 +735,12 @@ ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals, Datum ltree_gist_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(LtreeGistOptions)); add_local_int_reloption(relopts, "siglen", diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 42d0b7a5d65f..f43aafb1f524 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -963,7 +963,12 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) Datum gtrgm_options(PG_FUNCTION_ARGS) { - local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + local_relopts *relopts; + + if (PG_ARGISNULL(0)) + PG_RETURN_VOID(); + + relopts = (local_relopts *) PG_GETARG_POINTER(0); init_local_reloptions(relopts, sizeof(TrgmGistOptions)); add_local_int_reloption(relopts, "siglen", -- 2.55.0