Skip to content

Commit 2dcadd4

Browse files
committed
Speed up summary truncate replacement logic
This was calling strlen on every iteration of the loop, causing excessive runtime on deeply nested queries (e.g. hundreds of UNION ALL). In passing, make explicit an assumption that the replacement string is as long, or shorter, than the pattern we're matching against.
1 parent 180ef56 commit 2dcadd4

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/pg_query_summary_truncate.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,23 @@ global_replace(char *str, char *pattern, char *replacement)
287287
{
288288
size_t plen = strlen(pattern);
289289
size_t rlen = strlen(replacement);
290+
size_t slen = strlen(str);
290291

291-
for (size_t i = 0; i < strlen(str); i++)
292+
Assert(plen >= rlen);
293+
294+
for (size_t i = 0; i < slen; i++)
292295
{
293296
if (memcmp(str + i, pattern, plen) == 0)
294297
{
295-
size_t len = strlen(str + i + plen);
296-
297298
memcpy(str + i, replacement, rlen);
298-
memmove(str + i + rlen, str + i + plen, len + 1);
299+
300+
// Shorten the string if needed
301+
if (plen > rlen)
302+
{
303+
size_t skip = i + plen;
304+
memmove(str + i + rlen, str + skip, slen - skip + 1);
305+
slen -= (plen - rlen);
306+
}
299307
}
300308
}
301309
}

0 commit comments

Comments
 (0)