nocfbot-0064-Modernize-idioms-in-row-pattern-recognition-code.txt

text/plain

Filename: nocfbot-0064-Modernize-idioms-in-row-pattern-recognition-code.txt
Type: text/plain
Part: 64
Message: Re: Row pattern recognition
From ad3e63eea24c4f80f8d18ef7b5cc40fff14e4828 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Mon, 8 Jun 2026 13:59:43 +0900
Subject: [PATCH 64/68] Modernize idioms in row pattern recognition code

Replace appendStringInfo() with appendStringInfoString() for the eight
constant string literals that contain no format specifiers, avoiding an
unnecessary trip through vsnprintf().

Replace the four palloc(n * sizeof(type)) calls in _copyRPRPattern() and
_readRPRPattern() with palloc_array()/palloc0_array(), which make the
element type and count explicit and guard against size multiplication
overflow.

Replace an open-coded maximum in scanRPRPatternRecursive() with Max().

These are mechanical idiom changes only; behavior, output, and ABI are
unchanged, and the row pattern regression tests pass with no .out diffs.
---
 src/backend/commands/explain.c    | 15 ++++++++-------
 src/backend/nodes/copyfuncs.c     |  4 ++--
 src/backend/nodes/readfuncs.c     |  4 ++--
 src/backend/optimizer/plan/rpr.c  |  3 +--
 src/backend/utils/adt/ruleutils.c |  3 ++-
 5 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 7ba0b6df849..7992829d5c4 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -2932,7 +2932,8 @@ append_rpr_quantifier(StringInfo buf, RPRPatternElement *elem)
 	if (RPRElemIsReluctant(elem))
 	{
 		if (elem->min == 1 && elem->max == 1)
-			appendStringInfo(buf, "{1}");	/* make reluctant ? unambiguous */
+			appendStringInfoString(buf, "{1}"); /* make reluctant ?
+												 * unambiguous */
 		appendStringInfoChar(buf, '?');
 	}
 
@@ -3929,7 +3930,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 
 		/* Match/mismatch counts with length min/max/avg */
 		ExplainIndentText(es);
-		appendStringInfo(es->str, "NFA: ");
+		appendStringInfoString(es->str, "NFA: ");
 		if (winstate->nfaMatchesSucceeded > 0)
 		{
 			double		avgLen = (double) winstate->nfaMatchLen.total / winstate->nfaMatchesSucceeded;
@@ -3943,7 +3944,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 		}
 		else
 		{
-			appendStringInfo(es->str, "0 matched");
+			appendStringInfoString(es->str, "0 matched");
 		}
 		if (winstate->nfaMatchesFailed > 0)
 		{
@@ -3958,7 +3959,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 		}
 		else
 		{
-			appendStringInfo(es->str, ", 0 mismatched");
+			appendStringInfoString(es->str, ", 0 mismatched");
 		}
 		appendStringInfoChar(es->str, '\n');
 
@@ -3966,7 +3967,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 		if (winstate->nfaContextsAbsorbed > 0 || winstate->nfaContextsSkipped > 0)
 		{
 			ExplainIndentText(es);
-			appendStringInfo(es->str, "NFA: ");
+			appendStringInfoString(es->str, "NFA: ");
 
 			if (winstate->nfaContextsAbsorbed > 0)
 			{
@@ -3981,7 +3982,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 			}
 			else
 			{
-				appendStringInfo(es->str, "0 absorbed");
+				appendStringInfoString(es->str, "0 absorbed");
 			}
 
 			if (winstate->nfaContextsSkipped > 0)
@@ -3997,7 +3998,7 @@ show_rpr_nfa_stats(WindowAggState *winstate, ExplainState *es)
 			}
 			else
 			{
-				appendStringInfo(es->str, ", 0 skipped");
+				appendStringInfoString(es->str, ", 0 skipped");
 			}
 
 			appendStringInfoChar(es->str, '\n');
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index e67ad39bdb8..17d45930d7b 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -178,13 +178,13 @@ _copyRPRPattern(const RPRPattern *from)
 
 	/* Deep copy the varNames array (DEFINE clause is required) */
 	Assert(from->numVars > 0);
-	newnode->varNames = palloc0(from->numVars * sizeof(char *));
+	newnode->varNames = palloc0_array(char *, from->numVars);
 	for (int i = 0; i < from->numVars; i++)
 		newnode->varNames[i] = pstrdup(from->varNames[i]);
 
 	/* Deep copy the elements array (always has at least one element + FIN) */
 	Assert(from->numElements >= 2);
-	newnode->elements = palloc(from->numElements * sizeof(RPRPatternElement));
+	newnode->elements = palloc_array(RPRPatternElement, from->numElements);
 	memcpy(newnode->elements, from->elements,
 		   from->numElements * sizeof(RPRPatternElement));
 
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 5bbde5bcad2..6c39c6fe06d 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -582,7 +582,7 @@ _readRPRPattern(void)
 	token = pg_strtok(&length); /* get '(' or '<>' */
 	if (local_node->numVars > 0 && token[0] == '(')
 	{
-		local_node->varNames = palloc(local_node->numVars * sizeof(char *));
+		local_node->varNames = palloc_array(char *, local_node->numVars);
 		for (int i = 0; i < local_node->numVars; i++)
 		{
 			token = pg_strtok(&length);
@@ -600,7 +600,7 @@ _readRPRPattern(void)
 	token = pg_strtok(&length); /* get '(' or '<>' */
 	if (local_node->numElements > 0 && token[0] == '(')
 	{
-		local_node->elements = palloc0(local_node->numElements * sizeof(RPRPatternElement));
+		local_node->elements = palloc0_array(RPRPatternElement, local_node->numElements);
 		for (int i = 0; i < local_node->numElements; i++)
 		{
 			RPRPatternElement *elem = &local_node->elements[i];
diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c
index 143ea034fb3..9364136b071 100644
--- a/src/backend/optimizer/plan/rpr.c
+++ b/src/backend/optimizer/plan/rpr.c
@@ -1048,8 +1048,7 @@ scanRPRPatternRecursive(RPRPatternNode *node, char **varNames, int *numVars,
 						  depth, RPR_DEPTH_MAX - 1));
 
 	/* Track maximum depth */
-	if (depth > *maxDepth)
-		*maxDepth = depth;
+	*maxDepth = Max(*maxDepth, depth);
 
 	switch (node->nodeType)
 	{
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 2b8439e452e..e8087d4316a 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -7140,7 +7140,8 @@ append_pattern_quantifier(StringInfo buf, RPRPatternNode *node)
 	if (node->reluctant)
 	{
 		if (!has_quantifier)
-			appendStringInfo(buf, "{1}");	/* make reluctant ? unambiguous */
+			appendStringInfoString(buf, "{1}"); /* make reluctant ?
+												 * unambiguous */
 		appendStringInfoChar(buf, '?');
 	}
 }
-- 
2.50.1 (Apple Git-155)