1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-20 00:42:27 +03:00

Fix arrays comparison in CompareOpclassOptions()

The current code calls array_eq() and does not provide FmgrInfo.  This commit
provides initialization of FmgrInfo and uses C collation as the safe option
for text comparison because we don't know anything about the semantics of
opclass options.

Backpatch to 13, where opclass options were introduced.

Reported-by: Nicolas Maus
Discussion: https://postgr.es/m/18692-72ea398df3ec6712%40postgresql.org
Backpatch-through: 13
This commit is contained in:
Alexander Korotkov 2024-11-12 01:44:20 +02:00
parent 0c53d54c81
commit 713b8546ab
3 changed files with 16 additions and 2 deletions

View File

@ -2372,6 +2372,9 @@ ERROR: value 2025 out of bounds for option "siglen"
DETAIL: Valid values are between "1" and "2024". DETAIL: Valid values are between "1" and "2024".
create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024)); create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024));
set enable_seqscan=off; 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,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
t | sml t | sml
-------------+---------- -------------+----------

View File

@ -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)); create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024));
set enable_seqscan=off; 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,'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,'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; select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;

View File

@ -26,6 +26,7 @@
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_am.h" #include "catalog/pg_am.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h" #include "catalog/pg_constraint.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
@ -349,10 +350,12 @@ static bool
CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts) CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts)
{ {
int i; int i;
FmgrInfo fm;
if (!opts1 && !opts2) if (!opts1 && !opts2)
return true; return true;
fmgr_info(F_ARRAY_EQ, &fm);
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
Datum opt1 = opts1 ? opts1[i] : (Datum) 0; Datum opt1 = opts1 ? opts1[i] : (Datum) 0;
@ -368,8 +371,12 @@ CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts)
else if (opt2 == (Datum) 0) else if (opt2 == (Datum) 0)
return false; return false;
/* Compare non-NULL text[] datums. */ /*
if (!DatumGetBool(DirectFunctionCall2(array_eq, opt1, opt2))) * Compare non-NULL text[] datums. Use C collation to enforce binary
* equivalence of texts, because we don't know anything about the
* semantics of opclass options.
*/
if (!DatumGetBool(FunctionCall2Coll(&fm, C_COLLATION_OID, opt1, opt2)))
return false; return false;
} }