From 2c22afaa4e29cbd773bae3f043a941f82ff30e2d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 6 May 2014 22:49:32 -0400 Subject: [PATCH] hash_any returns Datum, not uint32 (and definitely not "int"). The coding in JsonbHashScalarValue might have accidentally failed to fail given current representational choices, but the key word there would be "accidental". Insert the appropriate datatype conversion macro. And use the right conversion macro for hash_numeric's result, too. In passing make the code a bit cleaner and less repetitive by factoring out the xor step from the switch. --- src/backend/utils/adt/jsonb_util.c | 51 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index a9bf0d3a7d..411144618d 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,7 +1123,31 @@ arrayToJsonbSortedArray(ArrayType *array) void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash) { - int tmp; + uint32 tmp; + + /* Compute hash value for scalarVal */ + switch (scalarVal->type) + { + case jbvNull: + tmp = 0x01; + break; + case jbvString: + tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val, + scalarVal->val.string.len)); + break; + case jbvNumeric: + /* Must hash equal numerics to equal hash codes */ + tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric, + NumericGetDatum(scalarVal->val.numeric))); + break; + case jbvBool: + 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 @@ -1131,28 +1155,7 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash) * key/value/element's hash value. */ *hash = (*hash << 1) | (*hash >> 31); - switch (scalarVal->type) - { - case jbvNull: - *hash ^= 0x01; - return; - case jbvString: - tmp = hash_any((unsigned char *) scalarVal->val.string.val, - scalarVal->val.string.len); - *hash ^= tmp; - return; - case jbvNumeric: - /* Must be unaffected by trailing zeroes */ - tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric, - NumericGetDatum(scalarVal->val.numeric))); - *hash ^= tmp; - return; - case jbvBool: - *hash ^= scalarVal->val.boolean ? 0x02 : 0x04; - return; - default: - elog(ERROR, "invalid jsonb scalar type"); - } + *hash ^= tmp; } /*