From 5cc0f02ea41128e9c8588ab058319e1b93aef87b Mon Sep 17 00:00:00 2001
From: Amul Sul <amul.sul@enterprisedb.com>
Date: Tue, 13 Dec 2022 12:19:47 +0530
Subject: [PATCH v1 07/25] Change cidr_in and inet_in to allow non-throw error
 reporting

---
 src/backend/utils/adt/network.c    | 14 +++++------
 src/test/regress/expected/inet.out | 37 ++++++++++++++++++++++++++++++
 src/test/regress/sql/inet.sql      |  9 ++++++++
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index 6d580ea78f6..42a4d9d44ec 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -72,7 +72,7 @@ static inet *internal_inetpl(inet *ip, int64 addend);
  * Common INET/CIDR input routine
  */
 static inet *
-network_in(char *src, bool is_cidr)
+network_in(char *src, bool is_cidr, Node *escontext)
 {
 	int			bits;
 	inet	   *dst;
@@ -93,7 +93,7 @@ network_in(char *src, bool is_cidr)
 	bits = pg_inet_net_pton(ip_family(dst), src, ip_addr(dst),
 							is_cidr ? ip_addrsize(dst) : -1);
 	if ((bits < 0) || (bits > ip_maxbits(dst)))
-		ereport(ERROR,
+		ereturn(escontext, NULL,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 		/* translator: first %s is inet or cidr */
 				 errmsg("invalid input syntax for type %s: \"%s\"",
@@ -105,7 +105,7 @@ network_in(char *src, bool is_cidr)
 	if (is_cidr)
 	{
 		if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
-			ereport(ERROR,
+			ereturn(escontext, NULL,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 					 errmsg("invalid cidr value: \"%s\"", src),
 					 errdetail("Value has bits set to right of mask.")));
@@ -122,7 +122,7 @@ inet_in(PG_FUNCTION_ARGS)
 {
 	char	   *src = PG_GETARG_CSTRING(0);
 
-	PG_RETURN_INET_P(network_in(src, false));
+	PG_RETURN_INET_P(network_in(src, false, fcinfo->context));
 }
 
 Datum
@@ -130,7 +130,7 @@ cidr_in(PG_FUNCTION_ARGS)
 {
 	char	   *src = PG_GETARG_CSTRING(0);
 
-	PG_RETURN_INET_P(network_in(src, true));
+	PG_RETURN_INET_P(network_in(src, true, fcinfo->context));
 }
 
 
@@ -1742,7 +1742,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
 
 	clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
 
-	PG_RETURN_INET_P(network_in(remote_host, false));
+	PG_RETURN_INET_P(network_in(remote_host, false, NULL));
 }
 
 
@@ -1814,7 +1814,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
 
 	clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
 
-	PG_RETURN_INET_P(network_in(local_host, false));
+	PG_RETURN_INET_P(network_in(local_host, false, NULL));
 }
 
 
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index d5bf9e2aaa5..c9f466ac1d3 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -1056,3 +1056,40 @@ SELECT a FROM (VALUES
  ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
 (91 rows)
 
+-- test non-error-throwing API for some core types
+SELECT pg_input_is_valid('1234', 'cidr');
+ pg_input_is_valid 
+-------------------
+ f
+(1 row)
+
+SELECT pg_input_error_message('1234', 'cidr');
+           pg_input_error_message           
+--------------------------------------------
+ invalid input syntax for type cidr: "1234"
+(1 row)
+
+SELECT pg_input_is_valid('192.168.198.200/24', 'cidr');
+ pg_input_is_valid 
+-------------------
+ f
+(1 row)
+
+SELECT pg_input_error_message('192.168.198.200/24', 'cidr');
+          pg_input_error_message          
+------------------------------------------
+ invalid cidr value: "192.168.198.200/24"
+(1 row)
+
+SELECT pg_input_is_valid('1234', 'inet');
+ pg_input_is_valid 
+-------------------
+ f
+(1 row)
+
+SELECT pg_input_error_message('1234', 'inet');
+           pg_input_error_message           
+--------------------------------------------
+ invalid input syntax for type inet: "1234"
+(1 row)
+
diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql
index d2ac85bb7f0..abfcd4242f8 100644
--- a/src/test/regress/sql/inet.sql
+++ b/src/test/regress/sql/inet.sql
@@ -252,3 +252,12 @@ SELECT a FROM (VALUES
   ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet),
   ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet)
 ) AS i(a) ORDER BY a;
+
+-- test non-error-throwing API for some core types
+SELECT pg_input_is_valid('1234', 'cidr');
+SELECT pg_input_error_message('1234', 'cidr');
+SELECT pg_input_is_valid('192.168.198.200/24', 'cidr');
+SELECT pg_input_error_message('192.168.198.200/24', 'cidr');
+
+SELECT pg_input_is_valid('1234', 'inet');
+SELECT pg_input_error_message('1234', 'inet');
-- 
2.18.0

