From 25680283fe0c9ef21a640763b712f277a6ca0188 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Fri, 8 Nov 2024 00:23:00 +0200 Subject: [PATCH v1] Fix arrays comparison in CompareOpclassOptions() The current code calls array_eq() without providing FmgrInfo. This commit makes this check stricter and simpler using datumIsEqual(), which should be fine the the current usage scenario. Reported-by: Nicolas Maus Discussion: https://postgr.es/m/18692-72ea398df3ec6712%40postgresql.org --- contrib/pg_trgm/expected/pg_trgm.out | 3 +++ contrib/pg_trgm/sql/pg_trgm.sql | 4 ++++ src/backend/commands/indexcmds.c | 24 ++++++++++++++---------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out index ce4bf1d4e51..0b70d9de256 100644 --- a/contrib/pg_trgm/expected/pg_trgm.out +++ b/contrib/pg_trgm/expected/pg_trgm.out @@ -2372,6 +2372,9 @@ ERROR: value 2025 out of bounds for option "siglen" DETAIL: Valid values are between "1" and "2024". create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024)); set enable_seqscan=off; +-- check index compatibility handling when opclass option is specified +alter table test_trgm alter column t type varchar(768); +alter table test_trgm alter column t type text; select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t; t | sml -------------+---------- diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql index 6a9da24d5a7..340c9891899 100644 --- a/contrib/pg_trgm/sql/pg_trgm.sql +++ b/contrib/pg_trgm/sql/pg_trgm.sql @@ -52,6 +52,10 @@ create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2025)); create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024)); set enable_seqscan=off; +-- check index compatibility handling when opclass option is specified +alter table test_trgm alter column t type varchar(768); +alter table test_trgm alter column t type text; + select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t; select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t; select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 2f652463e3c..01fc89a638c 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -60,6 +60,7 @@ #include "storage/procarray.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/guc.h" #include "utils/injection_point.h" @@ -371,19 +372,22 @@ CompareOpclassOptions(const Datum *opts1, const Datum *opts2, int natts) Datum opt1 = opts1 ? opts1[i] : (Datum) 0; Datum opt2 = opts2 ? opts2[i] : (Datum) 0; - if (opt1 == (Datum) 0) + if (opt1 && opt2) { - if (opt2 == (Datum) 0) - continue; - else + /* + * Compare non-NULL text[] datums. We are strict and require + * arrays to be binary same. This is fine with the current usage + * scenario involving get_reloptions(), then re-parsing and + * transformRelOptions(). + */ + if (!datumIsEqual(opts1[i], opts2[i], false, -1)) + return false; + } + else + { + if (opt1 != opt2) return false; } - else if (opt2 == (Datum) 0) - return false; - - /* Compare non-NULL text[] datums. */ - if (!DatumGetBool(DirectFunctionCall2(array_eq, opt1, opt2))) - return false; } return true; -- 2.39.5 (Apple Git-154)