mirror of
https://github.com/postgres/postgres.git
synced 2026-06-10 17:20:31 -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:
parent
891a57c739
commit
dc9e7c9ed9
3 changed files with 47 additions and 0 deletions
|
|
@ -2146,6 +2146,7 @@ expression_tree_walker_impl(Node *node,
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
case T_SortGroupClause:
|
case T_SortGroupClause:
|
||||||
case T_CTESearchClause:
|
case T_CTESearchClause:
|
||||||
|
case T_GraphLabelRef:
|
||||||
case T_GraphPropertyRef:
|
case T_GraphPropertyRef:
|
||||||
case T_MergeSupportFunc:
|
case T_MergeSupportFunc:
|
||||||
/* primitive node types with no expression subnodes */
|
/* primitive node types with no expression subnodes */
|
||||||
|
|
@ -2709,6 +2710,8 @@ expression_tree_walker_impl(Node *node,
|
||||||
{
|
{
|
||||||
GraphElementPattern *gep = (GraphElementPattern *) node;
|
GraphElementPattern *gep = (GraphElementPattern *) node;
|
||||||
|
|
||||||
|
if (WALK(gep->labelexpr))
|
||||||
|
return true;
|
||||||
if (WALK(gep->subexpr))
|
if (WALK(gep->subexpr))
|
||||||
return true;
|
return true;
|
||||||
if (WALK(gep->whereClause))
|
if (WALK(gep->whereClause))
|
||||||
|
|
@ -3072,6 +3075,8 @@ expression_tree_mutator_impl(Node *node,
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
case T_SortGroupClause:
|
case T_SortGroupClause:
|
||||||
case T_CTESearchClause:
|
case T_CTESearchClause:
|
||||||
|
case T_GraphLabelRef:
|
||||||
|
case T_GraphPropertyRef:
|
||||||
case T_MergeSupportFunc:
|
case T_MergeSupportFunc:
|
||||||
return copyObject(node);
|
return copyObject(node);
|
||||||
case T_WithCheckOption:
|
case T_WithCheckOption:
|
||||||
|
|
@ -3825,6 +3830,30 @@ expression_tree_mutator_impl(Node *node,
|
||||||
return (Node *) newnode;
|
return (Node *) newnode;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
elog(ERROR, "unrecognized node type: %d",
|
elog(ERROR, "unrecognized node type: %d",
|
||||||
(int) nodeTag(node));
|
(int) nodeTag(node));
|
||||||
|
|
@ -4807,6 +4836,8 @@ raw_expression_tree_walker_impl(Node *node,
|
||||||
{
|
{
|
||||||
GraphElementPattern *gep = (GraphElementPattern *) node;
|
GraphElementPattern *gep = (GraphElementPattern *) node;
|
||||||
|
|
||||||
|
if (WALK(gep->labelexpr))
|
||||||
|
return true;
|
||||||
if (WALK(gep->subexpr))
|
if (WALK(gep->subexpr))
|
||||||
return true;
|
return true;
|
||||||
if (WALK(gep->whereClause))
|
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
|
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));
|
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
|
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
|
-- 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 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));
|
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
|
-- leave the objects behind for pg_upgrade/pg_dump tests
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue