Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3c63578

Browse files
committed
Load and keep conversion function info when SET CLIENT_ENCODING TO is
executed to prevent database access while performing encodingconversion.
1 parentb53c851 commit3c63578

File tree

1 file changed

+93
-14
lines changed

1 file changed

+93
-14
lines changed

‎src/backend/utils/mb/mbutils.c

Lines changed: 93 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
* client encoding and server internal encoding.
44
* (currently mule internal code (mic) is used)
55
* Tatsuo Ishii
6-
* $Id: mbutils.c,v 1.29 2002/07/25 10:07:12 ishii Exp $
6+
* $Id: mbutils.c,v 1.30 2002/08/08 06:35:26 ishii Exp $
77
*/
88
#include"postgres.h"
99
#include"access/xact.h"
1010
#include"miscadmin.h"
1111
#include"mb/pg_wchar.h"
1212
#include"utils/builtins.h"
13+
#include"utils/memutils.h"
1314
#include"utils/syscache.h"
1415
#include"catalog/namespace.h"
1516

@@ -22,13 +23,30 @@ static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
2223
staticpg_enc2name*DatabaseEncoding=&pg_enc2name_tbl[PG_SQL_ASCII];
2324

2425
/*
25-
* set the client encoding. if encoding conversion between
26-
* client/server encoding is not supported, returns -1
26+
* Caches for conversion function info. Note that Fcinfo.flinfo is
27+
* allocated in TopMemoryContext so that it survives outside
28+
* transactions. See SetClientEncoding() for more details.
2729
*/
30+
staticFmgrInfo*ToServerConvPorc=NULL;
31+
staticFmgrInfo*ToClientConvPorc=NULL;
32+
33+
/* Internal functions */
34+
staticunsignedchar*
35+
perform_default_encoding_conversion(unsignedchar*src,intlen,boolis_client_to_server);
36+
37+
/*
38+
* Set the client encoding and save fmgrinfo for the converion
39+
* function if necessary. if encoding conversion between client/server
40+
* encoding is not supported, returns -1
41+
*/
2842
int
2943
SetClientEncoding(intencoding,booldoit)
3044
{
3145
intcurrent_server_encoding;
46+
Oidto_server_proc,to_client_proc;
47+
FmgrInfo*to_server=NULL;
48+
FmgrInfo*to_client=NULL;
49+
MemoryContextoldcontext;
3250

3351
current_server_encoding=GetDatabaseEncoding();
3452

@@ -46,18 +64,35 @@ SetClientEncoding(int encoding, bool doit)
4664
* bootstrap or initprocessing mode since namespace functions will
4765
* not work.
4866
*/
49-
if (IsNormalProcessingMode())
67+
if (IsTransactionState())
5068
{
51-
if (!OidIsValid(FindDefaultConversionProc(encoding,current_server_encoding))||
52-
!OidIsValid(FindDefaultConversionProc(current_server_encoding,encoding)))
53-
return (-1);
69+
to_server_proc=FindDefaultConversionProc(encoding,current_server_encoding);
70+
to_client_proc=FindDefaultConversionProc(current_server_encoding,encoding);
71+
72+
if (!OidIsValid(to_server_proc)|| !OidIsValid(to_client_proc))
73+
return-1;
74+
75+
/*
76+
* load the fmgr info into TopMemoryContext so that it
77+
* survives outside transaction.
78+
*/
79+
oldcontext=MemoryContextSwitchTo(TopMemoryContext);
80+
to_server=palloc(sizeof(FmgrInfo));
81+
to_client=palloc(sizeof(FmgrInfo));
82+
fmgr_info(to_server_proc,to_server);
83+
fmgr_info(to_client_proc,to_client);
84+
MemoryContextSwitchTo(oldcontext);
5485
}
5586

5687
if (!doit)
5788
return0;
5889

59-
ClientEncoding=&pg_enc2name_tbl[encoding];
60-
90+
if (IsTransactionState())
91+
{
92+
ClientEncoding=&pg_enc2name_tbl[encoding];
93+
ToServerConvPorc=to_server;
94+
ToClientConvPorc=to_client;
95+
}
6196
return0;
6297
}
6398

@@ -95,7 +130,6 @@ pg_get_client_encoding_name(void)
95130
* (SJIS JIS X0201 half width kanna -> UTF-8 is the worst case).
96131
* So "4" should be enough for the moment.
97132
*/
98-
99133
unsignedchar*
100134
pg_do_encoding_conversion(unsignedchar*src,intlen,
101135
intsrc_encoding,intdest_encoding)
@@ -231,8 +265,7 @@ pg_client_to_server(unsigned char *s, int len)
231265
if (ClientEncoding->encoding==DatabaseEncoding->encoding)
232266
returns;
233267

234-
returnpg_do_encoding_conversion(s,len,ClientEncoding->encoding,
235-
DatabaseEncoding->encoding);
268+
returnperform_default_encoding_conversion(s,len, true);
236269
}
237270

238271
/*
@@ -247,8 +280,54 @@ pg_server_to_client(unsigned char *s, int len)
247280
if (ClientEncoding->encoding==DatabaseEncoding->encoding)
248281
returns;
249282

250-
returnpg_do_encoding_conversion(s,len,DatabaseEncoding->encoding,
251-
ClientEncoding->encoding);
283+
returnperform_default_encoding_conversion(s,len, false);
284+
}
285+
286+
/*
287+
* Perform default encoding conversion using cached FmgrInfo. Since
288+
* this function does not access database at all, it is safe to call
289+
* outside transactions. Explicit setting client encoding required
290+
* before calling this function. Otherwise no conversion is
291+
* performed.
292+
*/
293+
staticunsignedchar*
294+
perform_default_encoding_conversion(unsignedchar*src,intlen,boolis_client_to_server)
295+
{
296+
unsignedchar*result;
297+
intsrc_encoding,dest_encoding;
298+
FmgrInfo*flinfo;
299+
300+
if (is_client_to_server)
301+
{
302+
src_encoding=ClientEncoding->encoding;
303+
dest_encoding=DatabaseEncoding->encoding;
304+
flinfo=ToServerConvPorc;
305+
}
306+
else
307+
{
308+
src_encoding=DatabaseEncoding->encoding;
309+
dest_encoding=ClientEncoding->encoding;
310+
flinfo=ToClientConvPorc;
311+
}
312+
313+
if (flinfo==NULL)
314+
returnsrc;
315+
316+
if (src_encoding==dest_encoding)
317+
returnsrc;
318+
319+
if (src_encoding==PG_SQL_ASCII||dest_encoding==PG_SQL_ASCII)
320+
returnsrc;
321+
322+
result=palloc(len*4+1);
323+
324+
FunctionCall5(flinfo,
325+
Int32GetDatum(src_encoding),
326+
Int32GetDatum(dest_encoding),
327+
CStringGetDatum(src),
328+
CStringGetDatum(result),
329+
Int32GetDatum(len));
330+
returnresult;
252331
}
253332

254333
/* convert a multi-byte string to a wchar */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp