Skip to content

Commit be24f8e

Browse files
RUBY-319: Support reading decimals in scientific notation with positive exponent
1 parent a493a5b commit be24f8e

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# master
2+
Bug Fixes:
3+
* [RUBY-319](https://datastax-oss.atlassian.net/browse/RUBY-319) Support reading decimals in scientific notation with positive exponent.
24

35
# 3.2.1
46

lib/cassandra/protocol/cql_byte_buffer.rb

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,30 @@ def read_varint(len = bytesize, signed = true)
5353
end
5454

5555
def read_decimal(len = bytesize)
56-
size = read_signed_int
56+
scale = read_signed_int
5757
number_string = read_varint(len - 4).to_s
58-
if number_string.length <= size
59-
if number_string.start_with?(MINUS)
60-
number_string = number_string[1, number_string.length - 1]
61-
fraction_string = MINUS + ZERO << DECIMAL_POINT
58+
if scale < 0
59+
# Special case where the actual scale is positive; scale in the protocol is actually negative of
60+
# reality.
61+
BigDecimal.new(number_string + '0' * -scale)
62+
else
63+
if number_string.length <= scale
64+
if number_string.start_with?(MINUS)
65+
number_string = number_string[1, number_string.length - 1]
66+
fraction_string = MINUS + ZERO << DECIMAL_POINT
67+
else
68+
fraction_string = ZERO + DECIMAL_POINT
69+
end
70+
(scale - number_string.length).times { fraction_string << ZERO }
71+
fraction_string << number_string
6272
else
63-
fraction_string = ZERO + DECIMAL_POINT
73+
fraction_string = number_string[0, number_string.length - scale]
74+
fraction_string << DECIMAL_POINT
75+
fraction_string <<
76+
number_string[number_string.length - scale, number_string.length]
6477
end
65-
(size - number_string.length).times { fraction_string << ZERO }
66-
fraction_string << number_string
67-
else
68-
fraction_string = number_string[0, number_string.length - size]
69-
fraction_string << DECIMAL_POINT
70-
fraction_string <<
71-
number_string[number_string.length - size, number_string.length]
78+
BigDecimal.new(fraction_string)
7279
end
73-
BigDecimal.new(fraction_string)
7480
rescue Errors::DecodingError => e
7581
raise Errors::DecodingError, e.message, e.backtrace
7682
end

lib/cassandra/protocol/cql_protocol_handler.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,7 @@ def initialize(request, timeout, scheduler)
270270
def time_out!
271271
unless future.completed?
272272
@timed_out = true
273-
# rubocop:disable Style/SignalException
274273
fail(Errors::TimeoutError.new('Timed out'))
275-
# rubocop:enable Style/SignalException
276274
end
277275
end
278276

spec/cassandra/protocol/cql_byte_buffer_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ module Protocol
102102
buffer.read_decimal.should == BigDecimal.new('-0.031108612692221094')
103103
end
104104

105+
it 'decodes a decimal with negative scale' do
106+
buffer = described_class.new("\xff\xff\xff\xfa\x0a")
107+
buffer.read_decimal.should == BigDecimal.new('10000000')
108+
end
109+
110+
it 'decodes a negative decimal with negative scale' do
111+
buffer = described_class.new("\xff\xff\xff\xf9\xfd")
112+
buffer.read_decimal.should == BigDecimal.new('-30000000')
113+
end
114+
105115
it 'consumes the bytes' do
106116
buffer << 'HELLO'
107117
buffer.read_decimal(buffer.length - 5)

0 commit comments

Comments
 (0)