From: | "Stephen R(dot) van den Berg" <srb(at)cuci(dot)nl> |
---|---|
To: | pgsql-patches(at)postgresql(dot)org |
Subject: | contrib/xinetops for 8.1 "patch" |
Date: | 2005-11-13 11:52:28 |
Message-ID: | 20051113115228.GA22593@cuci.nl |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-patches |
I've been meaning to send it in for a while now, IMHO it could be
made part of the main distribution as well, but contrib is fine
if not everyone likes it.
I included the source in patch-format, since I didn't feel comfortable
attaching a tar.gz file on this list.
Below is an excerpt from the included README:
-------------------------------- cut here ---------------------------------
inet extended operations
~~~~~~~~~~~~~~~~~~~~~~~~
This directory contains definitions for extended operators on the
inet data type.
Operators available are:
~ & | + -
It supports the "natural" arithmetic with IP addresses and integers.
It is useful for applications which have to hand out and administer
ranges of IP-addresses (like a Radius or DHCP server).
Copyright (c) 2003-2006, Stephen R. van den Berg, The Netherlands.
<srb(at)cuci(dot)nl>
This module is distributed under the same BSD license as PostgreSQL.
-------------------------------- cut here ---------------------------------
diff -ur xinetops.old/Makefile xinetops/Makefile
--- xinetops.old/Makefile 2005-11-13 12:36:39.000000000 +0100
+++ xinetops/Makefile 2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,11 @@
+# $Id: Makefile 523 2005-11-13 11:29:44Z srb $
+
+subdir = contrib/xinetops
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+
+MODULES = xinetops
+DATA_built = xinetops.sql
+DOCS = README.xinetops
+
+include $(top_srcdir)/contrib/contrib-global.mk
diff -ur xinetops.old/README.xinetops xinetops/README.xinetops
--- xinetops.old/README.xinetops 2005-11-13 12:36:39.000000000 +0100
+++ xinetops/README.xinetops 2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,19 @@
+
+inet extended operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+This directory contains definitions for extended operators on the
+inet data type.
+
+Operators available are:
+
+ ~ & | + -
+
+It supports the "natural" arithmetic with IP addresses and integers.
+It is useful for applications which have to hand out and administer
+ranges of IP-addresses (like a Radius or DHCP server).
+
+Copyright (c) 2003-2006, Stephen R. van den Berg, The Netherlands.
+ <srb(at)cuci(dot)nl>
+
+This module is distributed under the same BSD license as PostgreSQL.
diff -ur xinetops.old/xinetops.c xinetops/xinetops.c
--- xinetops.old/xinetops.c 2005-11-13 12:36:39.000000000 +0100
+++ xinetops/xinetops.c 2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,254 @@
+/*
+ * PostgreSQL type definitions for extended inet operations.
+ * Copyright (c) 2003-2006, S.R. van den Berg, The Netherlands
+ * <srb(at)cuci(dot)nl>
+ *
+ * This module is distributed under the same BSD license as PostgreSQL.
+ *
+ * $Id: xinetops.c 524 2005-11-13 11:44:43Z srb $
+ */
+
+#include "postgres.h"
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "catalog/pg_type.h"
+#include "utils/builtins.h"
+#include "utils/inet.h"
+
+#define ip_family(inetptr) \
+ (((inet_struct *)VARDATA(inetptr))->family)
+
+#define ip_bits(inetptr) \
+ (((inet_struct *)VARDATA(inetptr))->bits)
+
+#define ip_type(inetptr) \
+ (((inet_struct *)VARDATA(inetptr))->type)
+
+#define ip_addr(inetptr) \
+ (((inet_struct *)VARDATA(inetptr))->ipaddr)
+
+static int
+ip_addrsize(inet *inetptr)
+{
+ switch (ip_family(inetptr))
+ {
+ case PGSQL_AF_INET:
+ return 4;
+ case PGSQL_AF_INET6:
+ return 16;
+ default:
+ return -1;
+ }
+}
+
+
+PG_FUNCTION_INFO_V1(inet_not);
+
+Datum
+inet_not(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ inet *dst;
+
+ dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+ /* make sure any unused bits are zeroed */
+ MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
+
+ {
+ int nb = ip_addrsize(ip);
+ unsigned char*pip = ip_addr(ip);
+ unsigned char*pdst = ip_addr(dst);
+
+ while (nb-->0)
+ {
+ pdst[nb] = pip[nb];
+ }
+ }
+ ip_bits(dst) = ip_bits(ip);
+
+ ip_family(dst) = ip_family(ip);
+ ip_type(dst) = 0;
+ VARATT_SIZEP(dst) = VARHDRSZ
+ + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ + ip_addrsize(dst);
+
+ PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_or);
+
+Datum
+inet_or(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ inet *ip2 = PG_GETARG_INET_P(1);
+ inet *dst;
+
+ dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+ /* make sure any unused bits are zeroed */
+ MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
+
+ if (ip_family(ip) != ip_family(ip2))
+ elog(ERROR, "mismatch in address family (%d)!=(%d)",
+ ip_family(ip), ip_family(ip2));
+ else
+ {
+ int nb = ip_addrsize(ip);
+ unsigned char*pip = ip_addr(ip);
+ unsigned char*pip2 = ip_addr(ip2);
+ unsigned char*pdst = ip_addr(dst);
+
+ while (nb-->0)
+ {
+ pdst[nb] = pip[nb]|pip2[nb];
+ }
+ }
+ ip_bits(dst) = ip_bits(ip);
+ if (ip_bits(dst)<ip_bits(ip2))
+ ip_bits(dst) = ip_bits(ip2);
+
+ ip_family(dst) = ip_family(ip);
+ ip_type(dst) = 0;
+ VARATT_SIZEP(dst) = VARHDRSZ
+ + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ + ip_addrsize(dst);
+
+ PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_and);
+
+Datum
+inet_and(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ inet *ip2 = PG_GETARG_INET_P(1);
+ inet *dst;
+
+ dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+ /* make sure any unused bits are zeroed */
+ MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
+
+ if (ip_family(ip) != ip_family(ip2))
+ elog(ERROR, "mismatch in address family (%d)!=(%d)",
+ ip_family(ip), ip_family(ip2));
+ else
+ {
+ int nb = ip_addrsize(ip);
+ unsigned char*pip = ip_addr(ip);
+ unsigned char*pip2 = ip_addr(ip2);
+ unsigned char*pdst = ip_addr(dst);
+
+ while (nb-->0)
+ {
+ pdst[nb] = pip[nb]&pip2[nb];
+ }
+ }
+ ip_bits(dst) = ip_bits(ip);
+ if (ip_bits(dst)<ip_bits(ip2))
+ ip_bits(dst) = ip_bits(ip2);
+
+ ip_family(dst) = ip_family(ip);
+ ip_type(dst) = 0;
+ VARATT_SIZEP(dst) = VARHDRSZ
+ + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ + ip_addrsize(dst);
+
+ PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_min);
+
+Datum
+inet_min(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ inet *ip2 = PG_GETARG_INET_P(1);
+ int res = 0;
+
+ if (ip_family(ip) != ip_family(ip2))
+ elog(ERROR, "mismatch in address family (%d)!=(%d)",
+ ip_family(ip), ip_family(ip2));
+ else
+ {
+ int nb = ip_addrsize(ip);
+ unsigned char*pip = ip_addr(ip);
+ unsigned char*pip2 = ip_addr(ip2);
+ unsigned sh = 1;
+
+ while (nb-->0)
+ {
+ res += sh*(pip[nb]-pip2[nb]);
+ sh <<= 8;
+ }
+ }
+
+ PG_RETURN_INT32(res);
+}
+
+static Datum
+i_inet_plusi(inet *ip, int iarg)
+{
+ inet *dst;
+
+ dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+ /* make sure any unused bits are zeroed */
+ MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
+
+ {
+ int nb = ip_addrsize(ip);
+ unsigned char*pip = ip_addr(ip);
+ unsigned char*pdst = ip_addr(dst);
+ int carry = 0;
+
+ while (nb-->0)
+ {
+ pdst[nb] = carry = pip[nb]+iarg+carry;
+ iarg >>=8;
+ carry >>=8;
+ }
+ }
+ ip_bits(dst) = ip_bits(ip);
+
+ ip_family(dst) = ip_family(ip);
+ ip_type(dst) = 0;
+ VARATT_SIZEP(dst) = VARHDRSZ
+ + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ + ip_addrsize(dst);
+
+ PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_plusi);
+
+Datum
+inet_plusi(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ int iarg = PG_GETARG_INT32(1);
+ return i_inet_plusi(ip,iarg);
+}
+
+PG_FUNCTION_INFO_V1(inet_iplus);
+
+Datum
+inet_iplus(PG_FUNCTION_ARGS)
+{
+ int iarg = PG_GETARG_INT32(0);
+ inet *ip = PG_GETARG_INET_P(1);
+ return i_inet_plusi(ip,iarg);
+}
+
+PG_FUNCTION_INFO_V1(inet_mini);
+
+Datum
+inet_mini(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ int iarg = PG_GETARG_INT32(1);
+ return i_inet_plusi(ip,-iarg);
+}
diff -ur xinetops.old/xinetops.sql.in xinetops/xinetops.sql.in
--- xinetops.old/xinetops.sql.in 2005-11-13 12:36:39.000000000 +0100
+++ xinetops/xinetops.sql.in 2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,104 @@
+--
+-- PostgreSQL type definitions for extended inet operations.
+-- Copyright (c) 2003-2006, S.R. van den Berg, The Netherlands
+-- <srb(at)cuci(dot)nl>
+--
+-- This module is distributed under the same BSD license as PostgreSQL.
+--
+-- $Id: xinetops.sql.in 524 2005-11-13 11:44:43Z srb $
+--
+
+-- Adjust this setting to control where the objects get created.
+SET search_path = public;
+
+SET autocommit TO 'on';
+
+--
+-- The various functions doing the work
+--
+
+CREATE FUNCTION inet_not(inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_or(inet, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_and(inet, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_plusi(inet, int)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_iplus(int, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_mini(inet, int)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_min(inet, inet)
+RETURNS int
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+--
+-- Now the operators.
+--
+
+CREATE OPERATOR ~ (
+ RIGHTARG = inet,
+ PROCEDURE = inet_not
+);
+
+CREATE OPERATOR | (
+ LEFTARG = inet,
+ RIGHTARG = inet,
+ COMMUTATOR = |,
+ PROCEDURE = inet_or
+);
+
+CREATE OPERATOR & (
+ LEFTARG = inet,
+ RIGHTARG = inet,
+ COMMUTATOR = &,
+ PROCEDURE = inet_and
+);
+
+CREATE OPERATOR + (
+ LEFTARG = inet,
+ RIGHTARG = int,
+ COMMUTATOR = +,
+ PROCEDURE = inet_plusi
+);
+
+CREATE OPERATOR + (
+ LEFTARG = int,
+ RIGHTARG = inet,
+ COMMUTATOR = +,
+ PROCEDURE = inet_iplus
+);
+
+CREATE OPERATOR - (
+ LEFTARG = inet,
+ RIGHTARG = int,
+ COMMUTATOR = -,
+ PROCEDURE = inet_mini
+);
+
+CREATE OPERATOR - (
+ LEFTARG = inet,
+ RIGHTARG = inet,
+ COMMUTATOR = -,
+ PROCEDURE = inet_min
+);
--
Sincerely, srb(at)cuci(dot)nl
Stephen R. van den Berg (AKA BuGless).
Skiing beyond this point may result in death and/or loss of skiing privileges.
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2005-11-13 15:28:28 | Re: Multi-table-unique-constraint |
Previous Message | Christopher Kings-Lynne | 2005-11-13 06:15:14 | Re: Multi-table-unique-constraint |