From bb25974cd77c5afb273c0acfbf150d35da0ea0cd Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Thu, 23 May 2024 15:12:59 +1200
Subject: [PATCH v2 3/3] Special-case text type conversion in
 datum_to_json_internal

---
 src/backend/utils/adt/json.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index a266f60ff3..371881dfd0 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -24,6 +24,7 @@
 #include "utils/builtins.h"
 #include "utils/date.h"
 #include "utils/datetime.h"
+#include "utils/fmgroids.h"
 #include "utils/json.h"
 #include "utils/jsonfuncs.h"
 #include "utils/lsyscache.h"
@@ -286,9 +287,15 @@ datum_to_json_internal(Datum val, bool is_null, StringInfo result,
 			pfree(jsontext);
 			break;
 		default:
-			outputstr = OidOutputFunctionCall(outfuncoid, val);
-			escape_json_cstring(result, outputstr);
-			pfree(outputstr);
+			/* special-case text types to save useless palloc/memcpy cycles */
+			if (outfuncoid == F_TEXTOUT || outfuncoid ==  F_VARCHAROUT || outfuncoid == F_BPCHAROUT)
+				escape_json_from_text(result, (text *) DatumGetPointer(val));
+			else
+			{
+				outputstr = OidOutputFunctionCall(outfuncoid, val);
+				escape_json_cstring(result, outputstr);
+				pfree(outputstr);
+			}
 			break;
 	}
 }
-- 
2.34.1

