Skip to content

Commit

Permalink
WIP for varnullingrels issue (#47)
Browse files Browse the repository at this point in the history
This is a work in progress for the new field that was
added to the struct Var called "varnullingrels".
According to the documentation, this field is responsible
for marking the Vars as nullable, if they are coming from
a JOIN, either LEFT JOIN, RIGHT JOIN, or FULL OUTER JOIN.
The changes were made following an "optional match" clause
which is being treated as a LEFT JOIN from our extension.

A function markRelsAsNulledBy is added because its internal
in Postgres and doesn't belong in a header file, therefore
it can't be exported. This function is added before the creation
of the Vars from the "make_vertex_expr" and "make_edge_expr",
to correctly mark the specific PNSI as nullable, so later in
the planner stage, the Vars will be correctly nulled.

Signed-off-by: Panagiotis Foliadis <[email protected]>
  • Loading branch information
panosfol authored and muhammadshoaib committed Nov 1, 2023
1 parent a0478cd commit 802e271
Showing 1 changed file with 53 additions and 1 deletion.
54 changes: 53 additions & 1 deletion src/backend/parser/cypher_clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ static bool isa_special_VLE_case(cypher_path *path);

static ParseNamespaceItem *find_pnsi(cypher_parsestate *cpstate, char *varname);

static void markRelsAsNulledBy(ParseState *pstate, int n, int jindex);
/*
* transform a cypher_clause
*/
Expand Down Expand Up @@ -4462,6 +4463,8 @@ static Expr *transform_cypher_edge(cypher_parsestate *cpstate,
Node *expr = NULL;
bool refs_var = false;
ParseNamespaceItem *pnsi = NULL;
int jindex;


/*
* If we have an edge name, get any potential variable or column
Expand Down Expand Up @@ -4662,6 +4665,10 @@ static Expr *transform_cypher_edge(cypher_parsestate *cpstate,
pnsi = addRangeTableEntry(pstate, label_range_var, alias,
label_range_var->inh, true);
Assert(pnsi != NULL);
if (pstate->parentParseState->p_lateral_active) {
jindex = list_length(pstate->p_rtable + 1);
markRelsAsNulledBy(pstate, pnsi->p_rtindex, jindex);
}

/*
* relation is visible (r.a in expression works) but attributes in the
Expand Down Expand Up @@ -4705,6 +4712,7 @@ static Expr *transform_cypher_node(cypher_parsestate *cpstate,
cypher_node *cn = NULL;
bool refs_var = false;
ParseNamespaceItem *pnsi;
int jindex;

/* if we have a node name, get any potential variable references */
if (node->name != NULL)
Expand Down Expand Up @@ -4898,8 +4906,13 @@ static Expr *transform_cypher_node(cypher_parsestate *cpstate,
pnsi = addRangeTableEntry(pstate, label_range_var, alias,
label_range_var->inh, true);

Assert(pnsi != NULL);


Assert(pnsi != NULL);
if (pstate->parentParseState->p_lateral_active) {
jindex = list_length(pstate->p_rtable + 1);
markRelsAsNulledBy(pstate, pnsi->p_rtindex, jindex);
}
/*
* relation is visible (r.a in expression works) but attributes in the
* relation are not visible (a in expression doesn't work)
Expand Down Expand Up @@ -6860,3 +6873,42 @@ ParseNamespaceItem *find_pnsi(cypher_parsestate *cpstate, char *varname)

return NULL;
}

static void
markRelsAsNulledBy(ParseState *pstate, int n, int jindex)
{
int varno;
ListCell *lc;
varno = n;

/* Note: we can't see FromExpr here */
/* if (IsA(n, RangeTblRef)) */
/* { */
/* varno = ((RangeTblRef *) n)->rtindex; */
/* } */
/* else if (IsA(n, JoinExpr)) */
/* { */
/* JoinExpr *j = (JoinExpr *) n; */

/* /\* recurse to children *\/ */
/* markRelsAsNulledBy(pstate, j->larg, jindex); */
/* markRelsAsNulledBy(pstate, j->rarg, jindex); */
/* varno = j->rtindex; */
/* } */
/* else */
/* { */
/* elog(ERROR, "unrecognized node type: %d", (int) nodeTag(n)); */
/* varno = 0; /\* keep compiler quiet *\/ */
/* } */

/*
* Now add jindex to the p_nullingrels set for relation varno. Since we
* maintain the p_nullingrels list lazily, we might need to extend it to
* make the varno'th entry exist.
*/
while (list_length(pstate->p_nullingrels) < varno)
pstate->p_nullingrels = lappend(pstate->p_nullingrels, NULL);
lc = list_nth_cell(pstate->p_nullingrels, varno - 1);
lfirst(lc) = bms_add_member((Bitmapset *) lfirst(lc), jindex);
}

0 comments on commit 802e271

Please sign in to comment.