44 * (currently mule internal code (mic) is used)
55 * Tatsuo Ishii
66 *
7- * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.54 2006/01/11 08:43:12 neilc Exp $
7+ * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.55 2006/01/12 22:04:02 neilc Exp $
88 */
99#include "postgres.h"
1010
1111#include "access/xact.h"
12+ #include "catalog/namespace.h"
1213#include "miscadmin.h"
1314#include "mb/pg_wchar.h"
1415#include "utils/builtins.h"
1516#include "utils/memutils.h"
1617#include "utils/syscache.h"
17- #include "catalog/namespace.h"
1818
1919/*
2020 * We handle for actual FE and BE encoding setting encoding-identificator
@@ -25,10 +25,12 @@ static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
2525static pg_enc2name * DatabaseEncoding = & pg_enc2name_tbl [PG_SQL_ASCII ];
2626
2727/*
28- * Caches for conversion function info. Note that these values are
29- * allocated in TopMemoryContext so that they survive across
30- * transactions. See SetClientEncoding() for more details.
28+ * Caches for conversion function info. These values are allocated in
29+ * MbProcContext. That context is a child of TopMemoryContext,
30+ * which allows these values to survive across transactions. See
31+ * SetClientEncoding() for more details.
3132 */
33+ static MemoryContext MbProcContext = NULL ;
3234static FmgrInfo * ToServerConvProc = NULL ;
3335static FmgrInfo * ToClientConvProc = NULL ;
3436
@@ -86,22 +88,10 @@ SetClientEncoding(int encoding, bool doit)
8688if (doit )
8789{
8890ClientEncoding = & pg_enc2name_tbl [encoding ];
89-
90- if (ToServerConvProc != NULL )
91- {
92- if (ToServerConvProc -> fn_extra )
93- pfree (ToServerConvProc -> fn_extra );
94- pfree (ToServerConvProc );
95- }
9691ToServerConvProc = NULL ;
97-
98- if (ToClientConvProc != NULL )
99- {
100- if (ToClientConvProc -> fn_extra )
101- pfree (ToClientConvProc -> fn_extra );
102- pfree (ToClientConvProc );
103- }
10492ToClientConvProc = NULL ;
93+ if (MbProcContext )
94+ MemoryContextReset (MbProcContext );
10595}
10696return 0 ;
10797}
@@ -134,33 +124,37 @@ SetClientEncoding(int encoding, bool doit)
134124if (!doit )
135125return 0 ;
136126
137- /*
138- * load the fmgr info into TopMemoryContext so that it survives outside
139- * transaction.
140- */
141- oldcontext = MemoryContextSwitchTo (TopMemoryContext );
127+ /* Before loading the new fmgr info, remove the old info, if any */
128+ ToServerConvProc = NULL ;
129+ ToClientConvProc = NULL ;
130+ if (MbProcContext != NULL )
131+ {
132+ MemoryContextReset (MbProcContext );
133+ }
134+ else
135+ {
136+ /*
137+ * This is the first time through, so create the context. Make
138+ * it a child of TopMemoryContext so that these values survive
139+ * across transactions.
140+ */
141+ MbProcContext = AllocSetContextCreate (TopMemoryContext ,
142+ "MbProcContext" ,
143+ ALLOCSET_SMALL_MINSIZE ,
144+ ALLOCSET_SMALL_INITSIZE ,
145+ ALLOCSET_SMALL_MAXSIZE );
146+ }
147+
148+ /* Load the fmgr info into MbProcContext */
149+ oldcontext = MemoryContextSwitchTo (MbProcContext );
142150to_server = palloc (sizeof (FmgrInfo ));
143151to_client = palloc (sizeof (FmgrInfo ));
144152fmgr_info (to_server_proc ,to_server );
145153fmgr_info (to_client_proc ,to_client );
146154MemoryContextSwitchTo (oldcontext );
147155
148156ClientEncoding = & pg_enc2name_tbl [encoding ];
149-
150- if (ToServerConvProc != NULL )
151- {
152- if (ToServerConvProc -> fn_extra )
153- pfree (ToServerConvProc -> fn_extra );
154- pfree (ToServerConvProc );
155- }
156157ToServerConvProc = to_server ;
157-
158- if (ToClientConvProc != NULL )
159- {
160- if (ToClientConvProc -> fn_extra )
161- pfree (ToClientConvProc -> fn_extra );
162- pfree (ToClientConvProc );
163- }
164158ToClientConvProc = to_client ;
165159
166160return 0 ;