Fix arrays comparison in CompareOpclassOptions()
authorAlexander Korotkov <[email protected]>
Mon, 11 Nov 2024 23:44:20 +0000 (01:44 +0200)
committerAlexander Korotkov <[email protected]>
Mon, 11 Nov 2024 23:54:38 +0000 (01:54 +0200)
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

contrib/pg_trgm/expected/pg_trgm.out
contrib/pg_trgm/sql/pg_trgm.sql
src/backend/commands/indexcmds.c

index 923c326c7bd86605d20dd9428e92bbe396608a8a..b4654fc24a770b4f40297ea3cf560832166c70ed 100644 (file)
@@ -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    
 -------------+----------
index bc2a6d525ccf3526c0e153347c9bc59004f07d05..cc5b4df03ff9d09a9672afccdafefca7532d54d2 100644 (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));
 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;
index 13fe116f715842df5f248db8d95e2ce354ceaed8..e0295d7b8aeb9d2eaccf03ccb23e37272cfccd7b 100644 (file)
@@ -26,6 +26,7 @@
 #include "catalog/index.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_am.h"
+#include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_opclass.h"
@@ -327,10 +328,12 @@ static bool
 CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts)
 {
    int         i;
+   FmgrInfo    fm;
 
    if (!opts1 && !opts2)
        return true;
 
+   fmgr_info(F_ARRAY_EQ, &fm);
    for (i = 0; i < natts; i++)
    {
        Datum       opt1 = opts1 ? opts1[i] : (Datum) 0;
@@ -346,8 +349,12 @@ CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts)
        else if (opt2 == (Datum) 0)
            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;
    }