Wrong value returned by record UDF


#1

The value inserted in the set is 301741175798074369. The value returned by the UDF is 301741175798074368.

aql> insert into dsc.test(pk,id) values(301741175798074369,301741175798074369) OK, 1 record affected.

aql> select * from dsc.test ±-------------------+ | id | ±-------------------+ | 301741175798074369 | ±-------------------+ 1 row in set (0.021 secs)

aql> register module 'test.lua’ OK, 1 module added.

aql> execute test.test() on dsc.test where pk = 301741175798074369 ±-----------------------------------------------------------------+ | test | ±-----------------------------------------------------------------+ | MAP(’{“number”:301741175798074368, “long”:301741175798074368}’) | ±-----------------------------------------------------------------+ 1 row in set (0.001 secs)

. .

test.lua

function test(rec)

    local retmap = map()

    retmap["long"] = rec["id"]
    retmap["number"] = tonumber(rec["id"])

    return retmap

end


#2

That’s very odd. Have you tried adding additional logging to the UDF? I would suggest adding logging to the UDF to log the key/rec passed, and the values within… That way you can understand if it is an issue passing the rec to the udf, or some issue within gathering the values/building the map…


#3

Perhaps you are running into the 56 bit limit in lua on storing numbers…or the fact that it stores all numbers as floats ?

https://www.lua.org/pil/2.3.html

2.3 – Numbers The number type represents real (double-precision floating-point) numbers. Lua has no integer type, as it does not need it. There is a widespread misconception about floating-point arithmetic errors and some people fear that even a simple increment can go weird with floating-point numbers. The fact is that, when you use a double to represent an integer, there is no rounding error at all (unless the number is greater than 100,000,000,000,000). Specifically, a Lua number can represent any long integer without rounding problems. Moreover, most modern CPUs do floating-point arithmetic as fast as (or even faster than) integer arithmetic.

It is easy to compile Lua so that it uses another type for numbers, such as longs or single-precision floats. This is particularly useful for platforms without hardware support for floating point. See the distribution for detailed instructions.

We can write numeric constants with an optional decimal part, plus an optional decimal exponent. Examples of valid numeric constants are:

4     0.4     4.57e-3     0.3e12     5e+20

Note: 301,741,175,798,074,369 is greater than: 100,000,000,000,000


#4

Thanks for pointing out this lua limitation. I am trying to process 8 byte integers using UDFs. But it seems it would not be possible with this lua limitation.

Also, I tried using the standard luajit bitops library as suggested in this post. Even this seems to limit integers to 32 bits. I am not able to process the higher order 32 bits.