BUG #9652: inet types don't support min/max

Started by Nonamealmost 12 years ago30 messages
#1Noname
darius@dons.net.au

The following bug has been logged on the website:

Bug reference: 9652
Logged by: Daniel O'Connor
Email address: darius@dons.net.au
PostgreSQL version: 9.2.7
Operating system: OSX Mavericks
Description:

reclog=> select * from foo;
bar
---------
1.2.3.4
(1 row)

reclog=> select min(bar) from foo;
ERROR: function min(inet) does not exist
LINE 1: select min(bar) from foo;
^
HINT: No function matches the given name and argument types. You might need
to add explicit type casts.

This is surprising to me since the inet type is ordered, hence min/max are
possible.

You also can't cast an inet to an integer or bigint although I guess that
isn't too surprising since v6 addrs are larger than bigints.

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#2Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Noname (#1)
1 attachment(s)
Re: BUG #9652: inet types don't support min/max

On Fri, Mar 21, 2014 at 5:17 PM, <darius@dons.net.au> wrote:

The following bug has been logged on the website:
reclog=> select * from foo;
bar
---------
1.2.3.4
(1 row)

reclog=> select min(bar) from foo;
ERROR: function min(inet) does not exist
LINE 1: select min(bar) from foo;
^
HINT: No function matches the given name and argument types. You might need
to add explicit type casts.

This is surprising to me since the inet type is ordered, hence min/max are
possible.

In the code, some comparison logic for the inet datatypes already present.
With those I thought it is easy to support the min and max aggregates also.
So I modified the code to support the aggregate functions of min and
max by using
the already existing inet comparison logic. Is there anything I am missing?

postgres=# create table tbl(f inet);
CREATE TABLE
postgres=# insert into tbl values('1.2.3.5');
INSERT 0 1
postgres=# insert into tbl values('1.2.3.4');
INSERT 0 1
postgres=# select min(f) from tbl;
min
---------
1.2.3.4
(1 row)

postgres=# select max(f) from tbl;
max
---------
1.2.3.5
(1 row)

Patch is attached.
This is the first time I am touching this area so please let me know
your suggestions.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg.patchapplication/octet-stream; name=inet_agg.patchDownload
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 520,525 **** network_ne(PG_FUNCTION_ARGS)
--- 520,548 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 140,145 **** DATA(insert ( 2050	n 0 array_larger	-				1073	2277	0	_null_ ));
--- 140,146 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				1060	1042	0	_null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				2800	27		0	_null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				3519	3500	0	_null_ ));
+ DATA(insert ( 3206	n 0 network_larger	-				1205	869		0	_null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				412		20		0	_null_ ));
***************
*** 162,167 **** DATA(insert ( 2051	n 0 array_smaller	-				1072	2277	0	_null_ ));
--- 163,169 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				1058	1042	0	_null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				2799	27		0	_null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				3518	3500	0	_null_ ));
+ DATA(insert ( 3207	n 0 network_smaller	-				1203	869		0	_null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				0		20		0	"0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2112,2117 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2112,2119 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3208 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DATA(insert OID = 3209 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3114,3119 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3116,3123 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3206 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3153,3158 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3157,3164 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3207 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 897,902 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 897,904 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
#3Keith Fiske
keith@omniti.com
In reply to: Haribabu Kommi (#2)
Re: BUG #9652: inet types don't support min/max

On Sun, Mar 23, 2014 at 10:42 PM, Haribabu Kommi
<kommi.haribabu@gmail.com>wrote:

On Fri, Mar 21, 2014 at 5:17 PM, <darius@dons.net.au> wrote:

The following bug has been logged on the website:
reclog=> select * from foo;
bar
---------
1.2.3.4
(1 row)

reclog=> select min(bar) from foo;
ERROR: function min(inet) does not exist
LINE 1: select min(bar) from foo;
^
HINT: No function matches the given name and argument types. You might

need

to add explicit type casts.

This is surprising to me since the inet type is ordered, hence min/max

are

possible.

In the code, some comparison logic for the inet datatypes already present.
With those I thought it is easy to support the min and max aggregates also.
So I modified the code to support the aggregate functions of min and
max by using
the already existing inet comparison logic. Is there anything I am missing?

postgres=# create table tbl(f inet);
CREATE TABLE
postgres=# insert into tbl values('1.2.3.5');
INSERT 0 1
postgres=# insert into tbl values('1.2.3.4');
INSERT 0 1
postgres=# select min(f) from tbl;
min
---------
1.2.3.4
(1 row)

postgres=# select max(f) from tbl;
max
---------
1.2.3.5
(1 row)

Patch is attached.
This is the first time I am touching this area so please let me know
your suggestions.

Regards,
Hari Babu
Fujitsu Australia

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

This is my first time reviewing a patch, so apologies if I've missed
something in the process.

I tried applying your patch to the current git HEAD as of 2014-05-27 and
the portion against pg_aggregate.h fails

postgres $ patch -Np1 -i ../inet_agg.patch
patching file src/backend/utils/adt/network.c
Hunk #1 succeeded at 471 (offset -49 lines).
patching file src/include/catalog/pg_aggregate.h
Hunk #1 FAILED at 140.
Hunk #2 FAILED at 162.
2 out of 2 hunks FAILED -- saving rejects to file
src/include/catalog/pg_aggregate.h.rej
patching file src/include/catalog/pg_proc.h
Hunk #1 succeeded at 2120 (offset 8 lines).
Hunk #2 succeeded at 3163 (offset 47 lines).
Hunk #3 succeeded at 3204 (offset 47 lines).
patching file src/include/utils/builtins.h
Hunk #1 succeeded at 907 (offset 10 lines).

Looks like starting around April 12th some additional changes were made to
the DATA lines in this file that have to be accounted for.

https://github.com/postgres/postgres/commits/master/src/include/catalog/pg_aggregate.h

Don't have the knowledge of how to fix this for the new format, but thought
I'd at least try to apply the patch and see if it works.

--
Keith Fiske
Database Administrator
OmniTI Computer Consulting, Inc.
http://www.keithf4.com

#4Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Keith Fiske (#3)
1 attachment(s)
Re: BUG #9652: inet types don't support min/max

On Thu, May 29, 2014 at 3:28 AM, Keith Fiske <keith@omniti.com> wrote:

On Sun, Mar 23, 2014 at 10:42 PM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

On Fri, Mar 21, 2014 at 5:17 PM, <darius@dons.net.au> wrote:

The following bug has been logged on the website:
reclog=> select * from foo;
bar
---------
1.2.3.4
(1 row)

reclog=> select min(bar) from foo;
ERROR: function min(inet) does not exist
LINE 1: select min(bar) from foo;
^
HINT: No function matches the given name and argument types. You might
need
to add explicit type casts.

This is surprising to me since the inet type is ordered, hence min/max
are
possible.

In the code, some comparison logic for the inet datatypes already present.
With those I thought it is easy to support the min and max aggregates
also.
So I modified the code to support the aggregate functions of min and
max by using
the already existing inet comparison logic. Is there anything I am
missing?

postgres=# create table tbl(f inet);
CREATE TABLE
postgres=# insert into tbl values('1.2.3.5');
INSERT 0 1
postgres=# insert into tbl values('1.2.3.4');
INSERT 0 1
postgres=# select min(f) from tbl;
min
---------
1.2.3.4
(1 row)

postgres=# select max(f) from tbl;
max
---------
1.2.3.5
(1 row)

Patch is attached.

This is my first time reviewing a patch, so apologies if I've missed
something in the process.

I tried applying your patch to the current git HEAD as of 2014-05-27 and the
portion against pg_aggregate.h fails

postgres $ patch -Np1 -i ../inet_agg.patch
patching file src/backend/utils/adt/network.c
Hunk #1 succeeded at 471 (offset -49 lines).
patching file src/include/catalog/pg_aggregate.h
Hunk #1 FAILED at 140.
Hunk #2 FAILED at 162.
2 out of 2 hunks FAILED -- saving rejects to file
src/include/catalog/pg_aggregate.h.rej
patching file src/include/catalog/pg_proc.h
Hunk #1 succeeded at 2120 (offset 8 lines).
Hunk #2 succeeded at 3163 (offset 47 lines).
Hunk #3 succeeded at 3204 (offset 47 lines).
patching file src/include/utils/builtins.h
Hunk #1 succeeded at 907 (offset 10 lines).

Looks like starting around April 12th some additional changes were made to
the DATA lines in this file that have to be accounted for.

https://github.com/postgres/postgres/commits/master/src/include/catalog/pg_aggregate.h

Don't have the knowledge of how to fix this for the new format, but thought
I'd at least try to apply the patch and see if it works.

Thanks for verifying the patch. Please find the re-based patch
attached in the mail.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v2.patchapplication/octet-stream; name=inet_agg_v2.patchDownload
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3251	n 0 network_larger	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3252	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3253 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
+ DESCR("larger of two network types");
+ DATA(insert OID = 3254 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3251 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3252 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/create_function_3.out
--- b/src/test/regress/expected/create_function_3.out
***************
*** 153,389 **** RESET SESSION AUTHORIZATION;
  SELECT proname, prorettype::regtype, proargtypes::regtype[]
         FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
         WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
!     proname     | prorettype |                             proargtypes                             
! ----------------+------------+---------------------------------------------------------------------
!  abstimeeq      | boolean    | [0:1]={abstime,abstime}
!  abstimege      | boolean    | [0:1]={abstime,abstime}
!  abstimegt      | boolean    | [0:1]={abstime,abstime}
!  abstimele      | boolean    | [0:1]={abstime,abstime}
!  abstimelt      | boolean    | [0:1]={abstime,abstime}
!  abstimene      | boolean    | [0:1]={abstime,abstime}
!  biteq          | boolean    | [0:1]={bit,bit}
!  bitge          | boolean    | [0:1]={bit,bit}
!  bitgt          | boolean    | [0:1]={bit,bit}
!  bitle          | boolean    | [0:1]={bit,bit}
!  bitlt          | boolean    | [0:1]={bit,bit}
!  bitne          | boolean    | [0:1]={bit,bit}
!  booleq         | boolean    | [0:1]={boolean,boolean}
!  boolge         | boolean    | [0:1]={boolean,boolean}
!  boolgt         | boolean    | [0:1]={boolean,boolean}
!  boolle         | boolean    | [0:1]={boolean,boolean}
!  boollt         | boolean    | [0:1]={boolean,boolean}
!  boolne         | boolean    | [0:1]={boolean,boolean}
!  bpchareq       | boolean    | [0:1]={character,character}
!  bpcharne       | boolean    | [0:1]={character,character}
!  byteaeq        | boolean    | [0:1]={bytea,bytea}
!  byteage        | boolean    | [0:1]={bytea,bytea}
!  byteagt        | boolean    | [0:1]={bytea,bytea}
!  byteale        | boolean    | [0:1]={bytea,bytea}
!  bytealt        | boolean    | [0:1]={bytea,bytea}
!  byteane        | boolean    | [0:1]={bytea,bytea}
!  cash_eq        | boolean    | [0:1]={money,money}
!  cash_ge        | boolean    | [0:1]={money,money}
!  cash_gt        | boolean    | [0:1]={money,money}
!  cash_le        | boolean    | [0:1]={money,money}
!  cash_lt        | boolean    | [0:1]={money,money}
!  cash_ne        | boolean    | [0:1]={money,money}
!  chareq         | boolean    | [0:1]={"\"char\"","\"char\""}
!  charge         | boolean    | [0:1]={"\"char\"","\"char\""}
!  chargt         | boolean    | [0:1]={"\"char\"","\"char\""}
!  charle         | boolean    | [0:1]={"\"char\"","\"char\""}
!  charlt         | boolean    | [0:1]={"\"char\"","\"char\""}
!  charne         | boolean    | [0:1]={"\"char\"","\"char\""}
!  cideq          | boolean    | [0:1]={cid,cid}
!  circle_eq      | boolean    | [0:1]={circle,circle}
!  circle_ge      | boolean    | [0:1]={circle,circle}
!  circle_gt      | boolean    | [0:1]={circle,circle}
!  circle_le      | boolean    | [0:1]={circle,circle}
!  circle_lt      | boolean    | [0:1]={circle,circle}
!  circle_ne      | boolean    | [0:1]={circle,circle}
!  date_eq        | boolean    | [0:1]={date,date}
!  date_ge        | boolean    | [0:1]={date,date}
!  date_gt        | boolean    | [0:1]={date,date}
!  date_le        | boolean    | [0:1]={date,date}
!  date_lt        | boolean    | [0:1]={date,date}
!  date_ne        | boolean    | [0:1]={date,date}
!  float48eq      | boolean    | [0:1]={real,"double precision"}
!  float48ge      | boolean    | [0:1]={real,"double precision"}
!  float48gt      | boolean    | [0:1]={real,"double precision"}
!  float48le      | boolean    | [0:1]={real,"double precision"}
!  float48lt      | boolean    | [0:1]={real,"double precision"}
!  float48ne      | boolean    | [0:1]={real,"double precision"}
!  float4eq       | boolean    | [0:1]={real,real}
!  float4ge       | boolean    | [0:1]={real,real}
!  float4gt       | boolean    | [0:1]={real,real}
!  float4le       | boolean    | [0:1]={real,real}
!  float4lt       | boolean    | [0:1]={real,real}
!  float4ne       | boolean    | [0:1]={real,real}
!  float84eq      | boolean    | [0:1]={"double precision",real}
!  float84ge      | boolean    | [0:1]={"double precision",real}
!  float84gt      | boolean    | [0:1]={"double precision",real}
!  float84le      | boolean    | [0:1]={"double precision",real}
!  float84lt      | boolean    | [0:1]={"double precision",real}
!  float84ne      | boolean    | [0:1]={"double precision",real}
!  float8eq       | boolean    | [0:1]={"double precision","double precision"}
!  float8ge       | boolean    | [0:1]={"double precision","double precision"}
!  float8gt       | boolean    | [0:1]={"double precision","double precision"}
!  float8le       | boolean    | [0:1]={"double precision","double precision"}
!  float8lt       | boolean    | [0:1]={"double precision","double precision"}
!  float8ne       | boolean    | [0:1]={"double precision","double precision"}
!  int24eq        | boolean    | [0:1]={smallint,integer}
!  int24ge        | boolean    | [0:1]={smallint,integer}
!  int24gt        | boolean    | [0:1]={smallint,integer}
!  int24le        | boolean    | [0:1]={smallint,integer}
!  int24lt        | boolean    | [0:1]={smallint,integer}
!  int24ne        | boolean    | [0:1]={smallint,integer}
!  int28eq        | boolean    | [0:1]={smallint,bigint}
!  int28ge        | boolean    | [0:1]={smallint,bigint}
!  int28gt        | boolean    | [0:1]={smallint,bigint}
!  int28le        | boolean    | [0:1]={smallint,bigint}
!  int28lt        | boolean    | [0:1]={smallint,bigint}
!  int28ne        | boolean    | [0:1]={smallint,bigint}
!  int2eq         | boolean    | [0:1]={smallint,smallint}
!  int2ge         | boolean    | [0:1]={smallint,smallint}
!  int2gt         | boolean    | [0:1]={smallint,smallint}
!  int2le         | boolean    | [0:1]={smallint,smallint}
!  int2lt         | boolean    | [0:1]={smallint,smallint}
!  int2ne         | boolean    | [0:1]={smallint,smallint}
!  int42eq        | boolean    | [0:1]={integer,smallint}
!  int42ge        | boolean    | [0:1]={integer,smallint}
!  int42gt        | boolean    | [0:1]={integer,smallint}
!  int42le        | boolean    | [0:1]={integer,smallint}
!  int42lt        | boolean    | [0:1]={integer,smallint}
!  int42ne        | boolean    | [0:1]={integer,smallint}
!  int48eq        | boolean    | [0:1]={integer,bigint}
!  int48ge        | boolean    | [0:1]={integer,bigint}
!  int48gt        | boolean    | [0:1]={integer,bigint}
!  int48le        | boolean    | [0:1]={integer,bigint}
!  int48lt        | boolean    | [0:1]={integer,bigint}
!  int48ne        | boolean    | [0:1]={integer,bigint}
!  int4eq         | boolean    | [0:1]={integer,integer}
!  int4ge         | boolean    | [0:1]={integer,integer}
!  int4gt         | boolean    | [0:1]={integer,integer}
!  int4le         | boolean    | [0:1]={integer,integer}
!  int4lt         | boolean    | [0:1]={integer,integer}
!  int4ne         | boolean    | [0:1]={integer,integer}
!  int82eq        | boolean    | [0:1]={bigint,smallint}
!  int82ge        | boolean    | [0:1]={bigint,smallint}
!  int82gt        | boolean    | [0:1]={bigint,smallint}
!  int82le        | boolean    | [0:1]={bigint,smallint}
!  int82lt        | boolean    | [0:1]={bigint,smallint}
!  int82ne        | boolean    | [0:1]={bigint,smallint}
!  int84eq        | boolean    | [0:1]={bigint,integer}
!  int84ge        | boolean    | [0:1]={bigint,integer}
!  int84gt        | boolean    | [0:1]={bigint,integer}
!  int84le        | boolean    | [0:1]={bigint,integer}
!  int84lt        | boolean    | [0:1]={bigint,integer}
!  int84ne        | boolean    | [0:1]={bigint,integer}
!  int8eq         | boolean    | [0:1]={bigint,bigint}
!  int8ge         | boolean    | [0:1]={bigint,bigint}
!  int8gt         | boolean    | [0:1]={bigint,bigint}
!  int8le         | boolean    | [0:1]={bigint,bigint}
!  int8lt         | boolean    | [0:1]={bigint,bigint}
!  int8ne         | boolean    | [0:1]={bigint,bigint}
!  interval_eq    | boolean    | [0:1]={interval,interval}
!  interval_ge    | boolean    | [0:1]={interval,interval}
!  interval_gt    | boolean    | [0:1]={interval,interval}
!  interval_le    | boolean    | [0:1]={interval,interval}
!  interval_lt    | boolean    | [0:1]={interval,interval}
!  interval_ne    | boolean    | [0:1]={interval,interval}
!  lseg_eq        | boolean    | [0:1]={lseg,lseg}
!  lseg_ge        | boolean    | [0:1]={lseg,lseg}
!  lseg_gt        | boolean    | [0:1]={lseg,lseg}
!  lseg_le        | boolean    | [0:1]={lseg,lseg}
!  lseg_lt        | boolean    | [0:1]={lseg,lseg}
!  lseg_ne        | boolean    | [0:1]={lseg,lseg}
!  macaddr_eq     | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_ge     | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_gt     | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_le     | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_lt     | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_ne     | boolean    | [0:1]={macaddr,macaddr}
!  nameeq         | boolean    | [0:1]={name,name}
!  namege         | boolean    | [0:1]={name,name}
!  namegt         | boolean    | [0:1]={name,name}
!  namele         | boolean    | [0:1]={name,name}
!  namelt         | boolean    | [0:1]={name,name}
!  namene         | boolean    | [0:1]={name,name}
!  network_eq     | boolean    | [0:1]={inet,inet}
!  network_ge     | boolean    | [0:1]={inet,inet}
!  network_gt     | boolean    | [0:1]={inet,inet}
!  network_le     | boolean    | [0:1]={inet,inet}
!  network_lt     | boolean    | [0:1]={inet,inet}
!  network_ne     | boolean    | [0:1]={inet,inet}
!  oideq          | boolean    | [0:1]={oid,oid}
!  oidge          | boolean    | [0:1]={oid,oid}
!  oidgt          | boolean    | [0:1]={oid,oid}
!  oidle          | boolean    | [0:1]={oid,oid}
!  oidlt          | boolean    | [0:1]={oid,oid}
!  oidne          | boolean    | [0:1]={oid,oid}
!  reltimeeq      | boolean    | [0:1]={reltime,reltime}
!  reltimege      | boolean    | [0:1]={reltime,reltime}
!  reltimegt      | boolean    | [0:1]={reltime,reltime}
!  reltimele      | boolean    | [0:1]={reltime,reltime}
!  reltimelt      | boolean    | [0:1]={reltime,reltime}
!  reltimene      | boolean    | [0:1]={reltime,reltime}
!  texteq         | boolean    | [0:1]={text,text}
!  textne         | boolean    | [0:1]={text,text}
!  tideq          | boolean    | [0:1]={tid,tid}
!  tidge          | boolean    | [0:1]={tid,tid}
!  tidgt          | boolean    | [0:1]={tid,tid}
!  tidle          | boolean    | [0:1]={tid,tid}
!  tidlt          | boolean    | [0:1]={tid,tid}
!  tidne          | boolean    | [0:1]={tid,tid}
!  time_eq        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_ge        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_gt        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_le        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_lt        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_ne        | boolean    | [0:1]={"time without time zone","time without time zone"}
!  timestamp_eq   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_ge   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_gt   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_le   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_lt   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_ne   | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamptz_eq | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_ge | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_gt | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_le | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_lt | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_ne | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timetz_eq      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_ge      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_gt      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_le      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_lt      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_ne      | boolean    | [0:1]={"time with time zone","time with time zone"}
!  tintervaleq    | boolean    | [0:1]={tinterval,tinterval}
!  tintervalge    | boolean    | [0:1]={tinterval,tinterval}
!  tintervalgt    | boolean    | [0:1]={tinterval,tinterval}
!  tintervalle    | boolean    | [0:1]={tinterval,tinterval}
!  tintervalleneq | boolean    | [0:1]={tinterval,reltime}
!  tintervallenge | boolean    | [0:1]={tinterval,reltime}
!  tintervallengt | boolean    | [0:1]={tinterval,reltime}
!  tintervallenle | boolean    | [0:1]={tinterval,reltime}
!  tintervallenlt | boolean    | [0:1]={tinterval,reltime}
!  tintervallenne | boolean    | [0:1]={tinterval,reltime}
!  tintervallt    | boolean    | [0:1]={tinterval,tinterval}
!  tintervalne    | boolean    | [0:1]={tinterval,tinterval}
!  uuid_eq        | boolean    | [0:1]={uuid,uuid}
!  uuid_ge        | boolean    | [0:1]={uuid,uuid}
!  uuid_gt        | boolean    | [0:1]={uuid,uuid}
!  uuid_le        | boolean    | [0:1]={uuid,uuid}
!  uuid_lt        | boolean    | [0:1]={uuid,uuid}
!  uuid_ne        | boolean    | [0:1]={uuid,uuid}
!  varbiteq       | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitge       | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitgt       | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitle       | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitlt       | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitne       | boolean    | [0:1]={"bit varying","bit varying"}
!  xideq          | boolean    | [0:1]={xid,xid}
! (228 rows)
  
  --
  -- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
--- 153,391 ----
  SELECT proname, prorettype::regtype, proargtypes::regtype[]
         FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
         WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
!      proname     | prorettype |                             proargtypes                             
! -----------------+------------+---------------------------------------------------------------------
!  abstimeeq       | boolean    | [0:1]={abstime,abstime}
!  abstimege       | boolean    | [0:1]={abstime,abstime}
!  abstimegt       | boolean    | [0:1]={abstime,abstime}
!  abstimele       | boolean    | [0:1]={abstime,abstime}
!  abstimelt       | boolean    | [0:1]={abstime,abstime}
!  abstimene       | boolean    | [0:1]={abstime,abstime}
!  biteq           | boolean    | [0:1]={bit,bit}
!  bitge           | boolean    | [0:1]={bit,bit}
!  bitgt           | boolean    | [0:1]={bit,bit}
!  bitle           | boolean    | [0:1]={bit,bit}
!  bitlt           | boolean    | [0:1]={bit,bit}
!  bitne           | boolean    | [0:1]={bit,bit}
!  booleq          | boolean    | [0:1]={boolean,boolean}
!  boolge          | boolean    | [0:1]={boolean,boolean}
!  boolgt          | boolean    | [0:1]={boolean,boolean}
!  boolle          | boolean    | [0:1]={boolean,boolean}
!  boollt          | boolean    | [0:1]={boolean,boolean}
!  boolne          | boolean    | [0:1]={boolean,boolean}
!  bpchareq        | boolean    | [0:1]={character,character}
!  bpcharne        | boolean    | [0:1]={character,character}
!  byteaeq         | boolean    | [0:1]={bytea,bytea}
!  byteage         | boolean    | [0:1]={bytea,bytea}
!  byteagt         | boolean    | [0:1]={bytea,bytea}
!  byteale         | boolean    | [0:1]={bytea,bytea}
!  bytealt         | boolean    | [0:1]={bytea,bytea}
!  byteane         | boolean    | [0:1]={bytea,bytea}
!  cash_eq         | boolean    | [0:1]={money,money}
!  cash_ge         | boolean    | [0:1]={money,money}
!  cash_gt         | boolean    | [0:1]={money,money}
!  cash_le         | boolean    | [0:1]={money,money}
!  cash_lt         | boolean    | [0:1]={money,money}
!  cash_ne         | boolean    | [0:1]={money,money}
!  chareq          | boolean    | [0:1]={"\"char\"","\"char\""}
!  charge          | boolean    | [0:1]={"\"char\"","\"char\""}
!  chargt          | boolean    | [0:1]={"\"char\"","\"char\""}
!  charle          | boolean    | [0:1]={"\"char\"","\"char\""}
!  charlt          | boolean    | [0:1]={"\"char\"","\"char\""}
!  charne          | boolean    | [0:1]={"\"char\"","\"char\""}
!  cideq           | boolean    | [0:1]={cid,cid}
!  circle_eq       | boolean    | [0:1]={circle,circle}
!  circle_ge       | boolean    | [0:1]={circle,circle}
!  circle_gt       | boolean    | [0:1]={circle,circle}
!  circle_le       | boolean    | [0:1]={circle,circle}
!  circle_lt       | boolean    | [0:1]={circle,circle}
!  circle_ne       | boolean    | [0:1]={circle,circle}
!  date_eq         | boolean    | [0:1]={date,date}
!  date_ge         | boolean    | [0:1]={date,date}
!  date_gt         | boolean    | [0:1]={date,date}
!  date_le         | boolean    | [0:1]={date,date}
!  date_lt         | boolean    | [0:1]={date,date}
!  date_ne         | boolean    | [0:1]={date,date}
!  float48eq       | boolean    | [0:1]={real,"double precision"}
!  float48ge       | boolean    | [0:1]={real,"double precision"}
!  float48gt       | boolean    | [0:1]={real,"double precision"}
!  float48le       | boolean    | [0:1]={real,"double precision"}
!  float48lt       | boolean    | [0:1]={real,"double precision"}
!  float48ne       | boolean    | [0:1]={real,"double precision"}
!  float4eq        | boolean    | [0:1]={real,real}
!  float4ge        | boolean    | [0:1]={real,real}
!  float4gt        | boolean    | [0:1]={real,real}
!  float4le        | boolean    | [0:1]={real,real}
!  float4lt        | boolean    | [0:1]={real,real}
!  float4ne        | boolean    | [0:1]={real,real}
!  float84eq       | boolean    | [0:1]={"double precision",real}
!  float84ge       | boolean    | [0:1]={"double precision",real}
!  float84gt       | boolean    | [0:1]={"double precision",real}
!  float84le       | boolean    | [0:1]={"double precision",real}
!  float84lt       | boolean    | [0:1]={"double precision",real}
!  float84ne       | boolean    | [0:1]={"double precision",real}
!  float8eq        | boolean    | [0:1]={"double precision","double precision"}
!  float8ge        | boolean    | [0:1]={"double precision","double precision"}
!  float8gt        | boolean    | [0:1]={"double precision","double precision"}
!  float8le        | boolean    | [0:1]={"double precision","double precision"}
!  float8lt        | boolean    | [0:1]={"double precision","double precision"}
!  float8ne        | boolean    | [0:1]={"double precision","double precision"}
!  int24eq         | boolean    | [0:1]={smallint,integer}
!  int24ge         | boolean    | [0:1]={smallint,integer}
!  int24gt         | boolean    | [0:1]={smallint,integer}
!  int24le         | boolean    | [0:1]={smallint,integer}
!  int24lt         | boolean    | [0:1]={smallint,integer}
!  int24ne         | boolean    | [0:1]={smallint,integer}
!  int28eq         | boolean    | [0:1]={smallint,bigint}
!  int28ge         | boolean    | [0:1]={smallint,bigint}
!  int28gt         | boolean    | [0:1]={smallint,bigint}
!  int28le         | boolean    | [0:1]={smallint,bigint}
!  int28lt         | boolean    | [0:1]={smallint,bigint}
!  int28ne         | boolean    | [0:1]={smallint,bigint}
!  int2eq          | boolean    | [0:1]={smallint,smallint}
!  int2ge          | boolean    | [0:1]={smallint,smallint}
!  int2gt          | boolean    | [0:1]={smallint,smallint}
!  int2le          | boolean    | [0:1]={smallint,smallint}
!  int2lt          | boolean    | [0:1]={smallint,smallint}
!  int2ne          | boolean    | [0:1]={smallint,smallint}
!  int42eq         | boolean    | [0:1]={integer,smallint}
!  int42ge         | boolean    | [0:1]={integer,smallint}
!  int42gt         | boolean    | [0:1]={integer,smallint}
!  int42le         | boolean    | [0:1]={integer,smallint}
!  int42lt         | boolean    | [0:1]={integer,smallint}
!  int42ne         | boolean    | [0:1]={integer,smallint}
!  int48eq         | boolean    | [0:1]={integer,bigint}
!  int48ge         | boolean    | [0:1]={integer,bigint}
!  int48gt         | boolean    | [0:1]={integer,bigint}
!  int48le         | boolean    | [0:1]={integer,bigint}
!  int48lt         | boolean    | [0:1]={integer,bigint}
!  int48ne         | boolean    | [0:1]={integer,bigint}
!  int4eq          | boolean    | [0:1]={integer,integer}
!  int4ge          | boolean    | [0:1]={integer,integer}
!  int4gt          | boolean    | [0:1]={integer,integer}
!  int4le          | boolean    | [0:1]={integer,integer}
!  int4lt          | boolean    | [0:1]={integer,integer}
!  int4ne          | boolean    | [0:1]={integer,integer}
!  int82eq         | boolean    | [0:1]={bigint,smallint}
!  int82ge         | boolean    | [0:1]={bigint,smallint}
!  int82gt         | boolean    | [0:1]={bigint,smallint}
!  int82le         | boolean    | [0:1]={bigint,smallint}
!  int82lt         | boolean    | [0:1]={bigint,smallint}
!  int82ne         | boolean    | [0:1]={bigint,smallint}
!  int84eq         | boolean    | [0:1]={bigint,integer}
!  int84ge         | boolean    | [0:1]={bigint,integer}
!  int84gt         | boolean    | [0:1]={bigint,integer}
!  int84le         | boolean    | [0:1]={bigint,integer}
!  int84lt         | boolean    | [0:1]={bigint,integer}
!  int84ne         | boolean    | [0:1]={bigint,integer}
!  int8eq          | boolean    | [0:1]={bigint,bigint}
!  int8ge          | boolean    | [0:1]={bigint,bigint}
!  int8gt          | boolean    | [0:1]={bigint,bigint}
!  int8le          | boolean    | [0:1]={bigint,bigint}
!  int8lt          | boolean    | [0:1]={bigint,bigint}
!  int8ne          | boolean    | [0:1]={bigint,bigint}
!  interval_eq     | boolean    | [0:1]={interval,interval}
!  interval_ge     | boolean    | [0:1]={interval,interval}
!  interval_gt     | boolean    | [0:1]={interval,interval}
!  interval_le     | boolean    | [0:1]={interval,interval}
!  interval_lt     | boolean    | [0:1]={interval,interval}
!  interval_ne     | boolean    | [0:1]={interval,interval}
!  lseg_eq         | boolean    | [0:1]={lseg,lseg}
!  lseg_ge         | boolean    | [0:1]={lseg,lseg}
!  lseg_gt         | boolean    | [0:1]={lseg,lseg}
!  lseg_le         | boolean    | [0:1]={lseg,lseg}
!  lseg_lt         | boolean    | [0:1]={lseg,lseg}
!  lseg_ne         | boolean    | [0:1]={lseg,lseg}
!  macaddr_eq      | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_ge      | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_gt      | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_le      | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_lt      | boolean    | [0:1]={macaddr,macaddr}
!  macaddr_ne      | boolean    | [0:1]={macaddr,macaddr}
!  nameeq          | boolean    | [0:1]={name,name}
!  namege          | boolean    | [0:1]={name,name}
!  namegt          | boolean    | [0:1]={name,name}
!  namele          | boolean    | [0:1]={name,name}
!  namelt          | boolean    | [0:1]={name,name}
!  namene          | boolean    | [0:1]={name,name}
!  network_eq      | boolean    | [0:1]={inet,inet}
!  network_ge      | boolean    | [0:1]={inet,inet}
!  network_gt      | boolean    | [0:1]={inet,inet}
!  network_larger  | inet       | [0:1]={inet,inet}
!  network_le      | boolean    | [0:1]={inet,inet}
!  network_lt      | boolean    | [0:1]={inet,inet}
!  network_ne      | boolean    | [0:1]={inet,inet}
!  network_smaller | inet       | [0:1]={inet,inet}
!  oideq           | boolean    | [0:1]={oid,oid}
!  oidge           | boolean    | [0:1]={oid,oid}
!  oidgt           | boolean    | [0:1]={oid,oid}
!  oidle           | boolean    | [0:1]={oid,oid}
!  oidlt           | boolean    | [0:1]={oid,oid}
!  oidne           | boolean    | [0:1]={oid,oid}
!  reltimeeq       | boolean    | [0:1]={reltime,reltime}
!  reltimege       | boolean    | [0:1]={reltime,reltime}
!  reltimegt       | boolean    | [0:1]={reltime,reltime}
!  reltimele       | boolean    | [0:1]={reltime,reltime}
!  reltimelt       | boolean    | [0:1]={reltime,reltime}
!  reltimene       | boolean    | [0:1]={reltime,reltime}
!  texteq          | boolean    | [0:1]={text,text}
!  textne          | boolean    | [0:1]={text,text}
!  tideq           | boolean    | [0:1]={tid,tid}
!  tidge           | boolean    | [0:1]={tid,tid}
!  tidgt           | boolean    | [0:1]={tid,tid}
!  tidle           | boolean    | [0:1]={tid,tid}
!  tidlt           | boolean    | [0:1]={tid,tid}
!  tidne           | boolean    | [0:1]={tid,tid}
!  time_eq         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_ge         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_gt         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_le         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_lt         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  time_ne         | boolean    | [0:1]={"time without time zone","time without time zone"}
!  timestamp_eq    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_ge    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_gt    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_le    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_lt    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamp_ne    | boolean    | [0:1]={"timestamp without time zone","timestamp without time zone"}
!  timestamptz_eq  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_ge  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_gt  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_le  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_lt  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timestamptz_ne  | boolean    | [0:1]={"timestamp with time zone","timestamp with time zone"}
!  timetz_eq       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_ge       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_gt       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_le       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_lt       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  timetz_ne       | boolean    | [0:1]={"time with time zone","time with time zone"}
!  tintervaleq     | boolean    | [0:1]={tinterval,tinterval}
!  tintervalge     | boolean    | [0:1]={tinterval,tinterval}
!  tintervalgt     | boolean    | [0:1]={tinterval,tinterval}
!  tintervalle     | boolean    | [0:1]={tinterval,tinterval}
!  tintervalleneq  | boolean    | [0:1]={tinterval,reltime}
!  tintervallenge  | boolean    | [0:1]={tinterval,reltime}
!  tintervallengt  | boolean    | [0:1]={tinterval,reltime}
!  tintervallenle  | boolean    | [0:1]={tinterval,reltime}
!  tintervallenlt  | boolean    | [0:1]={tinterval,reltime}
!  tintervallenne  | boolean    | [0:1]={tinterval,reltime}
!  tintervallt     | boolean    | [0:1]={tinterval,tinterval}
!  tintervalne     | boolean    | [0:1]={tinterval,tinterval}
!  uuid_eq         | boolean    | [0:1]={uuid,uuid}
!  uuid_ge         | boolean    | [0:1]={uuid,uuid}
!  uuid_gt         | boolean    | [0:1]={uuid,uuid}
!  uuid_le         | boolean    | [0:1]={uuid,uuid}
!  uuid_lt         | boolean    | [0:1]={uuid,uuid}
!  uuid_ne         | boolean    | [0:1]={uuid,uuid}
!  varbiteq        | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitge        | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitgt        | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitle        | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitlt        | boolean    | [0:1]={"bit varying","bit varying"}
!  varbitne        | boolean    | [0:1]={"bit varying","bit varying"}
!  xideq           | boolean    | [0:1]={xid,xid}
! (230 rows)
  
  --
  -- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#5Andres Freund
andres@2ndquadrant.com
In reply to: Haribabu Kommi (#4)
Re: [BUGS] BUG #9652: inet types don't support min/max

Hi,

On 2014-06-03 12:43:28 +1000, Haribabu Kommi wrote:

*** a/src/test/regress/expected/create_function_3.out
--- b/src/test/regress/expected/create_function_3.out
***************
*** 153,389 **** RESET SESSION AUTHORIZATION;
SELECT proname, prorettype::regtype, proargtypes::regtype[]
FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
!     proname     | prorettype |                             proargtypes                             
! ----------------+------------+---------------------------------------------------------------------
!  abstimeeq      | boolean    | [0:1]={abstime,abstime}

...

! xideq | boolean | [0:1]={xid,xid}
! (228 rows)

--
-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
--- 153,391 ----
SELECT proname, prorettype::regtype, proargtypes::regtype[]
FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
!      proname     | prorettype |                             proargtypes                             
! -----------------+------------+---------------------------------------------------------------------
!  abstimeeq       | boolean    | [0:1]={abstime,abstime}

...

! xideq | boolean | [0:1]={xid,xid}
! (230 rows)

I didn't reall look at the patch, but it very much looks to me like that
query result could use the \a\t treatment that rules.sql and
sanity_check.sql got. It's hard to see the actual difference
before/after the patch.
I'll patch that now, to reduce the likelihood of changes there causing
conflicts for more people.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#5)
Re: [HACKERS] BUG #9652: inet types don't support min/max

Andres Freund <andres@2ndquadrant.com> writes:

I didn't reall look at the patch, but it very much looks to me like that
query result could use the \a\t treatment that rules.sql and
sanity_check.sql got. It's hard to see the actual difference
before/after the patch.
I'll patch that now, to reduce the likelihood of changes there causing
conflicts for more people.

Personally, I would wonder why the regression tests contain such a query
in the first place. It seems like nothing but a major maintenance PITA.

regards, tom lane

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#7Andres Freund
andres@2ndquadrant.com
In reply to: Tom Lane (#6)
Re: [BUGS] BUG #9652: inet types don't support min/max

On 2014-06-03 10:24:46 -0400, Tom Lane wrote:

Andres Freund <andres@2ndquadrant.com> writes:

I didn't reall look at the patch, but it very much looks to me like that
query result could use the \a\t treatment that rules.sql and
sanity_check.sql got. It's hard to see the actual difference
before/after the patch.
I'll patch that now, to reduce the likelihood of changes there causing
conflicts for more people.

Personally, I would wonder why the regression tests contain such a query
in the first place. It seems like nothing but a major maintenance PITA.

I haven't added it, but it seems appropriate in that specific case. The
number of leakproof functions should be fairly small and every addition
should be carefully reviewed... I am e.g. not sure that it's a good idea
to declare network_smaller/greater as leakproof - but it's hard to catch
that on the basic of pg_proc.h alone.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#7)
Re: [HACKERS] BUG #9652: inet types don't support min/max

Andres Freund <andres@2ndquadrant.com> writes:

On 2014-06-03 10:24:46 -0400, Tom Lane wrote:

Personally, I would wonder why the regression tests contain such a query
in the first place. It seems like nothing but a major maintenance PITA.

I haven't added it, but it seems appropriate in that specific case. The
number of leakproof functions should be fairly small and every addition
should be carefully reviewed... I am e.g. not sure that it's a good idea
to declare network_smaller/greater as leakproof - but it's hard to catch
that on the basic of pg_proc.h alone.

Meh. I agree that new leakproof functions should be carefully reviewed,
but I have precisely zero faith that this regression test will contribute
to that. It hasn't even got a comment saying why changes here should
receive any scrutiny; moreover, it's not in a file where changes would be
likely to excite suspicion. (Probably it should be in opr_sanity, if
we're going to have such a thing at all.)

regards, tom lane

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#9Andres Freund
andres@2ndquadrant.com
In reply to: Tom Lane (#8)
Re: [HACKERS] BUG #9652: inet types don't support min/max

On 2014-06-03 10:37:53 -0400, Tom Lane wrote:

Andres Freund <andres@2ndquadrant.com> writes:

On 2014-06-03 10:24:46 -0400, Tom Lane wrote:

Personally, I would wonder why the regression tests contain such a query
in the first place. It seems like nothing but a major maintenance PITA.

I haven't added it, but it seems appropriate in that specific case. The
number of leakproof functions should be fairly small and every addition
should be carefully reviewed... I am e.g. not sure that it's a good idea
to declare network_smaller/greater as leakproof - but it's hard to catch
that on the basic of pg_proc.h alone.

Meh. I agree that new leakproof functions should be carefully reviewed,
but I have precisely zero faith that this regression test will contribute
to that.

Well, I personally wouldn't have noticed that the OP's patch marked the
new functions as leakproof without that test. At least not while looking
at the patch. pg_proc.h is just too hard to read.

It hasn't even got a comment saying why changes here should
receive any scrutiny; moreover, it's not in a file where changes would be
likely to excite suspicion. (Probably it should be in opr_sanity, if
we're going to have such a thing at all.)

I don't object to moving it there.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#10Keith Fiske
keith@omniti.com
In reply to: Andres Freund (#9)
Re: [HACKERS] BUG #9652: inet types don't support min/max

On Tue, Jun 3, 2014 at 10:48 AM, Andres Freund <andres@2ndquadrant.com>
wrote:

On 2014-06-03 10:37:53 -0400, Tom Lane wrote:

Andres Freund <andres@2ndquadrant.com> writes:

On 2014-06-03 10:24:46 -0400, Tom Lane wrote:

Personally, I would wonder why the regression tests contain such a

query

in the first place. It seems like nothing but a major maintenance

PITA.

I haven't added it, but it seems appropriate in that specific case. The
number of leakproof functions should be fairly small and every addition
should be carefully reviewed... I am e.g. not sure that it's a good

idea

to declare network_smaller/greater as leakproof - but it's hard to

catch

that on the basic of pg_proc.h alone.

Meh. I agree that new leakproof functions should be carefully reviewed,
but I have precisely zero faith that this regression test will contribute
to that.

Well, I personally wouldn't have noticed that the OP's patch marked the
new functions as leakproof without that test. At least not while looking
at the patch. pg_proc.h is just too hard to read.

It hasn't even got a comment saying why changes here should
receive any scrutiny; moreover, it's not in a file where changes would be
likely to excite suspicion. (Probably it should be in opr_sanity, if
we're going to have such a thing at all.)

I don't object to moving it there.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

Andres's changes on June 3rd to
https://github.com/postgres/postgres/commits/master/src/test/regress/expected/create_function_3.out
are causing patch v2 to fail for that regression test file.

postgres $ patch -p1 -i ../inet_agg_v2.patch
patching file src/backend/utils/adt/network.c
patching file src/include/catalog/pg_aggregate.h
patching file src/include/catalog/pg_proc.h
patching file src/include/utils/builtins.h
patching file src/test/regress/expected/create_function_3.out
Hunk #1 FAILED at 153.
1 out of 1 hunk FAILED -- saving rejects to file
src/test/regress/expected/create_function_3.out.rej
patching file src/test/regress/expected/inet.out
patching file src/test/regress/sql/inet.sql

Otherwise it applies without any issues to the latest HEAD. I built and
started a new instance, and I was able to test at least the basic min/max
functionality

keith=# create table test_inet (id serial, ipaddress inet);
CREATE TABLE
Time: 25.546 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.1');
INSERT 0 1
Time: 3.143 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.2');
INSERT 0 1
Time: 2.932 ms
keith=# insert into test_inet (ipaddress) values ('127.0.0.1');
INSERT 0 1
Time: 1.786 ms
keith=# select min(ipaddress) from test_inet;
min
-----------
127.0.0.1
(1 row)

Time: 3.371 ms
keith=# select max(ipaddress) from test_inet;
max
-------------
192.168.1.2
(1 row)

Time: 1.104 ms

--
Keith Fiske
Database Administrator
OmniTI Computer Consulting, Inc.
http://www.keithf4.com

#11Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Keith Fiske (#10)
1 attachment(s)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Wed, Jun 4, 2014 at 5:46 AM, Keith Fiske <keith@omniti.com> wrote:

Andres's changes on June 3rd to
https://github.com/postgres/postgres/commits/master/src/test/regress/expected/create_function_3.out
are causing patch v2 to fail for that regression test file.

postgres $ patch -p1 -i ../inet_agg_v2.patch
patching file src/backend/utils/adt/network.c
patching file src/include/catalog/pg_aggregate.h
patching file src/include/catalog/pg_proc.h
patching file src/include/utils/builtins.h
patching file src/test/regress/expected/create_function_3.out
Hunk #1 FAILED at 153.
1 out of 1 hunk FAILED -- saving rejects to file
src/test/regress/expected/create_function_3.out.rej
patching file src/test/regress/expected/inet.out
patching file src/test/regress/sql/inet.sql

Otherwise it applies without any issues to the latest HEAD. I built and
started a new instance, and I was able to test at least the basic min/max
functionality

keith=# create table test_inet (id serial, ipaddress inet);
CREATE TABLE
Time: 25.546 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.1');
INSERT 0 1
Time: 3.143 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.2');
INSERT 0 1
Time: 2.932 ms
keith=# insert into test_inet (ipaddress) values ('127.0.0.1');
INSERT 0 1
Time: 1.786 ms
keith=# select min(ipaddress) from test_inet;
min
-----------
127.0.0.1
(1 row)

Time: 3.371 ms
keith=# select max(ipaddress) from test_inet;
max
-------------
192.168.1.2
(1 row)

Time: 1.104 ms

Thanks for the test. Patch is re-based to the latest head.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v3.patchapplication/octet-stream; name=inet_agg_v3.patchDownload
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_greater(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3251	n 0 network_greater	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3252	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3253 (  network_greater	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_greater _null_ _null_ _null_ ));
+ DESCR("greater of two network types");
+ DATA(insert OID = 3254 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3251 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3252 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_greater(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/create_function_3.out
--- b/src/test/regress/expected/create_function_3.out
***************
*** 312,321 **** namelt|boolean|[0:1]={name,name}
--- 312,323 ----
  namene|boolean|[0:1]={name,name}
  network_eq|boolean|[0:1]={inet,inet}
  network_ge|boolean|[0:1]={inet,inet}
+ network_greater|inet|[0:1]={inet,inet}
  network_gt|boolean|[0:1]={inet,inet}
  network_le|boolean|[0:1]={inet,inet}
  network_lt|boolean|[0:1]={inet,inet}
  network_ne|boolean|[0:1]={inet,inet}
+ network_smaller|inet|[0:1]={inet,inet}
  oideq|boolean|[0:1]={oid,oid}
  oidge|boolean|[0:1]={oid,oid}
  oidgt|boolean|[0:1]={oid,oid}
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#12Keith Fiske
keith@omniti.com
In reply to: Haribabu Kommi (#11)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Tue, Jun 3, 2014 at 8:37 PM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

On Wed, Jun 4, 2014 at 5:46 AM, Keith Fiske <keith@omniti.com> wrote:

Andres's changes on June 3rd to

https://github.com/postgres/postgres/commits/master/src/test/regress/expected/create_function_3.out

are causing patch v2 to fail for that regression test file.

postgres $ patch -p1 -i ../inet_agg_v2.patch
patching file src/backend/utils/adt/network.c
patching file src/include/catalog/pg_aggregate.h
patching file src/include/catalog/pg_proc.h
patching file src/include/utils/builtins.h
patching file src/test/regress/expected/create_function_3.out
Hunk #1 FAILED at 153.
1 out of 1 hunk FAILED -- saving rejects to file
src/test/regress/expected/create_function_3.out.rej
patching file src/test/regress/expected/inet.out
patching file src/test/regress/sql/inet.sql

Otherwise it applies without any issues to the latest HEAD. I built and
started a new instance, and I was able to test at least the basic min/max
functionality

keith=# create table test_inet (id serial, ipaddress inet);
CREATE TABLE
Time: 25.546 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.1');
INSERT 0 1
Time: 3.143 ms
keith=# insert into test_inet (ipaddress) values ('192.168.1.2');
INSERT 0 1
Time: 2.932 ms
keith=# insert into test_inet (ipaddress) values ('127.0.0.1');
INSERT 0 1
Time: 1.786 ms
keith=# select min(ipaddress) from test_inet;
min
-----------
127.0.0.1
(1 row)

Time: 3.371 ms
keith=# select max(ipaddress) from test_inet;
max
-------------
192.168.1.2
(1 row)

Time: 1.104 ms

Thanks for the test. Patch is re-based to the latest head.

Regards,
Hari Babu
Fujitsu Australia

Applying patch against latest HEAD
(654e8e444749f053c3bf3fd543d10deb6aa6dd09) with no issues

$ patch -p1 -i ../inet_agg_v3.patch
patching file src/backend/utils/adt/network.c
patching file src/include/catalog/pg_aggregate.h
patching file src/include/catalog/pg_proc.h
patching file src/include/utils/builtins.h
patching file src/test/regress/expected/create_function_3.out
patching file src/test/regress/expected/inet.out
patching file src/test/regress/sql/inet.sql

Ran same min/max test as before and worked without issues.

--
Keith Fiske
Database Administrator
OmniTI Computer Consulting, Inc.
http://www.keithf4.com

#13Andres Freund
andres@2ndquadrant.com
In reply to: Tom Lane (#8)
1 attachment(s)
Re: [HACKERS] BUG #9652: inet types don't support min/max

On 2014-06-03 10:37:53 -0400, Tom Lane wrote:

It hasn't even got a comment saying why changes here should
receive any scrutiny; moreover, it's not in a file where changes would be
likely to excite suspicion. (Probably it should be in opr_sanity, if
we're going to have such a thing at all.)

I've written up the attached patch that moves the test to opr_sanity and
adds a littlebit of commentary. Will apply unless somebody protests in
the next 24h or so.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

Attachments:

0001-Move-regression-test-listing-of-builtin-leakproof-fu.patchtext/x-patch; charset=us-asciiDownload
>From 61339023f026be3e61acc5e29038e0b3484b4ddc Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 5 Jun 2014 00:52:49 +0200
Subject: [PATCH] Move regression test listing of builtin leakproof functions
 to opr_sanity.sql.

The original location in create_function_3.sql didn't invite the close
structinity warranted for adding new leakproof functions. Add comments
to the test explaining that functions should only be added after
careful consideration and understanding what a leakproof function is.

Per complaint from Tom Lane after 5eebb8d954ad.
---
 src/test/regress/expected/create_function_3.out | 238 ----------------------
 src/test/regress/expected/opr_sanity.out        | 249 +++++++++++++++++++++++-
 src/test/regress/sql/create_function_3.sql      |  14 --
 src/test/regress/sql/opr_sanity.sql             |  25 ++-
 4 files changed, 268 insertions(+), 258 deletions(-)

diff --git a/src/test/regress/expected/create_function_3.out b/src/test/regress/expected/create_function_3.out
index a4b2d99..6a4352c 100644
--- a/src/test/regress/expected/create_function_3.out
+++ b/src/test/regress/expected/create_function_3.out
@@ -149,244 +149,6 @@ CREATE FUNCTION functext_E_3(int) RETURNS bool LANGUAGE 'sql'
        LEAKPROOF AS 'SELECT $1 < 200';	-- failed
 ERROR:  only superuser can define a leakproof function
 RESET SESSION AUTHORIZATION;
----
--- list of built-in leakproof functions
----
--- temporarily disable fancy output, so catalog changes create less diff noise
-\a\t
-SELECT proname, prorettype::regtype, proargtypes::regtype[]
-       FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
-       WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
-abstimeeq|boolean|[0:1]={abstime,abstime}
-abstimege|boolean|[0:1]={abstime,abstime}
-abstimegt|boolean|[0:1]={abstime,abstime}
-abstimele|boolean|[0:1]={abstime,abstime}
-abstimelt|boolean|[0:1]={abstime,abstime}
-abstimene|boolean|[0:1]={abstime,abstime}
-biteq|boolean|[0:1]={bit,bit}
-bitge|boolean|[0:1]={bit,bit}
-bitgt|boolean|[0:1]={bit,bit}
-bitle|boolean|[0:1]={bit,bit}
-bitlt|boolean|[0:1]={bit,bit}
-bitne|boolean|[0:1]={bit,bit}
-booleq|boolean|[0:1]={boolean,boolean}
-boolge|boolean|[0:1]={boolean,boolean}
-boolgt|boolean|[0:1]={boolean,boolean}
-boolle|boolean|[0:1]={boolean,boolean}
-boollt|boolean|[0:1]={boolean,boolean}
-boolne|boolean|[0:1]={boolean,boolean}
-bpchareq|boolean|[0:1]={character,character}
-bpcharne|boolean|[0:1]={character,character}
-byteaeq|boolean|[0:1]={bytea,bytea}
-byteage|boolean|[0:1]={bytea,bytea}
-byteagt|boolean|[0:1]={bytea,bytea}
-byteale|boolean|[0:1]={bytea,bytea}
-bytealt|boolean|[0:1]={bytea,bytea}
-byteane|boolean|[0:1]={bytea,bytea}
-cash_eq|boolean|[0:1]={money,money}
-cash_ge|boolean|[0:1]={money,money}
-cash_gt|boolean|[0:1]={money,money}
-cash_le|boolean|[0:1]={money,money}
-cash_lt|boolean|[0:1]={money,money}
-cash_ne|boolean|[0:1]={money,money}
-chareq|boolean|[0:1]={"\"char\"","\"char\""}
-charge|boolean|[0:1]={"\"char\"","\"char\""}
-chargt|boolean|[0:1]={"\"char\"","\"char\""}
-charle|boolean|[0:1]={"\"char\"","\"char\""}
-charlt|boolean|[0:1]={"\"char\"","\"char\""}
-charne|boolean|[0:1]={"\"char\"","\"char\""}
-cideq|boolean|[0:1]={cid,cid}
-circle_eq|boolean|[0:1]={circle,circle}
-circle_ge|boolean|[0:1]={circle,circle}
-circle_gt|boolean|[0:1]={circle,circle}
-circle_le|boolean|[0:1]={circle,circle}
-circle_lt|boolean|[0:1]={circle,circle}
-circle_ne|boolean|[0:1]={circle,circle}
-date_eq|boolean|[0:1]={date,date}
-date_ge|boolean|[0:1]={date,date}
-date_gt|boolean|[0:1]={date,date}
-date_le|boolean|[0:1]={date,date}
-date_lt|boolean|[0:1]={date,date}
-date_ne|boolean|[0:1]={date,date}
-float48eq|boolean|[0:1]={real,"double precision"}
-float48ge|boolean|[0:1]={real,"double precision"}
-float48gt|boolean|[0:1]={real,"double precision"}
-float48le|boolean|[0:1]={real,"double precision"}
-float48lt|boolean|[0:1]={real,"double precision"}
-float48ne|boolean|[0:1]={real,"double precision"}
-float4eq|boolean|[0:1]={real,real}
-float4ge|boolean|[0:1]={real,real}
-float4gt|boolean|[0:1]={real,real}
-float4le|boolean|[0:1]={real,real}
-float4lt|boolean|[0:1]={real,real}
-float4ne|boolean|[0:1]={real,real}
-float84eq|boolean|[0:1]={"double precision",real}
-float84ge|boolean|[0:1]={"double precision",real}
-float84gt|boolean|[0:1]={"double precision",real}
-float84le|boolean|[0:1]={"double precision",real}
-float84lt|boolean|[0:1]={"double precision",real}
-float84ne|boolean|[0:1]={"double precision",real}
-float8eq|boolean|[0:1]={"double precision","double precision"}
-float8ge|boolean|[0:1]={"double precision","double precision"}
-float8gt|boolean|[0:1]={"double precision","double precision"}
-float8le|boolean|[0:1]={"double precision","double precision"}
-float8lt|boolean|[0:1]={"double precision","double precision"}
-float8ne|boolean|[0:1]={"double precision","double precision"}
-int24eq|boolean|[0:1]={smallint,integer}
-int24ge|boolean|[0:1]={smallint,integer}
-int24gt|boolean|[0:1]={smallint,integer}
-int24le|boolean|[0:1]={smallint,integer}
-int24lt|boolean|[0:1]={smallint,integer}
-int24ne|boolean|[0:1]={smallint,integer}
-int28eq|boolean|[0:1]={smallint,bigint}
-int28ge|boolean|[0:1]={smallint,bigint}
-int28gt|boolean|[0:1]={smallint,bigint}
-int28le|boolean|[0:1]={smallint,bigint}
-int28lt|boolean|[0:1]={smallint,bigint}
-int28ne|boolean|[0:1]={smallint,bigint}
-int2eq|boolean|[0:1]={smallint,smallint}
-int2ge|boolean|[0:1]={smallint,smallint}
-int2gt|boolean|[0:1]={smallint,smallint}
-int2le|boolean|[0:1]={smallint,smallint}
-int2lt|boolean|[0:1]={smallint,smallint}
-int2ne|boolean|[0:1]={smallint,smallint}
-int42eq|boolean|[0:1]={integer,smallint}
-int42ge|boolean|[0:1]={integer,smallint}
-int42gt|boolean|[0:1]={integer,smallint}
-int42le|boolean|[0:1]={integer,smallint}
-int42lt|boolean|[0:1]={integer,smallint}
-int42ne|boolean|[0:1]={integer,smallint}
-int48eq|boolean|[0:1]={integer,bigint}
-int48ge|boolean|[0:1]={integer,bigint}
-int48gt|boolean|[0:1]={integer,bigint}
-int48le|boolean|[0:1]={integer,bigint}
-int48lt|boolean|[0:1]={integer,bigint}
-int48ne|boolean|[0:1]={integer,bigint}
-int4eq|boolean|[0:1]={integer,integer}
-int4ge|boolean|[0:1]={integer,integer}
-int4gt|boolean|[0:1]={integer,integer}
-int4le|boolean|[0:1]={integer,integer}
-int4lt|boolean|[0:1]={integer,integer}
-int4ne|boolean|[0:1]={integer,integer}
-int82eq|boolean|[0:1]={bigint,smallint}
-int82ge|boolean|[0:1]={bigint,smallint}
-int82gt|boolean|[0:1]={bigint,smallint}
-int82le|boolean|[0:1]={bigint,smallint}
-int82lt|boolean|[0:1]={bigint,smallint}
-int82ne|boolean|[0:1]={bigint,smallint}
-int84eq|boolean|[0:1]={bigint,integer}
-int84ge|boolean|[0:1]={bigint,integer}
-int84gt|boolean|[0:1]={bigint,integer}
-int84le|boolean|[0:1]={bigint,integer}
-int84lt|boolean|[0:1]={bigint,integer}
-int84ne|boolean|[0:1]={bigint,integer}
-int8eq|boolean|[0:1]={bigint,bigint}
-int8ge|boolean|[0:1]={bigint,bigint}
-int8gt|boolean|[0:1]={bigint,bigint}
-int8le|boolean|[0:1]={bigint,bigint}
-int8lt|boolean|[0:1]={bigint,bigint}
-int8ne|boolean|[0:1]={bigint,bigint}
-interval_eq|boolean|[0:1]={interval,interval}
-interval_ge|boolean|[0:1]={interval,interval}
-interval_gt|boolean|[0:1]={interval,interval}
-interval_le|boolean|[0:1]={interval,interval}
-interval_lt|boolean|[0:1]={interval,interval}
-interval_ne|boolean|[0:1]={interval,interval}
-lseg_eq|boolean|[0:1]={lseg,lseg}
-lseg_ge|boolean|[0:1]={lseg,lseg}
-lseg_gt|boolean|[0:1]={lseg,lseg}
-lseg_le|boolean|[0:1]={lseg,lseg}
-lseg_lt|boolean|[0:1]={lseg,lseg}
-lseg_ne|boolean|[0:1]={lseg,lseg}
-macaddr_eq|boolean|[0:1]={macaddr,macaddr}
-macaddr_ge|boolean|[0:1]={macaddr,macaddr}
-macaddr_gt|boolean|[0:1]={macaddr,macaddr}
-macaddr_le|boolean|[0:1]={macaddr,macaddr}
-macaddr_lt|boolean|[0:1]={macaddr,macaddr}
-macaddr_ne|boolean|[0:1]={macaddr,macaddr}
-nameeq|boolean|[0:1]={name,name}
-namege|boolean|[0:1]={name,name}
-namegt|boolean|[0:1]={name,name}
-namele|boolean|[0:1]={name,name}
-namelt|boolean|[0:1]={name,name}
-namene|boolean|[0:1]={name,name}
-network_eq|boolean|[0:1]={inet,inet}
-network_ge|boolean|[0:1]={inet,inet}
-network_gt|boolean|[0:1]={inet,inet}
-network_le|boolean|[0:1]={inet,inet}
-network_lt|boolean|[0:1]={inet,inet}
-network_ne|boolean|[0:1]={inet,inet}
-oideq|boolean|[0:1]={oid,oid}
-oidge|boolean|[0:1]={oid,oid}
-oidgt|boolean|[0:1]={oid,oid}
-oidle|boolean|[0:1]={oid,oid}
-oidlt|boolean|[0:1]={oid,oid}
-oidne|boolean|[0:1]={oid,oid}
-reltimeeq|boolean|[0:1]={reltime,reltime}
-reltimege|boolean|[0:1]={reltime,reltime}
-reltimegt|boolean|[0:1]={reltime,reltime}
-reltimele|boolean|[0:1]={reltime,reltime}
-reltimelt|boolean|[0:1]={reltime,reltime}
-reltimene|boolean|[0:1]={reltime,reltime}
-texteq|boolean|[0:1]={text,text}
-textne|boolean|[0:1]={text,text}
-tideq|boolean|[0:1]={tid,tid}
-tidge|boolean|[0:1]={tid,tid}
-tidgt|boolean|[0:1]={tid,tid}
-tidle|boolean|[0:1]={tid,tid}
-tidlt|boolean|[0:1]={tid,tid}
-tidne|boolean|[0:1]={tid,tid}
-time_eq|boolean|[0:1]={"time without time zone","time without time zone"}
-time_ge|boolean|[0:1]={"time without time zone","time without time zone"}
-time_gt|boolean|[0:1]={"time without time zone","time without time zone"}
-time_le|boolean|[0:1]={"time without time zone","time without time zone"}
-time_lt|boolean|[0:1]={"time without time zone","time without time zone"}
-time_ne|boolean|[0:1]={"time without time zone","time without time zone"}
-timestamp_eq|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamp_ge|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamp_gt|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamp_le|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamp_lt|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamp_ne|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
-timestamptz_eq|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timestamptz_ge|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timestamptz_gt|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timestamptz_le|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timestamptz_lt|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timestamptz_ne|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
-timetz_eq|boolean|[0:1]={"time with time zone","time with time zone"}
-timetz_ge|boolean|[0:1]={"time with time zone","time with time zone"}
-timetz_gt|boolean|[0:1]={"time with time zone","time with time zone"}
-timetz_le|boolean|[0:1]={"time with time zone","time with time zone"}
-timetz_lt|boolean|[0:1]={"time with time zone","time with time zone"}
-timetz_ne|boolean|[0:1]={"time with time zone","time with time zone"}
-tintervaleq|boolean|[0:1]={tinterval,tinterval}
-tintervalge|boolean|[0:1]={tinterval,tinterval}
-tintervalgt|boolean|[0:1]={tinterval,tinterval}
-tintervalle|boolean|[0:1]={tinterval,tinterval}
-tintervalleneq|boolean|[0:1]={tinterval,reltime}
-tintervallenge|boolean|[0:1]={tinterval,reltime}
-tintervallengt|boolean|[0:1]={tinterval,reltime}
-tintervallenle|boolean|[0:1]={tinterval,reltime}
-tintervallenlt|boolean|[0:1]={tinterval,reltime}
-tintervallenne|boolean|[0:1]={tinterval,reltime}
-tintervallt|boolean|[0:1]={tinterval,tinterval}
-tintervalne|boolean|[0:1]={tinterval,tinterval}
-uuid_eq|boolean|[0:1]={uuid,uuid}
-uuid_ge|boolean|[0:1]={uuid,uuid}
-uuid_gt|boolean|[0:1]={uuid,uuid}
-uuid_le|boolean|[0:1]={uuid,uuid}
-uuid_lt|boolean|[0:1]={uuid,uuid}
-uuid_ne|boolean|[0:1]={uuid,uuid}
-varbiteq|boolean|[0:1]={"bit varying","bit varying"}
-varbitge|boolean|[0:1]={"bit varying","bit varying"}
-varbitgt|boolean|[0:1]={"bit varying","bit varying"}
-varbitle|boolean|[0:1]={"bit varying","bit varying"}
-varbitlt|boolean|[0:1]={"bit varying","bit varying"}
-varbitne|boolean|[0:1]={"bit varying","bit varying"}
-xideq|boolean|[0:1]={xid,xid}
--- restore normal output mode
-\a\t
 --
 -- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
 --
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 886e68a..b8a76e6 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -4,9 +4,9 @@
 -- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
 -- pg_amop, pg_amproc, pg_opclass, pg_opfamily.
 --
--- None of the SELECTs here should ever find any matching entries,
--- so the expected output is easy to maintain ;-).
--- A test failure indicates someone messed up an entry in the system tables.
+-- Every test failures in this file should be closely inspected. The
+-- description of the failing test should be read carefully before
+-- adjusting the expected output.
 --
 -- NB: we assume the oidjoins test will have caught any dangling links,
 -- that is OID or REGPROC fields that are not zero and do not match some
@@ -395,6 +395,249 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999;
 -----+---------
 (0 rows)
 
+-- List of built-in leakproof functions
+--
+-- Leakproof functions should only be added after carefully
+-- scrutinizing all possibly executed codepaths for possible
+-- information leaks. Don't add functions here unless you know what a
+-- leakproof function is. If unsure, don't mark it as such.
+-- temporarily disable fancy output, so catalog changes create less diff noise
+\a\t
+SELECT proname, prorettype::regtype, proargtypes::regtype[]
+FROM pg_proc JOIN pg_namespace
+     ON pronamespace = pg_namespace.oid
+WHERE nspname = 'pg_catalog' AND proleakproof
+ORDER BY proname, pg_proc.oid;
+abstimeeq|boolean|[0:1]={abstime,abstime}
+abstimege|boolean|[0:1]={abstime,abstime}
+abstimegt|boolean|[0:1]={abstime,abstime}
+abstimele|boolean|[0:1]={abstime,abstime}
+abstimelt|boolean|[0:1]={abstime,abstime}
+abstimene|boolean|[0:1]={abstime,abstime}
+biteq|boolean|[0:1]={bit,bit}
+bitge|boolean|[0:1]={bit,bit}
+bitgt|boolean|[0:1]={bit,bit}
+bitle|boolean|[0:1]={bit,bit}
+bitlt|boolean|[0:1]={bit,bit}
+bitne|boolean|[0:1]={bit,bit}
+booleq|boolean|[0:1]={boolean,boolean}
+boolge|boolean|[0:1]={boolean,boolean}
+boolgt|boolean|[0:1]={boolean,boolean}
+boolle|boolean|[0:1]={boolean,boolean}
+boollt|boolean|[0:1]={boolean,boolean}
+boolne|boolean|[0:1]={boolean,boolean}
+bpchareq|boolean|[0:1]={character,character}
+bpcharne|boolean|[0:1]={character,character}
+byteaeq|boolean|[0:1]={bytea,bytea}
+byteage|boolean|[0:1]={bytea,bytea}
+byteagt|boolean|[0:1]={bytea,bytea}
+byteale|boolean|[0:1]={bytea,bytea}
+bytealt|boolean|[0:1]={bytea,bytea}
+byteane|boolean|[0:1]={bytea,bytea}
+cash_eq|boolean|[0:1]={money,money}
+cash_ge|boolean|[0:1]={money,money}
+cash_gt|boolean|[0:1]={money,money}
+cash_le|boolean|[0:1]={money,money}
+cash_lt|boolean|[0:1]={money,money}
+cash_ne|boolean|[0:1]={money,money}
+chareq|boolean|[0:1]={"\"char\"","\"char\""}
+charge|boolean|[0:1]={"\"char\"","\"char\""}
+chargt|boolean|[0:1]={"\"char\"","\"char\""}
+charle|boolean|[0:1]={"\"char\"","\"char\""}
+charlt|boolean|[0:1]={"\"char\"","\"char\""}
+charne|boolean|[0:1]={"\"char\"","\"char\""}
+cideq|boolean|[0:1]={cid,cid}
+circle_eq|boolean|[0:1]={circle,circle}
+circle_ge|boolean|[0:1]={circle,circle}
+circle_gt|boolean|[0:1]={circle,circle}
+circle_le|boolean|[0:1]={circle,circle}
+circle_lt|boolean|[0:1]={circle,circle}
+circle_ne|boolean|[0:1]={circle,circle}
+date_eq|boolean|[0:1]={date,date}
+date_ge|boolean|[0:1]={date,date}
+date_gt|boolean|[0:1]={date,date}
+date_le|boolean|[0:1]={date,date}
+date_lt|boolean|[0:1]={date,date}
+date_ne|boolean|[0:1]={date,date}
+float48eq|boolean|[0:1]={real,"double precision"}
+float48ge|boolean|[0:1]={real,"double precision"}
+float48gt|boolean|[0:1]={real,"double precision"}
+float48le|boolean|[0:1]={real,"double precision"}
+float48lt|boolean|[0:1]={real,"double precision"}
+float48ne|boolean|[0:1]={real,"double precision"}
+float4eq|boolean|[0:1]={real,real}
+float4ge|boolean|[0:1]={real,real}
+float4gt|boolean|[0:1]={real,real}
+float4le|boolean|[0:1]={real,real}
+float4lt|boolean|[0:1]={real,real}
+float4ne|boolean|[0:1]={real,real}
+float84eq|boolean|[0:1]={"double precision",real}
+float84ge|boolean|[0:1]={"double precision",real}
+float84gt|boolean|[0:1]={"double precision",real}
+float84le|boolean|[0:1]={"double precision",real}
+float84lt|boolean|[0:1]={"double precision",real}
+float84ne|boolean|[0:1]={"double precision",real}
+float8eq|boolean|[0:1]={"double precision","double precision"}
+float8ge|boolean|[0:1]={"double precision","double precision"}
+float8gt|boolean|[0:1]={"double precision","double precision"}
+float8le|boolean|[0:1]={"double precision","double precision"}
+float8lt|boolean|[0:1]={"double precision","double precision"}
+float8ne|boolean|[0:1]={"double precision","double precision"}
+int24eq|boolean|[0:1]={smallint,integer}
+int24ge|boolean|[0:1]={smallint,integer}
+int24gt|boolean|[0:1]={smallint,integer}
+int24le|boolean|[0:1]={smallint,integer}
+int24lt|boolean|[0:1]={smallint,integer}
+int24ne|boolean|[0:1]={smallint,integer}
+int28eq|boolean|[0:1]={smallint,bigint}
+int28ge|boolean|[0:1]={smallint,bigint}
+int28gt|boolean|[0:1]={smallint,bigint}
+int28le|boolean|[0:1]={smallint,bigint}
+int28lt|boolean|[0:1]={smallint,bigint}
+int28ne|boolean|[0:1]={smallint,bigint}
+int2eq|boolean|[0:1]={smallint,smallint}
+int2ge|boolean|[0:1]={smallint,smallint}
+int2gt|boolean|[0:1]={smallint,smallint}
+int2le|boolean|[0:1]={smallint,smallint}
+int2lt|boolean|[0:1]={smallint,smallint}
+int2ne|boolean|[0:1]={smallint,smallint}
+int42eq|boolean|[0:1]={integer,smallint}
+int42ge|boolean|[0:1]={integer,smallint}
+int42gt|boolean|[0:1]={integer,smallint}
+int42le|boolean|[0:1]={integer,smallint}
+int42lt|boolean|[0:1]={integer,smallint}
+int42ne|boolean|[0:1]={integer,smallint}
+int48eq|boolean|[0:1]={integer,bigint}
+int48ge|boolean|[0:1]={integer,bigint}
+int48gt|boolean|[0:1]={integer,bigint}
+int48le|boolean|[0:1]={integer,bigint}
+int48lt|boolean|[0:1]={integer,bigint}
+int48ne|boolean|[0:1]={integer,bigint}
+int4eq|boolean|[0:1]={integer,integer}
+int4ge|boolean|[0:1]={integer,integer}
+int4gt|boolean|[0:1]={integer,integer}
+int4le|boolean|[0:1]={integer,integer}
+int4lt|boolean|[0:1]={integer,integer}
+int4ne|boolean|[0:1]={integer,integer}
+int82eq|boolean|[0:1]={bigint,smallint}
+int82ge|boolean|[0:1]={bigint,smallint}
+int82gt|boolean|[0:1]={bigint,smallint}
+int82le|boolean|[0:1]={bigint,smallint}
+int82lt|boolean|[0:1]={bigint,smallint}
+int82ne|boolean|[0:1]={bigint,smallint}
+int84eq|boolean|[0:1]={bigint,integer}
+int84ge|boolean|[0:1]={bigint,integer}
+int84gt|boolean|[0:1]={bigint,integer}
+int84le|boolean|[0:1]={bigint,integer}
+int84lt|boolean|[0:1]={bigint,integer}
+int84ne|boolean|[0:1]={bigint,integer}
+int8eq|boolean|[0:1]={bigint,bigint}
+int8ge|boolean|[0:1]={bigint,bigint}
+int8gt|boolean|[0:1]={bigint,bigint}
+int8le|boolean|[0:1]={bigint,bigint}
+int8lt|boolean|[0:1]={bigint,bigint}
+int8ne|boolean|[0:1]={bigint,bigint}
+interval_eq|boolean|[0:1]={interval,interval}
+interval_ge|boolean|[0:1]={interval,interval}
+interval_gt|boolean|[0:1]={interval,interval}
+interval_le|boolean|[0:1]={interval,interval}
+interval_lt|boolean|[0:1]={interval,interval}
+interval_ne|boolean|[0:1]={interval,interval}
+lseg_eq|boolean|[0:1]={lseg,lseg}
+lseg_ge|boolean|[0:1]={lseg,lseg}
+lseg_gt|boolean|[0:1]={lseg,lseg}
+lseg_le|boolean|[0:1]={lseg,lseg}
+lseg_lt|boolean|[0:1]={lseg,lseg}
+lseg_ne|boolean|[0:1]={lseg,lseg}
+macaddr_eq|boolean|[0:1]={macaddr,macaddr}
+macaddr_ge|boolean|[0:1]={macaddr,macaddr}
+macaddr_gt|boolean|[0:1]={macaddr,macaddr}
+macaddr_le|boolean|[0:1]={macaddr,macaddr}
+macaddr_lt|boolean|[0:1]={macaddr,macaddr}
+macaddr_ne|boolean|[0:1]={macaddr,macaddr}
+nameeq|boolean|[0:1]={name,name}
+namege|boolean|[0:1]={name,name}
+namegt|boolean|[0:1]={name,name}
+namele|boolean|[0:1]={name,name}
+namelt|boolean|[0:1]={name,name}
+namene|boolean|[0:1]={name,name}
+network_eq|boolean|[0:1]={inet,inet}
+network_ge|boolean|[0:1]={inet,inet}
+network_gt|boolean|[0:1]={inet,inet}
+network_le|boolean|[0:1]={inet,inet}
+network_lt|boolean|[0:1]={inet,inet}
+network_ne|boolean|[0:1]={inet,inet}
+oideq|boolean|[0:1]={oid,oid}
+oidge|boolean|[0:1]={oid,oid}
+oidgt|boolean|[0:1]={oid,oid}
+oidle|boolean|[0:1]={oid,oid}
+oidlt|boolean|[0:1]={oid,oid}
+oidne|boolean|[0:1]={oid,oid}
+reltimeeq|boolean|[0:1]={reltime,reltime}
+reltimege|boolean|[0:1]={reltime,reltime}
+reltimegt|boolean|[0:1]={reltime,reltime}
+reltimele|boolean|[0:1]={reltime,reltime}
+reltimelt|boolean|[0:1]={reltime,reltime}
+reltimene|boolean|[0:1]={reltime,reltime}
+texteq|boolean|[0:1]={text,text}
+textne|boolean|[0:1]={text,text}
+tideq|boolean|[0:1]={tid,tid}
+tidge|boolean|[0:1]={tid,tid}
+tidgt|boolean|[0:1]={tid,tid}
+tidle|boolean|[0:1]={tid,tid}
+tidlt|boolean|[0:1]={tid,tid}
+tidne|boolean|[0:1]={tid,tid}
+time_eq|boolean|[0:1]={"time without time zone","time without time zone"}
+time_ge|boolean|[0:1]={"time without time zone","time without time zone"}
+time_gt|boolean|[0:1]={"time without time zone","time without time zone"}
+time_le|boolean|[0:1]={"time without time zone","time without time zone"}
+time_lt|boolean|[0:1]={"time without time zone","time without time zone"}
+time_ne|boolean|[0:1]={"time without time zone","time without time zone"}
+timestamp_eq|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamp_ge|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamp_gt|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamp_le|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamp_lt|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamp_ne|boolean|[0:1]={"timestamp without time zone","timestamp without time zone"}
+timestamptz_eq|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timestamptz_ge|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timestamptz_gt|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timestamptz_le|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timestamptz_lt|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timestamptz_ne|boolean|[0:1]={"timestamp with time zone","timestamp with time zone"}
+timetz_eq|boolean|[0:1]={"time with time zone","time with time zone"}
+timetz_ge|boolean|[0:1]={"time with time zone","time with time zone"}
+timetz_gt|boolean|[0:1]={"time with time zone","time with time zone"}
+timetz_le|boolean|[0:1]={"time with time zone","time with time zone"}
+timetz_lt|boolean|[0:1]={"time with time zone","time with time zone"}
+timetz_ne|boolean|[0:1]={"time with time zone","time with time zone"}
+tintervaleq|boolean|[0:1]={tinterval,tinterval}
+tintervalge|boolean|[0:1]={tinterval,tinterval}
+tintervalgt|boolean|[0:1]={tinterval,tinterval}
+tintervalle|boolean|[0:1]={tinterval,tinterval}
+tintervalleneq|boolean|[0:1]={tinterval,reltime}
+tintervallenge|boolean|[0:1]={tinterval,reltime}
+tintervallengt|boolean|[0:1]={tinterval,reltime}
+tintervallenle|boolean|[0:1]={tinterval,reltime}
+tintervallenlt|boolean|[0:1]={tinterval,reltime}
+tintervallenne|boolean|[0:1]={tinterval,reltime}
+tintervallt|boolean|[0:1]={tinterval,tinterval}
+tintervalne|boolean|[0:1]={tinterval,tinterval}
+uuid_eq|boolean|[0:1]={uuid,uuid}
+uuid_ge|boolean|[0:1]={uuid,uuid}
+uuid_gt|boolean|[0:1]={uuid,uuid}
+uuid_le|boolean|[0:1]={uuid,uuid}
+uuid_lt|boolean|[0:1]={uuid,uuid}
+uuid_ne|boolean|[0:1]={uuid,uuid}
+varbiteq|boolean|[0:1]={"bit varying","bit varying"}
+varbitge|boolean|[0:1]={"bit varying","bit varying"}
+varbitgt|boolean|[0:1]={"bit varying","bit varying"}
+varbitle|boolean|[0:1]={"bit varying","bit varying"}
+varbitlt|boolean|[0:1]={"bit varying","bit varying"}
+varbitne|boolean|[0:1]={"bit varying","bit varying"}
+xideq|boolean|[0:1]={xid,xid}
+-- restore normal output mode
+\a\t
 -- **************** pg_cast ****************
 -- Catch bogus values in pg_cast columns (other than cases detected by
 -- oidjoins test).
diff --git a/src/test/regress/sql/create_function_3.sql b/src/test/regress/sql/create_function_3.sql
index e78a2ba..86d69ba 100644
--- a/src/test/regress/sql/create_function_3.sql
+++ b/src/test/regress/sql/create_function_3.sql
@@ -107,20 +107,6 @@ CREATE FUNCTION functext_E_3(int) RETURNS bool LANGUAGE 'sql'
 
 RESET SESSION AUTHORIZATION;
 
----
--- list of built-in leakproof functions
----
-
--- temporarily disable fancy output, so catalog changes create less diff noise
-\a\t
-
-SELECT proname, prorettype::regtype, proargtypes::regtype[]
-       FROM pg_proc JOIN pg_namespace ON pronamespace = pg_namespace.oid
-       WHERE nspname = 'pg_catalog' AND proleakproof ORDER BY proname;
-
--- restore normal output mode
-\a\t
-
 --
 -- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
 --
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index a932ff2..cf7ba43 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -4,9 +4,9 @@
 -- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
 -- pg_amop, pg_amproc, pg_opclass, pg_opfamily.
 --
--- None of the SELECTs here should ever find any matching entries,
--- so the expected output is easy to maintain ;-).
--- A test failure indicates someone messed up an entry in the system tables.
+-- Every test failures in this file should be closely inspected. The
+-- description of the failing test should be read carefully before
+-- adjusting the expected output.
 --
 -- NB: we assume the oidjoins test will have caught any dangling links,
 -- that is OID or REGPROC fields that are not zero and do not match some
@@ -298,6 +298,25 @@ FROM pg_proc as p1 LEFT JOIN pg_description as d
      ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0
 WHERE d.classoid IS NULL AND p1.oid <= 9999;
 
+-- List of built-in leakproof functions
+--
+-- Leakproof functions should only be added after carefully
+-- scrutinizing all possibly executed codepaths for possible
+-- information leaks. Don't add functions here unless you know what a
+-- leakproof function is. If unsure, don't mark it as such.
+
+-- temporarily disable fancy output, so catalog changes create less diff noise
+\a\t
+
+SELECT proname, prorettype::regtype, proargtypes::regtype[]
+FROM pg_proc JOIN pg_namespace
+     ON pronamespace = pg_namespace.oid
+WHERE nspname = 'pg_catalog' AND proleakproof
+ORDER BY proname, pg_proc.oid;
+
+-- restore normal output mode
+\a\t
+
 
 -- **************** pg_cast ****************
 
-- 
2.0.0.rc2.4.g1dc51c6.dirty

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#13)
Re: [HACKERS] BUG #9652: inet types don't support min/max

Andres Freund <andres@2ndquadrant.com> writes:

On 2014-06-03 10:37:53 -0400, Tom Lane wrote:

It hasn't even got a comment saying why changes here should
receive any scrutiny; moreover, it's not in a file where changes would be
likely to excite suspicion. (Probably it should be in opr_sanity, if
we're going to have such a thing at all.)

I've written up the attached patch that moves the test to opr_sanity and
adds a littlebit of commentary. Will apply unless somebody protests in
the next 24h or so.

+1, but as long as we're touching this, could we make the output be

SELECT oid::regprocedure, prorettype::regtype FROM pg_proc ...

Same information, but more readable IMO. (I'm not really sure why
we need to show prorettype here at all, btw.)

regards, tom lane

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#15Andres Freund
andres@2ndquadrant.com
In reply to: Haribabu Kommi (#11)
Re: [BUGS] BUG #9652: inet types don't support min/max

Hi,

On 2014-06-04 10:37:48 +1000, Haribabu Kommi wrote:

Thanks for the test. Patch is re-based to the latest head.

Did you look at the source of the conflict? Did you intentionally mark
the functions as leakproof and reviewed that that truly is the case? Or
was that caused by copy & paste?

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Andres Freund (#15)
1 attachment(s)
Re: [HACKERS] BUG #9652: inet types don't support min/max

On Thu, Jun 5, 2014 at 9:12 AM, Andres Freund <andres@2ndquadrant.com> wrote:

Hi,

On 2014-06-04 10:37:48 +1000, Haribabu Kommi wrote:

Thanks for the test. Patch is re-based to the latest head.

Did you look at the source of the conflict? Did you intentionally mark
the functions as leakproof and reviewed that that truly is the case? Or
was that caused by copy & paste?

Yes it is copy & paste mistake. I didn't know much about that parameter.
Thanks for the information. I changed it.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v4.patchapplication/octet-stream; name=inet_agg_v4.patchDownload
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_greater(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3255	n 0 network_greater	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3256	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3257 (  network_greater	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_greater _null_ _null_ _null_ ));
+ DESCR("greater of two network types");
+ DATA(insert OID = 3258 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3255 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3256 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_greater(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#17Asif Naeem
anaeem.it@gmail.com
In reply to: Haribabu Kommi (#16)
Re: [HACKERS] BUG #9652: inet types don't support min/max

Hi Haribabu,

I am not able to apply latest patch on REL9_4_STABLE or master branch i.e.

pc1dotnetpk:postgresql asif$ git apply

~/core/min_max_support_for_inet_datatypes/inet_agg_v4.patch
fatal: unrecognized input

pc1dotnetpk:postgresql asif$ patch -p0 <

~/core/min_max_support_for_inet_datatypes/inet_agg_v4.patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|*** a/src/backend/utils/adt/network.c
|--- b/src/backend/utils/adt/network.c
--------------------------
File to patch:

Is there any other utility required to apply the patch, Can you please
guide ?. Thanks.

Regards,
Muhammad Asif Naeem

On Thu, Jun 5, 2014 at 6:28 AM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

Show quoted text

On Thu, Jun 5, 2014 at 9:12 AM, Andres Freund <andres@2ndquadrant.com>
wrote:

Hi,

On 2014-06-04 10:37:48 +1000, Haribabu Kommi wrote:

Thanks for the test. Patch is re-based to the latest head.

Did you look at the source of the conflict? Did you intentionally mark
the functions as leakproof and reviewed that that truly is the case? Or
was that caused by copy & paste?

Yes it is copy & paste mistake. I didn't know much about that parameter.
Thanks for the information. I changed it.

Regards,
Hari Babu
Fujitsu Australia

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#18Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Asif Naeem (#17)
Re: [BUGS] BUG #9652: inet types don't support min/max

At 2014-06-30 16:35:45 +0500, anaeem.it@gmail.com wrote:

pc1dotnetpk:postgresql asif$ patch -p0 <

~/core/min_max_support_for_inet_datatypes/inet_agg_v4.patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|*** a/src/backend/utils/adt/network.c
|--- b/src/backend/utils/adt/network.c
--------------------------

You need to use patch -p1, to strip off the "a"/"b" prefix.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Asif Naeem
anaeem.it@gmail.com
In reply to: Abhijit Menon-Sen (#18)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Mon, Jun 30, 2014 at 4:45 PM, Abhijit Menon-Sen <ams@2ndquadrant.com>
wrote:

At 2014-06-30 16:35:45 +0500, anaeem.it@gmail.com wrote:

pc1dotnetpk:postgresql asif$ patch -p0 <

~/core/min_max_support_for_inet_datatypes/inet_agg_v4.patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|*** a/src/backend/utils/adt/network.c
|--- b/src/backend/utils/adt/network.c
--------------------------

You need to use patch -p1, to strip off the "a"/"b" prefix.

Thank you Abhijit, It worked.

Show quoted text

-- Abhijit

#20Asif Naeem
anaeem.it@gmail.com
In reply to: Asif Naeem (#19)
Re: [BUGS] BUG #9652: inet types don't support min/max

Hi Haribabu,

Thank you for sharing the patch. I have spent some time to review the
changes. Overall patch looks good to me, make check and manual testing
seems run fine with it. There seems no related doc/sgml changes ?. Patch
added network_smaller() and network_greater() functions but in PG source
code, general practice seems to be to use “smaller" and “larger” as related
function name postfix e.g. timestamp_smaller()/timestamp_larger(),
interval_smaller/interval_larger(), cashsmaller()/cashlarger() etc. Thanks.

Regards,
Muhammad Asif Naeem

On Mon, Jul 7, 2014 at 1:56 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Show quoted text

On Mon, Jun 30, 2014 at 4:45 PM, Abhijit Menon-Sen <ams@2ndquadrant.com>
wrote:

At 2014-06-30 16:35:45 +0500, anaeem.it@gmail.com wrote:

pc1dotnetpk:postgresql asif$ patch -p0 <

~/core/min_max_support_for_inet_datatypes/inet_agg_v4.patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|*** a/src/backend/utils/adt/network.c
|--- b/src/backend/utils/adt/network.c
--------------------------

You need to use patch -p1, to strip off the "a"/"b" prefix.

Thank you Abhijit, It worked.

-- Abhijit

#21Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Asif Naeem (#20)
1 attachment(s)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Mon, Jul 7, 2014 at 6:59 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Hi Haribabu,

Thank you for sharing the patch. I have spent some time to review the
changes. Overall patch looks good to me, make check and manual testing seems
run fine with it. There seems no related doc/sgml changes ?. Patch added
network_smaller() and network_greater() functions but in PG source code,
general practice seems to be to use “smaller" and “larger” as related
function name postfix e.g. timestamp_smaller()/timestamp_larger(),
interval_smaller/interval_larger(), cashsmaller()/cashlarger() etc. Thanks.

Thanks for reviewing the patch.

I corrected the function names as smaller and larger.
and also added documentation changes.

Updated patch attached in the mail.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v5.patchtext/x-patch; charset=US-ASCII; name=inet_agg_v5.patchDownload
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 8647,8652 **** CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
--- 8647,8676 ----
         <row>
          <entry>
           <indexterm>
+           <primary>max</primary>
+          </indexterm>
+          <literal><function>max(<type>inet</type>, <type>inet</type>)</function></literal>
+         </entry>
+         <entry><type>inet</type></entry>
+         <entry>larger of two inet types</entry>
+         <entry><literal>max('192.168.1.5', '192.168.1.4')</literal></entry>
+         <entry><literal>192.168.1.5</literal></entry>
+        </row>
+        <row>
+         <entry>
+          <indexterm>
+           <primary>min</primary>
+          </indexterm>
+          <literal><function>min(<type>inet</type>, <type>inet</type>)</function></literal>
+         </entry>
+         <entry><type>inet</type></entry>
+         <entry>smaller of two inet types</entry>
+         <entry><literal>min('192.168.1.5', '192.168.1.4')</literal></entry>
+         <entry><literal>192.168.1.4</literal></entry>
+        </row>
+        <row>
+         <entry>
+          <indexterm>
            <primary>netmask</primary>
           </indexterm>
           <literal><function>netmask(<type>inet</type>)</function></literal>
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3255	n 0 network_larger	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3256	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3257 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
+ DESCR("larger of two network types");
+ DATA(insert OID = 3258 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3255 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3256 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#22Amit Kapila
amit.kapila16@gmail.com
In reply to: Haribabu Kommi (#21)
Re: [BUGS] BUG #9652: inet types don't support min/max

Hi Asif,

On Wed, Jul 9, 2014 at 6:51 PM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

On Mon, Jul 7, 2014 at 6:59 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Hi Haribabu,

Thank you for sharing the patch. I have spent some time to review the
changes. Overall patch looks good to me, make check and manual testing

seems

run fine with it. There seems no related doc/sgml changes ?. Patch added
network_smaller() and network_greater() functions but in PG source code,
general practice seems to be to use “smaller" and “larger” as related
function name postfix e.g. timestamp_smaller()/timestamp_larger(),
interval_smaller/interval_larger(), cashsmaller()/cashlarger() etc.

Thanks.

Thanks for reviewing the patch.

I corrected the function names as smaller and larger.
and also added documentation changes.

Updated patch attached in the mail.

Hari has provided an updated patch as per your comments, if
you think patch is fine, could you please move it to Ready For Committer?

Incase your review is still pending, then it is okay. I have asked
as from your mail it seems to me that the new patch addresses all
your concerns.

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#23Asif Naeem
anaeem.it@gmail.com
In reply to: Haribabu Kommi (#21)
Re: [BUGS] BUG #9652: inet types don't support min/max

Hi Haribabu,

Sorry for being late. Thank you for sharing updated patch, sgml changes
seems not working i.e.

postgres=# select max('192.168.1.5', '192.168.1.4');

ERROR: function max(unknown, unknown) does not exist
LINE 1: select max('192.168.1.5', '192.168.1.4');
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
postgres=# select min('192.168.1.5', '192.168.1.4');
ERROR: function min(unknown, unknown) does not exist
LINE 1: select min('192.168.1.5', '192.168.1.4');
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

I would suggest the following or similar changes e.g.

doc/src/sgml/func.sgml

</indexterm>
<function>max(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
maximum value of <replaceable
@@ -12204,7 +12228,7 @@ NULL baz</literallayout>(3 rows)</entry>
</indexterm>
<function>min(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
minimum value of <replaceable

Other than this patch looks good to me. Thanks.

Regards,
Muhammad Asif Naeem

On Wed, Jul 9, 2014 at 6:21 PM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

Show quoted text

On Mon, Jul 7, 2014 at 6:59 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Hi Haribabu,

Thank you for sharing the patch. I have spent some time to review the
changes. Overall patch looks good to me, make check and manual testing

seems

run fine with it. There seems no related doc/sgml changes ?. Patch added
network_smaller() and network_greater() functions but in PG source code,
general practice seems to be to use “smaller" and “larger” as related
function name postfix e.g. timestamp_smaller()/timestamp_larger(),
interval_smaller/interval_larger(), cashsmaller()/cashlarger() etc.

Thanks.

Thanks for reviewing the patch.

I corrected the function names as smaller and larger.
and also added documentation changes.

Updated patch attached in the mail.

Regards,
Hari Babu
Fujitsu Australia

#24Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Asif Naeem (#23)
1 attachment(s)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Thu, Jul 24, 2014 at 5:59 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Sorry for being late. Thank you for sharing updated patch, sgml changes
seems not working i.e.

postgres=# select max('192.168.1.5', '192.168.1.4');
ERROR: function max(unknown, unknown) does not exist
LINE 1: select max('192.168.1.5', '192.168.1.4');

^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
postgres=# select min('192.168.1.5', '192.168.1.4');
ERROR: function min(unknown, unknown) does not exist
LINE 1: select min('192.168.1.5', '192.168.1.4');

^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

I didn't get your point. I tested the patch, the sgml changes are working fine.

I would suggest the following or similar changes e.g.

doc/src/sgml/func.sgml
</indexterm>
<function>max(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
maximum value of <replaceable
@@ -12204,7 +12228,7 @@ NULL baz</literallayout>(3 rows)</entry>
</indexterm>
<function>min(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
minimum value of <replaceable

Thanks for reviewing the patch.
I missed the above change. Corrected the same in the attached patch.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v6.patchapplication/octet-stream; name=inet_agg_v6.patchDownload
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 8647,8652 **** CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
--- 8647,8676 ----
         <row>
          <entry>
           <indexterm>
+           <primary>max</primary>
+          </indexterm>
+          <literal><function>max(<type>inet</type>, <type>inet</type>)</function></literal>
+         </entry>
+         <entry><type>inet</type></entry>
+         <entry>larger of two inet types</entry>
+         <entry><literal>max('192.168.1.5', '192.168.1.4')</literal></entry>
+         <entry><literal>192.168.1.5</literal></entry>
+        </row>
+        <row>
+         <entry>
+          <indexterm>
+           <primary>min</primary>
+          </indexterm>
+          <literal><function>min(<type>inet</type>, <type>inet</type>)</function></literal>
+         </entry>
+         <entry><type>inet</type></entry>
+         <entry>smaller of two inet types</entry>
+         <entry><literal>min('192.168.1.5', '192.168.1.4')</literal></entry>
+         <entry><literal>192.168.1.4</literal></entry>
+        </row>
+        <row>
+         <entry>
+          <indexterm>
            <primary>netmask</primary>
           </indexterm>
           <literal><function>netmask(<type>inet</type>)</function></literal>
***************
*** 12188,12194 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
--- 12212,12218 ----
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
***************
*** 12204,12210 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
--- 12228,12234 ----
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3255	n 0 network_larger	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3256	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3257 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
+ DESCR("larger of two network types");
+ DATA(insert OID = 3258 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3255 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3256 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#25Asif Naeem
anaeem.it@gmail.com
In reply to: Haribabu Kommi (#24)
Re: [BUGS] BUG #9652: inet types don't support min/max

Thank you Haribabu. Please see my comments inlined below i.e.

On Sun, Jul 27, 2014 at 11:42 AM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

On Thu, Jul 24, 2014 at 5:59 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Sorry for being late. Thank you for sharing updated patch, sgml changes
seems not working i.e.

postgres=# select max('192.168.1.5', '192.168.1.4');
ERROR: function max(unknown, unknown) does not exist
LINE 1: select max('192.168.1.5', '192.168.1.4');

^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
postgres=# select min('192.168.1.5', '192.168.1.4');
ERROR: function min(unknown, unknown) does not exist
LINE 1: select min('192.168.1.5', '192.168.1.4');

^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.

I didn't get your point. I tested the patch, the sgml changes are working
fine.

Sorry for not being clear, above mentioned test is related to following doc
(sgml) changes that seems not working as described i.e.

*Table 9-35. cidr and inet Functions*
FunctionReturn TypeDescriptionExampleResult

max(inet, inet)inetlarger of two inet typesmax('192.168.1.5', '192.168.1.4')
192.168.1.5min(inet, inet)inetsmaller of two inet typesmin('192.168.1.5',
'192.168.1.4')192.168.1.4

Can you please elaborate these sgml change ?

Show quoted text

I would suggest the following or similar changes e.g.

doc/src/sgml/func.sgml
</indexterm>
<function>max(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time

type</entry>

<entry>same as argument type</entry>
<entry>
maximum value of <replaceable
@@ -12204,7 +12228,7 @@ NULL baz</literallayout>(3 rows)</entry>
</indexterm>
<function>min(<replaceable
class="parameter">expression</replaceable>)</function>
</entry>
-      <entry>any array, numeric, string, or date/time type</entry>
+      <entry>any inet, array, numeric, string, or date/time

type</entry>

<entry>same as argument type</entry>
<entry>
minimum value of <replaceable

Thanks for reviewing the patch.
I missed the above change. Corrected the same in the attached patch.

Regards,
Hari Babu
Fujitsu Australia

#26Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Asif Naeem (#25)
1 attachment(s)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Mon, Aug 4, 2014 at 3:22 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Sorry for not being clear, above mentioned test is related to following doc (sgml) changes that seems not working as described i.e.

Table 9-35. cidr and inet Functions

FunctionReturn TypeDescriptionExampleResult

max(inet, inet) inetlarger of two inet typesmax('192.168.1.5', '192.168.1.4')192.168.1.5
min(inet, inet) inetsmaller of two inet typesmin('192.168.1.5', '192.168.1.4')192.168.1.4

Can you please elaborate these sgml change ?

I thought of adding them for newly added "network" functions but
mistakenly I kept the names as max and min.
Anyway with your suggestion in the earlier mail, these changes are not required.

I removed these changes in the attached patch.
Thanks for reviewing the patch.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v7.patchapplication/octet-stream; name=inet_agg_v7.patchDownload
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 12188,12194 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
--- 12188,12194 ----
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
***************
*** 12204,12210 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
--- 12204,12210 ----
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3255	n 0 network_larger	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3256	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2120,2125 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2120,2129 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3257 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
+ DESCR("larger of two network types");
+ DATA(insert OID = 3258 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3161,3166 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3165,3172 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3255 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3200,3205 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3206,3213 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3256 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 907,912 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 907,914 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#27Asif Naeem
anaeem.it@gmail.com
In reply to: Haribabu Kommi (#26)
Re: [BUGS] BUG #9652: inet types don't support min/max

Thank you for sharing updated patch. With latest 9.5 source code, patch
build is failing with following error message i.e.

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C catalog

schemapg.h
cd ../../../src/include/catalog && '/opt/local/bin/perl' ./duplicate_oids
3255
make[3]: *** [postgres.bki] Error 1
make[2]: *** [submake-schemapg] Error 2
make[1]: *** [all-backend-recurse] Error 2
make: *** [all-src-recurse] Error 2

New function is being added by following commit i.e.

commit b34e37bfefbed1bf9396dde18f308d8b96fd176c

Author: Robert Haas <rhaas@postgresql.org>
Date: Thu Aug 14 12:09:52 2014 -0400
Add sortsupport routines for text.
This provides a small but worthwhile speedup when sorting text, at
least
in cases to which the sortsupport machinery applies.
Robert Haas and Peter Geoghegan

It seems that you need to use another oid. Other than this patch looks good
to me, please share updated patch and feel free to assign it to committer.
Thanks.

Regards,
Muhammad Asif Naeem

On Tue, Aug 12, 2014 at 3:12 PM, Haribabu Kommi <kommi.haribabu@gmail.com>
wrote:

Show quoted text

On Mon, Aug 4, 2014 at 3:22 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Sorry for not being clear, above mentioned test is related to following

doc (sgml) changes that seems not working as described i.e.

Table 9-35. cidr and inet Functions

FunctionReturn TypeDescriptionExampleResult

max(inet, inet) inetlarger of two inet typesmax('192.168.1.5',

'192.168.1.4')192.168.1.5

min(inet, inet) inetsmaller of two inet typesmin('192.168.1.5',

'192.168.1.4')192.168.1.4

Can you please elaborate these sgml change ?

I thought of adding them for newly added "network" functions but
mistakenly I kept the names as max and min.
Anyway with your suggestion in the earlier mail, these changes are not
required.

I removed these changes in the attached patch.
Thanks for reviewing the patch.

Regards,
Hari Babu
Fujitsu Australia

#28Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Asif Naeem (#27)
1 attachment(s)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Mon, Aug 18, 2014 at 8:12 PM, Asif Naeem <anaeem.it@gmail.com> wrote:

Thank you for sharing updated patch. With latest 9.5 source code, patch
build is failing with following error message i.e.

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C catalog
schemapg.h
cd ../../../src/include/catalog && '/opt/local/bin/perl' ./duplicate_oids
3255
make[3]: *** [postgres.bki] Error 1
make[2]: *** [submake-schemapg] Error 2
make[1]: *** [all-backend-recurse] Error 2
make: *** [all-src-recurse] Error 2

New function is being added by following commit i.e.

commit b34e37bfefbed1bf9396dde18f308d8b96fd176c
Author: Robert Haas <rhaas@postgresql.org>
Date: Thu Aug 14 12:09:52 2014 -0400
Add sortsupport routines for text.
This provides a small but worthwhile speedup when sorting text, at
least
in cases to which the sortsupport machinery applies.
Robert Haas and Peter Geoghegan

It seems that you need to use another oid. Other than this patch looks good
to me, please share updated patch and feel free to assign it to committer.
Thanks.

Thanks for your review. Please find the rebased patch to latest HEAD.

Regards,
Hari Babu
Fujitsu Australia

Attachments:

inet_agg_v8.patchapplication/octet-stream; name=inet_agg_v8.patchDownload
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 12192,12198 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
--- 12192,12198 ----
         </indexterm>
         <function>max(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         maximum value of <replaceable
***************
*** 12208,12214 **** NULL baz</literallayout>(3 rows)</entry>
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
--- 12208,12214 ----
         </indexterm>
         <function>min(<replaceable class="parameter">expression</replaceable>)</function>
        </entry>
!       <entry>any array, inet, numeric, string, or date/time type</entry>
        <entry>same as argument type</entry>
        <entry>
         minimum value of <replaceable
*** a/src/backend/utils/adt/network.c
--- b/src/backend/utils/adt/network.c
***************
*** 471,476 **** network_ne(PG_FUNCTION_ARGS)
--- 471,499 ----
  	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
  }
  
+ Datum
+ network_smaller(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) < 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
+ 
+ Datum
+ network_larger(PG_FUNCTION_ARGS)
+ {
+ 	inet	   *a1 = PG_GETARG_INET_PP(0);
+ 	inet	   *a2 = PG_GETARG_INET_PP(1);
+ 
+ 	if (network_cmp_internal(a1, a2) > 0)
+ 		PG_RETURN_INET_P(a1);
+ 	else
+ 		PG_RETURN_INET_P(a2);
+ }
  /*
   * Support function for hash indexes on inet/cidr.
   */
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 164,169 **** DATA(insert ( 2050	n 0 array_larger	-				-				-				-				f f 1073	2277	0	0		0	_nu
--- 164,170 ----
  DATA(insert ( 2244	n 0 bpchar_larger	-				-				-				-				f f 1060	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2797	n 0 tidlarger		-				-				-				-				f f 2800	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3526	n 0 enum_larger		-				-				-				-				f f 3519	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3259	n 0 network_larger	-				-				-				-				f f 1205	869		0	0		0	_null_ _null_ ));
  
  /* min */
  DATA(insert ( 2131	n 0 int8smaller		-				-				-				-				f f 412		20		0	0		0	_null_ _null_ ));
***************
*** 186,191 **** DATA(insert ( 2051	n 0 array_smaller	-				-				-				-				f f 1072	2277	0	0		0	_n
--- 187,193 ----
  DATA(insert ( 2245	n 0 bpchar_smaller	-				-				-				-				f f 1058	1042	0	0		0	_null_ _null_ ));
  DATA(insert ( 2798	n 0 tidsmaller		-				-				-				-				f f 2799	27		0	0		0	_null_ _null_ ));
  DATA(insert ( 3527	n 0 enum_smaller	-				-				-				-				f f 3518	3500	0	0		0	_null_ _null_ ));
+ DATA(insert ( 3260	n 0 network_smaller	-				-				-				-				f f 1203	869		0	0		0	_null_ _null_ ));
  
  /* count */
  DATA(insert ( 2147	n 0 int8inc_any		-				int8inc_any		int8dec_any		-				f f 0		20		0	20		0	"0" "0" ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2122,2127 **** DATA(insert OID = 922 (  network_le			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 1
--- 2122,2131 ----
  DATA(insert OID = 923 (  network_gt			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_gt _null_ _null_ _null_ ));
  DATA(insert OID = 924 (  network_ge			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ge _null_ _null_ _null_ ));
  DATA(insert OID = 925 (  network_ne			PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_ne _null_ _null_ _null_ ));
+ DATA(insert OID = 3261 (  network_larger	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_larger _null_ _null_ _null_ ));
+ DESCR("larger of two network types");
+ DATA(insert OID = 3262 (  network_smaller	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_	network_smaller _null_ _null_ _null_ ));
+ DESCR("smaller of two network types");
  DATA(insert OID = 926 (  network_cmp		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_	network_cmp _null_ _null_ _null_ ));
  DESCR("less-equal-greater");
  DATA(insert OID = 927 (  network_sub		PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_	network_sub _null_ _null_ _null_ ));
***************
*** 3163,3168 **** DATA(insert OID = 2244 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3167,3174 ----
  DESCR("maximum value of all bpchar input values");
  DATA(insert OID = 2797 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("maximum value of all tid input values");
+ DATA(insert OID = 3259 (  max				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("maximum value of all inet input values");
  
  DATA(insert OID = 2131 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "20" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all bigint input values");
***************
*** 3202,3207 **** DATA(insert OID = 2245 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 1042 "
--- 3208,3215 ----
  DESCR("minimum value of all bpchar input values");
  DATA(insert OID = 2798 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 27 "27" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
  DESCR("minimum value of all tid input values");
+ DATA(insert OID = 3260 (  min				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 869 "869" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
+ DESCR("minimum value of all inet input values");
  
  /* count has two forms: count(any) and count(*) */
  DATA(insert OID = 2147 (  count				PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 20 "2276" _null_ _null_ _null_ _null_	aggregate_dummy _null_ _null_ _null_ ));
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 908,913 **** extern Datum network_eq(PG_FUNCTION_ARGS);
--- 908,915 ----
  extern Datum network_ge(PG_FUNCTION_ARGS);
  extern Datum network_gt(PG_FUNCTION_ARGS);
  extern Datum network_ne(PG_FUNCTION_ARGS);
+ extern Datum network_smaller(PG_FUNCTION_ARGS);
+ extern Datum network_larger(PG_FUNCTION_ARGS);
  extern Datum hashinet(PG_FUNCTION_ARGS);
  extern Datum network_sub(PG_FUNCTION_ARGS);
  extern Datum network_subeq(PG_FUNCTION_ARGS);
*** a/src/test/regress/expected/inet.out
--- b/src/test/regress/expected/inet.out
***************
*** 204,209 **** SELECT '' AS ten, i, c,
--- 204,215 ----
       | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t   | t
  (17 rows)
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+      max     |    min    
+ -------------+-----------
+  10:23::ffff | 9.1.2.3/8
+ (1 row)
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
   ten |   set_masklen    
*** a/src/test/regress/sql/inet.sql
--- b/src/test/regress/sql/inet.sql
***************
*** 56,61 **** SELECT '' AS ten, i, c,
--- 56,63 ----
    i && c AS ovr
    FROM INET_TBL;
  
+ SELECT max(i) as max, min(i) as min FROM INET_TBL;
+ 
  -- check the conversion to/from text and set_netmask
  SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
  
#29Tom Lane
tgl@sss.pgh.pa.us
In reply to: Haribabu Kommi (#28)
Re: [BUGS] BUG #9652: inet types don't support min/max

Haribabu Kommi <kommi.haribabu@gmail.com> writes:

Thanks for your review. Please find the rebased patch to latest HEAD.

Committed with minor (mostly cosmetic) alterations.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#30Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Tom Lane (#29)
Re: [BUGS] BUG #9652: inet types don't support min/max

On Fri, Aug 29, 2014 at 12:39 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Haribabu Kommi <kommi.haribabu@gmail.com> writes:

Thanks for your review. Please find the rebased patch to latest HEAD.

Committed with minor (mostly cosmetic) alterations.

Thanks.

Regards,
Hari Babu
Fujitsu Australia

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers