Skip to content

Commit

Permalink
Add PG::BinaryEncoder::Float4 and Float8
Browse files Browse the repository at this point in the history
  • Loading branch information
larskanis committed Mar 22, 2023
1 parent cfd17d1 commit d122cda
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
50 changes: 50 additions & 0 deletions ext/pg_binary_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,52 @@ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
return 8;
}

/*
* Document-class: PG::BinaryEncoder::Float4 < PG::SimpleEncoder
*
* This is the binary encoder class for the PostgreSQL +float4+ type.
*
*/
static VALUE
pg_bin_enc_float4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
{
union {
float f;
int32_t i;
} swap4;

if(out){
swap4.f = NUM2DBL(*intermediate);
write_nbo32(swap4.i, out);
}else{
*intermediate = value;
}
return 4;
}

/*
* Document-class: PG::BinaryEncoder::Float8 < PG::SimpleEncoder
*
* This is the binary encoder class for the PostgreSQL +float8+ type.
*
*/
static VALUE
pg_bin_enc_float8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
{
union {
double f;
int64_t i;
} swap8;

if(out){
swap8.f = NUM2DBL(*intermediate);
write_nbo64(swap8.i, out);
}else{
*intermediate = value;
}
return 8;
}

/*
* Document-class: PG::BinaryEncoder::Timestamp < PG::SimpleEncoder
*
Expand Down Expand Up @@ -207,6 +253,10 @@ init_pg_binary_encoder(void)
pg_define_coder( "Int4", pg_bin_enc_int4, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Int8", rb_cPG_SimpleEncoder ); */
pg_define_coder( "Int8", pg_bin_enc_int8, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Float4", rb_cPG_SimpleEncoder ); */
pg_define_coder( "Float4", pg_bin_enc_float4, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Float8", rb_cPG_SimpleEncoder ); */
pg_define_coder( "Float8", pg_bin_enc_float8, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "String", rb_cPG_SimpleEncoder ); */
pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
/* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
Expand Down
4 changes: 2 additions & 2 deletions lib/pg/basic_type_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ def register_default_types

register_type 1, 'bytea', PG::BinaryEncoder::Bytea, PG::BinaryDecoder::Bytea
register_type 1, 'bool', PG::BinaryEncoder::Boolean, PG::BinaryDecoder::Boolean
register_type 1, 'float4', nil, PG::BinaryDecoder::Float
register_type 1, 'float8', nil, PG::BinaryDecoder::Float
register_type 1, 'float4', PG::BinaryEncoder::Float4, PG::BinaryDecoder::Float
register_type 1, 'float8', PG::BinaryEncoder::Float8, PG::BinaryDecoder::Float
register_type 1, 'timestamp', PG::BinaryEncoder::TimestampUtc, PG::BinaryDecoder::TimestampUtc
register_type 1, 'timestamptz', PG::BinaryEncoder::TimestampUtc, PG::BinaryDecoder::TimestampUtcToLocal

Expand Down
8 changes: 4 additions & 4 deletions spec/pg/basic_type_map_based_on_result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,19 @@
end

it "can type cast #copy_data binary input with encoder" do
@conn.exec( "CREATE TEMP TABLE copytable (b bytea, i INT, ts timestamp)" )
@conn.exec( "CREATE TEMP TABLE copytable (b bytea, i INT, ts timestamp, f4 float4, f8 float8)" )

# Retrieve table OIDs per empty result set.
res = @conn.exec_params( "SELECT * FROM copytable LIMIT 0", [], 1 )
tm = basic_type_mapping.build_column_map( res )
row_encoder = PG::BinaryEncoder::CopyRow.new type_map: tm

@conn.copy_data( "COPY copytable FROM STDIN WITH (FORMAT binary)", row_encoder ) do |res|
@conn.put_copy_data ["\xff\x00\n\r'", 123, Time.utc(2023, 3, 17, 3, 4, 5.6789123)]
@conn.put_copy_data [" xyz ", -444, Time.new(1990, 12, 17, 18, 44, 45, "+03:30")]
@conn.put_copy_data ["\xff\x00\n\r'", 123, Time.utc(2023, 3, 17, 3, 4, 5.6789123), 12.345, -12.345e67]
@conn.put_copy_data [" xyz ", -444, Time.new(1990, 12, 17, 18, 44, 45, "+03:30"), -Float::INFINITY, Float::NAN]
end
res = @conn.exec( "SELECT * FROM copytable" )
expect( res.values ).to eq( [["\\xff000a0d27", "123", "2023-03-17 03:04:05.678912"], ["\\x202078797a2020", "-444", "1990-12-17 15:14:45"]] )
expect( res.values ).to eq( [["\\xff000a0d27", "123", "2023-03-17 03:04:05.678912", "12.345", "-1.2345e+68"], ["\\x202078797a2020", "-444", "1990-12-17 15:14:45", "-Infinity", "NaN"]] )
end
end
end
Expand Down

0 comments on commit d122cda

Please sign in to comment.