Trying to translate a uint256 number which is encoded as a 64-char / 256-bit hex. Eventually the result should be stored in a numeric(78,0) which is enough to encode an uint256.
For smaller hex-strings there's pretty direct ways to encode to int4/int8 but this won't do here.
Therefore trying to chunk the hex up in 4 64-bit parts, which can all be represented by a int8. Then glue it up with some bitshifting and done.
Unfortunately didn't realise int8 is signed so that gives me wrong results (code below). I guess I could chunk the hex up in smaller parts and make it work with a lot of hassle, but by now I'm wondering that there must somehow be a better way. Anyone?
-- 1. Split 256 bits into 4 seperate parts which are represented by int8's which can all hold 64 bits (4 * 64 = 256)
-- 2. cast int8 to numeric(78,0) which can hold a uint256, and some bitshifting (but not really since not supported by numeric) to get all parts
-- 3. add up the parts to arrive at the final number
--
-- WRONG RESULT: since int8 are signed.
select
val_a + val_b + val_c + val_d as value
from(
select
-- concat('x', substr(value, 0, 64))::bit(256) value_as_bits, -- all data as 256 bits
concat('x', substr(value, 0, 16))::bit(64)::int8::numeric(78,0) * 2^48::numeric(78,0) val_a,
concat('x', substr(value, 0 + 16, 16))::bit(64)::int8::numeric(78,0) * 2^32::numeric(78,0) val_b,
concat('x', substr(value, 0 + 32, 16))::bit(64)::int8::numeric(78,0) * 2^16::numeric(78,0) val_c,
concat('x', substr(value, 0 + 48, 16))::bit(64)::int8::numeric(78,0) val_d -- '-8257646570878140416' issue here since int8 is not unsigned
from (
select '000000000000000000000000000000000000000015b19218d66f231d61600000' as value -- hex representation of an unsigned 256 bit number
) as x
) as x;
;