]> granicus.if.org Git - postgresql/commitdiff
Fix contrib/btree_gist to handle collations properly.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Apr 2011 00:19:58 +0000 (20:19 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Apr 2011 00:19:58 +0000 (20:19 -0400)
Make use of the collation attached to the index column, instead of
hard-wiring DEFAULT_COLLATION_OID.  (Note: in theory this could require
reindexing btree_gist indexes on textual columns, but I rather doubt anyone
has one with a non-default declared collation as yet.)

contrib/btree_gist/btree_bit.c
contrib/btree_gist/btree_bytea.c
contrib/btree_gist/btree_numeric.c
contrib/btree_gist/btree_text.c
contrib/btree_gist/btree_utils_num.c
contrib/btree_gist/btree_utils_var.c
contrib/btree_gist/btree_utils_var.h

index 9884d0fb9677b629b2987d11f897b0eb07f25ee7..8675d2488de0f0667cca983fd5fbbb0358e6aeb9 100644 (file)
@@ -29,40 +29,51 @@ Datum               gbt_bit_same(PG_FUNCTION_ARGS);
 /* define for comparison */
 
 static bool
-gbt_bitgt(const void *a, const void *b)
+gbt_bitgt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(bitgt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(bitgt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_bitge(const void *a, const void *b)
+gbt_bitge(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(bitge, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(bitge,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_biteq(const void *a, const void *b)
+gbt_biteq(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(biteq, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(biteq,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_bitle(const void *a, const void *b)
+gbt_bitle(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(bitle, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(bitle,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_bitlt(const void *a, const void *b)
+gbt_bitlt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(bitlt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(bitlt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static int32
-gbt_bitcmp(const bytea *a, const bytea *b)
+gbt_bitcmp(const void *a, const void *b, Oid collation)
 {
-       return
-               (DatumGetInt32(DirectFunctionCall2(byteacmp, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetInt32(DirectFunctionCall2(byteacmp,
+                                                                                        PointerGetDatum(a),
+                                                                                        PointerGetDatum(b)));
 }
 
 
@@ -134,7 +145,7 @@ gbt_bit_consistent(PG_FUNCTION_ARGS)
 
        /* Oid          subtype = PG_GETARG_OID(3); */
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
-       bool            retval = FALSE;
+       bool            retval;
        GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
        GBT_VARKEY_R r = gbt_var_key_readable(key);
 
@@ -142,12 +153,14 @@ gbt_bit_consistent(PG_FUNCTION_ARGS)
        *recheck = false;
 
        if (GIST_LEAF(entry))
-               retval = gbt_var_consistent(&r, query, &strategy, TRUE, &tinfo);
+               retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
+                                                                       TRUE, &tinfo);
        else
        {
                bytea      *q = gbt_bit_xfrm((bytea *) query);
 
-               retval = gbt_var_consistent(&r, (void *) q, &strategy, FALSE, &tinfo);
+               retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
+                                                                       FALSE, &tinfo);
        }
        PG_RETURN_BOOL(retval);
 }
@@ -160,7 +173,8 @@ gbt_bit_union(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        int32      *size = (int *) PG_GETARG_POINTER(1);
 
-       PG_RETURN_POINTER(gbt_var_union(entryvec, size, &tinfo));
+       PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
+                                                                       &tinfo));
 }
 
 
@@ -170,7 +184,8 @@ gbt_bit_picksplit(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
-       gbt_var_picksplit(entryvec, v, &tinfo);
+       gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
+                                         &tinfo);
        PG_RETURN_POINTER(v);
 }
 
@@ -181,7 +196,8 @@ gbt_bit_same(PG_FUNCTION_ARGS)
        Datum           d2 = PG_GETARG_DATUM(1);
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_same(result, d1, d2, &tinfo));
+       *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+       PG_RETURN_POINTER(result);
 }
 
 
@@ -192,5 +208,6 @@ gbt_bit_penalty(PG_FUNCTION_ARGS)
        GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
        float      *result = (float *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, &tinfo));
+       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
+                                                                         &tinfo));
 }
index 843046461224742efb7432af978ae182d39be12b..e45509d15caadd07b4215d3f22a1fecebac0522e 100644 (file)
@@ -27,41 +27,51 @@ Datum               gbt_bytea_same(PG_FUNCTION_ARGS);
 /* define for comparison */
 
 static bool
-gbt_byteagt(const void *a, const void *b)
+gbt_byteagt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(byteagt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(byteagt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_byteage(const void *a, const void *b)
+gbt_byteage(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(byteage, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(byteage,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_byteaeq(const void *a, const void *b)
+gbt_byteaeq(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(byteaeq, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(byteaeq,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_byteale(const void *a, const void *b)
+gbt_byteale(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(byteale, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(byteale,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_bytealt(const void *a, const void *b)
+gbt_bytealt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(bytealt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(bytealt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
-
 static int32
-gbt_byteacmp(const bytea *a, const bytea *b)
+gbt_byteacmp(const void *a, const void *b, Oid collation)
 {
-       return
-               (DatumGetInt32(DirectFunctionCall2(byteacmp, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetInt32(DirectFunctionCall2(byteacmp,
+                                                                                        PointerGetDatum(a),
+                                                                                        PointerGetDatum(b)));
 }
 
 
@@ -111,7 +121,8 @@ gbt_bytea_consistent(PG_FUNCTION_ARGS)
        /* All cases served by this function are exact */
        *recheck = false;
 
-       retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
+       retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
+                                                               GIST_LEAF(entry), &tinfo);
        PG_RETURN_BOOL(retval);
 }
 
@@ -123,7 +134,8 @@ gbt_bytea_union(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        int32      *size = (int *) PG_GETARG_POINTER(1);
 
-       PG_RETURN_POINTER(gbt_var_union(entryvec, size, &tinfo));
+       PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
+                                                                       &tinfo));
 }
 
 
@@ -133,7 +145,8 @@ gbt_bytea_picksplit(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
-       gbt_var_picksplit(entryvec, v, &tinfo);
+       gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
+                                         &tinfo);
        PG_RETURN_POINTER(v);
 }
 
@@ -144,7 +157,8 @@ gbt_bytea_same(PG_FUNCTION_ARGS)
        Datum           d2 = PG_GETARG_DATUM(1);
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_same(result, d1, d2, &tinfo));
+       *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+       PG_RETURN_POINTER(result);
 }
 
 
@@ -155,5 +169,6 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS)
        GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
        float      *result = (float *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, &tinfo));
+       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
+                                                                         &tinfo));
 }
index fa82497e2b9fc4986ce36aef0fd473de3bb39982..e962c6dd32743e9638c9a2d3bb8d0383e80358c1 100644 (file)
@@ -32,41 +32,51 @@ Datum               gbt_numeric_same(PG_FUNCTION_ARGS);
 /* define for comparison */
 
 static bool
-gbt_numeric_gt(const void *a, const void *b)
+gbt_numeric_gt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(numeric_gt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(numeric_gt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_numeric_ge(const void *a, const void *b)
+gbt_numeric_ge(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(numeric_ge, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(numeric_ge,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_numeric_eq(const void *a, const void *b)
+gbt_numeric_eq(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(numeric_eq, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(numeric_eq,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_numeric_le(const void *a, const void *b)
+gbt_numeric_le(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(numeric_le, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(numeric_le,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
 static bool
-gbt_numeric_lt(const void *a, const void *b)
+gbt_numeric_lt(const void *a, const void *b, Oid collation)
 {
-       return (DatumGetBool(DirectFunctionCall2(numeric_lt, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetBool(DirectFunctionCall2(numeric_lt,
+                                                                                       PointerGetDatum(a),
+                                                                                       PointerGetDatum(b)));
 }
 
-
 static int32
-gbt_numeric_cmp(const bytea *a, const bytea *b)
+gbt_numeric_cmp(const void *a, const void *b, Oid collation)
 {
-       return
-               (DatumGetInt32(DirectFunctionCall2(numeric_cmp, PointerGetDatum(a), PointerGetDatum(b))));
+       return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
+                                                                                        PointerGetDatum(a),
+                                                                                        PointerGetDatum(b)));
 }
 
 
@@ -116,7 +126,8 @@ gbt_numeric_consistent(PG_FUNCTION_ARGS)
        /* All cases served by this function are exact */
        *recheck = false;
 
-       retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
+       retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
+                                                               GIST_LEAF(entry), &tinfo);
        PG_RETURN_BOOL(retval);
 }
 
@@ -128,7 +139,8 @@ gbt_numeric_union(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        int32      *size = (int *) PG_GETARG_POINTER(1);
 
-       PG_RETURN_POINTER(gbt_var_union(entryvec, size, &tinfo));
+       PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
+                                                                       &tinfo));
 }
 
 
@@ -139,7 +151,8 @@ gbt_numeric_same(PG_FUNCTION_ARGS)
        Datum           d2 = PG_GETARG_DATUM(1);
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_same(result, d1, d2, &tinfo));
+       *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+       PG_RETURN_POINTER(result);
 }
 
 
@@ -163,7 +176,7 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS)
 
        rk = gbt_var_key_readable(org);
        uni = PointerGetDatum(gbt_var_key_copy(&rk, TRUE));
-       gbt_var_bin_union(&uni, newe, &tinfo);
+       gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo);
        ok = gbt_var_key_readable(org);
        uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
 
@@ -224,6 +237,7 @@ gbt_numeric_picksplit(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
-       gbt_var_picksplit(entryvec, v, &tinfo);
+       gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
+                                         &tinfo);
        PG_RETURN_POINTER(v);
 }
index c6b57f82de9875776bd39e731a6a06a296486d03..3d4f8c13c8684e887d7e5f10652e085972903249 100644 (file)
@@ -3,7 +3,6 @@
  */
 #include "btree_gist.h"
 #include "btree_utils_var.h"
-#include "catalog/pg_collation.h"
 #include "utils/builtins.h"
 
 /*
@@ -31,55 +30,55 @@ Datum               gbt_text_same(PG_FUNCTION_ARGS);
 /* define for comparison */
 
 static bool
-gbt_textgt(const void *a, const void *b)
+gbt_textgt(const void *a, const void *b, Oid collation)
 {
        return DatumGetBool(DirectFunctionCall2Coll(text_gt,
-                                                                                               DEFAULT_COLLATION_OID,
+                                                                                               collation,
                                                                                                PointerGetDatum(a),
                                                                                                PointerGetDatum(b)));
 }
 
 static bool
-gbt_textge(const void *a, const void *b)
+gbt_textge(const void *a, const void *b, Oid collation)
 {
        return DatumGetBool(DirectFunctionCall2Coll(text_ge,
-                                                                                               DEFAULT_COLLATION_OID,
+                                                                                               collation,
                                                                                                PointerGetDatum(a),
                                                                                                PointerGetDatum(b)));
 }
 
 static bool
-gbt_texteq(const void *a, const void *b)
+gbt_texteq(const void *a, const void *b, Oid collation)
 {
        return DatumGetBool(DirectFunctionCall2Coll(texteq,
-                                                                                               DEFAULT_COLLATION_OID,
+                                                                                               collation,
                                                                                                PointerGetDatum(a),
                                                                                                PointerGetDatum(b)));
 }
 
 static bool
-gbt_textle(const void *a, const void *b)
+gbt_textle(const void *a, const void *b, Oid collation)
 {
        return DatumGetBool(DirectFunctionCall2Coll(text_le,
-                                                                                               DEFAULT_COLLATION_OID,
+                                                                                               collation,
                                                                                                PointerGetDatum(a),
                                                                                                PointerGetDatum(b)));
 }
 
 static bool
-gbt_textlt(const void *a, const void *b)
+gbt_textlt(const void *a, const void *b, Oid collation)
 {
        return DatumGetBool(DirectFunctionCall2Coll(text_lt,
-                                                                                               DEFAULT_COLLATION_OID,
+                                                                                               collation,
                                                                                                PointerGetDatum(a),
                                                                                                PointerGetDatum(b)));
 }
 
 static int32
-gbt_textcmp(const bytea *a, const bytea *b)
+gbt_textcmp(const void *a, const void *b, Oid collation)
 {
        return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
-                                                                                                DEFAULT_COLLATION_OID,
+                                                                                                collation,
                                                                                                 PointerGetDatum(a),
                                                                                                 PointerGetDatum(b)));
 }
@@ -169,7 +168,8 @@ gbt_text_consistent(PG_FUNCTION_ARGS)
                tinfo.eml = pg_database_encoding_max_length();
        }
 
-       retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
+       retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
+                                                               GIST_LEAF(entry), &tinfo);
 
        PG_RETURN_BOOL(retval);
 }
@@ -197,7 +197,8 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS)
                tinfo.eml = pg_database_encoding_max_length();
        }
 
-       retval = gbt_var_consistent(&r, trim, &strategy, GIST_LEAF(entry), &tinfo);
+       retval = gbt_var_consistent(&r, trim, strategy, PG_GET_COLLATION(),
+                                                               GIST_LEAF(entry), &tinfo);
        PG_RETURN_BOOL(retval);
 }
 
@@ -208,7 +209,8 @@ gbt_text_union(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        int32      *size = (int *) PG_GETARG_POINTER(1);
 
-       PG_RETURN_POINTER(gbt_var_union(entryvec, size, &tinfo));
+       PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
+                                                                       &tinfo));
 }
 
 
@@ -218,7 +220,8 @@ gbt_text_picksplit(PG_FUNCTION_ARGS)
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
        GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
-       gbt_var_picksplit(entryvec, v, &tinfo);
+       gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
+                                         &tinfo);
        PG_RETURN_POINTER(v);
 }
 
@@ -229,7 +232,8 @@ gbt_text_same(PG_FUNCTION_ARGS)
        Datum           d2 = PG_GETARG_DATUM(1);
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_same(result, d1, d2, &tinfo));
+       *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+       PG_RETURN_POINTER(result);
 }
 
 
@@ -240,5 +244,6 @@ gbt_text_penalty(PG_FUNCTION_ARGS)
        GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
        float      *result = (float *) PG_GETARG_POINTER(2);
 
-       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, &tinfo));
+       PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
+                                                                         &tinfo));
 }
index 64c95854df89d15376ecc6dd7994fe6a971276e0..a3da5802df29aa9b825b4b7123e3f5f2ea484449 100644 (file)
@@ -184,9 +184,11 @@ gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
 
 
 /*
-** The GiST consistent method
-*/
-
+ * The GiST consistent method
+ *
+ * Note: we currently assume that no datatypes that use this routine are
+ * collation-aware; so we don't bother passing collation through.
+ */
 bool
 gbt_num_consistent(const GBT_NUMKEY_R *key,
                                   const void *query,
index d74013af8828d987a3c0bc4ba5a9b12f74597b21..e73799bb21c430dad613a291729bc4c8c5d37d84 100644 (file)
@@ -8,11 +8,24 @@
 #include <float.h>
 
 #include "btree_utils_var.h"
-#include "catalog/pg_collation.h"
 #include "utils/pg_locale.h"
 #include "utils/builtins.h"
 #include "utils/rel.h"
 
+/* used for key sorting */
+typedef struct
+{
+       int                     i;
+       GBT_VARKEY *t;
+} Vsrt;
+
+typedef struct
+{
+       const gbtree_vinfo *tinfo;
+       Oid                     collation;
+} gbt_vsrt_arg;
+
+
 PG_FUNCTION_INFO_V1(gbt_var_decompress);
 Datum          gbt_var_decompress(PG_FUNCTION_ARGS);
 
@@ -140,13 +153,11 @@ gbt_var_node_cp_len(const GBT_VARKEY *node, const gbtree_vinfo *tinfo)
 
 /*
  * returns true, if query matches prefix ( common prefix )
-*/
+ */
 static bool
 gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo *tinfo)
 {
-
        bool            out = FALSE;
-       int32           k = 0;
        int32           qlen = VARSIZE(query) - VARHDRSZ;
        int32           nlen = VARSIZE(pf) - VARHDRSZ;
 
@@ -155,27 +166,7 @@ gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo *tinf
                char       *q = VARDATA(query);
                char       *n = VARDATA(pf);
 
-               if (tinfo->eml > 1)
-               {
-                       out = (varstr_cmp(q, nlen, n, nlen, DEFAULT_COLLATION_OID) == 0);
-               }
-               else
-               {
-                       out = TRUE;
-                       for (k = 0; k < nlen; k++)
-                       {
-                               if (*n != *q)
-                               {
-                                       out = FALSE;
-                                       break;
-                               }
-                               if (k < (nlen - 1))
-                               {
-                                       q++;
-                                       n++;
-                               }
-                       }
-               }
+               out = (memcmp(q, n, nlen) == 0);
        }
 
        return out;
@@ -184,17 +175,14 @@ gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo *tinf
 
 /*
  * returns true, if query matches node using common prefix
-*/
-
+ */
 static bool
 gbt_var_node_pf_match(const GBT_VARKEY_R *node, const bytea *query, const gbtree_vinfo *tinfo)
 {
-
        return (tinfo->trnc && (
                                                        gbt_bytea_pf_match(node->lower, query, tinfo) ||
                                                        gbt_bytea_pf_match(node->upper, query, tinfo)
                                                        ));
-
 }
 
 
@@ -232,9 +220,9 @@ gbt_var_node_truncate(const GBT_VARKEY *node, int32 cpf_length, const gbtree_vin
 
 
 void
-gbt_var_bin_union(Datum *u, GBT_VARKEY *e, const gbtree_vinfo *tinfo)
+gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
+                                 const gbtree_vinfo *tinfo)
 {
-
        GBT_VARKEY *nk = NULL;
        GBT_VARKEY *tmp = NULL;
        GBT_VARKEY_R nr;
@@ -252,14 +240,14 @@ gbt_var_bin_union(Datum *u, GBT_VARKEY *e, const gbtree_vinfo *tinfo)
 
                GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u));
 
-               if ((*tinfo->f_cmp) ((bytea *) ro.lower, (bytea *) eo.lower) > 0)
+               if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0)
                {
                        nr.lower = eo.lower;
                        nr.upper = ro.upper;
                        nk = gbt_var_key_copy(&nr, TRUE);
                }
 
-               if ((*tinfo->f_cmp) ((bytea *) ro.upper, (bytea *) eo.upper) < 0)
+               if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0)
                {
                        nr.upper = eo.upper;
                        nr.lower = ro.lower;
@@ -308,7 +296,8 @@ gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo)
 
 
 GBT_VARKEY *
-gbt_var_union(const GistEntryVector *entryvec, int32 *size, const gbtree_vinfo *tinfo)
+gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
+                         const gbtree_vinfo *tinfo)
 {
 
        int                     i = 0,
@@ -326,7 +315,7 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, const gbtree_vinfo *
        for (i = 1; i < numranges; i++)
        {
                cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key);
-               gbt_var_bin_union(&out, cur, tinfo);
+               gbt_var_bin_union(&out, cur, collation, tinfo);
        }
 
 
@@ -347,9 +336,10 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, const gbtree_vinfo *
 
 
 bool
-gbt_var_same(bool *result, const Datum d1, const Datum d2, const gbtree_vinfo *tinfo)
+gbt_var_same(Datum d1, Datum d2, Oid collation,
+                        const gbtree_vinfo *tinfo)
 {
-
+       bool            result;
        GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(d1);
        GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(d2);
        GBT_VARKEY_R r1,
@@ -359,22 +349,19 @@ gbt_var_same(bool *result, const Datum d1, const Datum d2, const gbtree_vinfo *t
        r2 = gbt_var_key_readable(t2);
 
        if (t1 && t2)
-       {
-               *result = (((*tinfo->f_cmp) ((bytea *) r1.lower, (bytea *) r2.lower) == 0
-                                       && (*tinfo->f_cmp) ((bytea *) r1.upper, (bytea *) r2.upper) == 0) ? TRUE : FALSE);
-       }
+               result = ((*tinfo->f_cmp) (r1.lower, r2.lower, collation) == 0 &&
+                                 (*tinfo->f_cmp) (r1.upper, r2.upper, collation) == 0);
        else
-               *result = (t1 == NULL && t2 == NULL) ? TRUE : FALSE;
+               result = (t1 == NULL && t2 == NULL);
 
-       PG_RETURN_POINTER(result);
+       return result;
 }
 
 
-
 float *
-gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, const gbtree_vinfo *tinfo)
+gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
+                               Oid collation, const gbtree_vinfo *tinfo)
 {
-
        GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key);
        GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
        GBT_VARKEY_R ok,
@@ -394,21 +381,19 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, const gbtree
 
        if ((VARSIZE(ok.lower) - VARHDRSZ) == 0 && (VARSIZE(ok.upper) - VARHDRSZ) == 0)
                *res = 0.0;
-       else if (!(
-                          (
-                               ((*tinfo->f_cmp) (nk.lower, ok.lower) >= 0 || gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) &&
-                               ((*tinfo->f_cmp) (nk.upper, ok.upper) <= 0 || gbt_bytea_pf_match(ok.upper, nk.upper, tinfo))
-                               )
-                          ))
+       else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, collation) >= 0 ||
+                               gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) &&
+                          ((*tinfo->f_cmp) (nk.upper, ok.upper, collation) <= 0 ||
+                               gbt_bytea_pf_match(ok.upper, nk.upper, tinfo))))
        {
                Datum           d = PointerGetDatum(0);
                double          dres = 0.0;
                int32           ol,
                                        ul;
 
-               gbt_var_bin_union(&d, orge, tinfo);
+               gbt_var_bin_union(&d, orge, collation, tinfo);
                ol = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
-               gbt_var_bin_union(&d, newe, tinfo);
+               gbt_var_bin_union(&d, newe, collation, tinfo);
                ul = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
 
                if (ul < ol)
@@ -444,18 +429,19 @@ gbt_vsrt_cmp(const void *a, const void *b, void *arg)
 {
        GBT_VARKEY_R ar = gbt_var_key_readable(((const Vsrt *) a)->t);
        GBT_VARKEY_R br = gbt_var_key_readable(((const Vsrt *) b)->t);
-       const gbtree_vinfo *tinfo = (const gbtree_vinfo *) arg;
+       const gbt_vsrt_arg *varg = (const gbt_vsrt_arg *) arg;
        int                     res;
 
-       res = (*tinfo->f_cmp) (ar.lower, br.lower);
+       res = (*varg->tinfo->f_cmp) (ar.lower, br.lower, varg->collation);
        if (res == 0)
-               return (*tinfo->f_cmp) (ar.upper, br.upper);
+               return (*varg->tinfo->f_cmp) (ar.upper, br.upper, varg->collation);
 
        return res;
 }
 
 GIST_SPLITVEC *
-gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_vinfo *tinfo)
+gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
+                                 Oid collation, const gbtree_vinfo *tinfo)
 {
        OffsetNumber i,
                                maxoff = entryvec->n - 1;
@@ -464,6 +450,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
                                nbytes;
        char       *cur;
        GBT_VARKEY **sv = NULL;
+       gbt_vsrt_arg varg;
 
        arr = (Vsrt *) palloc((maxoff + 1) * sizeof(Vsrt));
        nbytes = (maxoff + 2) * sizeof(OffsetNumber);
@@ -497,11 +484,13 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
        }
 
        /* sort */
+       varg.tinfo = tinfo;
+       varg.collation = collation;
        qsort_arg((void *) &arr[FirstOffsetNumber],
                          maxoff - FirstOffsetNumber + 1,
                          sizeof(Vsrt),
                          gbt_vsrt_cmp,
-                         (void *) tinfo);
+                         (void *) &varg);
 
        /* We do simply create two parts */
 
@@ -509,13 +498,13 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
        {
                if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
                {
-                       gbt_var_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
+                       gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo);
                        v->spl_left[v->spl_nleft] = arr[i].i;
                        v->spl_nleft++;
                }
                else
                {
-                       gbt_var_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
+                       gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo);
                        v->spl_right[v->spl_nright] = arr[i].i;
                        v->spl_nright++;
                }
@@ -546,63 +535,61 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
  * The GiST consistent method
  */
 bool
-gbt_var_consistent(
-                                  GBT_VARKEY_R *key,
+gbt_var_consistent(GBT_VARKEY_R *key,
                                   const void *query,
-                                  const StrategyNumber *strategy,
+                                  StrategyNumber strategy,
+                                  Oid collation,
                                   bool is_leaf,
-                                  const gbtree_vinfo *tinfo
-)
+                                  const gbtree_vinfo *tinfo)
 {
        bool            retval = FALSE;
 
-       switch (*strategy)
+       switch (strategy)
        {
                case BTLessEqualStrategyNumber:
                        if (is_leaf)
-                               retval = (*tinfo->f_ge) (query, (void *) key->lower);
+                               retval = (*tinfo->f_ge) (query, key->lower, collation);
                        else
-                               retval = (*tinfo->f_cmp) ((bytea *) query, key->lower) >= 0
+                               retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
                                        || gbt_var_node_pf_match(key, query, tinfo);
                        break;
                case BTLessStrategyNumber:
                        if (is_leaf)
-                               retval = (*tinfo->f_gt) (query, (void *) key->lower);
+                               retval = (*tinfo->f_gt) (query, key->lower, collation);
                        else
-                               retval = (*tinfo->f_cmp) ((bytea *) query, key->lower) >= 0
+                               retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
                                        || gbt_var_node_pf_match(key, query, tinfo);
                        break;
                case BTEqualStrategyNumber:
                        if (is_leaf)
-                               retval = (*tinfo->f_eq) (query, (void *) key->lower);
+                               retval = (*tinfo->f_eq) (query, key->lower, collation);
                        else
-                               retval = (
-                                                 (
-                                               (*tinfo->f_cmp) (key->lower, (bytea *) query) <= 0 &&
-                                 (*tinfo->f_cmp) ((bytea *) query, (void *) key->upper) <= 0
-                                                  ) || gbt_var_node_pf_match(key, query, tinfo)
-                                       );
+                               retval =
+                                       ((*tinfo->f_cmp) (key->lower, query, collation) <= 0 &&
+                                        (*tinfo->f_cmp) (query, key->upper, collation) <= 0) ||
+                                       gbt_var_node_pf_match(key, query, tinfo);
                        break;
                case BTGreaterStrategyNumber:
                        if (is_leaf)
-                               retval = (*tinfo->f_lt) (query, (void *) key->upper);
+                               retval = (*tinfo->f_lt) (query, key->upper, collation);
                        else
-                               retval = (*tinfo->f_cmp) ((bytea *) query, key->upper) <= 0
+                               retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
                                        || gbt_var_node_pf_match(key, query, tinfo);
                        break;
                case BTGreaterEqualStrategyNumber:
                        if (is_leaf)
-                               retval = (*tinfo->f_le) (query, (void *) key->upper);
+                               retval = (*tinfo->f_le) (query, key->upper, collation);
                        else
-                               retval = (*tinfo->f_cmp) ((bytea *) query, key->upper) <= 0
+                               retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
                                        || gbt_var_node_pf_match(key, query, tinfo);
                        break;
                case BtreeGistNotEqualStrategyNumber:
-                       retval = !((*tinfo->f_eq) (query, key->lower) && (*tinfo->f_eq) (query, key->upper));
+                       retval = !((*tinfo->f_eq) (query, key->lower, collation) &&
+                                          (*tinfo->f_eq) (query, key->upper, collation));
                        break;
                default:
                        retval = FALSE;
        }
 
-       return (retval);
+       return retval;
 }
index 2c1012f3235a3b1ae8b1313201bb6c8c400fdd3f..fe91d122e67baf1f1d66806523a657f04dd9be25 100644 (file)
@@ -18,18 +18,9 @@ typedef struct
                           *upper;
 } GBT_VARKEY_R;
 
-/* used for key sorting */
-typedef struct
-{
-       int                     i;
-       GBT_VARKEY *t;
-} Vsrt;
-
 /*
-  type description
-*/
-
-
+ * type description
+ */
 typedef struct
 {
 
@@ -42,12 +33,12 @@ typedef struct
 
        /* Methods */
 
-       bool            (*f_gt) (const void *, const void *);   /* greater then */
-       bool            (*f_ge) (const void *, const void *);   /* greater equal */
-       bool            (*f_eq) (const void *, const void *);   /* equal */
-       bool            (*f_le) (const void *, const void *);   /* less equal */
-       bool            (*f_lt) (const void *, const void *);   /* less then */
-       int32           (*f_cmp) (const bytea *, const bytea *);                /* node compare */
+       bool            (*f_gt) (const void *, const void *, Oid);      /* greater than */
+       bool            (*f_ge) (const void *, const void *, Oid);      /* greater equal */
+       bool            (*f_eq) (const void *, const void *, Oid);      /* equal */
+       bool            (*f_le) (const void *, const void *, Oid);      /* less equal */
+       bool            (*f_lt) (const void *, const void *, Oid);      /* less than */
+       int32           (*f_cmp) (const void *, const void *, Oid);     /* compare */
        GBT_VARKEY *(*f_l2n) (GBT_VARKEY *);            /* convert leaf to node */
 } gbtree_vinfo;
 
@@ -60,21 +51,22 @@ extern GBT_VARKEY *gbt_var_key_copy(const GBT_VARKEY_R *u, bool force_node);
 extern GISTENTRY *gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo);
 
 extern GBT_VARKEY *gbt_var_union(const GistEntryVector *entryvec, int32 *size,
-                         const gbtree_vinfo *tinfo);
+                         Oid collation, const gbtree_vinfo *tinfo);
 
-extern bool gbt_var_same(bool *result, const Datum d1, const Datum d2,
+extern bool gbt_var_same(Datum d1, Datum d2, Oid collation,
                         const gbtree_vinfo *tinfo);
 
 extern float *gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
-                               const gbtree_vinfo *tinfo);
+                               Oid collation, const gbtree_vinfo *tinfo);
 
 extern bool gbt_var_consistent(GBT_VARKEY_R *key, const void *query,
-                                  const StrategyNumber *strategy, bool is_leaf,
+                                  StrategyNumber strategy, Oid collation, bool is_leaf,
                                   const gbtree_vinfo *tinfo);
 
 extern GIST_SPLITVEC *gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-                                 const gbtree_vinfo *tinfo);
-extern void gbt_var_bin_union(Datum *u, GBT_VARKEY *e,
+                                 Oid collation, const gbtree_vinfo *tinfo);
+
+extern void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
                                  const gbtree_vinfo *tinfo);
 
 #endif