From 2a3b3f96df7f52441ad13e574b8ce3f42b71740b Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Wed, 26 Sep 2018 05:00:36 -0400 Subject: [PATCH 1/2] hstore - add extended hash function v1 --- contrib/hstore/Makefile | 3 ++- contrib/hstore/expected/hstore.out | 12 ++++++++++++ contrib/hstore/hstore--1.5--1.6.sql | 12 ++++++++++++ contrib/hstore/hstore--unpackaged--1.0.sql | 1 + contrib/hstore/hstore.control | 2 +- contrib/hstore/hstore_op.c | 20 ++++++++++++++++++++ contrib/hstore/sql/hstore.sql | 9 +++++++++ 7 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 contrib/hstore/hstore--1.5--1.6.sql diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile index 46d26f8052..8170e307fe 100644 --- a/contrib/hstore/Makefile +++ b/contrib/hstore/Makefile @@ -5,7 +5,8 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \ $(WIN32RES) 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.1--1.2.sql hstore--1.0--1.1.sql \ hstore--unpackaged--1.0.sql diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out index f0d421602d..4f1db01b3e 100644 --- a/contrib/hstore/expected/hstore.out +++ b/contrib/hstore/expected/hstore.out @@ -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}}] (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) + diff --git a/contrib/hstore/hstore--1.5--1.6.sql b/contrib/hstore/hstore--1.5--1.6.sql new file mode 100644 index 0000000000..c5a2bae02f --- /dev/null +++ b/contrib/hstore/hstore--1.5--1.6.sql @@ -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); diff --git a/contrib/hstore/hstore--unpackaged--1.0.sql b/contrib/hstore/hstore--unpackaged--1.0.sql index 19a7802805..2128165433 100644 --- a/contrib/hstore/hstore--unpackaged--1.0.sql +++ b/contrib/hstore/hstore--unpackaged--1.0.sql @@ -71,6 +71,7 @@ ALTER EXTENSION hstore ADD operator #<=#(hstore,hstore); ALTER EXTENSION hstore ADD operator family btree_hstore_ops using btree; ALTER EXTENSION hstore ADD operator class btree_hstore_ops using btree; ALTER EXTENSION hstore ADD function hstore_hash(hstore); +ALTER EXTENSION hstore ADD function hstore_hash_extended(hstore,int8); ALTER EXTENSION hstore ADD operator family hash_hstore_ops using hash; ALTER EXTENSION hstore ADD operator class hash_hstore_ops using hash; ALTER EXTENSION hstore ADD type ghstore; diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control index 8a719475b8..93688cdd83 100644 --- a/contrib/hstore/hstore.control +++ b/contrib/hstore/hstore.control @@ -1,5 +1,5 @@ # hstore extension comment = 'data type for storing sets of (key, value) pairs' -default_version = '1.5' +default_version = '1.6' module_pathname = '$libdir/hstore' relocatable = true diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c index 8f9277f8da..898324bbe9 100644 --- a/contrib/hstore/hstore_op.c +++ b/contrib/hstore/hstore_op.c @@ -1253,3 +1253,23 @@ hstore_hash(PG_FUNCTION_ARGS) PG_FREE_IF_COPY(hs, 0); 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); + Datum hval = hash_any_extended((unsigned char *) VARDATA(hs), + VARSIZE(hs) - VARHDRSZ, + PG_GETARG_INT64(1)); + + /* Same approach as 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); +} diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql index d64b9f77c7..76ac48b021 100644 --- a/contrib/hstore/sql/hstore.sql +++ b/contrib/hstore/sql/hstore.sql @@ -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'); 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; + +-- 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); -- 2.18.0