]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add parse location to IndexElem.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 4 Jan 2026 18:23:26 +0000 (13:23 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 4 Jan 2026 19:16:20 +0000 (14:16 -0500)
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

src/backend/bootstrap/bootparse.y
src/backend/nodes/nodeFuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_utilcmd.c
src/include/catalog/catversion.h
src/include/nodes/parsenodes.h
src/test/regress/expected/insert_conflict.out

index 971fd3277efa2cd84eb26bdc757e566f333a8a9a..d0c3a87852631d5109e50c6a25a387d3a9881e2a 100644 (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;
                                }
                ;
index c7660df92f4e36e20d21e0a5ebba95a8b3c8cd52..d29664ca5d4e8f88509f98ded5b950345707fe00 100644 (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;
index 9ea81250ce8fdac39e07af9e391c15776952568c..713ee5c10a219787bde83e46615a854e18bb662a 100644 (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;
                                }
                ;
 
index e72e44fa1ea43da84d6e45feeb99788e138424c7..e35fd25c9bb2b8124418165ea582cfc2e8f078a1 100644 (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;
index 96f442c41450c999a055e1b00ad9020d41587482..652f7538c37d4755589f99cffe31bf301b0e8f98 100644 (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);
        }
 
index 2feec1f7b430b5e85c647efadb576db71a3a7823..4eb435eb1ecfc4167018065254e099dc858053b6 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202601011
+#define CATALOG_VERSION_NO     202601041
 
 #endif
index 896c4f34cc095142bade449c77bac2b47edec172..aac4bfc70d996217867a98d97f53dbf78a2bdf78 100644 (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;
 
 /*
index 91fbe91844d2a38915e5c788a652b882a09b3830..b0e12962088e4cb7d62230c558c779f838381b90 100644 (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;