Class HashCanonicalValue
java.lang.Object
dev.frostlake.functions.scalar.hash.HashCanonicalValue
The bytes HASH and HASH_AGG hash for one argument: a TYPE-CLASS tag followed by a canonical rendering
of the value. The tag and the rendering together decide which arguments hash ALIKE, which is the only
part of Snowflake's HASH that can be reproduced from outside — the 64-bit values themselves come from a
proprietary algorithm and are deliberately not imitated.
The classes are live-verified, and two of them are counter-intuitive:
- Numbers hash by VALUE, never by declared type or scale. 1, 1.00, 1.0000,
1::NUMBER(38,10)and1.0::FLOATare one hash; so are 2.5 and 2.50. Trailing zeros are stripped, and-0.0renders as 0. - BOOLEAN is in the NUMBER class — TRUE hashes bit-identically to 1 and FALSE to 0, though neither equals the string 'true'.
- Every temporal is in the NUMBER class too, as its epoch offset in its own natural
unit: a DATE by DAYS, a TIME by seconds since midnight, a TIMESTAMP by epoch seconds, fractions
included. So
DATE '1970-01-02'andTIME '00:00:01'both hash as the number 1, while a DATE and the TIMESTAMP at its midnight do NOT collide — their unit differs. - A BINARY hashes as the STRING of its bytes:
X'31'and'1'are one hash. The raw bytes are used, not a decode, so two binaries that are both invalid UTF-8 stay distinct. - A VARIANT hashes as the value it holds — a VARIANT number equals the bare number and a VARIANT string the bare string. The two exceptions are a VARIANT BOOLEAN and a VARIANT JSON null, which each keep their own class: neither collides with the SQL boolean nor with SQL NULL.
A container hashes as its canonical JSON, which is why key order does not matter for an object and element order does for an array, and why an array never collides with the string of its own text.
-
Method Summary
-
Method Details
-
encode
The tagged bytes for one HASH argument.
-