Skip to content

Commit eb6f291

Browse files
committed
Add a 64-bit hash function for type hstore.
There's some question about the correctness of the hash function, but if it's wrong, the 32-bit version is also wrong. Amul Sul, reviewed by Hironobu Suzuki Discussion: https://postgr.es/m/CAAJ_b947JjnNr9Cp45iNjSqKf6PA5mCTmKsRwPjows93YwQrmw@mail.gmail.com
1 parent 48c41fa commit eb6f291

File tree

6 files changed

+64
-5
lines changed

6 files changed

+64
-5
lines changed

contrib/hstore/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
55
$(WIN32RES)
66

77
EXTENSION = hstore
8-
DATA = hstore--1.4.sql hstore--1.4--1.5.sql \
8+
DATA = hstore--1.4.sql \
9+
hstore--1.5--1.6.sql \
10+
hstore--1.4--1.5.sql \
911
hstore--1.3--1.4.sql hstore--1.2--1.3.sql \
1012
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
1113
hstore--unpackaged--1.0.sql

contrib/hstore/expected/hstore.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,3 +1515,15 @@ select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_jso
15151515
{"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
15161516
(1 row)
15171517

1518+
-- Check the hstore_hash() and hstore_hash_extended() function explicitly.
1519+
SELECT v as value, hstore_hash(v)::bit(32) as standard,
1520+
hstore_hash_extended(v, 0)::bit(32) as extended0,
1521+
hstore_hash_extended(v, 1)::bit(32) as extended1
1522+
FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'),
1523+
('e => 012345'), ('g => 2.345e+4')) x(v)
1524+
WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32)
1525+
OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32);
1526+
value | standard | extended0 | extended1
1527+
-------+----------+-----------+-----------
1528+
(0 rows)
1529+

contrib/hstore/hstore--1.5--1.6.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* contrib/hstore/hstore--1.5--1.6.sql */
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use "ALTER EXTENSION hstore UPDATE TO '1.6'" to load this file. \quit
5+
6+
CREATE FUNCTION hstore_hash_extended(hstore, int8)
7+
RETURNS int8
8+
AS 'MODULE_PATHNAME','hstore_hash_extended'
9+
LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
10+
11+
ALTER OPERATOR FAMILY hash_hstore_ops USING hash ADD
12+
FUNCTION 2 hstore_hash_extended(hstore, int8);

contrib/hstore/hstore.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# hstore extension
22
comment = 'data type for storing sets of (key, value) pairs'
3-
default_version = '1.5'
3+
default_version = '1.6'
44
module_pathname = '$libdir/hstore'
55
relocatable = true

contrib/hstore/hstore_op.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,9 +1240,10 @@ hstore_hash(PG_FUNCTION_ARGS)
12401240
VARSIZE(hs) - VARHDRSZ);
12411241

12421242
/*
1243-
* this is the only place in the code that cares whether the overall
1244-
* varlena size exactly matches the true data size; this assertion should
1245-
* be maintained by all the other code, but we make it explicit here.
1243+
* This (along with hstore_hash_extended) is the only place in the code
1244+
* that cares whether the overall varlena size exactly matches the true
1245+
* data size; this assertion should be maintained by all the other code,
1246+
* but we make it explicit here.
12461247
*/
12471248
Assert(VARSIZE(hs) ==
12481249
(HS_COUNT(hs) != 0 ?
@@ -1253,3 +1254,26 @@ hstore_hash(PG_FUNCTION_ARGS)
12531254
PG_FREE_IF_COPY(hs, 0);
12541255
PG_RETURN_DATUM(hval);
12551256
}
1257+
1258+
PG_FUNCTION_INFO_V1(hstore_hash_extended);
1259+
Datum
1260+
hstore_hash_extended(PG_FUNCTION_ARGS)
1261+
{
1262+
HStore *hs = PG_GETARG_HSTORE_P(0);
1263+
uint64 seed = PG_GETARG_INT64(1);
1264+
Datum hval;
1265+
1266+
hval = hash_any_extended((unsigned char *) VARDATA(hs),
1267+
VARSIZE(hs) - VARHDRSZ,
1268+
seed);
1269+
1270+
/* See comment in hstore_hash */
1271+
Assert(VARSIZE(hs) ==
1272+
(HS_COUNT(hs) != 0 ?
1273+
CALCDATASIZE(HS_COUNT(hs),
1274+
HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
1275+
HSHRDSIZE));
1276+
1277+
PG_FREE_IF_COPY(hs, 0);
1278+
PG_RETURN_DATUM(hval);
1279+
}

contrib/hstore/sql/hstore.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,12 @@ insert into test_json_agg values ('rec1','"a key" =>1, b => t, c => null, d=> 12
350350
('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
351351
select json_agg(q) from test_json_agg q;
352352
select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
353+
354+
-- Check the hstore_hash() and hstore_hash_extended() function explicitly.
355+
SELECT v as value, hstore_hash(v)::bit(32) as standard,
356+
hstore_hash_extended(v, 0)::bit(32) as extended0,
357+
hstore_hash_extended(v, 1)::bit(32) as extended1
358+
FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'),
359+
('e => 012345'), ('g => 2.345e+4')) x(v)
360+
WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32)
361+
OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy