1
0
mirror of https://github.com/postgres/postgres.git synced 2026-01-26 09:41:40 +03:00

Add parse location to IndexElem.

This patch mostly just fills in the field, although a few error
reports in resolve_unique_index_expr() are adjusted to use it.
The next commit will add more uses.

catversion bump out of an abundance of caution: I'm not sure
IndexElem can appear in stored rules, but I'm not sure it can't
either.

Author: Álvaro Herrera <alvherre@kurilemu.de>
Co-authored-by: jian he <jian.universality@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACJufxH3OgXF1hrzGAaWyNtye2jHEmk9JbtrtGv-KJK6tsGo5w@mail.gmail.com
Discussion: https://postgr.es/m/202512121327.f2zimsr6guso@alvherre.pgsql
This commit is contained in:
Tom Lane
2026-01-04 13:23:26 -05:00
parent ac94ce8194
commit 62299bbd90
8 changed files with 24 additions and 11 deletions

View File

@@ -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;
}
;

View File

@@ -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;

View File

@@ -8454,6 +8454,7 @@ index_elem_options:
$$->opclassopts = NIL;
$$->ordering = $3;
$$->nulls_ordering = $4;
/* location will be filled in index_elem production */
}
| 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 will be filled in index_elem production */
}
;
@@ -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;
}
;

View File

@@ -3288,21 +3288,18 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("%s is not allowed in ON CONFLICT clause",
"ASC/DESC"),
parser_errposition(pstate,
exprLocation((Node *) infer))));
parser_errposition(pstate, ielem->location)));
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))));
parser_errposition(pstate, ielem->location)));
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)));
parser_errposition(pstate, ielem->location));
if (!ielem->expr)
{
@@ -3342,7 +3339,7 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
pInfer->infercollid = InvalidOid;
else
pInfer->infercollid = LookupCollation(pstate, ielem->collation,
exprLocation(pInfer->expr));
ielem->location);
if (!ielem->opclass)
pInfer->inferopclass = InvalidOid;

View File

@@ -1962,6 +1962,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
}
}
iparam->location = -1;
index->indexParams = lappend(index->indexParams, iparam);
}
@@ -1993,6 +1995,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
/* Copy the original index column name */
iparam->indexcolname = pstrdup(NameStr(attr->attname));
iparam->location = -1;
index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
}
/* Copy reloptions if any */
@@ -2813,6 +2817,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 +2934,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
iparam->collation = NIL;
iparam->opclass = NIL;
iparam->opclassopts = NIL;
iparam->location = -1;
index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
}

View File

@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202601011
#define CATALOG_VERSION_NO 202601041
#endif

View File

@@ -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;
/*

View File

@@ -5,15 +5,15 @@ create table insertconflicttest(key int4, fruit text);
-- invalid clauses
insert into insertconflicttest values (1) on conflict (key int4_ops (fillfactor=10)) do nothing;
ERROR: operator class options are not allowed in ON CONFLICT clause
LINE 1: ...rt into insertconflicttest values (1) on conflict (key int4_...
LINE 1: ...t into insertconflicttest values (1) on conflict (key int4_o...
^
insert into insertconflicttest values (1) on conflict (key asc) do nothing;
ERROR: ASC/DESC is not allowed in ON CONFLICT clause
LINE 1: ...rt into insertconflicttest values (1) on conflict (key asc) ...
LINE 1: ...t into insertconflicttest values (1) on conflict (key asc) d...
^
insert into insertconflicttest values (1) on conflict (key nulls last) do nothing;
ERROR: NULLS FIRST/LAST is not allowed in ON CONFLICT clause
LINE 1: ...rt into insertconflicttest values (1) on conflict (key nulls...
LINE 1: ...t into insertconflicttest values (1) on conflict (key nulls ...
^
-- These things should work through a view, as well
create view insertconflictview as select * from insertconflicttest;