v20260415-0001-Collation-of-expressions-in-GRAPH_TABLE-CO.patch
text/x-patch
Filename: v20260415-0001-Collation-of-expressions-in-GRAPH_TABLE-CO.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v20260415-0001
Subject: Collation of expressions in GRAPH_TABLE COLUMNS clause
| File | + | − |
|---|---|---|
| src/backend/parser/parse_clause.c | 6 | 0 |
| src/backend/parser/parse_graphtable.c | 11 | 1 |
| src/test/regress/expected/graph_table.out | 4 | 4 |
| src/test/regress/sql/graph_table.sql | 2 | 2 |
From 7481f0d29508fc656efdd5ff2a692eeea406ac7a Mon Sep 17 00:00:00 2001 From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Date: Wed, 15 Apr 2026 16:18:37 +0530 Subject: [PATCH v20260415 1/3] Collation of expressions in GRAPH_TABLE COLUMNS clause GRAPH_TABLE clause is converted into a rangetable entry which is ignored by assign_query_collations(). Hence we assign collations while transforming its parts. Expressions in COLUMNS clause missed that treatment. While at also add comments about collation assignment to the parts of GRAPH_TABLE clause and also fix a small grammar issue. Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://www.postgresql.org/message-id/CAHg+QDc4aaiufYSgrwMMPMMRTPtQ66SghcrPFbWJFZMqNaG+BA@mail.gmail.com --- src/backend/parser/parse_clause.c | 6 ++++++ src/backend/parser/parse_graphtable.c | 12 +++++++++++- src/test/regress/expected/graph_table.out | 8 ++++---- src/test/regress/sql/graph_table.sql | 4 ++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 967eea44f1c..4270c2382c4 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -1003,6 +1003,12 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt) columns = lappend(columns, te); } + /* + * Assign collations to column expressions now since + * assign_query_collations() does not process rangetable entries. + */ + assign_list_collations(pstate, columns); + table_close(rel, NoLock); pstate->p_graph_table_pstate = NULL; diff --git a/src/backend/parser/parse_graphtable.c b/src/backend/parser/parse_graphtable.c index 30ddce5aa9f..87386859a5c 100644 --- a/src/backend/parser/parse_graphtable.c +++ b/src/backend/parser/parse_graphtable.c @@ -252,6 +252,11 @@ transformGraphElementPattern(ParseState *pstate, GraphElementPattern *gep) gep->labelexpr = transformLabelExpr(gpstate, gep->labelexpr); gep->whereClause = transformExpr(pstate, gep->whereClause, EXPR_KIND_WHERE); + + /* + * Assign collations here for the reason mentioned in the prologue of + * transformGraphPattern(). + */ assign_expr_collations(pstate, gep->whereClause); gpstate->cur_gep = NULL; @@ -366,9 +371,14 @@ transformPathPatternList(ParseState *pstate, List *path_pattern) * Transform a GraphPattern. * * A GraphPattern consists of a list of one or more path patterns and an - * optional where clause. Transform them. We use the previously constructure + * optional where clause. Transform them. We use the previously constructed * list of variables in the GraphTableParseState to resolve property references * in the WHERE clause. + * + * Since most parts of the GraphPattern do not require collation assignment, we + * assign collations to the required expressions as they are transformed. This + * avoids the need to traverse the whole GraphPattern again and avoids exposing + * it to assign_expr_collations(). */ Node * transformGraphPattern(ParseState *pstate, GraphPattern *graph_pattern) diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index b579e3df635..057f283c43d 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -652,13 +652,13 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-(a) COLUMNS (a.vname AS self)); v33 (1 row) --- test collation specified in the expression +-- test explicit and implicit collation assignment INSERT INTO e3_3 VALUES (2003, 2003, 'E331', 10011); -SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) COLUMNS (a.vname AS self, b.ename AS loop_name)) ORDER BY loop_name COLLATE "C" ASC; +SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) COLUMNS (upper(a.vname) AS self, b.ename AS loop_name)) ORDER BY loop_name COLLATE "C" ASC; self | loop_name ------+----------- - v33 | E331 - v33 | e331 + V33 | E331 + V33 | e331 (2 rows) SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b IS el2 WHERE b.ename > 'E331' COLLATE "C"]->(a)-[b]->(a) COLUMNS (a.vname AS self, b.ename AS loop_name)); diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 4ff98817420..278064818ff 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -394,9 +394,9 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(c)-[b]->(d) COLUMNS (a.vname AS an SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[c]-(a) COLUMNS (a.vname AS self, c.ename AS loop_name)); SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-(a) COLUMNS (a.vname AS self)); --- test collation specified in the expression +-- test explicit and implicit collation assignment INSERT INTO e3_3 VALUES (2003, 2003, 'E331', 10011); -SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) COLUMNS (a.vname AS self, b.ename AS loop_name)) ORDER BY loop_name COLLATE "C" ASC; +SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) COLUMNS (upper(a.vname) AS self, b.ename AS loop_name)) ORDER BY loop_name COLLATE "C" ASC; SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b IS el2 WHERE b.ename > 'E331' COLLATE "C"]->(a)-[b]->(a) COLUMNS (a.vname AS self, b.ename AS loop_name)); SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) WHERE b.ename > 'E331' COLLATE "C" COLUMNS (a.vname AS self, b.ename AS loop_name)); SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b]->(a)-[b]->(a) COLUMNS (a.vname AS self, b.ename AS loop_name)) WHERE loop_name > 'E331' COLLATE "C"; base-commit: f30d0c720f2ec979ab1b5b44b1f9f201d6efdf8c -- 2.34.1