Skip site navigation (1) Skip section navigation (2)

contrib/xinetops for 8.1 "patch"

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 (view raw or flat)
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.

Responses

pgsql-patches by date

Next:From: Tom LaneDate: 2005-11-13 15:28:28
Subject: Re: Multi-table-unique-constraint
Previous:From: Christopher Kings-LynneDate: 2005-11-13 06:15:14
Subject: Re: Multi-table-unique-constraint

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group