[ 
https://issues.apache.org/jira/browse/AVRO-2592?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ryan Skraba updated AVRO-2592:
------------------------------
    Description: 
The Decimal Conversion from/to Bytebuffer is using the methods that consider 
the current position, e.g. remaining().

[https://github.com/apache/avro/blob/release-1.9.1/lang/java/avro/src/main/java/org/apache/avro/Conversions.java#L82]

At first sight that looks like a good idea. But actually it creates all sorts 
of problems.

For example this code fails with "Zero Length BigInteger":

 
{code:java}
BigDecimal d = BigDecimal.valueOf(3.1415); BigDecimal d = 
BigDecimal.valueOf(3.1415);

Decimal decimaltype = LogicalTypes.decimal(7, 4); ByteBuffer buffer = 
DECIMAL_CONVERTER.toBytes(d, null, decimaltype);

System.out.println(DECIMAL_CONVERTER.fromBytes(buffer, null, 
decimaltype).toString());

BigDecimal n = DECIMAL_CONVERTER.fromBytes(buffer, null, decimaltype);

System.out.println(n.toString());{code}
 

Reason is obvious. The first call to fromBytes() moves the position from 0 to 
the last byte. The second invocation reads from the last position, hence zero 
records.

There are other situations this might cause issues, e.g. a user might create 
the ByteBuffer via other means and it is normal that the position is after the 
last byte. Then the serialization would not work either. And many other.

As the ByteBuffer is used to wrap a single BigDecimal, I would suggest to 
remove all position-aware/setting methods and read/write from position zero.

 

 

  was:
The Decimal Conversion from/to Bytebuffer is using the methods that consider 
the current position, e.g. remaining().

[https://github.com/rdblue/avro-java/blob/master/avro/src/main/java/org/apache/avro/Conversions.java#L83]

 

At first sight that looks like a good idea. But actually it creates all sorts 
of problems.

For example this code fails with "Zero Length BigInteger":

 
{code:java}
BigDecimal d = BigDecimal.valueOf(3.1415); BigDecimal d = 
BigDecimal.valueOf(3.1415);

Decimal decimaltype = LogicalTypes.decimal(7, 4); ByteBuffer buffer = 
DECIMAL_CONVERTER.toBytes(d, null, decimaltype);

System.out.println(DECIMAL_CONVERTER.fromBytes(buffer, null, 
decimaltype).toString());

BigDecimal n = DECIMAL_CONVERTER.fromBytes(buffer, null, decimaltype);

System.out.println(n.toString());{code}
 

Reason is obvious. The first call to fromBytes() moves the position from 0 to 
the last byte. The second invocation reads from the last position, hence zero 
records.

There are other situations this might cause issues, e.g. a user might create 
the ByteBuffer via other means and it is normal that the position is after the 
last byte. Then the serialization would not work either. And many other.

As the ByteBuffer is used to wrap a single BigDecimal, I would suggest to 
remove all position-aware/setting methods and read/write from position zero.

 

 


> Avro decimal fails on certain conditions - ByteBuffer.position() is the root 
> cause
> ----------------------------------------------------------------------------------
>
>                 Key: AVRO-2592
>                 URL: https://issues.apache.org/jira/browse/AVRO-2592
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: java
>    Affects Versions: 1.9.1
>            Reporter: Werner Daehn
>            Priority: Blocker
>
> The Decimal Conversion from/to Bytebuffer is using the methods that consider 
> the current position, e.g. remaining().
> [https://github.com/apache/avro/blob/release-1.9.1/lang/java/avro/src/main/java/org/apache/avro/Conversions.java#L82]
> At first sight that looks like a good idea. But actually it creates all sorts 
> of problems.
> For example this code fails with "Zero Length BigInteger":
>  
> {code:java}
> BigDecimal d = BigDecimal.valueOf(3.1415); BigDecimal d = 
> BigDecimal.valueOf(3.1415);
> Decimal decimaltype = LogicalTypes.decimal(7, 4); ByteBuffer buffer = 
> DECIMAL_CONVERTER.toBytes(d, null, decimaltype);
> System.out.println(DECIMAL_CONVERTER.fromBytes(buffer, null, 
> decimaltype).toString());
> BigDecimal n = DECIMAL_CONVERTER.fromBytes(buffer, null, decimaltype);
> System.out.println(n.toString());{code}
>  
> Reason is obvious. The first call to fromBytes() moves the position from 0 to 
> the last byte. The second invocation reads from the last position, hence zero 
> records.
> There are other situations this might cause issues, e.g. a user might create 
> the ByteBuffer via other means and it is normal that the position is after 
> the last byte. Then the serialization would not work either. And many other.
> As the ByteBuffer is used to wrap a single BigDecimal, I would suggest to 
> remove all position-aware/setting methods and read/write from position zero.
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to