[ 
https://issues.apache.org/jira/browse/AVRO-3902?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17786346#comment-17786346
 ] 

Martin Tzvetanov Grigorov commented on AVRO-3902:
-------------------------------------------------

This comment has been made 8 years ago - 
[https://github.com/apache/avro/commit/2863a185ee8c6a036ce811e1ecd80eefd7f54401]

I think it is OK to use both Number constants and BigInt today!

> 64bit long support for JavaScript
> ---------------------------------
>
>                 Key: AVRO-3902
>                 URL: https://issues.apache.org/jira/browse/AVRO-3902
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: javascript, js
>    Affects Versions: 1.11.3
>            Reporter: Philippe Ozil
>            Priority: Major
>
> The latest version of avro-js cannot deserialize large numeric values that 
> fit in a 64 bit Long. It's limited to the values that fit in the [maximum 
> safe integer in 
> JavaScript|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER]
>  (2^53 – 1).
> Attempting to read larger values such as 1698100138468892700 triggers a 
> deserialization error:
> ?? Error: invalid "long": 1698100138468892700??
>  
> The avro-js documentation provides a solution for this: [specifying a custom 
> Long 
> type|https://github.com/apache/avro/blob/main/lang/js/doc/Advanced-usage.md#custom-long-types]
>  however, this documentation page is not easy to find and can easily be 
> missed.
> I understand that you may not want to change the default behavior of the 
> library for backward compatibility reasons but could you at least mention 
> this important limitation in the main documentation page?
>  
> Also, there's now a native JS solution for supporting large values in long 
> type: 
> [BigInt|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt].
>  I believe that this should be the preferred approach since it doesn't 
> introduce extra dependencies.
> This is the native long-safe implementation (inspired from 
> [avsc|https://github.com/mtth/avsc/wiki/Advanced-usage#custom-long-types]):
> {code:js}
> const longType = avro.types.LongType.using({
>   fromBuffer: (buf) => buf.readBigInt64LE(),
>   toBuffer: (n) => {
>     const buf = Buffer.alloc(8);
>     buf.writeBigInt64LE(n);
>     return buf;
>   },
>   fromJSON: BigInt,
>   toJSON: Number,
>   isValid: (n) => typeof n === 'bigint',
>   compare: (n1, n2) => { return n1 === n2 ? 0 : (n1 < n2 ? -1 : 1); }
> });{code}
>  
> This is an alternate implementation that I wrote. It uses regular Number 
> whenever possible and falls back to BigInt when the value exceeds the max 
> safe value for Number. This could be a good built-in alternative for avro-js 
> in which we avoid throwing a deserialization error.
> {code:js}
> const CUSTOM_LONG_AVRO_TYPE = avro.types.LongType.using({
>     fromBuffer: (buf) => {
>         const big = buf.readBigInt64LE();
>         if (big > Number.MAX_SAFE_INTEGER) {
>             return big;
>         }
>         return Number(BigInt.asIntN(64, big));
>     },
>     toBuffer: (n) => {
>         const buf = Buffer.alloc(8);
>         if (n instanceof BigInt) {
>             buf.writeBigInt64LE(n);
>         } else {
>             buf.writeBigInt64LE(BigInt(n));
>         }
>         return buf;
>     },
>     fromJSON: BigInt,
>     toJSON: Number,
>     isValid: (n) => {
>         const type = typeof n;
>         return type === 'bigint' || type === 'number';
>     },
>     compare: (n1, n2) => {
>         return n1 === n2 ? 0 : n1 < n2 ? -1 : 1;
>     }
> });{code}
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to