diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index a5592d5..02fe9b4 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -2255,8 +2255,7 @@ text_name(PG_FUNCTION_ARGS) len = VARSIZE_ANY_EXHDR(s); /* Truncate oversize input */ - if (len >= NAMEDATALEN) - len = NAMEDATALEN - 1; + len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1); result = (Name) palloc(NAMEDATALEN); memcpy(NameStr(*result), VARDATA_ANY(s), len); diff --git a/src/test/regress/expected/name.out b/src/test/regress/expected/name.out index b359d52..f4b58f1 100644 --- a/src/test/regress/expected/name.out +++ b/src/test/regress/expected/name.out @@ -15,6 +15,19 @@ SELECT name 'name string' = name 'name string ' AS "False"; f (1 row) +-- name truncation with unicode characters +SELECT length(repeat(U&'\0400', 32)::unknown::name::bytea, 'utf8') as length_from_unknown; + length_from_unknown +--------------------- + 31 +(1 row) + +SELECT length(repeat(U&'\0400', 32)::text::name::bytea, 'utf8') as length_from_text; + length_from_text +------------------ + 31 +(1 row) + -- -- -- diff --git a/src/test/regress/sql/name.sql b/src/test/regress/sql/name.sql index 1c7a671..9f7a5f0 100644 --- a/src/test/regress/sql/name.sql +++ b/src/test/regress/sql/name.sql @@ -8,6 +8,10 @@ SELECT name 'name string' = name 'name string' AS "True"; SELECT name 'name string' = name 'name string ' AS "False"; +-- name truncation with unicode characters +SELECT length(repeat(U&'\0400', 32)::unknown::name::bytea, 'utf8') as length_from_unknown; +SELECT length(repeat(U&'\0400', 32)::text::name::bytea, 'utf8') as length_from_text; + -- -- --