Add hash operator class

The uri = uri operator was marked as HASHES, but no hash function or
hash operator class was defined.  Hash joins would therefore fail.

Bug report and original patch by Grégoire HUBERT (@chanmix51).

closes #3
This commit is contained in:
Peter Eisentraut 2015-08-29 16:17:13 -04:00
parent cf854ebea1
commit cd80642413
7 changed files with 63 additions and 2 deletions

View File

@ -1,11 +1,12 @@
PG_CONFIG = pg_config
PKG_CONFIG = pkg-config
extension_version = 0
extension_version = 1
EXTENSION = uri
MODULE_big = uri
OBJS = uri.o
DATA = uri--0--1.sql
DATA_built = uri--$(extension_version).sql
ifeq (no,$(shell $(PKG_CONFIG) liburiparser || echo no))

View File

@ -289,3 +289,14 @@ SELECT DISTINCT b FROM test ORDER BY b;
ssh://username@review.openstack.org:29418/openstack/nova.git
(17 rows)
CREATE TABLE test2 (x text, y uri);
INSERT INTO test2 VALUES ('foo', 'http://www.postgresql.org/');
-- check hashing (issue petere/pguri#3)
SET enable_nestloop = off;
SET enable_mergejoin = off;
SELECT * FROM test JOIN test2 ON b = y AND a = 1;
a | b | x | y
---+----------------------------+-----+----------------------------
1 | http://www.postgresql.org/ | foo | http://www.postgresql.org/
(1 row)

View File

@ -48,3 +48,12 @@ SELECT b AS uri,
\x off
SELECT DISTINCT b FROM test ORDER BY b;
CREATE TABLE test2 (x text, y uri);
INSERT INTO test2 VALUES ('foo', 'http://www.postgresql.org/');
-- check hashing (issue petere/pguri#3)
SET enable_nestloop = off;
SET enable_mergejoin = off;
SELECT * FROM test JOIN test2 ON b = y AND a = 1;

10
uri--0--1.sql Normal file
View File

@ -0,0 +1,10 @@
CREATE FUNCTION uri_hash(uri) RETURNS integer
IMMUTABLE
STRICT
LANGUAGE C
AS '$libdir/uri';
CREATE OPERATOR CLASS uri_ops_hash
DEFAULT FOR TYPE uri USING hash AS
OPERATOR 1 =,
FUNCTION 1 uri_hash(uri);

19
uri.c
View File

@ -1,4 +1,5 @@
#include <postgres.h>
#include <access/hash.h>
#include <catalog/pg_type.h>
#include <fmgr.h>
#include <lib/stringinfo.h>
@ -16,9 +17,11 @@ typedef struct varlena uritype;
#define DatumGetUriP(X) ((uritype *) PG_DETOAST_DATUM(X))
#define DatumGetUriPP(X) ((uritype *) PG_DETOAST_DATUM_PACKED(X))
#define UriPGetDatum(X) PointerGetDatum(X)
#define PG_GETARG_URI_P(n) DatumGetUriP(PG_GETARG_DATUM(n))
#define PG_GETARG_URI_PP(n) DatumGetUriPP(PG_GETARG_DATUM(n))
#define PG_RETURN_URI_P(x) PG_RETURN_POINTER(x)
@ -436,3 +439,19 @@ uri_cmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(_uri_cmp(arg1, arg2));
}
PG_FUNCTION_INFO_V1(uri_hash);
Datum
uri_hash(PG_FUNCTION_ARGS)
{
uritype *key = PG_GETARG_URI_PP(0);
Datum result;
result = hash_any((unsigned char *) VARDATA_ANY(key),
VARSIZE_ANY_EXHDR(key));
/* Avoid leaking memory for toasted inputs */
PG_FREE_IF_COPY(key, 0);
return result;
}

View File

@ -1,4 +1,4 @@
comment = 'uri type'
default_version = 0
default_version = 1
module_pathname = '$libdir/uri'
relocatable = true

11
uri.sql
View File

@ -130,6 +130,12 @@ CREATE FUNCTION uri_cmp(uri, uri) RETURNS integer
LANGUAGE C
AS '$libdir/uri';
CREATE FUNCTION uri_hash(uri) RETURNS integer
IMMUTABLE
STRICT
LANGUAGE C
AS '$libdir/uri';
CREATE OPERATOR < (
LEFTARG = uri,
RIGHTARG = uri,
@ -200,3 +206,8 @@ CREATE OPERATOR CLASS uri_ops
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 uri_cmp(uri, uri);
CREATE OPERATOR CLASS uri_ops_hash
DEFAULT FOR TYPE uri USING hash AS
OPERATOR 1 =,
FUNCTION 1 uri_hash(uri);