Skip to content

Commit 950d047

Browse files
committed
Give inet/cidr datatypes their own hash function that ignores the inet vs
cidr type bit, the same as network_eq does. This is needed for hash joins and hash aggregation to work correctly on these types. Per bug report from Michael Fuhr, 2004-04-13. Also, improve hash function for int8 as suggested by Greg Stark.
1 parent 0e338bb commit 950d047

File tree

9 files changed

+77
-18
lines changed

9 files changed

+77
-18
lines changed

src/backend/access/hash/hashfunc.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.39 2003/11/29 19:51:40 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.40 2004/06/13 21:57:24 tgl Exp $
1212
*
1313
* NOTES
1414
* These functions are stored in pg_amproc. For each operator class
@@ -44,8 +44,26 @@ hashint4(PG_FUNCTION_ARGS)
4444
Datum
4545
hashint8(PG_FUNCTION_ARGS)
4646
{
47-
/* we just use the low 32 bits... */
47+
/*
48+
* The idea here is to produce a hash value compatible with the values
49+
* produced by hashint4 and hashint2 for logically equivalent inputs;
50+
* this is necessary if we ever hope to support cross-type hash joins
51+
* across these input types. Since all three types are signed, we can
52+
* xor the high half of the int8 value if the sign is positive, or the
53+
* complement of the high half when the sign is negative.
54+
*/
55+
#ifndef INT64_IS_BUSTED
56+
int64 val = PG_GETARG_INT64(0);
57+
uint32 lohalf = (uint32) val;
58+
uint32 hihalf = (uint32) (val >> 32);
59+
60+
lohalf ^= (val >= 0) ? hihalf : ~hihalf;
61+
62+
PG_RETURN_UINT32(~lohalf);
63+
#else
64+
/* here if we can't count on "x >> 32" to work sanely */
4865
PG_RETURN_UINT32(~((uint32) PG_GETARG_INT64(0)));
66+
#endif
4967
}
5068

5169
Datum

src/backend/utils/adt/network.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/*
22
* PostgreSQL type definitions for the INET and CIDR types.
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.51 2004/06/13 19:56:50 tgl Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.52 2004/06/13 21:57:25 tgl Exp $
55
*
66
* Jon Postel RIP 16 Oct 1998
77
*/
88

99
#include "postgres.h"
1010

11-
#include <errno.h>
1211
#include <sys/socket.h>
1312
#include <netinet/in.h>
1413
#include <arpa/inet.h>
1514

15+
#include "access/hash.h"
1616
#include "catalog/pg_type.h"
1717
#include "libpq/ip.h"
1818
#include "libpq/libpq-be.h"
@@ -42,7 +42,7 @@ static int ip_addrsize(inet *inetptr);
4242
(((inet_struct *)VARDATA(inetptr))->type)
4343

4444
#define ip_addr(inetptr) \
45-
(((inet_struct *)VARDATA(inetptr))->ip_addr)
45+
(((inet_struct *)VARDATA(inetptr))->ipaddr)
4646

4747
#define ip_maxbits(inetptr) \
4848
(ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
@@ -60,7 +60,7 @@ ip_addrsize(inet *inetptr)
6060
case PGSQL_AF_INET6:
6161
return 16;
6262
default:
63-
return -1;
63+
return 0;
6464
}
6565
}
6666

@@ -424,6 +424,27 @@ network_ne(PG_FUNCTION_ARGS)
424424
PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
425425
}
426426

427+
/*
428+
* Support function for hash indexes on inet/cidr.
429+
*
430+
* Since network_cmp considers only ip_family, ip_bits, and ip_addr,
431+
* only these fields may be used in the hash; in particular don't use type.
432+
*/
433+
Datum
434+
hashinet(PG_FUNCTION_ARGS)
435+
{
436+
inet *addr = PG_GETARG_INET_P(0);
437+
int addrsize = ip_addrsize(addr);
438+
unsigned char key[sizeof(inet_struct)];
439+
440+
Assert(addrsize + 2 <= sizeof(key));
441+
key[0] = ip_family(addr);
442+
key[1] = ip_bits(addr);
443+
memcpy(key + 2, ip_addr(addr), addrsize);
444+
445+
return hash_any(key, addrsize + 2);
446+
}
447+
427448
/*
428449
* Boolean network-inclusion tests.
429450
*/

src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.234 2004/06/06 19:06:59 tgl Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.235 2004/06/13 21:57:25 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200406061
56+
#define CATALOG_VERSION_NO 200406131
5757

5858
#endif

src/include/catalog/pg_amproc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
22-
* $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.48 2004/03/22 01:38:17 tgl Exp $
22+
* $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.49 2004/06/13 21:57:25 tgl Exp $
2323
*
2424
* NOTES
2525
* the genbki.sh script reads this file and generates .bki
@@ -136,11 +136,11 @@ DATA(insert ( 2234 0 1 381 ));
136136
/* hash */
137137
DATA(insert ( 427 0 1 1080 ));
138138
DATA(insert ( 431 0 1 454 ));
139-
DATA(insert ( 433 0 1 456 ));
139+
DATA(insert ( 433 0 1 422 ));
140140
DATA(insert ( 435 0 1 450 ));
141141
DATA(insert ( 1971 0 1 451 ));
142142
DATA(insert ( 1973 0 1 452 ));
143-
DATA(insert ( 1975 0 1 456 ));
143+
DATA(insert ( 1975 0 1 422 ));
144144
DATA(insert ( 1977 0 1 449 ));
145145
DATA(insert ( 1979 0 1 450 ));
146146
DATA(insert ( 1981 0 1 949 ));

src/include/catalog/pg_proc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.336 2004/06/13 19:56:51 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.337 2004/06/13 21:57:26 tgl Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -851,6 +851,8 @@ DATA(insert OID = 398 ( hashint2vector PGNSP PGUID 12 f f t f i 1 23 "22" _n
851851
DESCR("hash");
852852
DATA(insert OID = 399 ( hashmacaddr PGNSP PGUID 12 f f t f i 1 23 "829" _null_ hashmacaddr - _null_ ));
853853
DESCR("hash");
854+
DATA(insert OID = 422 ( hashinet PGNSP PGUID 12 f f t f i 1 23 "869" _null_ hashinet - _null_ ));
855+
DESCR("hash");
854856
DATA(insert OID = 458 ( text_larger PGNSP PGUID 12 f f t f i 2 25 "25 25" _null_ text_larger - _null_ ));
855857
DESCR("larger of two");
856858
DATA(insert OID = 459 ( text_smaller PGNSP PGUID 12 f f t f i 2 25 "25 25" _null_ text_smaller - _null_ ));

src/include/utils/builtins.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.242 2004/06/13 19:56:52 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.243 2004/06/13 21:57:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -664,6 +664,7 @@ extern Datum network_eq(PG_FUNCTION_ARGS);
664664
extern Datum network_ge(PG_FUNCTION_ARGS);
665665
extern Datum network_gt(PG_FUNCTION_ARGS);
666666
extern Datum network_ne(PG_FUNCTION_ARGS);
667+
extern Datum hashinet(PG_FUNCTION_ARGS);
667668
extern Datum network_sub(PG_FUNCTION_ARGS);
668669
extern Datum network_subeq(PG_FUNCTION_ARGS);
669670
extern Datum network_sup(PG_FUNCTION_ARGS);

src/include/utils/inet.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/inet.h,v 1.17 2003/11/29 22:41:15 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/inet.h,v 1.18 2004/06/13 21:57:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -20,10 +20,10 @@
2020
*/
2121
typedef struct
2222
{
23-
unsigned char family;
24-
unsigned char bits;
25-
unsigned char type;
26-
unsigned char ip_addr[16]; /* 128 bits of address */
23+
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
24+
unsigned char bits; /* number of bits in netmask */
25+
unsigned char type; /* 0 = inet, 1 = cidr */
26+
unsigned char ipaddr[16]; /* up to 128 bits of address */
2727
} inet_struct;
2828

2929
/*

src/test/regress/expected/opr_sanity.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,16 @@ WHERE p1.oprcanhash AND NOT EXISTS
487487
-----+---------
488488
(0 rows)
489489

490+
-- And the converse.
491+
SELECT p1.oid, p1.oprname, op.opcname
492+
FROM pg_operator AS p1, pg_opclass op, pg_amop p
493+
WHERE amopopr = p1.oid AND amopclaid = op.oid
494+
AND opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash')
495+
AND NOT p1.oprcanhash;
496+
oid | oprname | opcname
497+
-----+---------+---------
498+
(0 rows)
499+
490500
-- Check that each operator defined in pg_operator matches its oprcode entry
491501
-- in pg_proc. Easiest to do this separately for each oprkind.
492502
SELECT p1.oid, p1.oprname, p2.oid, p2.proname

src/test/regress/sql/opr_sanity.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,13 @@ WHERE p1.oprcanhash AND NOT EXISTS
409409
WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
410410
amopopr = p1.oid);
411411

412+
-- And the converse.
413+
414+
SELECT p1.oid, p1.oprname, op.opcname
415+
FROM pg_operator AS p1, pg_opclass op, pg_amop p
416+
WHERE amopopr = p1.oid AND amopclaid = op.oid
417+
AND opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash')
418+
AND NOT p1.oprcanhash;
412419

413420
-- Check that each operator defined in pg_operator matches its oprcode entry
414421
-- in pg_proc. Easiest to do this separately for each oprkind.

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