Skip to content

Instantly share code, notes, and snippets.

@koshigoe
Last active November 15, 2018 06:20
Show Gist options
  • Save koshigoe/de7c1feb6ba913345d49c7e2638073d1 to your computer and use it in GitHub Desktop.
Save koshigoe/de7c1feb6ba913345d49c7e2638073d1 to your computer and use it in GitHub Desktop.
String#[0] may return a byte, not a character.
require 'pg'
# $ docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=password -d postgres:9.6
conn = PG.connect(host: 'localhost', port: 5432, user: 'postgres', password: 'password', dbname: 'postgres')
conn.exec <<SQL
drop table if exists test_copy_to;
create table test_copy_to (str varchar);
insert into test_copy_to (str) values ('Ä');
SQL
puts ['str', 'str[0]', 'str.encoding'].join("\t")
puts ['---', '------', '------------'].join("\t")
dec = PG::TextDecoder::CopyRow.new
conn.copy_data('COPY test_copy_to TO STDOUT', dec) do
while row = conn.get_copy_data
# NOTE: I expect `row[0][0]` return `"Ä"`, but got `"\xC3"`.
puts [row[0].inspect, row[0][0].inspect, row[0].encoding].join("\t")
# NOTE: I learned this workaround.
row[0].force_encoding('utf-8')
puts [row[0].inspect, row[0][0].inspect, row[0].encoding].join("\t")
end
end
dec = PG::TextDecoder::CopyRow.new(type_map: PG::TypeMapByColumn.new([PG::TextDecoder::Bytea.new]))
conn.copy_data('COPY (select * from test_copy_to) TO STDOUT', dec) do
while row = conn.get_copy_data
# NOTE: I learned this workaround.
str = row[0].force_encoding('utf-8')
puts [str.inspect, str[0].inspect, str.encoding].join("\t")
end
end
str = conn.exec('select * from test_copy_to').getvalue(0, 0)
puts [str.inspect, str[0].inspect, str.encoding].join("\t")
__END__
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
str str[0] str.encoding
--- ------ ------------
"Ä" "\xC3" UTF-8
"Ä" "Ä" UTF-8
"Ä" "Ä" UTF-8
"Ä" "Ä" UTF-8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment