mirror of
https://github.com/postgres/postgres.git
synced 2026-05-06 16:59:45 -04:00
Handle nodes that may appear in GraphPattern expression trees
expression_tree_mutator_impl() did not handle T_GraphPattern, T_GraphElementPattern, and T_GraphPropertyRef. The corresponding expression_tree_walker_impl() already handles all three node types. This causes an "unrecognized node type" error whenever a GRAPH_TABLE appeared in an expression tree. While at it, also update raw_expression_tree_walker() and expression_tree_walker() to handle missing nodes that may appear in GraphPattern expression trees. When raw_expression_tree_walker() is called, GraphElementPattern::labelexpr contains ColumnRefs instead of GraphLabelRefs. Hence those are not handled in raw_expression_tree_walker(). Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDc97WFTSkXg%3Dg_ZAH8GnY2gJrvq72cs%2BYjqEAuZgXnkAQ%40mail.gmail.com
This commit is contained in:
@@ -2146,6 +2146,7 @@ expression_tree_walker_impl(Node *node,
|
||||
case T_RangeTblRef:
|
||||
case T_SortGroupClause:
|
||||
case T_CTESearchClause:
|
||||
case T_GraphLabelRef:
|
||||
case T_GraphPropertyRef:
|
||||
case T_MergeSupportFunc:
|
||||
/* primitive node types with no expression subnodes */
|
||||
@@ -2709,6 +2710,8 @@ expression_tree_walker_impl(Node *node,
|
||||
{
|
||||
GraphElementPattern *gep = (GraphElementPattern *) node;
|
||||
|
||||
if (WALK(gep->labelexpr))
|
||||
return true;
|
||||
if (WALK(gep->subexpr))
|
||||
return true;
|
||||
if (WALK(gep->whereClause))
|
||||
@@ -3072,6 +3075,8 @@ expression_tree_mutator_impl(Node *node,
|
||||
case T_RangeTblRef:
|
||||
case T_SortGroupClause:
|
||||
case T_CTESearchClause:
|
||||
case T_GraphLabelRef:
|
||||
case T_GraphPropertyRef:
|
||||
case T_MergeSupportFunc:
|
||||
return copyObject(node);
|
||||
case T_WithCheckOption:
|
||||
@@ -3825,6 +3830,30 @@ expression_tree_mutator_impl(Node *node,
|
||||
return (Node *) newnode;
|
||||
}
|
||||
break;
|
||||
case T_GraphElementPattern:
|
||||
{
|
||||
GraphElementPattern *gep = (GraphElementPattern *) node;
|
||||
GraphElementPattern *newnode;
|
||||
|
||||
FLATCOPY(newnode, gep, GraphElementPattern);
|
||||
MUTATE(newnode->labelexpr, gep->labelexpr, Node *);
|
||||
MUTATE(newnode->subexpr, gep->subexpr, List *);
|
||||
MUTATE(newnode->whereClause, gep->whereClause, Node *);
|
||||
newnode->quantifier = list_copy(gep->quantifier);
|
||||
return (Node *) newnode;
|
||||
}
|
||||
break;
|
||||
case T_GraphPattern:
|
||||
{
|
||||
GraphPattern *gp = (GraphPattern *) node;
|
||||
GraphPattern *newnode;
|
||||
|
||||
FLATCOPY(newnode, gp, GraphPattern);
|
||||
MUTATE(newnode->path_pattern_list, gp->path_pattern_list, List *);
|
||||
MUTATE(newnode->whereClause, gp->whereClause, Node *);
|
||||
return (Node *) newnode;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized node type: %d",
|
||||
(int) nodeTag(node));
|
||||
@@ -4807,6 +4836,8 @@ raw_expression_tree_walker_impl(Node *node,
|
||||
{
|
||||
GraphElementPattern *gep = (GraphElementPattern *) node;
|
||||
|
||||
if (WALK(gep->labelexpr))
|
||||
return true;
|
||||
if (WALK(gep->subexpr))
|
||||
return true;
|
||||
if (WALK(gep->whereClause))
|
||||
|
||||
@@ -1032,4 +1032,15 @@ SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE src.vprop1 >
|
||||
ERROR: subqueries within GRAPH_TABLE reference are not supported
|
||||
SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE out_degree(src.vname) > (SELECT max(out_degree(nname)) FROM GRAPH_TABLE (g1 MATCH (node) COLUMNS (node.vname AS nname))) COLUMNS(src.vname AS sname, dest.vname AS dname));
|
||||
ERROR: subqueries within GRAPH_TABLE reference are not supported
|
||||
-- GRAPH_TABLE subquery in HAVING clause (tests expression mutator)
|
||||
SELECT src.vname, count(*) FROM v1 AS src
|
||||
GROUP BY src.vname
|
||||
HAVING count(*) >= (SELECT count(*) FROM GRAPH_TABLE (g1 MATCH (a IS vl1 | vl2) COLUMNS (a.vname AS n)) WHERE n = src.vname);
|
||||
vname | count
|
||||
-------+-------
|
||||
v13 | 1
|
||||
v12 | 1
|
||||
v11 | 1
|
||||
(3 rows)
|
||||
|
||||
-- leave the objects behind for pg_upgrade/pg_dump tests
|
||||
|
||||
@@ -590,4 +590,9 @@ SELECT * FROM customers co WHERE co.customer_id = (SELECT customer_id FROM GRAPH
|
||||
SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE src.vprop1 > (SELECT max(v1.vprop1) FROM v1) COLUMNS(src.vname AS sname, dest.vname AS dname));
|
||||
SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE out_degree(src.vname) > (SELECT max(out_degree(nname)) FROM GRAPH_TABLE (g1 MATCH (node) COLUMNS (node.vname AS nname))) COLUMNS(src.vname AS sname, dest.vname AS dname));
|
||||
|
||||
-- GRAPH_TABLE subquery in HAVING clause (tests expression mutator)
|
||||
SELECT src.vname, count(*) FROM v1 AS src
|
||||
GROUP BY src.vname
|
||||
HAVING count(*) >= (SELECT count(*) FROM GRAPH_TABLE (g1 MATCH (a IS vl1 | vl2) COLUMNS (a.vname AS n)) WHERE n = src.vname);
|
||||
|
||||
-- leave the objects behind for pg_upgrade/pg_dump tests
|
||||
|
||||
Reference in New Issue
Block a user