From 0a4a5ae8830dd411237e0221b58aaa554aa3b97b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Fri, 12 Dec 2025 14:22:00 +0100
Subject: [PATCH] add Location to IndexElem

---
 src/backend/nodes/nodeFuncs.c     | 3 +++
 src/backend/parser/gram.y         | 5 +++++
 src/backend/parser/parse_clause.c | 8 ++++----
 src/include/nodes/parsenodes.h    | 1 +
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 024a2b2fd84..89b7d80c0aa 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -1726,6 +1726,9 @@ exprLocation(const Node *expr)
 		case T_ColumnDef:
 			loc = ((const ColumnDef *) expr)->location;
 			break;
+		case T_IndexElem:
+			loc = ((const IndexElem *) expr)->location;
+			break;
 		case T_Constraint:
 			loc = ((const Constraint *) expr)->location;
 			break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7856ce9d78f..a9bad1bff04 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -8402,6 +8402,7 @@ index_elem_options:
 			$$->opclassopts = NIL;
 			$$->ordering = $3;
 			$$->nulls_ordering = $4;
+			$$->location = @1;
 		}
 	| opt_collate any_name reloptions opt_asc_desc opt_nulls_order
 		{
@@ -8414,6 +8415,7 @@ index_elem_options:
 			$$->opclassopts = $3;
 			$$->ordering = $4;
 			$$->nulls_ordering = $5;
+			$$->location = @1;
 		}
 	;
 
@@ -8426,16 +8428,19 @@ index_elem: ColId index_elem_options
 				{
 					$$ = $2;
 					$$->name = $1;
+					$$->location = @1;
 				}
 			| func_expr_windowless index_elem_options
 				{
 					$$ = $2;
 					$$->expr = $1;
+					$$->location = @1;
 				}
 			| '(' a_expr ')' index_elem_options
 				{
 					$$ = $4;
 					$$->expr = $2;
+					$$->location = @1;
 				}
 		;
 
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 57609e2d55c..34693c8a9e6 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -3289,20 +3289,20 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
 					 errmsg("%s is not allowed in ON CONFLICT clause",
 							"ASC/DESC"),
 					 parser_errposition(pstate,
-										exprLocation((Node *) infer))));
+										exprLocation((Node *) ielem))));
 		if (ielem->nulls_ordering != SORTBY_NULLS_DEFAULT)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 					 errmsg("%s is not allowed in ON CONFLICT clause",
 							"NULLS FIRST/LAST"),
 					 parser_errposition(pstate,
-										exprLocation((Node *) infer))));
+										exprLocation((Node *) ielem))));
 		if (ielem->opclassopts)
 			ereport(ERROR,
 					errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 					errmsg("operator class options are not allowed in ON CONFLICT clause"),
 					parser_errposition(pstate,
-									   exprLocation((Node *) infer)));
+									   exprLocation((Node *) ielem)));
 
 		if (!ielem->expr)
 		{
@@ -3342,7 +3342,7 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
 			pInfer->infercollid = InvalidOid;
 		else
 			pInfer->infercollid = LookupCollation(pstate, ielem->collation,
-												  exprLocation(pInfer->expr));
+												  exprLocation((Node *) ielem));
 
 		if (!ielem->opclass)
 			pInfer->inferopclass = InvalidOid;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d14294a4ece..48738aa26f0 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -816,6 +816,7 @@ typedef struct IndexElem
 	List	   *opclassopts;	/* opclass-specific options, or NIL */
 	SortByDir	ordering;		/* ASC/DESC/default */
 	SortByNulls nulls_ordering; /* FIRST/LAST/default */
+	ParseLoc	location;		/* token location, or -1 if unknown */
 } IndexElem;
 
 /*
-- 
2.47.3

