diff --git a/ext/pg_connection.c b/ext/pg_connection.c index 448b1fc10..8d7d31013 100644 --- a/ext/pg_connection.c +++ b/ext/pg_connection.c @@ -4171,17 +4171,23 @@ static VALUE pgconn_set_default_encoding( VALUE self ) { PGconn *conn = pg_get_pgconn( self ); - rb_encoding *enc; - const char *encname; + rb_encoding *rb_enc; rb_check_frozen(self); - if (( enc = rb_default_internal_encoding() )) { - encname = pg_get_rb_encoding_as_pg_encoding( enc ); - if ( pgconn_set_client_encoding_async(self, rb_str_new_cstr(encname)) != 0 ) - rb_warning( "Failed to set the default_internal encoding to %s: '%s'", - encname, PQerrorMessage(conn) ); + if (( rb_enc = rb_default_internal_encoding() )) { + rb_encoding * conn_encoding = pg_conn_enc_get( conn ); + + /* Don't set the server encoding, if it's unnecessary. + * This is important for connection proxies, who disallow configuration settings. + */ + if ( conn_encoding != rb_enc ) { + const char *encname = pg_get_rb_encoding_as_pg_encoding( rb_enc ); + if ( pgconn_set_client_encoding_async(self, rb_str_new_cstr(encname)) != 0 ) + rb_warning( "Failed to set the default_internal encoding to %s: '%s'", + encname, PQerrorMessage(conn) ); + } pgconn_set_internal_encoding_index( self ); - return rb_enc_from_encoding( enc ); + return rb_enc_from_encoding( rb_enc ); } else { pgconn_set_internal_encoding_index( self ); return Qnil; diff --git a/spec/pg/connection_spec.rb b/spec/pg/connection_spec.rb index 80409d00b..67ddcedad 100644 --- a/spec/pg/connection_spec.rb +++ b/spec/pg/connection_spec.rb @@ -2368,6 +2368,22 @@ def wait_check_socket(conn) end end + it "doesn't change anything if Encoding.default_internal it set to DB default encoding", :without_transaction do + begin + prev_encoding = Encoding.default_internal + Encoding.default_internal = Encoding::UTF_8 + + # PG.connect shouldn't emit a "set client_encoding" for UTF_8, since the server is already on UTF8. + conn = PG.connect( @conninfo ) + expect( conn.internal_encoding ).to eq( Encoding::UTF_8 ) + res = conn.exec( "SELECT setting, source FROM pg_settings WHERE name='client_encoding'" ) + expect( res[0].values ).to eq( ['UTF8', 'default'] ) + ensure + conn.finish if conn + Encoding.default_internal = prev_encoding + end + end + it "allows users of the async interface to set the client_encoding to the default_internal" do begin prev_encoding = Encoding.default_internal