|
6 | 6 | #include <limits.h> |
7 | 7 |
|
8 | 8 | #include "access/stratnum.h" |
| 9 | +#include "mb/pg_wchar.h" |
9 | 10 | #include "utils/builtins.h" |
10 | 11 | #include "utils/date.h" |
11 | 12 | #include "utils/float.h" |
12 | 13 | #include "utils/inet.h" |
13 | 14 | #include "utils/numeric.h" |
14 | 15 | #include "utils/timestamp.h" |
15 | 16 | #include "utils/uuid.h" |
| 17 | +#include "varatt.h" |
16 | 18 |
|
17 | 19 | PG_MODULE_MAGIC_EXT( |
18 | 20 | .name = "btree_gin", |
@@ -630,13 +632,24 @@ leftmostvalue_text(void) |
630 | 632 | return PointerGetDatum(cstring_to_text_with_len("", 0)); |
631 | 633 | } |
632 | 634 |
|
| 635 | +static Datum |
| 636 | +cvt_name_text(Datum input) |
| 637 | +{ |
| 638 | + Name val = DatumGetName(input); |
| 639 | + |
| 640 | + return PointerGetDatum(cstring_to_text(NameStr(*val))); |
| 641 | +} |
| 642 | + |
633 | 643 | static const bool text_rhs_is_varlena[] = |
634 | | -{true}; |
| 644 | +{true, false}; |
| 645 | + |
| 646 | +static const btree_gin_convert_function text_cvt_fns[] = |
| 647 | +{NULL, cvt_name_text}; |
635 | 648 |
|
636 | 649 | static const PGFunction text_cmp_fns[] = |
637 | | -{bttextcmp}; |
| 650 | +{bttextcmp, btnametextcmp}; |
638 | 651 |
|
639 | | -GIN_SUPPORT(text, leftmostvalue_text, text_rhs_is_varlena, NULL, text_cmp_fns) |
| 652 | +GIN_SUPPORT(text, leftmostvalue_text, text_rhs_is_varlena, text_cvt_fns, text_cmp_fns) |
640 | 653 |
|
641 | 654 | static const bool bpchar_rhs_is_varlena[] = |
642 | 655 | {true}; |
@@ -836,13 +849,37 @@ leftmostvalue_name(void) |
836 | 849 | return NameGetDatum(result); |
837 | 850 | } |
838 | 851 |
|
| 852 | +static Datum |
| 853 | +cvt_text_name(Datum input) |
| 854 | +{ |
| 855 | + text *val = DatumGetTextPP(input); |
| 856 | + NameData *result = (NameData *) palloc0(NAMEDATALEN); |
| 857 | + int len = VARSIZE_ANY_EXHDR(val); |
| 858 | + |
| 859 | + /* |
| 860 | + * Truncate oversize input. We're assuming this will produce a result |
| 861 | + * considered less than the original. That could be a bad assumption in |
| 862 | + * some collations, but fortunately an index on "name" is generally going |
| 863 | + * to use C collation. |
| 864 | + */ |
| 865 | + if (len >= NAMEDATALEN) |
| 866 | + len = pg_mbcliplen(VARDATA_ANY(val), len, NAMEDATALEN - 1); |
| 867 | + |
| 868 | + memcpy(NameStr(*result), VARDATA_ANY(val), len); |
| 869 | + |
| 870 | + return NameGetDatum(result); |
| 871 | +} |
| 872 | + |
839 | 873 | static const bool name_rhs_is_varlena[] = |
840 | | -{false}; |
| 874 | +{false, true}; |
| 875 | + |
| 876 | +static const btree_gin_convert_function name_cvt_fns[] = |
| 877 | +{NULL, cvt_text_name}; |
841 | 878 |
|
842 | 879 | static const PGFunction name_cmp_fns[] = |
843 | | -{btnamecmp}; |
| 880 | +{btnamecmp, bttextnamecmp}; |
844 | 881 |
|
845 | | -GIN_SUPPORT(name, leftmostvalue_name, name_rhs_is_varlena, NULL, name_cmp_fns) |
| 882 | +GIN_SUPPORT(name, leftmostvalue_name, name_rhs_is_varlena, name_cvt_fns, name_cmp_fns) |
846 | 883 |
|
847 | 884 | static Datum |
848 | 885 | leftmostvalue_bool(void) |
|
0 commit comments