bool expr_contains_node()

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));
}