MCPcopy Create free account
hub / github.com/pingcap/tidb / HashValue

Method HashValue

pkg/types/json_binary.go:567–616  ·  view source on GitHub ↗

HashValue converts certain JSON values for aggregate comparisons. For example int64(3) == float64(3.0) Other than the numeric condition, this function has to construct a bidirectional map between hash value and the original representation

(buf []byte)

Source from the content-addressed store, hash-verified

565// Other than the numeric condition, this function has to construct a bidirectional map between hash value
566// and the original representation
567func (bj BinaryJSON) HashValue(buf []byte) []byte {
568 switch bj.TypeCode {
569 case JSONTypeCodeInt64:
570 // Convert to a FLOAT if no precision is lost.
571 // In the future, it will be better to convert to a DECIMAL value instead
572 // See: https://github.com/pingcap/tidb/issues/9988
573
574 // A double precision float can have 52-bit in fraction part.
575 if getInt64FractionLength(bj.GetInt64()) <= 52 {
576 buf = append(buf, JSONTypeCodeFloat64)
577 buf = appendBinaryFloat64(buf, float64(bj.GetInt64()))
578 } else {
579 buf = append(buf, bj.TypeCode)
580 buf = append(buf, bj.Value...)
581 }
582 case JSONTypeCodeUint64:
583 // A double precision float can have 52-bit in fraction part.
584 if getUint64FractionLength(bj.GetUint64()) <= 52 {
585 buf = append(buf, JSONTypeCodeFloat64)
586 buf = appendBinaryFloat64(buf, float64(bj.GetUint64()))
587 } else {
588 buf = append(buf, bj.TypeCode)
589 buf = append(buf, bj.Value...)
590 }
591 case JSONTypeCodeArray:
592 // this hash value is bidirectional, because you can get the element one-by-one
593 // and you know the end of it, as the elemCount is also appended here
594 buf = append(buf, bj.TypeCode)
595 elemCount := int(jsonEndian.Uint32(bj.Value))
596 buf = append(buf, bj.Value[0:dataSizeOff]...)
597 for i := 0; i < elemCount; i++ {
598 buf = bj.ArrayGetElem(i).HashValue(buf)
599 }
600 case JSONTypeCodeObject:
601 // this hash value is bidirectional, because you can get the key using the json
602 // string format, and get the value accordingly.
603 buf = append(buf, bj.TypeCode)
604 elemCount := int(jsonEndian.Uint32(bj.Value))
605 buf = append(buf, bj.Value[0:dataSizeOff]...)
606 for i := 0; i < elemCount; i++ {
607 keyJSON := CreateBinaryJSON(string(bj.objectGetKey(i)))
608 buf = append(buf, keyJSON.Value...)
609 buf = bj.objectGetVal(i).HashValue(buf)
610 }
611 default:
612 buf = append(buf, bj.TypeCode)
613 buf = append(buf, bj.Value...)
614 }
615 return buf
616}
617
618// GetValue return the primitive value of the JSON.
619func (bj BinaryJSON) GetValue() any {

Callers 8

TestHashValueFunction · 0.80
getIndexedValueMethod · 0.80
evalAndEncodeFunction · 0.80
encodeHashChunkRowIdxFunction · 0.80
SerializeKeysFunction · 0.80
HashChunkSelectedFunction · 0.80
HashGroupKeyFunction · 0.80

Calls 9

GetInt64Method · 0.95
GetUint64Method · 0.95
ArrayGetElemMethod · 0.95
objectGetKeyMethod · 0.95
objectGetValMethod · 0.95
getInt64FractionLengthFunction · 0.85
appendBinaryFloat64Function · 0.85
getUint64FractionLengthFunction · 0.85
CreateBinaryJSONFunction · 0.85

Tested by 2

TestHashValueFunction · 0.64