From 55d0b2adb204999a293ab1075c3af28cbf5d57e4 Mon Sep 17 00:00:00 2001
From: sohardforaname <organic_chemistry@foxmail.com>
Date: Wed, 26 Aug 2026 23:20:38 +0800
Subject: [PATCH] Speed up repeat() for larger counts

Build repeated strings by reusing and doubling the portion of the result
already produced, reducing the number of memcpy() calls. Use memset()
for single-byte input strings.
---
 src/backend/utils/adt/oracle_compat.c | 35 ++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 7422a454397..602ac1a4bcb 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -1165,7 +1165,7 @@ repeat(PG_FUNCTION_ARGS)
 	text	   *result;
 	int			slen,
 				tlen;
-	int			i;
+	int			curcount;
 	char	   *cp,
 			   *sp;
 
@@ -1186,10 +1186,37 @@ repeat(PG_FUNCTION_ARGS)
 	SET_VARSIZE(result, tlen);
 	cp = VARDATA(result);
 	sp = VARDATA_ANY(string);
-	for (i = 0; i < count; i++)
+
+	if (count == 0 || slen == 0)
+		PG_RETURN_TEXT_P(result);
+
+	if (slen == 1)
+	{
+		memset(cp, *sp, count);
+		CHECK_FOR_INTERRUPTS();
+		PG_RETURN_TEXT_P(result);
+	}
+
+	memcpy(cp, sp, slen);
+	cp += slen;
+	CHECK_FOR_INTERRUPTS();
+
+	curcount = 1;
+
+	/*
+	 * Reuse the portion of the result already produced, doubling the number
+	 * of copies on each iteration until the requested count is reached.
+	 *
+	 * chunk is never greater than curcount, so the source and destination
+	 * ranges of memcpy() do not overlap.
+	 */
+	while (curcount < count)
 	{
-		memcpy(cp, sp, slen);
-		cp += slen;
+		int			chunk = Min(curcount, count - curcount);
+
+		memcpy(cp, VARDATA(result), chunk * slen);
+		cp += chunk * slen;
+		curcount += chunk;
 		CHECK_FOR_INTERRUPTS();
 	}
 
-- 
2.43.0

