From f8a18a1d8e129156123e1fc4b990d52a6f9c8539 Mon Sep 17 00:00:00 2001
From: myzhen <zhenmingyang@yeah.net>
Date: Tue, 6 Jan 2026 18:42:28 +0800
Subject: [PATCH] Fix incorrect column name in error message for range
 partition bound check.

When range partition boundary value lists contain MINVALUE or MAXVALUE, and subsequent
boundary values cannot be implicitly cast to the corresponding partition key data type,
the error message references an incorrect column name.
---
 src/backend/parser/parse_utilcmd.c | 85 ++++++++++++------------------
 1 file changed, 35 insertions(+), 50 deletions(-)

diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 3f4393b52ea..6d909d407a7 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -140,7 +140,6 @@ static void setSchemaName(const char *context_schema, char **stmt_schema_name);
 static void transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound);
 static List *transformPartitionRangeBounds(ParseState *pstate, List *blist,
 										   Relation parent);
-static void validateInfiniteBounds(ParseState *pstate, List *blist);
 static Const *transformPartitionBoundValue(ParseState *pstate, Node *val,
 										   const char *colName, Oid colType, int32 colTypmod,
 										   Oid partCollation);
@@ -4755,6 +4754,7 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
 	PartitionKey key = RelationGetPartitionKey(parent);
 	List	   *partexprs = get_partition_exprs(key);
 	ListCell   *lc;
+	PartitionRangeDatumKind kind = PARTITION_RANGE_DATUM_VALUE;
 	int			i,
 				j;
 
@@ -4804,6 +4804,39 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
 			}
 		}
 
+		/*
+		 * Once we see MINVALUE or MAXVALUE for one column, the remaining columns
+		 * must be the same.
+		 */
+		if (kind == PARTITION_RANGE_DATUM_VALUE && prd)
+			kind = prd->kind;
+
+		if (kind != PARTITION_RANGE_DATUM_VALUE &&
+			(prd == NULL ||
+			 kind != prd->kind))
+		{
+			switch (kind)
+			{
+				case PARTITION_RANGE_DATUM_VALUE:
+					/* shouldn't happen, but keep compiler quiet */
+					break;
+
+				case PARTITION_RANGE_DATUM_MAXVALUE:
+					ereport(ERROR,
+							(errcode(ERRCODE_DATATYPE_MISMATCH),
+							 errmsg("every bound following MAXVALUE must also be MAXVALUE"),
+							 parser_errposition(pstate, exprLocation(expr))));
+					break;
+
+				case PARTITION_RANGE_DATUM_MINVALUE:
+					ereport(ERROR,
+							(errcode(ERRCODE_DATATYPE_MISMATCH),
+							 errmsg("every bound following MINVALUE must also be MINVALUE"),
+							 parser_errposition(pstate, exprLocation(expr))));
+					break;
+			}
+		}
+
 		if (prd == NULL)
 		{
 			char	   *colname;
@@ -4841,65 +4874,17 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
 			prd = makeNode(PartitionRangeDatum);
 			prd->kind = PARTITION_RANGE_DATUM_VALUE;
 			prd->value = (Node *) value;
-			++i;
 		}
 
 		prd->location = exprLocation(expr);
+		++i;
 
 		result = lappend(result, prd);
 	}
 
-	/*
-	 * Once we see MINVALUE or MAXVALUE for one column, the remaining columns
-	 * must be the same.
-	 */
-	validateInfiniteBounds(pstate, result);
-
 	return result;
 }
 
-/*
- * validateInfiniteBounds
- *
- * Check that a MAXVALUE or MINVALUE specification in a partition bound is
- * followed only by more of the same.
- */
-static void
-validateInfiniteBounds(ParseState *pstate, List *blist)
-{
-	ListCell   *lc;
-	PartitionRangeDatumKind kind = PARTITION_RANGE_DATUM_VALUE;
-
-	foreach(lc, blist)
-	{
-		PartitionRangeDatum *prd = lfirst_node(PartitionRangeDatum, lc);
-
-		if (kind == prd->kind)
-			continue;
-
-		switch (kind)
-		{
-			case PARTITION_RANGE_DATUM_VALUE:
-				kind = prd->kind;
-				break;
-
-			case PARTITION_RANGE_DATUM_MAXVALUE:
-				ereport(ERROR,
-						(errcode(ERRCODE_DATATYPE_MISMATCH),
-						 errmsg("every bound following MAXVALUE must also be MAXVALUE"),
-						 parser_errposition(pstate, exprLocation((Node *) prd))));
-				break;
-
-			case PARTITION_RANGE_DATUM_MINVALUE:
-				ereport(ERROR,
-						(errcode(ERRCODE_DATATYPE_MISMATCH),
-						 errmsg("every bound following MINVALUE must also be MINVALUE"),
-						 parser_errposition(pstate, exprLocation((Node *) prd))));
-				break;
-		}
-	}
-}
-
 /*
  * Transform one entry in a partition bound spec, producing a constant.
  */
-- 
2.28.0.windows.1

