in src/backend/parser/cypher_analyze.c [690:995]
bool expr_contains_node(cypher_expression_condition is_expr, Node *expr)
{
if (!expr)
{
return false;
}
switch (nodeTag(expr))
{
case T_A_Const:
case T_ColumnRef:
case T_A_Indirection:
{
break;
}
case T_A_Expr:
{
A_Expr *a = (A_Expr *)expr;
switch (a->kind)
{
case AEXPR_OP:
case AEXPR_IN:
{
if (expr_contains_node(is_expr, a->lexpr) ||
expr_contains_node(is_expr, a->rexpr))
{
return true;
}
break;
}
default:
ereport(ERROR, (errmsg_internal("unrecognized A_Expr kind: %d",
a->kind)));
}
break;
}
case T_BoolExpr:
{
BoolExpr *b = (BoolExpr *)expr;
ListCell *la;
foreach(la, b->args)
{
Node *arg = lfirst(la);
if (expr_contains_node(is_expr, arg))
{
return true;
}
}
break;
}
case T_NullTest:
{
NullTest *n = (NullTest *)expr;
if (expr_contains_node(is_expr, (Node *)n->arg))
{
return true;
}
break;
}
case T_CaseExpr:
{
CaseExpr *cexpr = (CaseExpr *)expr;
ListCell *l;
if (cexpr->arg && expr_contains_node(is_expr, (Node *) cexpr->arg))
{
return true;
}
foreach(l, cexpr->args)
{
CaseWhen *w = lfirst_node(CaseWhen, l);
Node *warg;
warg = (Node *) w->expr;
if (expr_contains_node(is_expr, warg))
{
return true;
}
warg = (Node *)w->result;
if (expr_contains_node(is_expr, warg))
{
return true;
}
}
if (expr_contains_node(is_expr , (Node *)cexpr->defresult))
{
return true;
}
break;
}
case T_CaseTestExpr:
{
break;
}
case T_CoalesceExpr:
{
CoalesceExpr *cexpr = (CoalesceExpr *) expr;
ListCell *args;
foreach(args, cexpr->args)
{
Node *e = (Node *)lfirst(args);
if (expr_contains_node(is_expr, e))
{
return true;
}
}
break;
}
case T_ExtensibleNode:
{
if (is_ag_node(expr, cypher_bool_const))
{
return is_expr(expr);
}
if (is_ag_node(expr, cypher_integer_const))
{
return is_expr(expr);
}
if (is_ag_node(expr, cypher_param))
{
return is_expr(expr);
}
if (is_ag_node(expr, cypher_map))
{
cypher_map *cm = (cypher_map *)expr;
ListCell *le;
Assert(list_length(cm->keyvals) % 2 == 0);
le = list_head(cm->keyvals);
while(le != NULL)
{
Node *val;
le = lnext(cm->keyvals, le);
val = lfirst(le);
if (expr_contains_node(is_expr, val))
{
return true;
}
le = lnext(cm->keyvals, le);
}
break;
}
if (is_ag_node(expr, cypher_map_projection))
{
cypher_map_projection *cmp = (cypher_map_projection *)expr;
ListCell *lc;
foreach(lc, cmp->map_elements)
{
cypher_map_projection_element *elem;
elem = lfirst(lc);
if (expr_contains_node(is_expr, elem->value))
{
return true;
}
}
break;
}
if (is_ag_node(expr, cypher_list))
{
cypher_list *cl = (cypher_list *)expr;
ListCell *le = NULL;
foreach(le, cl->elems)
{
Node *texpr = lfirst(le);
if (expr_contains_node(is_expr, texpr))
{
return true;
}
}
break;
}
if (is_ag_node(expr, cypher_string_match))
{
cypher_string_match *csm = (cypher_string_match *)expr;
if (expr_contains_node(is_expr, csm->lhs) ||
expr_contains_node(is_expr, csm->rhs))
{
return true;
}
break;
}
if (is_ag_node(expr, cypher_typecast))
{
cypher_typecast *t = (cypher_typecast *) expr;
if (expr_contains_node(is_expr, t->expr))
{
return true;
}
break;
}
if (is_ag_node(expr, cypher_comparison_aexpr))
{
cypher_comparison_aexpr *a = (cypher_comparison_aexpr *) expr;
if (expr_contains_node(is_expr, a->lexpr) ||
expr_contains_node(is_expr, a->rexpr))
{
return true;
}
break;
}
if (is_ag_node(expr, cypher_comparison_boolexpr))
{
cypher_comparison_boolexpr *b = (cypher_comparison_boolexpr *) expr;
ListCell *la;
foreach(la, b->args)
{
Node *arg = lfirst(la);
if (expr_contains_node(is_expr, arg))
{
return true;
}
}
break;
}
if (is_ag_node(expr, cypher_unwind))
{
cypher_unwind* lc = (cypher_unwind *)expr;
if (expr_contains_node(is_expr, lc->where) ||
expr_contains_node(is_expr, lc->collect))
{
return true;
}
break;
}
if (is_ag_node(expr, cypher_sub_pattern))
{
break;
}
if (is_ag_node(expr, cypher_sub_query))
{
break;
}
ereport(ERROR,
(errmsg_internal("unrecognized ExtensibleNode: %s",
((ExtensibleNode *)expr)->extnodename)));
break;
}
case T_FuncCall:
{
FuncCall *fn = (FuncCall *)expr;
ListCell *arg;
foreach(arg, fn->args)
{
Node *farg = NULL;
farg = (Node *)lfirst(arg);
if (expr_contains_node(is_expr, farg))
{
return true;
}
}
break;
}
case T_SubLink:
{
SubLink *s = (SubLink *)expr;
if (expr_contains_node(is_expr, s->subselect))
{
return true;
}
break;
}
default:
ereport(ERROR, (errmsg_internal("unrecognized node type: %d",
nodeTag(expr))));
}
return (is_expr(expr));
}