Skip to content

Commit 769065c

Browse files
committed
Prefer pg_any_to_server/pg_server_to_any over pg_do_encoding_conversion.
A large majority of the callers of pg_do_encoding_conversion were specifying the database encoding as either source or target of the conversion, meaning that we can use the less general functions pg_any_to_server/pg_server_to_any instead. The main advantage of using the latter functions is that they can make use of a cached conversion-function lookup in the common case that the other encoding is the current client_encoding. It's notationally cleaner too in most cases, not least because of the historical artifact that the latter functions use "char *" rather than "unsigned char *" in their APIs. Note that pg_any_to_server will apply an encoding verification step in some cases where pg_do_encoding_conversion would have just done nothing. This seems to me to be a good idea at most of these call sites, though it partially negates the performance benefit. Per discussion of bug #9210.
1 parent 49c817e commit 769065c

File tree

12 files changed

+51
-100
lines changed

12 files changed

+51
-100
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,11 +1458,9 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
14581458
{
14591459
char *enc;
14601460

1461-
enc = (char *)
1462-
pg_do_encoding_conversion((unsigned char *) qstr,
1463-
entry->query_len,
1464-
entry->encoding,
1465-
GetDatabaseEncoding());
1461+
enc = pg_any_to_server(qstr,
1462+
entry->query_len,
1463+
entry->encoding);
14661464

14671465
values[i++] = CStringGetTextDatum(enc);
14681466

contrib/sslinfo/sslinfo.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,7 @@ ASN1_STRING_to_text(ASN1_STRING *str)
158158
nullterm = '\0';
159159
BIO_write(membuf, &nullterm, 1);
160160
size = BIO_get_mem_data(membuf, &sp);
161-
dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
162-
size - 1,
163-
PG_UTF8,
164-
GetDatabaseEncoding());
161+
dp = pg_any_to_server(sp, size - 1, PG_UTF8);
165162
result = cstring_to_text(dp);
166163
if (dp != sp)
167164
pfree(dp);
@@ -323,10 +320,7 @@ X509_NAME_to_text(X509_NAME *name)
323320
nullterm = '\0';
324321
BIO_write(membuf, &nullterm, 1);
325322
size = BIO_get_mem_data(membuf, &sp);
326-
dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
327-
size - 1,
328-
PG_UTF8,
329-
GetDatabaseEncoding());
323+
dp = pg_any_to_server(sp, size - 1, PG_UTF8);
330324
result = cstring_to_text(dp);
331325
if (dp != sp)
332326
pfree(dp);

src/backend/commands/extension.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,6 @@ read_extension_script_file(const ExtensionControlFile *control,
635635
const char *filename)
636636
{
637637
int src_encoding;
638-
int dest_encoding = GetDatabaseEncoding();
639638
bytea *content;
640639
char *src_str;
641640
char *dest_str;
@@ -645,7 +644,7 @@ read_extension_script_file(const ExtensionControlFile *control,
645644

646645
/* use database encoding if not given */
647646
if (control->encoding < 0)
648-
src_encoding = dest_encoding;
647+
src_encoding = GetDatabaseEncoding();
649648
else
650649
src_encoding = control->encoding;
651650

@@ -655,10 +654,7 @@ read_extension_script_file(const ExtensionControlFile *control,
655654
pg_verify_mbstr_len(src_encoding, src_str, len, false);
656655

657656
/* convert the encoding to the database encoding */
658-
dest_str = (char *) pg_do_encoding_conversion((unsigned char *) src_str,
659-
len,
660-
src_encoding,
661-
dest_encoding);
657+
dest_str = pg_any_to_server(src_str, len, src_encoding);
662658

663659
/* if no conversion happened, we have to arrange for null termination */
664660
if (dest_str == src_str)

src/backend/snowball/dict_snowball.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,7 @@ dsnowball_lexize(PG_FUNCTION_ARGS)
255255
{
256256
char *recoded;
257257

258-
recoded = (char *) pg_do_encoding_conversion((unsigned char *) txt,
259-
strlen(txt),
260-
GetDatabaseEncoding(),
261-
PG_UTF8);
258+
recoded = pg_server_to_any(txt, strlen(txt), PG_UTF8);
262259
if (recoded != txt)
263260
{
264261
pfree(txt);
@@ -284,10 +281,7 @@ dsnowball_lexize(PG_FUNCTION_ARGS)
284281
{
285282
char *recoded;
286283

287-
recoded = (char *) pg_do_encoding_conversion((unsigned char *) txt,
288-
strlen(txt),
289-
PG_UTF8,
290-
GetDatabaseEncoding());
284+
recoded = pg_any_to_server(txt, strlen(txt), PG_UTF8);
291285
if (recoded != txt)
292286
{
293287
pfree(txt);

src/backend/tsearch/ts_locale.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,7 @@ t_readline(FILE *fp)
209209
(void) pg_verify_mbstr(PG_UTF8, buf, len, false);
210210

211211
/* And convert */
212-
recoded = (char *) pg_do_encoding_conversion((unsigned char *) buf,
213-
len,
214-
PG_UTF8,
215-
GetDatabaseEncoding());
212+
recoded = pg_any_to_server(buf, len, PG_UTF8);
216213
if (recoded == buf)
217214
{
218215
/*

src/backend/utils/adt/pg_locale.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,7 @@ db_encoding_strdup(int encoding, const char *str)
418418
char *mstr;
419419

420420
/* convert the string to the database encoding */
421-
pstr = (char *) pg_do_encoding_conversion(
422-
(unsigned char *) str, strlen(str),
423-
encoding, GetDatabaseEncoding());
421+
pstr = pg_any_to_server(str, strlen(str), encoding);
424422
mstr = strdup(pstr);
425423
if (pstr != str)
426424
pfree(pstr);
@@ -581,35 +579,32 @@ strftime_win32(char *dst, size_t dstlen, const wchar_t *format, const struct tm
581579
{
582580
size_t len;
583581
wchar_t wbuf[MAX_L10N_DATA];
584-
int encoding;
585-
586-
encoding = GetDatabaseEncoding();
587582

588583
len = wcsftime(wbuf, MAX_L10N_DATA, format, tm);
589584
if (len == 0)
590-
585+
{
591586
/*
592587
* strftime call failed - return 0 with the contents of dst
593588
* unspecified
594589
*/
595590
return 0;
591+
}
596592

597593
len = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, dst, dstlen, NULL, NULL);
598594
if (len == 0)
599-
elog(ERROR,
600-
"could not convert string to UTF-8: error code %lu", GetLastError());
595+
elog(ERROR, "could not convert string to UTF-8: error code %lu",
596+
GetLastError());
601597

602598
dst[len] = '\0';
603-
if (encoding != PG_UTF8)
599+
if (GetDatabaseEncoding() != PG_UTF8)
604600
{
605-
char *convstr =
606-
(char *) pg_do_encoding_conversion((unsigned char *) dst,
607-
len, PG_UTF8, encoding);
601+
char *convstr = pg_any_to_server(dst, len, PG_UTF8);
608602

609-
if (dst != convstr)
603+
if (convstr != dst)
610604
{
611605
strlcpy(dst, convstr, dstlen);
612606
len = strlen(dst);
607+
pfree(convstr);
613608
}
614609
}
615610

src/backend/utils/adt/xml.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,7 @@ xml_recv(PG_FUNCTION_ARGS)
345345
xmlFreeDoc(doc);
346346

347347
/* Now that we know what we're dealing with, convert to server encoding */
348-
newstr = (char *) pg_do_encoding_conversion((unsigned char *) str,
349-
nbytes,
350-
encoding,
351-
GetDatabaseEncoding());
348+
newstr = pg_any_to_server(str, nbytes, encoding);
352349

353350
if (newstr != str)
354351
{
@@ -1793,10 +1790,8 @@ sqlchar_to_unicode(char *s)
17931790
char *utf8string;
17941791
pg_wchar ret[2]; /* need space for trailing zero */
17951792

1796-
utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s,
1797-
pg_mblen(s),
1798-
GetDatabaseEncoding(),
1799-
PG_UTF8);
1793+
/* note we're not assuming s is null-terminated */
1794+
utf8string = pg_server_to_any(s, pg_mblen(s), PG_UTF8);
18001795

18011796
pg_encoding_mb2wchar_with_len(PG_UTF8, utf8string, ret,
18021797
pg_encoding_mblen(PG_UTF8, utf8string));
@@ -1892,19 +1887,15 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped,
18921887
static char *
18931888
unicode_to_sqlchar(pg_wchar c)
18941889
{
1895-
unsigned char utf8string[5]; /* need room for trailing zero */
1890+
char utf8string[8]; /* need room for trailing zero */
18961891
char *result;
18971892

18981893
memset(utf8string, 0, sizeof(utf8string));
1899-
unicode_to_utf8(c, utf8string);
1900-
1901-
result = (char *) pg_do_encoding_conversion(utf8string,
1902-
pg_encoding_mblen(PG_UTF8,
1903-
(char *) utf8string),
1904-
PG_UTF8,
1905-
GetDatabaseEncoding());
1906-
/* if pg_do_encoding_conversion didn't strdup, we must */
1907-
if (result == (char *) utf8string)
1894+
unicode_to_utf8(c, (unsigned char *) utf8string);
1895+
1896+
result = pg_any_to_server(utf8string, strlen(utf8string), PG_UTF8);
1897+
/* if pg_any_to_server didn't strdup, we must */
1898+
if (result == utf8string)
19081899
result = pstrdup(result);
19091900
return result;
19101901
}

src/backend/utils/mb/mbutils.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,9 @@ pgwin32_message_to_UTF16(const char *str, int len, int *utf16len)
10771077
char *utf8;
10781078

10791079
utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
1080-
len, GetMessageEncoding(), PG_UTF8);
1080+
len,
1081+
GetMessageEncoding(),
1082+
PG_UTF8);
10811083
if (utf8 != str)
10821084
len = strlen(utf8);
10831085

src/pl/plperl/plperl.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3811,9 +3811,7 @@ hv_store_string(HV *hv, const char *key, SV *val)
38113811
char *hkey;
38123812
SV **ret;
38133813

3814-
hkey = (char *)
3815-
pg_do_encoding_conversion((unsigned char *) key, strlen(key),
3816-
GetDatabaseEncoding(), PG_UTF8);
3814+
hkey = pg_server_to_any(key, strlen(key), PG_UTF8);
38173815

38183816
/*
38193817
* This seems nowhere documented, but under Perl 5.8.0 and up, hv_store()
@@ -3841,9 +3839,7 @@ hv_fetch_string(HV *hv, const char *key)
38413839
char *hkey;
38423840
SV **ret;
38433841

3844-
hkey = (char *)
3845-
pg_do_encoding_conversion((unsigned char *) key, strlen(key),
3846-
GetDatabaseEncoding(), PG_UTF8);
3842+
hkey = pg_server_to_any(key, strlen(key), PG_UTF8);
38473843

38483844
/* See notes in hv_store_string */
38493845
hlen = -(int) strlen(hkey);

src/pl/plperl/plperl_helpers.h

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,11 @@
99
static inline char *
1010
utf_u2e(char *utf8_str, size_t len)
1111
{
12-
int enc = GetDatabaseEncoding();
1312
char *ret;
1413

15-
/*
16-
* When we are in a PG_UTF8 or SQL_ASCII database
17-
* pg_do_encoding_conversion() will not do any conversion (which is good)
18-
* or verification (not so much), so we need to run the verification step
19-
* separately.
20-
*/
21-
if (enc == PG_UTF8 || enc == PG_SQL_ASCII)
22-
{
23-
pg_verify_mbstr_len(enc, utf8_str, len, false);
24-
ret = utf8_str;
25-
}
26-
else
27-
ret = (char *) pg_do_encoding_conversion((unsigned char *) utf8_str,
28-
len, PG_UTF8, enc);
14+
ret = pg_any_to_server(utf8_str, len, PG_UTF8);
2915

16+
/* ensure we have a copy even if no conversion happened */
3017
if (ret == utf8_str)
3118
ret = pstrdup(ret);
3219

@@ -41,12 +28,14 @@ utf_u2e(char *utf8_str, size_t len)
4128
static inline char *
4229
utf_e2u(const char *str)
4330
{
44-
char *ret =
45-
(char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
46-
GetDatabaseEncoding(), PG_UTF8);
31+
char *ret;
4732

33+
ret = pg_server_to_any(str, strlen(str), PG_UTF8);
34+
35+
/* ensure we have a copy even if no conversion happened */
4836
if (ret == str)
4937
ret = pstrdup(ret);
38+
5039
return ret;
5140
}
5241

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy