diff options
Diffstat (limited to 'src/backend/utils/adt/jsonb_util.c')
-rw-r--r-- | src/backend/utils/adt/jsonb_util.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index a9bf0d3a7d1..411144618d6 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -1114,7 +1114,7 @@ arrayToJsonbSortedArray(ArrayType *array) } /* - * Hash a JsonbValue scalar value, mixing in the hash value with an existing + * Hash a JsonbValue scalar value, mixing the hash value into an existing * hash provided by the caller. * * Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY @@ -1123,36 +1123,39 @@ arrayToJsonbSortedArray(ArrayType *array) void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash) { - int tmp; + uint32 tmp; - /* - * Combine hash values of successive keys, values and elements by rotating - * the previous value left 1 bit, then XOR'ing in the new - * key/value/element's hash value. - */ - *hash = (*hash << 1) | (*hash >> 31); + /* Compute hash value for scalarVal */ switch (scalarVal->type) { case jbvNull: - *hash ^= 0x01; - return; + tmp = 0x01; + break; case jbvString: - tmp = hash_any((unsigned char *) scalarVal->val.string.val, - scalarVal->val.string.len); - *hash ^= tmp; - return; + tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val, + scalarVal->val.string.len)); + break; case jbvNumeric: - /* Must be unaffected by trailing zeroes */ - tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric, + /* Must hash equal numerics to equal hash codes */ + tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric, NumericGetDatum(scalarVal->val.numeric))); - *hash ^= tmp; - return; + break; case jbvBool: - *hash ^= scalarVal->val.boolean ? 0x02 : 0x04; - return; + tmp = scalarVal->val.boolean ? 0x02 : 0x04; + break; default: elog(ERROR, "invalid jsonb scalar type"); + tmp = 0; /* keep compiler quiet */ + break; } + + /* + * Combine hash values of successive keys, values and elements by rotating + * the previous value left 1 bit, then XOR'ing in the new + * key/value/element's hash value. + */ + *hash = (*hash << 1) | (*hash >> 31); + *hash ^= tmp; } /* |