mirror of
https://github.com/postgres/postgres.git
synced 2025-04-18 13:44:19 +03:00
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
This commit is contained in:
parent
48c41fa974
commit
eb6f29141b
@ -5,7 +5,9 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
|
|||||||
$(WIN32RES)
|
$(WIN32RES)
|
||||||
|
|
||||||
EXTENSION = hstore
|
EXTENSION = hstore
|
||||||
DATA = hstore--1.4.sql hstore--1.4--1.5.sql \
|
DATA = hstore--1.4.sql \
|
||||||
|
hstore--1.5--1.6.sql \
|
||||||
|
hstore--1.4--1.5.sql \
|
||||||
hstore--1.3--1.4.sql hstore--1.2--1.3.sql \
|
hstore--1.3--1.4.sql hstore--1.2--1.3.sql \
|
||||||
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
|
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
|
||||||
hstore--unpackaged--1.0.sql
|
hstore--unpackaged--1.0.sql
|
||||||
|
@ -1515,3 +1515,15 @@ select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_jso
|
|||||||
{"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
|
{"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Check the hstore_hash() and hstore_hash_extended() function explicitly.
|
||||||
|
SELECT v as value, hstore_hash(v)::bit(32) as standard,
|
||||||
|
hstore_hash_extended(v, 0)::bit(32) as extended0,
|
||||||
|
hstore_hash_extended(v, 1)::bit(32) as extended1
|
||||||
|
FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'),
|
||||||
|
('e => 012345'), ('g => 2.345e+4')) x(v)
|
||||||
|
WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32)
|
||||||
|
OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32);
|
||||||
|
value | standard | extended0 | extended1
|
||||||
|
-------+----------+-----------+-----------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
12
contrib/hstore/hstore--1.5--1.6.sql
Normal file
12
contrib/hstore/hstore--1.5--1.6.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* contrib/hstore/hstore--1.5--1.6.sql */
|
||||||
|
|
||||||
|
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION hstore UPDATE TO '1.6'" to load this file. \quit
|
||||||
|
|
||||||
|
CREATE FUNCTION hstore_hash_extended(hstore, int8)
|
||||||
|
RETURNS int8
|
||||||
|
AS 'MODULE_PATHNAME','hstore_hash_extended'
|
||||||
|
LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
|
||||||
|
|
||||||
|
ALTER OPERATOR FAMILY hash_hstore_ops USING hash ADD
|
||||||
|
FUNCTION 2 hstore_hash_extended(hstore, int8);
|
@ -1,5 +1,5 @@
|
|||||||
# hstore extension
|
# hstore extension
|
||||||
comment = 'data type for storing sets of (key, value) pairs'
|
comment = 'data type for storing sets of (key, value) pairs'
|
||||||
default_version = '1.5'
|
default_version = '1.6'
|
||||||
module_pathname = '$libdir/hstore'
|
module_pathname = '$libdir/hstore'
|
||||||
relocatable = true
|
relocatable = true
|
||||||
|
@ -1240,9 +1240,10 @@ hstore_hash(PG_FUNCTION_ARGS)
|
|||||||
VARSIZE(hs) - VARHDRSZ);
|
VARSIZE(hs) - VARHDRSZ);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is the only place in the code that cares whether the overall
|
* This (along with hstore_hash_extended) is the only place in the code
|
||||||
* varlena size exactly matches the true data size; this assertion should
|
* that cares whether the overall varlena size exactly matches the true
|
||||||
* be maintained by all the other code, but we make it explicit here.
|
* data size; this assertion should be maintained by all the other code,
|
||||||
|
* but we make it explicit here.
|
||||||
*/
|
*/
|
||||||
Assert(VARSIZE(hs) ==
|
Assert(VARSIZE(hs) ==
|
||||||
(HS_COUNT(hs) != 0 ?
|
(HS_COUNT(hs) != 0 ?
|
||||||
@ -1253,3 +1254,26 @@ hstore_hash(PG_FUNCTION_ARGS)
|
|||||||
PG_FREE_IF_COPY(hs, 0);
|
PG_FREE_IF_COPY(hs, 0);
|
||||||
PG_RETURN_DATUM(hval);
|
PG_RETURN_DATUM(hval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PG_FUNCTION_INFO_V1(hstore_hash_extended);
|
||||||
|
Datum
|
||||||
|
hstore_hash_extended(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
HStore *hs = PG_GETARG_HSTORE_P(0);
|
||||||
|
uint64 seed = PG_GETARG_INT64(1);
|
||||||
|
Datum hval;
|
||||||
|
|
||||||
|
hval = hash_any_extended((unsigned char *) VARDATA(hs),
|
||||||
|
VARSIZE(hs) - VARHDRSZ,
|
||||||
|
seed);
|
||||||
|
|
||||||
|
/* See comment in hstore_hash */
|
||||||
|
Assert(VARSIZE(hs) ==
|
||||||
|
(HS_COUNT(hs) != 0 ?
|
||||||
|
CALCDATASIZE(HS_COUNT(hs),
|
||||||
|
HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
|
||||||
|
HSHRDSIZE));
|
||||||
|
|
||||||
|
PG_FREE_IF_COPY(hs, 0);
|
||||||
|
PG_RETURN_DATUM(hval);
|
||||||
|
}
|
||||||
|
@ -350,3 +350,12 @@ insert into test_json_agg values ('rec1','"a key" =>1, b => t, c => null, d=> 12
|
|||||||
('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
|
('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
|
||||||
select json_agg(q) from test_json_agg q;
|
select json_agg(q) from test_json_agg q;
|
||||||
select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
|
select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
|
||||||
|
|
||||||
|
-- Check the hstore_hash() and hstore_hash_extended() function explicitly.
|
||||||
|
SELECT v as value, hstore_hash(v)::bit(32) as standard,
|
||||||
|
hstore_hash_extended(v, 0)::bit(32) as extended0,
|
||||||
|
hstore_hash_extended(v, 1)::bit(32) as extended1
|
||||||
|
FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'),
|
||||||
|
('e => 012345'), ('g => 2.345e+4')) x(v)
|
||||||
|
WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32)
|
||||||
|
OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user