Hi,

On the back of this thread[1] over at pgsql-general, I've attached a patch that 
marks the functions in btree_gist as PARALLEL SAFE.
This is primarily to allow parallel plans to be considered when btree_gist's 
<-> operator is used in any context; for example in an expression
that will be evaluated at execution time, or in a functional column in btree or 
gist indexes.

In the latter example, despite the functions already being marked IMMUTABLE, 
attempts to retrieve precomputed values from a functional index during an index 
scan or index-only scan still require the function to be marked PARALLEL SAFE 
to prevent dropping down to a serial plan.

It requires btree_gist's version to be bumped to 1.6.

In line with this commit[2], and for the same reasons, all functions defined by 
btree_gist are being marked as safe:

---

"... Note that some of the markings added by this commit don't have any
effect; for example, gseg_picksplit() isn't likely to be mentioned
explicitly in a query and therefore it's parallel-safety marking will
never be consulted.  But this commit just marks everything for
consistency: if it were somehow used in a query, that would be fine as
far as parallel query is concerned, since it does not consult any
backend-private state, attempt to write data, etc."

---

I haven't added any more tests, but neither did I find any added with the above 
commit.

"CREATE EXTENSION btree_gist" runs successfully, as does "make check-world".

This is the first patch I've submitted, so if I've omitted something then 
please let me know.
Thanks for your time,
Steven.


[1] 
https://www.postgresql.org/message-id/DB7PR09MB2537E18FF90C1C1BBF49D628FD830%40DB7PR09MB2537.eurprd09.prod.outlook.com
[2] 
https://github.com/postgres/postgres/commit/2910fc8239fa501b662c5459d7ba16a4bc35e7e8


(Apologies if my company's footer appears here)

** Cantab Capital Partners LLP is now named GAM Systematic LLP. Please note 
that our email addresses have changed from @cantabcapital.com to @gam.com.**

This email was sent by and on behalf of GAM Investments. GAM Investments is the 
corporate brand for GAM Holding AG and its direct and indirect subsidiaries. 
These companies may be referred to as ‘GAM’ or ‘GAM Investments’. In the United 
Kingdom, the business of GAM Investments is conducted by GAM (U.K.) Limited 
(No. 01664573) or one or more entities under the control of GAM (U.K.) Limited, 
including the following entities authorised and regulated by the Financial 
Conduct Authority: GAM International Management Limited (No. 01802911), GAM 
London Limited (No. 00874802), GAM Sterling Management Limited (No. 01750352), 
GAM Unit Trust Management Company Limited (No. 2873560) and GAM Systematic LLP 
(No. OC317557). GAM (U.K.) Limited and its regulated entities are registered in 
England and Wales. The registered office and principal place of business of GAM 
(U.K.) Limited and its regulated entities is at 8 Finsbury Circus, London, 
England, EC2M 7GB. The registered office of GAM Systematic LLP is at City 
House, Hills Road, Cambridge, CB2 1RE. This email, and any attachments, is 
confidential and may be privileged or otherwise protected from disclosure. It 
is intended solely for the stated addressee(s) and access to it by any other 
person is unauthorised. If you are not the intended recipient, you must not 
disclose, copy, circulate or in any other way use or rely on the information 
contained herein. If you have received this email in error, please inform us 
immediately and delete all copies of it. See - 
https://www.gam.com/en/legal/email-disclosures-eu/ for further information on 
confidentiality, the risks of non-secure electronic communication, and certain 
disclosures which we are required to make in accordance with applicable 
legislation and regulations. If you cannot access this link, please notify us 
by reply message and we will send the contents to you. GAM Investments will 
collect and use information about you in the course of your interactions with 
us. Full details about the data types we collect and what we use this for and 
your related rights is set out in our online privacy policy at 
https://www.gam.com/en/legal/privacy-policy. Please familiarise yourself with 
this policy and check it from time to time for updates as it supplements this 
notice.
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index a85db35e55..e92d974a1a 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -31,7 +31,8 @@ OBJS =  \
 EXTENSION = btree_gist
 DATA = btree_gist--1.0--1.1.sql \
        btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql \
-       btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.sql
+       btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.sql \
+       btree_gist--1.5--1.6.sql
 PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
diff --git a/contrib/btree_gist/btree_gist--1.5--1.6.sql b/contrib/btree_gist/btree_gist--1.5--1.6.sql
new file mode 100644
index 0000000000..87cbf68818
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.5--1.6.sql
@@ -0,0 +1,189 @@
+/* contrib/btree_gist/btree_gist--1.5--1.6.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.6'" to load this file. \quit
+
+-- gbtreekey* input/output functions.
+ALTER FUNCTION gbtreekey4_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey4_out(gbtreekey4) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey8_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey8_out(gbtreekey8) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey16_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey16_out(gbtreekey16) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey32_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey32_out(gbtreekey32) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey_var_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION gbtreekey_var_out(gbtreekey_var) PARALLEL SAFE;
+
+-- Distance operator (<->) functions
+ALTER FUNCTION cash_dist(money, money) PARALLEL SAFE;
+ALTER FUNCTION date_dist(date, date) PARALLEL SAFE;
+ALTER FUNCTION float4_dist(real, real) PARALLEL SAFE;
+ALTER FUNCTION float8_dist(double precision, double precision) PARALLEL SAFE;
+ALTER FUNCTION int2_dist(smallint, smallint) PARALLEL SAFE;
+ALTER FUNCTION int4_dist(integer, integer) PARALLEL SAFE;
+ALTER FUNCTION int8_dist(bigint, bigint) PARALLEL SAFE;
+ALTER FUNCTION interval_dist(interval, interval) PARALLEL SAFE;
+ALTER FUNCTION oid_dist(oid, oid) PARALLEL SAFE;
+ALTER FUNCTION time_dist(time without time zone, time without time zone) PARALLEL SAFE;
+ALTER FUNCTION ts_dist(timestamp without time zone, timestamp without time zone) PARALLEL SAFE;
+ALTER FUNCTION tstz_dist(timestamp with time zone, timestamp with time zone) PARALLEL SAFE;
+
+-- GiST access methods
+ALTER FUNCTION gbt_oid_consistent(internal, oid, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_distance(internal, oid, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_decompress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_var_decompress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_var_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_consistent(internal, smallint, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_distance(internal, smallint, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_consistent(internal, integer, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_distance(internal, integer, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_consistent(internal, bigint, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_distance(internal, bigint, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_consistent(internal, real, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_distance(internal, real, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_consistent(internal, double precision, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_distance(internal, double precision, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_consistent(internal, timestamp without time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_distance(internal, timestamp without time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_tstz_consistent(internal, timestamp with time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_tstz_distance(internal, timestamp with time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_tstz_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_consistent(internal, time without time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_distance(internal, time without time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_timetz_consistent(internal, time with time zone, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_timetz_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_consistent(internal, date, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_distance(internal, date, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_consistent(internal, interval, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_distance(internal, interval, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_decompress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_consistent(internal, money, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_distance(internal, money, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_consistent(internal, macaddr, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_consistent(internal, text, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bpchar_consistent(internal, character, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bpchar_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_consistent(internal, bytea, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_consistent(internal, numeric, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_consistent(internal, bit, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_consistent(internal, inet, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_consistent(internal, uuid, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_uuid_same(gbtreekey32, gbtreekey32, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_consistent(internal, macaddr8, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_macad8_same(gbtreekey16, gbtreekey16, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_consistent(internal, anyenum, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_fetch(internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal) PARALLEL SAFE;
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index cd2d7eb4ab..e5c41fe8f3 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,6 +1,6 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.5'
+default_version = '1.6'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
 trusted = true

Reply via email to