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