From 76ef2ae62de3a65f7dc1b9e32efa8bd032eb7eee Mon Sep 17 00:00:00 2001
From: "dgrowley@gmail.com" <dgrowley@gmail.com>
Date: Wed, 10 Jun 2020 11:06:17 +1200
Subject: [PATCH 2/2] Have pg_itoa, pg_ltoa and pg_lltoa return the length of
 the string

Core by no means makes excessive use of these functions, but quite a large
number of those usages do require the caller to call strlen() on the
string.  This is quite wasteful since these functions do have a good idea
of the length of the string already, so we might as well just have them
return that.
---
 src/backend/access/common/printsimple.c | 10 ++++----
 src/backend/utils/adt/int.c             |  4 +---
 src/backend/utils/adt/numutils.c        | 32 +++++++++++++++----------
 src/include/utils/builtins.h            |  6 ++---
 4 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
index 0f0b54bdae..df27700df9 100644
--- a/src/backend/access/common/printsimple.c
+++ b/src/backend/access/common/printsimple.c
@@ -103,9 +103,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
 				{
 					int32		num = DatumGetInt32(value);
 					char		str[12];	/* sign, 10 digits and '\0' */
+					int			len;
 
-					pg_ltoa(num, str);
-					pq_sendcountedtext(&buf, str, strlen(str), false);
+					len = pg_ltoa(num, str);
+					pq_sendcountedtext(&buf, str, len, false);
 				}
 				break;
 
@@ -113,9 +114,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
 				{
 					int64		num = DatumGetInt64(value);
 					char		str[MAXINT8LEN + 1];
+					int			len;
 
-					pg_lltoa(num, str);
-					pq_sendcountedtext(&buf, str, strlen(str), false);
+					len = pg_lltoa(num, str);
+					pq_sendcountedtext(&buf, str, len, false);
 				}
 				break;
 
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 63c59c56b3..418c13e1b4 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -191,9 +191,7 @@ int2vectorout(PG_FUNCTION_ARGS)
 	{
 		if (num != 0)
 			*rp++ = ' ';
-		pg_itoa(int2Array->values[num], rp);
-		while (*++rp != '\0')
-			;
+		rp += pg_itoa(int2Array->values[num], rp);
 	}
 	*rp = '\0';
 	PG_RETURN_CSTRING(result);
diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c
index 13877fdc1d..608539b0ce 100644
--- a/src/backend/utils/adt/numutils.c
+++ b/src/backend/utils/adt/numutils.c
@@ -327,16 +327,17 @@ invalid_syntax:
 
 /*
  * pg_itoa: converts a signed 16-bit integer to its string representation
+ * and returns strlen(a).
  *
  * Caller must ensure that 'a' points to enough memory to hold the result
  * (at least 7 bytes, counting a leading sign and trailing NUL).
  *
  * It doesn't seem worth implementing this separately.
  */
-void
+int
 pg_itoa(int16 i, char *a)
 {
-	pg_ltoa((int32) i, a);
+	return pg_ltoa((int32) i, a);
 }
 
 /*
@@ -404,26 +405,28 @@ pg_ultoa_n(uint32 value, char *a)
 }
 
 /*
- * NUL-terminate the output of pg_ultoa_n.
+ * pg_ltoa: converts a signed 32-bit integer to its string representation and
+ * returns strlen(a).
  *
  * It is the caller's responsibility to ensure that a is at least 12 bytes long,
  * which is enough room to hold a minus sign, a maximally long int32, and the
  * above terminating NUL.
  */
-void
+int
 pg_ltoa(int32 value, char *a)
 {
 
 	uint32		uvalue = (uint32) value;
-	int			len;
+	int			len = 0;
 
 	if (value < 0)
 	{
 		uvalue = (uint32) 0 - uvalue;
-		*a++ = '-';
+		a[len++] = '-';
 	}
-	len = pg_ultoa_n(uvalue, a);
+	len += pg_ultoa_n(uvalue, a + len);
 	a[len] = '\0';
+	return len;
 }
 
 /*
@@ -512,24 +515,27 @@ pg_ulltoa_n(uint64 value, char *a)
 }
 
 /*
- * pg_lltoa: convert a signed 64-bit integer to its string representation
+ * pg_lltoa: converts a signed 64-bit integer to its string representation and
+ * returns strlen(a).
  *
  * Caller must ensure that 'a' points to enough memory to hold the result
  * (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
  */
-void
+int
 pg_lltoa(int64 value, char *a)
 {
-	int			len;
+	int			len = 0;
 	uint64		uvalue = value;
 
 	if (value < 0)
 	{
-		*a++ = '-';
 		uvalue = (uint64) 0 - uvalue;
+		a[len++] = '-';
 	}
-	len = pg_ulltoa_n(uvalue, a);
-	a[len] = 0;
+
+	len += pg_ulltoa_n(uvalue, a + len);
+	a[len] = '\0';
+	return len;
 }
 
 
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index a352a8b773..019c150f22 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -47,11 +47,11 @@ extern int	namestrcmp(Name name, const char *str);
 extern int32 pg_atoi(const char *s, int size, int c);
 extern int16 pg_strtoint16(const char *s);
 extern int32 pg_strtoint32(const char *s);
-extern void pg_itoa(int16 i, char *a);
+extern int pg_itoa(int16 i, char *a);
 int			pg_ultoa_n(uint32 l, char *a);
 int			pg_ulltoa_n(uint64 l, char *a);
-extern void pg_ltoa(int32 l, char *a);
-extern void pg_lltoa(int64 ll, char *a);
+extern int pg_ltoa(int32 l, char *a);
+extern int pg_lltoa(int64 ll, char *a);
 extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth);
 extern char *pg_ultostr(char *str, uint32 value);
 extern uint64 pg_strtouint64(const char *str, char **endptr, int base);
-- 
2.25.1

