Would you modify this so it can go in /contrib or pgfoundry? Is there general interest for this?
--------------------------------------------------------------------------- Ilya A. Kovalenko wrote: > Greetings, > > I suggest function for "inet" increment w/ int8 (signed). > > FUNCTION inet_inc(int, int8) RETURNS inet > > Function, useful for making address pools (using also > existing "inet" compare functions to trap boundaries). > > Notes: > This version lets address wrap around 0-*ff boundary. > Uses couple of non-POSIX functions - betoh64() and htobe64() > Tested on i386 with OpenBSD 3.7 > PostgreSQL 8.0.2 > > ----------------------------------------------------- > #include <sys/types.h> > #include <sys/socket.h> > #include <netinet/in.h> > #include <arpa/inet.h> > > #include "postgres.h" /* general Postgres declarations */ > > #include "fmgr.h" /* for argument/result macros */ > #include "utils/inet.h" > > Datum inet_inc(PG_FUNCTION_ARGS); > > //------ stolen from backend/utils/adt/network.c -------- > > #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) > #define ip_maxbits(inetptr) \ > (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128) > > static int > ip_addrsize(inet *inetptr) > { > switch (ip_family(inetptr)) > { > case PGSQL_AF_INET: > return 4; > case PGSQL_AF_INET6: > return 16; > default: > return 0; > } > } > //------------------------------------------------------- > > PG_FUNCTION_INFO_V1(inet_inc); > > Datum > inet_inc(PG_FUNCTION_ARGS) > { > inet *src = PG_GETARG_INET_P(0); > int64 arg = PG_GETARG_INT64(1); > inet *dst; > uint64 wsp; > > // allocate destination structure > dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct)); > > // copy to destination > *((inet_struct *)VARDATA(dst)) = *((inet_struct *)VARDATA(src)); > > if (ip_family(dst) == PGSQL_AF_INET) > { > // Increment v4 address w/ item truncated to 32 bits > *((uint32*)(ip_addr(dst))) = > htonl(ntohl(*((int32*)(ip_addr(dst)))) + (int32)arg); > } > else > { > // Increment v6 address low qword (store to workspace) > wsp = htobe64(betoh64(*((int64*)(ip_addr(dst) + 8))) + arg); > *((uint64*)(ip_addr(dst) + 8)) = wsp; > > // Carry/borrow high qword > if ( arg > 0 && wsp < *((uint64*)(ip_addr(src) + 8)) ) > { *((int64*)(ip_addr(dst))) = > htobe64(betoh64(*((int64*)(ip_addr(dst)))) + 1); > } > else > if ( arg < 0 && wsp > *((uint64*)(ip_addr(src) + 8)) ) > { *((int64*)(ip_addr(dst))) = > htobe64(betoh64(*((int64*)(ip_addr(dst)))) - 1); > } > } > > // Return result > VARATT_SIZEP(dst) = VARHDRSZ > + ((char *) ip_addr(dst) - (char *) VARDATA(dst)) > + ip_addrsize(dst); > > PG_RETURN_INET_P(dst); > > } > ----------------------------------------------------- > > Thank you > > Ilya A. Kovalenko (mailto:[EMAIL PROTECTED]) > SpecialEQ SW section > JSC Oganer-Service > > P.S. Treat as Public Domain > > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Don't 'kill -9' the postmaster > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 ---------------------------(end of broadcast)--------------------------- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly