From 4c4c18bd8104114351ca58a73a9d92fbb0c85dd2 Mon Sep 17 00:00:00 2001
From: Amul Sul <amul.sul@enterprisedb.com>
Date: Tue, 13 Dec 2022 17:29:04 +0530
Subject: [PATCH v1 13/25] Change macaddr8_in to allow non-throw error
 reporting

---
 src/backend/utils/adt/mac8.c           | 36 +++++++++++++-------------
 src/test/regress/expected/macaddr8.out | 25 ++++++++++++++++++
 src/test/regress/sql/macaddr8.sql      |  6 +++++
 3 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/adt/mac8.c b/src/backend/utils/adt/mac8.c
index 24d219f6386..adb253a6ac0 100644
--- a/src/backend/utils/adt/mac8.c
+++ b/src/backend/utils/adt/mac8.c
@@ -35,7 +35,8 @@
 #define lobits(addr) \
   ((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
 
-static unsigned char hex2_to_uchar(const unsigned char *ptr, const unsigned char *str);
+static unsigned char hex2_to_uchar(const unsigned char *ptr, const unsigned char *str,
+								   Node *escontext);
 
 static const signed char hexlookup[128] = {
 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -58,7 +59,8 @@ static const signed char hexlookup[128] = {
  * the entire string, which is used only for error reporting.
  */
 static inline unsigned char
-hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
+hex2_to_uchar(const unsigned char *ptr, const unsigned char *str,
+			  Node *escontext)
 {
 	unsigned char ret = 0;
 	signed char lookup;
@@ -88,13 +90,10 @@ hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
 	return ret;
 
 invalid_input:
-	ereport(ERROR,
+	ereturn(escontext, 0,
 			(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 			 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
 					str)));
-
-	/* We do not actually reach here */
-	return 0;
 }
 
 /*
@@ -104,6 +103,7 @@ Datum
 macaddr8_in(PG_FUNCTION_ARGS)
 {
 	const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
+	Node	   *escontext = fcinfo->context;
 	const unsigned char *ptr = str;
 	macaddr8   *result;
 	unsigned char a = 0,
@@ -136,32 +136,32 @@ macaddr8_in(PG_FUNCTION_ARGS)
 		switch (count)
 		{
 			case 1:
-				a = hex2_to_uchar(ptr, str);
+				a = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 2:
-				b = hex2_to_uchar(ptr, str);
+				b = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 3:
-				c = hex2_to_uchar(ptr, str);
+				c = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 4:
-				d = hex2_to_uchar(ptr, str);
+				d = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 5:
-				e = hex2_to_uchar(ptr, str);
+				e = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 6:
-				f = hex2_to_uchar(ptr, str);
+				f = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 7:
-				g = hex2_to_uchar(ptr, str);
+				g = hex2_to_uchar(ptr, str, escontext);
 				break;
 			case 8:
-				h = hex2_to_uchar(ptr, str);
+				h = hex2_to_uchar(ptr, str, escontext);
 				break;
 			default:
 				/* must be trailing garbage... */
-				ereport(ERROR,
+				ereturn(escontext, (Datum) 0,
 						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 						 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
 								str)));
@@ -179,7 +179,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
 
 			/* Have to use the same spacer throughout */
 			else if (spacer != *ptr)
-				ereport(ERROR,
+				ereturn(escontext, (Datum) 0,
 						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 						 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
 								str)));
@@ -197,7 +197,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
 
 				/* If we found a space and then non-space, it's invalid */
 				if (*ptr)
-					ereport(ERROR,
+					ereturn(escontext, (Datum) 0,
 							(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 							 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
 									str)));
@@ -216,7 +216,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
 		e = 0xFE;
 	}
 	else if (count != 8)
-		ereport(ERROR,
+		ereturn(escontext, (Datum) 0,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
 						str)));
diff --git a/src/test/regress/expected/macaddr8.out b/src/test/regress/expected/macaddr8.out
index 74f53a121f2..bf681988f87 100644
--- a/src/test/regress/expected/macaddr8.out
+++ b/src/test/regress/expected/macaddr8.out
@@ -352,3 +352,28 @@ SELECT  b | '01:02:03:04:05:06' FROM macaddr8_data;
 (20 rows)
 
 DROP TABLE macaddr8_data;
+-- test non-error-throwing API for some core types
+SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+ pg_input_is_valid 
+-------------------
+ f
+(1 row)
+
+SELECT pg_input_error_message('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+                      pg_input_error_message                       
+-------------------------------------------------------------------
+ invalid input syntax for type macaddr8: "08:00:2b:01:02:03:04:ZZ"
+(1 row)
+
+SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8');
+ pg_input_is_valid 
+-------------------
+ f
+(1 row)
+
+SELECT pg_input_error_message('08:00:2b:01:02:03:04:', 'macaddr8');
+                     pg_input_error_message                      
+-----------------------------------------------------------------
+ invalid input syntax for type macaddr8: "08:00:2b:01:02:03:04:"
+(1 row)
+
diff --git a/src/test/regress/sql/macaddr8.sql b/src/test/regress/sql/macaddr8.sql
index 57a227c5ab7..b29f785b41e 100644
--- a/src/test/regress/sql/macaddr8.sql
+++ b/src/test/regress/sql/macaddr8.sql
@@ -87,3 +87,9 @@ SELECT  b & '00:00:00:ff:ff:ff' FROM macaddr8_data;
 SELECT  b | '01:02:03:04:05:06' FROM macaddr8_data;
 
 DROP TABLE macaddr8_data;
+
+-- test non-error-throwing API for some core types
+SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+SELECT pg_input_error_message('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8');
+SELECT pg_input_error_message('08:00:2b:01:02:03:04:', 'macaddr8');
-- 
2.18.0

