client_encoding directive is ignored in postgresql.conf

From: Tatsuo Ishii <t-ishii(at)sra(dot)co(dot)jp>
To: pgsql-hackers(at)postgresql(dot)org
Subject: client_encoding directive is ignored in postgresql.conf
Date: 2003-01-29 13:24:04
Message-ID: 20030129.222404.41628888.t-ishii@sra.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

There is a nasty bug with the client_encoding directive in
postgresql.conf. It is simply ignored. This bug exists in both 7.3 or
later and in current. Interesting thing is "show client_encoding"
command shows expected encoding but this only shows the GUC internal
variable and the actual internal encoding state does not reflect
postgresql.conf. The cause of the bug is as follows:

1) postgresql.conf is read by GUC while postmaster starting up.
2) assign_client_encoding() is called to reflect client_encoding
directive in postgresq.conf
3) Since database access is not available during GUC processing, it
just set GUC variable and leave the real client encoding state as
it is.

Possible solution would be setting a flag during 2) and doing actual
client encoding processing after the database access becomes
possible. Included patches (against 7.3 stable tree) implement
this. New function InitializeClientEncoding() does client encoding
things and is called between call to InitializeSearchPath() and
on_shmem_exit() in InitPostgres().

Comments?

P.S. Related bug exists in
fe-connect.c:PostgresPollingStatusType(). In this function to set the
client side encoding, getdatabaseencoding() is called. This is simply
wrong since it does not return the client encoding specified by
postgressql.conf's client_encoding directive. Instead
pg_client_encoding() should be called. (fix to this is included in the
patches)
--
Tatsuo Ishii

-------------------------------------------------------------------------------
Index: backend/utils/init/postinit.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/init/postinit.c,v
retrieving revision 1.117.2.1
diff -c -r1.117.2.1 postinit.c
*** backend/utils/init/postinit.c 21 Nov 2002 06:36:27 -0000 1.117.2.1
--- backend/utils/init/postinit.c 29 Jan 2003 13:13:04 -0000
***************
*** 397,402 ****
--- 397,405 ----
/* set default namespace search path */
InitializeSearchPath();

+ /* initialize client encoding */
+ InitializeClientEncoding();
+
/*
* Set up process-exit callback to do pre-shutdown cleanup. This
* should be last because we want shmem_exit to call this routine
Index: backend/utils/mb/mbutils.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/mb/mbutils.c,v
retrieving revision 1.36.2.1
diff -c -r1.36.2.1 mbutils.c
*** backend/utils/mb/mbutils.c 26 Nov 2002 02:37:13 -0000 1.36.2.1
--- backend/utils/mb/mbutils.c 29 Jan 2003 13:13:05 -0000
***************
*** 37,42 ****
--- 37,44 ----
int len, bool is_client_to_server);
static int cliplen(const unsigned char *str, int len, int limit);

+ /* Flag to we need to initialize client encoding info */
+ static bool need_to_init_client_encoding = -1;

/*
* Set the client encoding and save fmgrinfo for the converion
***************
*** 58,63 ****
--- 60,72 ----
if (!PG_VALID_FE_ENCODING(encoding))
return (-1);

+ /* If we cannot actualy set client encoding info, remeber it
+ * so that we could set it using InitializeClientEncoding()
+ * in InitPostgres()
+ */
+ if (current_server_encoding != encoding && !IsTransactionState())
+ need_to_init_client_encoding = encoding;
+
if (current_server_encoding == encoding ||
(current_server_encoding == PG_SQL_ASCII || encoding == PG_SQL_ASCII))
{
***************
*** 113,118 ****
--- 122,140 ----
ToClientConvProc = to_client;
}
return 0;
+ }
+
+ /* Initialize client encoding if necessary.
+ * called from InitPostgres() once during backend starting up.
+ */
+ void
+ InitializeClientEncoding()
+ {
+ if (need_to_init_client_encoding > 0)
+ {
+ SetClientEncoding(need_to_init_client_encoding, 1);
+ need_to_init_client_encoding = -1;
+ }
}

/*
Index: include/mb/pg_wchar.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/mb/pg_wchar.h,v
retrieving revision 1.44
diff -c -r1.44 pg_wchar.h
*** include/mb/pg_wchar.h 4 Sep 2002 20:31:42 -0000 1.44
--- include/mb/pg_wchar.h 29 Jan 2003 13:13:25 -0000
***************
*** 295,300 ****
--- 295,301 ----

extern void SetDefaultClientEncoding(void);
extern int SetClientEncoding(int encoding, bool doit);
+ extern void InitializeClientEncoding(void);
extern int pg_get_client_encoding(void);
extern const char *pg_get_client_encoding_name(void);

Index: interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.213.2.1
diff -c -r1.213.2.1 fe-connect.c
*** interfaces/libpq/fe-connect.c 8 Jan 2003 21:33:53 -0000 1.213.2.1
--- interfaces/libpq/fe-connect.c 29 Jan 2003 13:13:27 -0000
***************
*** 1621,1627 ****
* for it. We must use begin/commit in case autocommit
* is off by default.
*/
! if (!PQsendQuery(conn, "begin; select getdatabaseencoding(); commit"))
goto error_return;

conn->setenv_state = SETENV_STATE_ENCODINGS_WAIT;
--- 1621,1627 ----
* for it. We must use begin/commit in case autocommit
* is off by default.
*/
! if (!PQsendQuery(conn, "begin; select pg_client_encoding(); commit"))
goto error_return;

conn->setenv_state = SETENV_STATE_ENCODINGS_WAIT;

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Reggie Burnett 2003-01-29 14:14:15 Re: Request for qualified column names
Previous Message Rod Taylor 2003-01-29 13:17:37 Re: Please include hier-patch in next PostgreSQL version