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:
@@ -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;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202601011
|
||||
#define CATALOG_VERSION_NO 202601041
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user