From 758cd2f2f6e7a9e5b649cdafedf861de0541e292 Mon Sep 17 00:00:00 2001
From: Ranier Vilela <ranier.vf@gmail.com>
Date: Wed, 30 Aug 2023 14:44:02 -0300
Subject: [PATCH 3/3] Avoid unecessary calls to strlen function.

cstring_to_text call strlen to calculate the size of string parameter.
Where we can know the size, we can avoid.

Author: Ranier Vilela (ranier.vf@gmail.com)
---
 src/backend/commands/event_trigger.c |  2 +-
 src/backend/utils/adt/arrayfuncs.c   |  2 +-
 src/backend/utils/adt/formatting.c   |  2 +-
 src/backend/utils/adt/misc.c         |  4 ++--
 src/backend/utils/adt/quote.c        |  2 +-
 src/backend/utils/adt/timestamp.c    |  5 +++--
 src/backend/utils/adt/tsquery.c      |  2 +-
 src/backend/utils/adt/varlena.c      | 18 +++++++++---------
 src/pl/plpgsql/src/pl_exec.c         |  2 +-
 9 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index d4b00d1a82..a487abbd59 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -347,7 +347,7 @@ filter_list_to_array(List *filterlist)
 		result = pstrdup(value);
 		for (p = result; *p; p++)
 			*p = pg_ascii_toupper((unsigned char) *p);
-		data[i++] = PointerGetDatum(cstring_to_text(result));
+		data[i++] = PointerGetDatum(cstring_to_text_with_len(result, p - result));
 		pfree(result);
 	}
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 7828a6264b..b4b1fe37c3 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -1708,7 +1708,7 @@ array_dims(PG_FUNCTION_ARGS)
 		p += strlen(p);
 	}
 
-	PG_RETURN_TEXT_P(cstring_to_text(buf));
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, p - buf));
 }
 
 /*
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index e27ea8ef97..cc6db71d81 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -6059,7 +6059,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
 do { \
 	int len = VARSIZE_ANY_EXHDR(fmt); \
 	if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ)		\
-		PG_RETURN_TEXT_P(cstring_to_text("")); \
+		PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0)); \
 	result	= (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ);	\
 	format	= NUM_cache(len, &Num, fmt, &shouldFree);		\
 } while (0)
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 5d78d6dc06..ee45639720 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -319,7 +319,7 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 	 */
 	if (tablespaceOid == DEFAULTTABLESPACE_OID ||
 		tablespaceOid == GLOBALTABLESPACE_OID)
-		PG_RETURN_TEXT_P(cstring_to_text(""));
+		PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0));
 
 	/*
 	 * Find the location of the tablespace by reading the symbolic link that
@@ -360,7 +360,7 @@ pg_tablespace_location(PG_FUNCTION_ARGS)
 						sourcepath)));
 	targetpath[rllen] = '\0';
 
-	PG_RETURN_TEXT_P(cstring_to_text(targetpath));
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(targetpath, rllen));
 }
 
 /*
diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c
index f2f633befa..441f94581a 100644
--- a/src/backend/utils/adt/quote.c
+++ b/src/backend/utils/adt/quote.c
@@ -125,7 +125,7 @@ Datum
 quote_nullable(PG_FUNCTION_ARGS)
 {
 	if (PG_ARGISNULL(0))
-		PG_RETURN_TEXT_P(cstring_to_text("NULL"));
+		PG_RETURN_TEXT_P(cstring_to_text_with_len("NULL", 4));
 	else
 		PG_RETURN_DATUM(DirectFunctionCall1(quote_literal,
 											PG_GETARG_DATUM(0)));
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 0e50aaec5a..4a91e4cf75 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -1632,14 +1632,15 @@ timeofday(PG_FUNCTION_ARGS)
 	char		templ[128];
 	char		buf[128];
 	pg_time_t	tt;
+	int			len;
 
 	gettimeofday(&tp, NULL);
 	tt = (pg_time_t) tp.tv_sec;
 	pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
 				pg_localtime(&tt, session_timezone));
-	snprintf(buf, sizeof(buf), templ, tp.tv_usec);
+	len = snprintf(buf, sizeof(buf), templ, tp.tv_usec);
 
-	PG_RETURN_TEXT_P(cstring_to_text(buf));
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
 }
 
 /*
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 67ad876a27..3855677f0d 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -1382,7 +1382,7 @@ tsquerytree(PG_FUNCTION_ARGS)
 
 	if (!q)
 	{
-		res = cstring_to_text("T");
+		res = cstring_to_text_with_len("T", 1);
 	}
 	else
 	{
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 72e1e24fe0..495dff4e65 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -924,7 +924,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 			 * string.
 			 */
 			if (E < 1)
-				return cstring_to_text("");
+				return cstring_to_text_with_len("", 0);
 
 			L1 = E - S1;
 		}
@@ -987,7 +987,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 			 * string.
 			 */
 			if (E < 1)
-				return cstring_to_text("");
+				return cstring_to_text_with_len("", 0);
 
 			/*
 			 * if E is past the end of the string, the tuple toaster will
@@ -1019,7 +1019,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 		{
 			if (slice != (text *) DatumGetPointer(str))
 				pfree(slice);
-			return cstring_to_text("");
+			return cstring_to_text_with_len("", 0);
 		}
 
 		/* Now we can get the actual length of the slice in MB characters */
@@ -1034,7 +1034,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 		{
 			if (slice != (text *) DatumGetPointer(str))
 				pfree(slice);
-			return cstring_to_text("");
+			return cstring_to_text_with_len("", 0);
 		}
 
 		/*
@@ -4386,7 +4386,7 @@ split_part(PG_FUNCTION_ARGS)
 
 	/* return empty string for empty input string */
 	if (inputstring_len < 1)
-		PG_RETURN_TEXT_P(cstring_to_text(""));
+		PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0));
 
 	/* handle empty field separator */
 	if (fldsep_len < 1)
@@ -4395,7 +4395,7 @@ split_part(PG_FUNCTION_ARGS)
 		if (fldnum == 1 || fldnum == -1)
 			PG_RETURN_TEXT_P(inputstring);
 		else
-			PG_RETURN_TEXT_P(cstring_to_text(""));
+			PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0));
 	}
 
 	/* find the first field separator */
@@ -4411,7 +4411,7 @@ split_part(PG_FUNCTION_ARGS)
 		if (fldnum == 1 || fldnum == -1)
 			PG_RETURN_TEXT_P(inputstring);
 		else
-			PG_RETURN_TEXT_P(cstring_to_text(""));
+			PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0));
 	}
 
 	/*
@@ -4443,7 +4443,7 @@ split_part(PG_FUNCTION_ARGS)
 		if (fldnum <= 0)
 		{
 			text_position_cleanup(&state);
-			PG_RETURN_TEXT_P(cstring_to_text(""));
+			PG_RETURN_TEXT_P(cstring_to_text_with_len("", 0));
 		}
 
 		/* reset to pointing at first match, but now with positive fldnum */
@@ -4479,7 +4479,7 @@ split_part(PG_FUNCTION_ARGS)
 												   inputstring_len - last_len);
 		}
 		else
-			result_text = cstring_to_text("");
+			result_text = cstring_to_text_with_len("", 0);
 	}
 	else
 	{
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 4b76f7699a..b84ce322e2 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -5058,7 +5058,7 @@ exec_assign_c_string(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
 	if (str != NULL)
 		value = cstring_to_text(str);
 	else
-		value = cstring_to_text("");
+		value = cstring_to_text_with_len("", 0);
 	MemoryContextSwitchTo(oldcontext);
 
 	exec_assign_value(estate, target, PointerGetDatum(value), false,
-- 
2.32.0.windows.1

