From 7e3a5330e1059b57e489b802abcc62676fd19ccc Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Fri, 8 Sep 2017 12:29:02 +0530 Subject: [PATCH 2/2] citext - add extended hash function --- contrib/citext/citext--1.4--1.5.sql | 8 ++++++++ contrib/citext/citext--1.5.sql | 8 +++++++- contrib/citext/citext--unpackaged--1.0.sql | 1 + contrib/citext/citext.c | 20 ++++++++++++++++++++ contrib/citext/expected/citext.out | 12 ++++++++++++ contrib/citext/expected/citext_1.out | 12 ++++++++++++ contrib/citext/sql/citext.sql | 9 +++++++++ 7 files changed, 69 insertions(+), 1 deletion(-) diff --git a/contrib/citext/citext--1.4--1.5.sql b/contrib/citext/citext--1.4--1.5.sql index d69f7b1..a06c42d 100644 --- a/contrib/citext/citext--1.4--1.5.sql +++ b/contrib/citext/citext--1.4--1.5.sql @@ -2,3 +2,11 @@ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION citext UPDATE TO '1.5'" to load this file. \quit + +CREATE FUNCTION citext_hash_extended(citext, int8) +RETURNS int8 +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; + +ALTER OPERATOR FAMILY citext_ops USING hash ADD + FUNCTION 2 citext_hash_extended(citext, int8); diff --git a/contrib/citext/citext--1.5.sql b/contrib/citext/citext--1.5.sql index ce984e3..4d7ec4d 100644 --- a/contrib/citext/citext--1.5.sql +++ b/contrib/citext/citext--1.5.sql @@ -203,6 +203,11 @@ RETURNS int4 AS 'MODULE_PATHNAME' LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; +CREATE FUNCTION citext_hash_extended(citext, int8) +RETURNS int8 +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; + -- -- The btree indexing operator class. -- @@ -223,7 +228,8 @@ DEFAULT FOR TYPE CITEXT USING btree AS CREATE OPERATOR CLASS citext_ops DEFAULT FOR TYPE citext USING hash AS OPERATOR 1 = (citext, citext), - FUNCTION 1 citext_hash(citext); + FUNCTION 1 citext_hash(citext), + FUNCTION 2 citext_hash_extended(citext, int8); -- -- Aggregates. diff --git a/contrib/citext/citext--unpackaged--1.0.sql b/contrib/citext/citext--unpackaged--1.0.sql index ef6d6b0..9b1161b 100644 --- a/contrib/citext/citext--unpackaged--1.0.sql +++ b/contrib/citext/citext--unpackaged--1.0.sql @@ -33,6 +33,7 @@ ALTER EXTENSION citext ADD operator <(citext,citext); ALTER EXTENSION citext ADD operator <=(citext,citext); ALTER EXTENSION citext ADD function citext_cmp(citext,citext); ALTER EXTENSION citext ADD function citext_hash(citext); +ALTER EXTENSION citext ADD function citext_hash_extended(citext,int8); ALTER EXTENSION citext ADD operator family citext_ops using btree; ALTER EXTENSION citext ADD operator class citext_ops using btree; ALTER EXTENSION citext ADD operator family citext_ops using hash; diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c index 0ba4782..a959446 100644 --- a/contrib/citext/citext.c +++ b/contrib/citext/citext.c @@ -100,6 +100,26 @@ citext_hash(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +PG_FUNCTION_INFO_V1(citext_hash_extended); + +Datum +citext_hash_extended(PG_FUNCTION_ARGS) +{ + text *txt = PG_GETARG_TEXT_PP(0); + uint64 seed = PG_GETARG_INT64(1); + char *str; + Datum result; + + str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID); + result = hash_any_extended((unsigned char *) str, strlen(str), seed); + pfree(str); + + /* Avoid leaking memory for toasted inputs */ + PG_FREE_IF_COPY(txt, 0); + + PG_RETURN_DATUM(result); +} + /* * ================== * OPERATOR FUNCTIONS diff --git a/contrib/citext/expected/citext.out b/contrib/citext/expected/citext.out index 9cc94f4..8f03fc9 100644 --- a/contrib/citext/expected/citext.out +++ b/contrib/citext/expected/citext.out @@ -222,6 +222,18 @@ SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; t (1 row) +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + -- Do some tests using a table and index. CREATE TEMP TABLE try ( name citext PRIMARY KEY diff --git a/contrib/citext/expected/citext_1.out b/contrib/citext/expected/citext_1.out index d1fb1e1..b46be4d 100644 --- a/contrib/citext/expected/citext_1.out +++ b/contrib/citext/expected/citext_1.out @@ -222,6 +222,18 @@ SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; t (1 row) +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + -- Do some tests using a table and index. CREATE TEMP TABLE try ( name citext PRIMARY KEY diff --git a/contrib/citext/sql/citext.sql b/contrib/citext/sql/citext.sql index f70f9eb..e97bb7e 100644 --- a/contrib/citext/sql/citext.sql +++ b/contrib/citext/sql/citext.sql @@ -89,6 +89,15 @@ SELECT citext_cmp('aardvark'::citext, 'aardVark'::citext) AS zero; SELECT citext_cmp('AARDVARK'::citext, 'AARDVARK'::citext) AS zero; SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + -- Do some tests using a table and index. CREATE TEMP TABLE try ( -- 2.6.2