]> granicus.if.org Git - postgresql/commitdiff
hash_any returns Datum, not uint32 (and definitely not "int").
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 May 2014 02:49:32 +0000 (22:49 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 May 2014 02:49:40 +0000 (22:49 -0400)
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

index a9bf0d3a7d1aee87d79df09fda9327586cdfb208..411144618d68133e308612631f63612a852f0ab7 100644 (file)
@@ -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;
 }
 
 /*