static void transform_match_pattern()

in src/backend/parser/cypher_clause.c [3167:3279]


static void transform_match_pattern(cypher_parsestate *cpstate, Query *query,
                                    List *pattern, Node *where)
{
    ParseState *pstate = (ParseState *)cpstate;
    ListCell *lc;
    List *quals = NIL;
    Expr *q = NULL;
    Expr *expr = NULL;

    /*
     * Loop through a comma separated list of paths like (u)-[e]-(v), (w), (x)
     */
    foreach (lc, pattern)
    {
        List *qual = NULL;
        cypher_path *path = NULL;

        /* get the path and transform it */
        path = (cypher_path *) lfirst(lc);

        qual = transform_match_path(cpstate, query, path);

        quals = list_concat(quals, qual);
    }

    if (quals != NIL)
    {
        q = makeBoolExpr(AND_EXPR, quals, -1);
        expr = (Expr *)transformExpr(&cpstate->pstate, (Node *)q,
                                     EXPR_KIND_WHERE);
    }

    if (cpstate->property_constraint_quals != NIL)
    {
        Expr *prop_qual = makeBoolExpr(AND_EXPR,
                                       cpstate->property_constraint_quals, -1);

        if (expr == NULL)
        {
            expr = prop_qual;
        }
        else
        {
            expr = makeBoolExpr(AND_EXPR, list_make2(expr, prop_qual), -1);
        }
    }

    /* transform the where clause quals and add to the quals, */
    if (where != NULL)
    {
        Expr *where_qual;

        where_qual = (Expr *)transform_cypher_expr(cpstate, where,
                                                   EXPR_KIND_WHERE);
        if (expr == NULL)
        {
            expr = where_qual;
        }
        else
        {
            /*
             * coerce the WHERE clause to a boolean before AND with the property
             * constraints, otherwise there could be evaluation issues.
             */
            where_qual = (Expr *)coerce_to_boolean(pstate, (Node *)where_qual,
                                                   "WHERE");

            expr = makeBoolExpr(AND_EXPR, list_make2(expr, where_qual), -1);
        }
    }

    /*
     * Coerce to WHERE clause to a bool, denoting whether the constructed
     * clause is true or false.
     */
    if (expr != NULL)
    {
        expr = (Expr *)coerce_to_boolean(pstate, (Node *)expr, "WHERE");
    }

    query->rtable = cpstate->pstate.p_rtable;
    query->rteperminfos = cpstate->pstate.p_rteperminfos;

    if (cpstate->p_list_comp)
    {
        List *groupList = NIL;

        query->jointree = makeFromExpr(cpstate->pstate.p_joinlist, NULL);
        query->havingQual = (Node *)expr;

        foreach (lc, query->targetList)
        {
            TargetEntry *te = lfirst(lc);
            ColumnRef *cref = makeNode(ColumnRef);

            cref->fields = list_make1(makeString(te->resname));
            cref->location = exprLocation((Node *)te->expr);

            groupList = lappend(groupList, cref);
        }

        query->groupClause = transform_group_clause(cpstate, groupList,
                                                    &query->groupingSets,
                                                    &query->targetList,
                                                    query->sortClause,
                                                    EXPR_KIND_GROUP_BY);
    }
    else
    {
        query->jointree = makeFromExpr(cpstate->pstate.p_joinlist,
                                       (Node *)expr);
    }
}