in src/backend/utils/adt/agtype_util.c [1555:1636]
void agtype_hash_scalar_value_extended(const agtype_value *scalar_val,
uint64 *hash, uint64 seed)
{
uint64 tmp = 0;
switch (scalar_val->type)
{
case AGTV_NULL:
tmp = seed + 0x01;
break;
case AGTV_STRING:
tmp = DatumGetUInt64(hash_any_extended(
(const unsigned char *)scalar_val->val.string.val,
scalar_val->val.string.len, seed));
break;
case AGTV_NUMERIC:
tmp = DatumGetUInt64(DirectFunctionCall2(
hash_numeric_extended, NumericGetDatum(scalar_val->val.numeric),
UInt64GetDatum(seed)));
break;
case AGTV_BOOL:
if (seed)
{
tmp = DatumGetUInt64(DirectFunctionCall2(
hashcharextended, BoolGetDatum(scalar_val->val.boolean),
UInt64GetDatum(seed)));
}
else
{
tmp = scalar_val->val.boolean ? 0x02 : 0x04;
}
break;
case AGTV_INTEGER:
tmp = DatumGetUInt64(DirectFunctionCall2(
hashint8extended, Int64GetDatum(scalar_val->val.int_value),
UInt64GetDatum(seed)));
break;
case AGTV_FLOAT:
tmp = DatumGetUInt64(DirectFunctionCall2(
hashfloat8extended, Float8GetDatum(scalar_val->val.float_value),
UInt64GetDatum(seed)));
break;
case AGTV_VERTEX:
{
graphid id;
agtype_value *id_agt = GET_AGTYPE_VALUE_OBJECT_VALUE(scalar_val, "id");
id = id_agt->val.int_value;
tmp = DatumGetUInt64(DirectFunctionCall2(
hashint8extended, Float8GetDatum(id), UInt64GetDatum(seed)));
break;
}
case AGTV_EDGE:
{
graphid id;
agtype_value *id_agt = GET_AGTYPE_VALUE_OBJECT_VALUE(scalar_val, "id");
id = id_agt->val.int_value;
tmp = DatumGetUInt64(DirectFunctionCall2(
hashint8extended, Float8GetDatum(id), UInt64GetDatum(seed)));
break;
}
case AGTV_PATH:
{
int i;
for (i = 0; i < scalar_val->val.array.num_elems; i++)
{
agtype_value v;
v = scalar_val->val.array.elems[i];
agtype_hash_scalar_value_extended(&v, &tmp, seed);
}
break;
}
default:
ereport(
ERROR,
(errmsg("invalid agtype scalar type %d to compute hash extended",
scalar_val->type)));
break;
}
*hash = ROTATE_HIGH_AND_LOW_32BITS(*hash);
*hash ^= tmp;
}