Skip to content

Commit 202548d

Browse files
committed
Teach convert_to_scalar about datatypes timetz, inet, cidr, macaddr.
1 parent e8637ec commit 202548d

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

src/backend/utils/adt/network.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* is for IP V4 CIDR notation, but prepared for V6: just
44
* add the necessary bits where the comments indicate.
55
*
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.29 2001/03/22 03:59:52 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.30 2001/06/09 22:16:18 tgl Exp $
77
*
88
* Jon Postel RIP 16 Oct 1998
99
*/
@@ -16,6 +16,7 @@
1616
#include <netinet/in.h>
1717
#include <arpa/inet.h>
1818

19+
#include "catalog/pg_type.h"
1920
#include "utils/builtins.h"
2021
#include "utils/inet.h"
2122

@@ -564,6 +565,55 @@ network_netmask(PG_FUNCTION_ARGS)
564565
PG_RETURN_INET_P(dst);
565566
}
566567

568+
569+
/*
570+
* Convert a value of a network datatype to an approximate scalar value.
571+
* This is used for estimating selectivities of inequality operators
572+
* involving network types.
573+
*
574+
* Currently, inet/cidr values are simply converted to the IPv4 address;
575+
* this will need more thought when IPv6 is supported too. MAC addresses
576+
* are converted to their numeric equivalent as well (OK since we have a
577+
* double to play in).
578+
*/
579+
double
580+
convert_network_to_scalar(Datum value, Oid typid)
581+
{
582+
switch (typid)
583+
{
584+
case INETOID:
585+
case CIDROID:
586+
{
587+
inet *ip = DatumGetInetP(value);
588+
589+
if (ip_family(ip) == AF_INET)
590+
return (double) ip_v4addr(ip);
591+
else
592+
/* Go for an IPV6 address here, before faulting out: */
593+
elog(ERROR, "unknown address family (%d)", ip_family(ip));
594+
break;
595+
}
596+
case MACADDROID:
597+
{
598+
macaddr *mac = DatumGetMacaddrP(value);
599+
double res;
600+
601+
res = (mac->a << 16) | (mac->b << 8) | (mac->c);
602+
res *= 256*256*256;
603+
res += (mac->d << 16) | (mac->e << 8) | (mac->f);
604+
return res;
605+
}
606+
}
607+
608+
/*
609+
* Can't get here unless someone tries to use scalarltsel/scalargtsel
610+
* on an operator with one network and one non-network operand.
611+
*/
612+
elog(ERROR, "convert_network_to_scalar: unsupported type %u", typid);
613+
return 0;
614+
}
615+
616+
567617
/*
568618
* Bitwise comparison for V4 addresses. Add V6 implementation!
569619
*/

src/backend/utils/adt/selfuncs.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.92 2001/06/05 05:26:04 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.93 2001/06/09 22:16:18 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1326,6 +1326,9 @@ icnlikejoinsel(PG_FUNCTION_ARGS)
13261326
* scale needed by scalarltsel()/scalargtsel().
13271327
* Returns "true" if successful.
13281328
*
1329+
* XXX this routine is a hack: ideally we should look up the conversion
1330+
* subroutines in pg_type.
1331+
*
13291332
* All numeric datatypes are simply converted to their equivalent
13301333
* "double" values. XXX what about NUMERIC values that are outside
13311334
* the range of "double"?
@@ -1398,10 +1401,22 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
13981401
case RELTIMEOID:
13991402
case TINTERVALOID:
14001403
case TIMEOID:
1404+
case TIMETZOID:
14011405
*scaledvalue = convert_timevalue_to_scalar(value, valuetypid);
14021406
*scaledlobound = convert_timevalue_to_scalar(lobound, boundstypid);
14031407
*scaledhibound = convert_timevalue_to_scalar(hibound, boundstypid);
14041408
return true;
1409+
1410+
/*
1411+
* Built-in network types
1412+
*/
1413+
case INETOID:
1414+
case CIDROID:
1415+
case MACADDROID:
1416+
*scaledvalue = convert_network_to_scalar(value, valuetypid);
1417+
*scaledlobound = convert_network_to_scalar(lobound, boundstypid);
1418+
*scaledhibound = convert_network_to_scalar(hibound, boundstypid);
1419+
return true;
14051420
}
14061421
/* Don't know how to convert */
14071422
return false;
@@ -1694,6 +1709,13 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
16941709
}
16951710
case TIMEOID:
16961711
return DatumGetTimeADT(value);
1712+
case TIMETZOID:
1713+
{
1714+
TimeTzADT *timetz = DatumGetTimeTzADTP(value);
1715+
1716+
/* use GMT-equivalent time */
1717+
return (double) (timetz->time + timetz->zone);
1718+
}
16971719
}
16981720

16991721
/*

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-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: builtins.h,v 1.149 2001/06/07 00:09:31 momjian Exp $
10+
* $Id: builtins.h,v 1.150 2001/06/09 22:16:17 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -514,6 +514,7 @@ extern Datum network_broadcast(PG_FUNCTION_ARGS);
514514
extern Datum network_host(PG_FUNCTION_ARGS);
515515
extern Datum network_show(PG_FUNCTION_ARGS);
516516
extern Datum network_abbrev(PG_FUNCTION_ARGS);
517+
extern double convert_network_to_scalar(Datum value, Oid typid);
517518

518519
/* mac.c */
519520
extern Datum macaddr_in(PG_FUNCTION_ARGS);

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