aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/nodeFuncs.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2021-02-01 13:54:59 +0100
committerPeter Eisentraut <peter@eisentraut.org>2021-02-01 14:32:51 +0100
commit3696a600e2292d43c00949ddf0352e4ebb487e5b (patch)
tree11f19c8c9e5757c44b8da02d0e1f7b41f8ec5f13 /src/backend/nodes/nodeFuncs.c
parentbb513b364b4fe31574574c8d0afbb2255268b321 (diff)
downloadpostgresql-3696a600e2292d43c00949ddf0352e4ebb487e5b.tar.gz
postgresql-3696a600e2292d43c00949ddf0352e4ebb487e5b.zip
SEARCH and CYCLE clauses
This adds the SQL standard feature that adds the SEARCH and CYCLE clauses to recursive queries to be able to do produce breadth- or depth-first search orders and detect cycles. These clauses can be rewritten into queries using existing syntax, and that is what this patch does in the rewriter. Reviewed-by: Vik Fearing <vik@postgresfriends.org> Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/db80ceee-6f97-9b4a-8ee8-3ba0c58e5be2@2ndquadrant.com
Diffstat (limited to 'src/backend/nodes/nodeFuncs.c')
-rw-r--r--src/backend/nodes/nodeFuncs.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 6be19916fce..49357ac5c2d 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -1566,6 +1566,12 @@ exprLocation(const Node *expr)
case T_OnConflictClause:
loc = ((const OnConflictClause *) expr)->location;
break;
+ case T_CTESearchClause:
+ loc = ((const CTESearchClause *) expr)->location;
+ break;
+ case T_CTECycleClause:
+ loc = ((const CTECycleClause *) expr)->location;
+ break;
case T_CommonTableExpr:
loc = ((const CommonTableExpr *) expr)->location;
break;
@@ -1909,6 +1915,7 @@ expression_tree_walker(Node *node,
case T_NextValueExpr:
case T_RangeTblRef:
case T_SortGroupClause:
+ case T_CTESearchClause:
/* primitive node types with no expression subnodes */
break;
case T_WithCheckOption:
@@ -2148,6 +2155,16 @@ expression_tree_walker(Node *node,
return true;
}
break;
+ case T_CTECycleClause:
+ {
+ CTECycleClause *cc = (CTECycleClause *) node;
+
+ if (walker(cc->cycle_mark_value, context))
+ return true;
+ if (walker(cc->cycle_mark_default, context))
+ return true;
+ }
+ break;
case T_CommonTableExpr:
{
CommonTableExpr *cte = (CommonTableExpr *) node;
@@ -2156,7 +2173,13 @@ expression_tree_walker(Node *node,
* Invoke the walker on the CTE's Query node, so it can
* recurse into the sub-query if it wants to.
*/
- return walker(cte->ctequery, context);
+ if (walker(cte->ctequery, context))
+ return true;
+
+ if (walker(cte->search_clause, context))
+ return true;
+ if (walker(cte->cycle_clause, context))
+ return true;
}
break;
case T_List:
@@ -2615,6 +2638,7 @@ expression_tree_mutator(Node *node,
case T_NextValueExpr:
case T_RangeTblRef:
case T_SortGroupClause:
+ case T_CTESearchClause:
return (Node *) copyObject(node);
case T_WithCheckOption:
{
@@ -3019,6 +3043,17 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
break;
+ case T_CTECycleClause:
+ {
+ CTECycleClause *cc = (CTECycleClause *) node;
+ CTECycleClause *newnode;
+
+ FLATCOPY(newnode, cc, CTECycleClause);
+ MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
+ MUTATE(newnode->cycle_mark_default, cc->cycle_mark_default, Node *);
+ return (Node *) newnode;
+ }
+ break;
case T_CommonTableExpr:
{
CommonTableExpr *cte = (CommonTableExpr *) node;
@@ -3031,6 +3066,10 @@ expression_tree_mutator(Node *node,
* recurse into the sub-query if it wants to.
*/
MUTATE(newnode->ctequery, cte->ctequery, Node *);
+
+ MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *);
+ MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
+
return (Node *) newnode;
}
break;
@@ -3913,6 +3952,7 @@ raw_expression_tree_walker(Node *node,
}
break;
case T_CommonTableExpr:
+ /* search_clause and cycle_clause are not interesting here */
return walker(((CommonTableExpr *) node)->ctequery, context);
default:
elog(ERROR, "unrecognized node type: %d",