v2-0001-add-Location-to-IndexElem.patch
text/x-patch
Filename: v2-0001-add-Location-to-IndexElem.patch
Type: text/x-patch
Part: 1
From 6bd9a9a3b4dbb32ca01cc456ad5e5131c485b367 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Wed, 31 Dec 2025 16:05:20 +0800
Subject: [PATCH v2 1/2] add Location to IndexElem
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add location information to each IndexElem so that error reporting can precisely
identify the specific invalid element. This is particularly useful for
subsequent refactoring in ComputeIndexAttrs.
Author: Álvaro Herrera <alvherre(at)kurilemu(dot)de>
comitfest: https://commitfest.postgresql.org/patch/6322
discussion: https://postgr.es/m/CACJufxH3OgXF1hrzGAaWyNtye2jHEmk9JbtrtGv-KJK6tsGo5w@mail.gmail.com
---
src/backend/bootstrap/bootparse.y | 1 +
src/backend/nodes/nodeFuncs.c | 3 +++
src/backend/parser/gram.y | 5 +++++
src/backend/parser/parse_clause.c | 8 ++++----
src/backend/parser/parse_utilcmd.c | 4 ++++
src/include/nodes/parsenodes.h | 1 +
6 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 9833f52c1be..da0e7dea497 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -415,6 +415,7 @@ boot_index_param:
n->opclass = list_make1(makeString($2));
n->ordering = SORTBY_DEFAULT;
n->nulls_ordering = SORTBY_NULLS_DEFAULT;
+ n->location = -1;
$$ = n;
}
;
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 28f4e11e30f..3f407e7d00f 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -8454,6 +8454,7 @@ index_elem_options:
$$->opclassopts = NIL;
$$->ordering = $3;
$$->nulls_ordering = $4;
+ $$->location = @1;
}
| opt_collate any_name reloptions opt_asc_desc opt_nulls_order
{
@@ -8466,6 +8467,7 @@ index_elem_options:
$$->opclassopts = $3;
$$->ordering = $4;
$$->nulls_ordering = $5;
+ $$->location = @1;
}
;
@@ -8478,16 +8480,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/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 2b7b084f216..535c4060dd4 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1883,6 +1883,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
int16 opt = source_idx->rd_indoption[keyno];
iparam = makeNode(IndexElem);
+ iparam->location = -1;
if (AttributeNumberIsValid(attnum))
{
@@ -1974,6 +1975,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
keyno);
iparam = makeNode(IndexElem);
+ iparam->location = -1;
if (AttributeNumberIsValid(attnum))
{
@@ -2813,6 +2815,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
iparam->opclassopts = NIL;
iparam->ordering = SORTBY_DEFAULT;
iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
+ iparam->location = -1;
index->indexParams = lappend(index->indexParams, iparam);
}
@@ -2929,6 +2932,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
iparam->collation = NIL;
iparam->opclass = NIL;
iparam->opclassopts = NIL;
+ iparam->location = -1;
index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
}
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index bc7adba4a0f..b15b937660f 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.34.1