Hi John, > I've pushed 0001.
Many thanks! > For 0002, it seems like we could additionally give > hash_any_extended() the same treatment in a few call sites? Fair point. Fixed. -- Best regards, Aleksander Alekseev
From 7aaf12edf5d10c8ed8954d5ae67bad3b6ed5f0d1 Mon Sep 17 00:00:00 2001 From: Aleksander Alekseev <[email protected]> Date: Tue, 3 Feb 2026 16:45:10 +0300 Subject: [PATCH v7] Avoid unnecessary type casting when using hash_any() / hash_any_extended() hash_any() is merely a wrapper for hash_bytes(). Call it directly when possible in order to avoid unnecessary type casting. Same for hash_any_extended() which is just a wrapper for hash_bytes_extended(). Additionally, improve the comment for addHyperLogLog(). Previously the comment suggested to use hash_any() whose return value is Datum. Since the argument of addHyperLogLog() is uint32, recommending hash_bytes() is more appropriate. Author: Aleksander Alekseev <[email protected]> Suggested-by: John Naylor <[email protected]> Reviewed-by: John Naylor <[email protected]> Discussion: https://postgr.es/m/CAJ7c6TMPhDRQMmkUHPv8oOK97B1mR8NRS61DgjpdaZUPAwaeZQ%40mail.gmail.com --- contrib/ltree/ltree_op.c | 4 ++-- src/backend/access/tablesample/bernoulli.c | 4 ++-- src/backend/access/tablesample/system.c | 4 ++-- src/backend/commands/async.c | 10 ++++----- src/backend/lib/bloomfilter.c | 2 +- src/backend/lib/hyperloglog.c | 2 +- src/backend/nodes/bitmapset.c | 4 ++-- src/backend/nodes/queryjumblefuncs.c | 10 ++++----- src/backend/tsearch/ts_typanalyze.c | 4 ++-- src/backend/utils/adt/bytea.c | 4 ++-- src/backend/utils/adt/jsonb_gin.c | 2 +- src/backend/utils/adt/jsonb_util.c | 10 ++++----- src/backend/utils/adt/numeric.c | 26 +++++++++++----------- src/backend/utils/adt/varlena.c | 4 ++-- src/backend/utils/cache/funccache.c | 8 +++---- 15 files changed, 49 insertions(+), 49 deletions(-) diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c index 1f9f02cf453..c9cbd3e8ed7 100644 --- a/contrib/ltree/ltree_op.c +++ b/contrib/ltree/ltree_op.c @@ -181,7 +181,7 @@ hash_ltree(PG_FUNCTION_ARGS) while (an > 0) { - uint32 levelHash = DatumGetUInt32(hash_any((unsigned char *) al->name, al->len)); + uint32 levelHash = hash_bytes((unsigned char *) al->name, al->len); /* * Combine hash values of successive elements by multiplying the @@ -224,7 +224,7 @@ hash_ltree_extended(PG_FUNCTION_ARGS) while (an > 0) { - uint64 levelHash = DatumGetUInt64(hash_any_extended((unsigned char *) al->name, al->len, seed)); + uint64 levelHash = hash_bytes_extended((unsigned char *) al->name, al->len, seed); result = (result << 5) - result + levelHash; diff --git a/src/backend/access/tablesample/bernoulli.c b/src/backend/access/tablesample/bernoulli.c index a8ec1e1b9ac..5d30277c732 100644 --- a/src/backend/access/tablesample/bernoulli.c +++ b/src/backend/access/tablesample/bernoulli.c @@ -214,8 +214,8 @@ bernoulli_nextsampletuple(SampleScanState *node, hashinput[1] = tupoffset; - hash = DatumGetUInt32(hash_any((const unsigned char *) hashinput, - (int) sizeof(hashinput))); + hash = hash_bytes((const unsigned char *) hashinput, + (int) sizeof(hashinput)); if (hash < sampler->cutoff) break; } diff --git a/src/backend/access/tablesample/system.c b/src/backend/access/tablesample/system.c index a2b9ba8eea9..de13dd8cab9 100644 --- a/src/backend/access/tablesample/system.c +++ b/src/backend/access/tablesample/system.c @@ -202,8 +202,8 @@ system_nextsampleblock(SampleScanState *node, BlockNumber nblocks) hashinput[0] = nextblock; - hash = DatumGetUInt32(hash_any((const unsigned char *) hashinput, - (int) sizeof(hashinput))); + hash = hash_bytes((const unsigned char *) hashinput, + (int) sizeof(hashinput)); if (hash < sampler->cutoff) break; } diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 4069dde3ba6..b24dd63b3fa 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -674,9 +674,9 @@ globalChannelTableHash(const void *key, size_t size, void *arg) const GlobalChannelKey *k = (const GlobalChannelKey *) key; dshash_hash h; - h = DatumGetUInt32(hash_uint32(k->dboid)); - h ^= DatumGetUInt32(hash_any((const unsigned char *) k->channel, - strnlen(k->channel, NAMEDATALEN))); + h = murmurhash32(k->dboid); + h ^= hash_bytes((const unsigned char *) k->channel, + strnlen(k->channel, NAMEDATALEN)); return h; } @@ -3251,8 +3251,8 @@ notification_hash(const void *key, Size keysize) Assert(keysize == sizeof(Notification *)); /* We don't bother to include the payload's trailing null in the hash */ - return DatumGetUInt32(hash_any((const unsigned char *) k->data, - k->channel_len + k->payload_len + 1)); + return hash_bytes((const unsigned char *) k->data, + k->channel_len + k->payload_len + 1); } /* diff --git a/src/backend/lib/bloomfilter.c b/src/backend/lib/bloomfilter.c index 73b3768a172..369a1e870e8 100644 --- a/src/backend/lib/bloomfilter.c +++ b/src/backend/lib/bloomfilter.c @@ -256,7 +256,7 @@ k_hashes(bloom_filter *filter, uint32 *hashes, unsigned char *elem, size_t len) int i; /* Use 64-bit hashing to get two independent 32-bit hashes */ - hash = DatumGetUInt64(hash_any_extended(elem, len, filter->seed)); + hash = hash_bytes_extended(elem, len, filter->seed); x = (uint32) hash; y = (uint32) (hash >> 32); m = filter->m; diff --git a/src/backend/lib/hyperloglog.c b/src/backend/lib/hyperloglog.c index 2b94b758fcf..5d2287bbf3f 100644 --- a/src/backend/lib/hyperloglog.c +++ b/src/backend/lib/hyperloglog.c @@ -158,7 +158,7 @@ freeHyperLogLog(hyperLogLogState *cState) * Adds element to the estimator, from caller-supplied hash. * * It is critical that the hash value passed be an actual hash value, typically - * generated using hash_any(). The algorithm relies on a specific bit-pattern + * generated using hash_bytes(). The algorithm relies on a specific bit-pattern * observable in conjunction with stochastic averaging. There must be a * uniform distribution of bits in hash values for each distinct original value * observed. diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 4a12b047789..4dd97e55842 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -1546,8 +1546,8 @@ bms_hash_value(const Bitmapset *a) if (a == NULL) return 0; /* All empty sets hash to 0 */ - return DatumGetUInt32(hash_any((const unsigned char *) a->words, - a->nwords * sizeof(bitmapword))); + return hash_bytes((const unsigned char *) a->words, + a->nwords * sizeof(bitmapword)); } /* diff --git a/src/backend/nodes/queryjumblefuncs.c b/src/backend/nodes/queryjumblefuncs.c index 094d2872644..e5f645dc29e 100644 --- a/src/backend/nodes/queryjumblefuncs.c +++ b/src/backend/nodes/queryjumblefuncs.c @@ -221,9 +221,9 @@ DoJumble(JumbleState *jstate, Node *node) jstate->highest_extern_param_id = 0; /* Process the jumble buffer and produce the hash value */ - return DatumGetInt64(hash_any_extended(jstate->jumble, - jstate->jumble_len, - 0)); + return (int64) hash_bytes_extended(jstate->jumble, + jstate->jumble_len, + 0); } /* @@ -271,8 +271,8 @@ AppendJumbleInternal(JumbleState *jstate, const unsigned char *item, { int64 start_hash; - start_hash = DatumGetInt64(hash_any_extended(jumble, - JUMBLE_SIZE, 0)); + start_hash = (int64) hash_bytes_extended(jumble, + JUMBLE_SIZE, 0); memcpy(jumble, &start_hash, sizeof(start_hash)); jumble_len = sizeof(start_hash); } diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c index 48ee050e37f..6ca8ead3988 100644 --- a/src/backend/tsearch/ts_typanalyze.c +++ b/src/backend/tsearch/ts_typanalyze.c @@ -496,8 +496,8 @@ lexeme_hash(const void *key, Size keysize) { const LexemeHashKey *l = (const LexemeHashKey *) key; - return DatumGetUInt32(hash_any((const unsigned char *) l->lexeme, - l->length)); + return hash_bytes((const unsigned char *) l->lexeme, + l->length); } /* diff --git a/src/backend/utils/adt/bytea.c b/src/backend/utils/adt/bytea.c index da32f9c53c6..3b1b02a7125 100644 --- a/src/backend/utils/adt/bytea.c +++ b/src/backend/utils/adt/bytea.c @@ -1106,8 +1106,8 @@ bytea_abbrev_convert(Datum original, SortSupport ssup) * in order to compensate for cases where differences are past * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing. */ - hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data, - Min(len, PG_CACHE_LINE_SIZE))); + hash = hash_bytes((unsigned char *) authoritative_data, + Min(len, PG_CACHE_LINE_SIZE)); if (len > PG_CACHE_LINE_SIZE) hash ^= murmurhash32((uint32) len); diff --git a/src/backend/utils/adt/jsonb_gin.c b/src/backend/utils/adt/jsonb_gin.c index d72a6441c5e..f5dbd5589d3 100644 --- a/src/backend/utils/adt/jsonb_gin.c +++ b/src/backend/utils/adt/jsonb_gin.c @@ -1333,7 +1333,7 @@ make_text_key(char flag, const char *str, int len) { uint32 hashval; - hashval = DatumGetUInt32(hash_any((const unsigned char *) str, len)); + hashval = hash_bytes((const unsigned char *) str, len); snprintf(hashbuf, sizeof(hashbuf), "%08x", hashval); str = hashbuf; len = 8; diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index b23facb6dac..509082cfb94 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -1451,8 +1451,8 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash) tmp = 0x01; break; case jbvString: - tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val, - scalarVal->val.string.len)); + tmp = hash_bytes((const unsigned char *) scalarVal->val.string.val, + scalarVal->val.string.len); break; case jbvNumeric: /* Must hash equal numerics to equal hash codes */ @@ -1494,9 +1494,9 @@ JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash, tmp = seed + 0x01; break; case jbvString: - tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val, - scalarVal->val.string.len, - seed)); + tmp = hash_bytes_extended((const unsigned char *) scalarVal->val.string.val, + scalarVal->val.string.len, + seed); break; case jbvNumeric: tmp = DatumGetUInt64(DirectFunctionCall2(hash_numeric_extended, diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 238f2e89f1d..65e6c677e59 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -2717,8 +2717,8 @@ Datum hash_numeric(PG_FUNCTION_ARGS) { Numeric key = PG_GETARG_NUMERIC(0); - Datum digit_hash; - Datum result; + uint32 digit_hash; + uint32 result; int weight; int start_offset; int end_offset; @@ -2780,13 +2780,13 @@ hash_numeric(PG_FUNCTION_ARGS) * this shouldn't affect correctness. */ hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset; - digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset), - hash_len * sizeof(NumericDigit)); + digit_hash = hash_bytes((unsigned char *) (NUMERIC_DIGITS(key) + start_offset), + hash_len * sizeof(NumericDigit)); /* Mix in the weight, via XOR */ result = digit_hash ^ weight; - PG_RETURN_DATUM(result); + PG_RETURN_UINT32(result); } /* @@ -2798,8 +2798,8 @@ hash_numeric_extended(PG_FUNCTION_ARGS) { Numeric key = PG_GETARG_NUMERIC(0); uint64 seed = PG_GETARG_INT64(1); - Datum digit_hash; - Datum result; + uint64 digit_hash; + uint64 result; int weight; int start_offset; int end_offset; @@ -2840,14 +2840,14 @@ hash_numeric_extended(PG_FUNCTION_ARGS) Assert(start_offset + end_offset < NUMERIC_NDIGITS(key)); hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset; - digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key) - + start_offset), - hash_len * sizeof(NumericDigit), - seed); + digit_hash = hash_bytes_extended((unsigned char *) (NUMERIC_DIGITS(key) + + start_offset), + hash_len * sizeof(NumericDigit), + seed); - result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight); + result = digit_hash ^ weight; - PG_RETURN_DATUM(result); + PG_RETURN_UINT64(result); } diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 910fc24313b..6c95fcb24b7 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -2154,8 +2154,8 @@ varstr_abbrev_convert(Datum original, SortSupport ssup) * in order to compensate for cases where differences are past * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing. */ - hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data, - Min(len, PG_CACHE_LINE_SIZE))); + hash = hash_bytes((unsigned char *) authoritative_data, + Min(len, PG_CACHE_LINE_SIZE)); if (len > PG_CACHE_LINE_SIZE) hash ^= murmurhash32((uint32) len); diff --git a/src/backend/utils/cache/funccache.c b/src/backend/utils/cache/funccache.c index 43f031d53a2..64f7b51ac41 100644 --- a/src/backend/utils/cache/funccache.c +++ b/src/backend/utils/cache/funccache.c @@ -89,13 +89,13 @@ cfunc_hash(const void *key, Size keysize) Assert(keysize == sizeof(CachedFunctionHashKey)); /* Hash all the fixed fields except callResultType */ - h = DatumGetUInt32(hash_any((const unsigned char *) k, - offsetof(CachedFunctionHashKey, callResultType))); + h = hash_bytes((const unsigned char *) k, + offsetof(CachedFunctionHashKey, callResultType)); /* Incorporate input argument types */ if (k->nargs > 0) h = hash_combine(h, - DatumGetUInt32(hash_any((const unsigned char *) k->argtypes, - k->nargs * sizeof(Oid)))); + hash_bytes((const unsigned char *) k->argtypes, + k->nargs * sizeof(Oid))); /* Incorporate callResultType if present */ if (k->callResultType) h = hash_combine(h, hashRowType(k->callResultType)); -- 2.43.0
