From b82d69abf64fc0c2fc6fdd491d7cecb8244680c2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 3 Jul 2026 15:31:58 -0400 Subject: [PATCH] Remove btree_gist's useless logic for encoding-aware truncation. gbt_var_node_cp_len() contained logic to ensure that its choice of a common prefix length didn't truncate away part of a multibyte character. However, that was really dead code, because we have not allowed truncation of text-string data types since ef770cbb6, and it seems unlikely that that behavior could ever get resurrected. The code is still reachable via gbt_var_penalty, but for that usage it hardly matters if we break in the middle of a multibyte character: we're just calculating a small correction factor that is arguably bunkum anyway in non-C locales. Hence, delete said code. That actually removes all need for gbtree_vinfo.eml, which allows const-ification of the gbtree_vinfo structs in which we were changing it, which removes one headache for future attempts to thread-ify the backend. (Curiously, all this infrastructure was itself added by ef770cbb6. Not sure why Teodor didn't see the contradiction.) Author: Tom Lane Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn --- contrib/btree_gist/btree_bit.c | 1 - contrib/btree_gist/btree_bytea.c | 1 - contrib/btree_gist/btree_numeric.c | 1 - contrib/btree_gist/btree_text.c | 21 ++-------------- contrib/btree_gist/btree_utils_var.c | 37 +++++----------------------- contrib/btree_gist/btree_utils_var.h | 2 -- 6 files changed, 8 insertions(+), 55 deletions(-) diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c index 8d8e9454268..5fb8c8b82f0 100644 --- a/contrib/btree_gist/btree_bit.c +++ b/contrib/btree_gist/btree_bit.c @@ -136,7 +136,6 @@ gbt_bit_l2n(GBT_VARKEY *leaf, FmgrInfo *flinfo) static const gbtree_vinfo tinfo = { gbt_t_bit, - 0, true, /* internal keys can be truncated */ gbt_bitgt, gbt_bitge, diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c index 8411598a99b..bcb469e8c86 100644 --- a/contrib/btree_gist/btree_bytea.c +++ b/contrib/btree_gist/btree_bytea.c @@ -73,7 +73,6 @@ gbt_byteacmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo) static const gbtree_vinfo tinfo = { gbt_t_bytea, - 0, true, /* internal keys can be truncated */ gbt_byteagt, gbt_byteage, diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c index 8a506865b17..7a75e2ed00d 100644 --- a/contrib/btree_gist/btree_numeric.c +++ b/contrib/btree_gist/btree_numeric.c @@ -83,7 +83,6 @@ gbt_numeric_cmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo) static const gbtree_vinfo tinfo = { gbt_t_numeric, - 0, false, /* no truncation permitted */ gbt_numeric_gt, gbt_numeric_ge, diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c index e7269ba3e7c..a8657fe461a 100644 --- a/contrib/btree_gist/btree_text.c +++ b/contrib/btree_gist/btree_text.c @@ -86,10 +86,9 @@ gbt_textcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo) * more complicated than C. The prefix-match hack used for simpler types * can't fix it, either. */ -static gbtree_vinfo tinfo = +static const gbtree_vinfo tinfo = { gbt_t_text, - 0, false, /* no truncation permitted */ gbt_textgt, gbt_textge, @@ -156,10 +155,9 @@ gbt_bpcharcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo) PointerGetDatum(b))); } -static gbtree_vinfo bptinfo = +static const gbtree_vinfo bptinfo = { gbt_t_bpchar, - 0, false, /* as above, no truncation permitted */ gbt_bpchargt, gbt_bpcharge, @@ -180,11 +178,6 @@ gbt_text_compress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - if (tinfo.eml == 0) - { - tinfo.eml = pg_database_encoding_max_length(); - } - PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo)); } @@ -212,11 +205,6 @@ gbt_text_consistent(PG_FUNCTION_ARGS) /* All cases served by this function are exact */ *recheck = false; - if (tinfo.eml == 0) - { - tinfo.eml = pg_database_encoding_max_length(); - } - retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(), GIST_LEAF(entry), &tinfo, fcinfo->flinfo); @@ -240,11 +228,6 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS) /* All cases served by this function are exact */ *recheck = false; - if (bptinfo.eml == 0) - { - bptinfo.eml = pg_database_encoding_max_length(); - } - retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(), GIST_LEAF(entry), &bptinfo, fcinfo->flinfo); PG_RETURN_BOOL(retval); diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c index ae101801355..3eeaee6bc35 100644 --- a/contrib/btree_gist/btree_utils_var.c +++ b/contrib/btree_gist/btree_utils_var.c @@ -10,7 +10,6 @@ #include "btree_gist.h" #include "btree_utils_var.h" -#include "mb/pg_wchar.h" #include "utils/rel.h" #include "varatt.h" @@ -126,56 +125,32 @@ gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo) /* * returns the common prefix length of a node key * - * If the underlying type is character data, the prefix length may point in - * the middle of a multibyte character. + * This is not used for any cases where the underlying type is character data + * (except in gbt_var_penalty, where it doesn't matter since we're just making + * an estimated correction not constructing a truncated string). If it were, + * we'd need to be careful not to truncate in the middle of a multibyte + * character. */ static int32 gbt_var_node_cp_len(const GBT_VARKEY *node, const gbtree_vinfo *tinfo) { GBT_VARKEY_R r = gbt_var_key_readable(node); int32 i = 0; - int32 l_left_to_match = 0; - int32 l_total = 0; int32 t1len = VARSIZE(r.lower) - VARHDRSZ; int32 t2len = VARSIZE(r.upper) - VARHDRSZ; int32 ml = Min(t1len, t2len); char *p1 = VARDATA(r.lower); char *p2 = VARDATA(r.upper); - const char *end1 = p1 + t1len; - const char *end2 = p2 + t2len; if (ml == 0) return 0; while (i < ml) { - if (tinfo->eml > 1 && l_left_to_match == 0) - { - l_total = pg_mblen_range(p1, end1); - if (l_total != pg_mblen_range(p2, end2)) - { - return i; - } - l_left_to_match = l_total; - } if (*p1 != *p2) - { - if (tinfo->eml > 1) - { - int32 l_matched_subset = l_total - l_left_to_match; - - /* end common prefix at final byte of last matching char */ - return i - l_matched_subset; - } - else - { - return i; - } - } - + return i; p1++; p2++; - l_left_to_match--; i++; } return ml; /* lower == upper */ diff --git a/contrib/btree_gist/btree_utils_var.h b/contrib/btree_gist/btree_utils_var.h index d746186544b..2ed7eaa86b2 100644 --- a/contrib/btree_gist/btree_utils_var.h +++ b/contrib/btree_gist/btree_utils_var.h @@ -60,8 +60,6 @@ typedef struct /* Attribs */ enum gbtree_type t; /* data type */ - int32 eml; /* cached pg_database_encoding_max_length (0: - * undefined) */ bool trnc; /* truncate (=compress) key */ /* Methods */