You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by GitBox <gi...@apache.org> on 2022/01/20 03:14:49 UTC

[GitHub] [incubator-age] emotionbug opened a new pull request #175: feat: Implement `OPTIONAL MATCH`

emotionbug opened a new pull request #175:
URL: https://github.com/apache/incubator-age/pull/175


   This implements the `OPTIONAL MATCH` clause.  Internally, it is implemented using `LEFT JOIN LATERAL` of PostgreSQL.
   Apart from the `OPTIONAL MATCH` implementation, it also includes code that solves the problem of `ORDER BY` Clause.
   
   Previous PR : #149 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r790492710



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,153 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *transform_clause_for_join(cypher_parsestate *cpstate,
+                                       cypher_clause *clause,
+                                       RangeTblEntry **rte,
+                                       ParseNamespaceItem **nsitem,
+                                       Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+                         RangeTblEntry *r_rte, List **res_colnames,
+                         List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+/*
+ * transform_cypher_optional_match_clause
+ *      Transform the previous clauses and OPTIONAL MATCH clauses to be LATERAL LEFT JOIN
+ *      to construct a result value.
+ */
+static RangeTblEntry *transform_cypher_optional_match_clause(cypher_parsestate *cpstate,
+                                                             cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+    JoinExpr* j = makeNode(JoinExpr);
+    List *res_colnames = NIL, *res_colvars = NIL;
+    Alias *l_alias, *r_alias;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);

Review comment:
       Good pointing. :) 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] jrgemignani commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
jrgemignani commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r789145725



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,157 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *
+transform_clause_for_join(cypher_parsestate *cpstate, cypher_clause *clause,
+                         RangeTblEntry **rte, ParseNamespaceItem **nsitem,
+                         Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void
+get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+             RangeTblEntry *r_rte, List **res_colnames,
+             List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+
+static RangeTblEntry *

Review comment:
       Don't break function here

##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,157 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *
+transform_clause_for_join(cypher_parsestate *cpstate, cypher_clause *clause,
+                         RangeTblEntry **rte, ParseNamespaceItem **nsitem,
+                         Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void

Review comment:
       Don't break function here

##########
File path: regress/sql/cypher_match.sql
##########
@@ -456,6 +456,39 @@ SELECT * FROM cypher('cypher_match', $$
 	RETURN u SKIP 7 LIMIT 3
 $$) AS (i agtype);
 
+
+-- 

Review comment:
       There are extra spaces here

##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,157 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *

Review comment:
       Don't break function declaration here

##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,157 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *
+transform_clause_for_join(cypher_parsestate *cpstate, cypher_clause *clause,
+                         RangeTblEntry **rte, ParseNamespaceItem **nsitem,
+                         Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void
+get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+             RangeTblEntry *r_rte, List **res_colnames,
+             List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+
+static RangeTblEntry *
+transform_cypher_optional_match_clause(cypher_parsestate *cpstate, cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+

Review comment:
       Put all of the variable declarations together without extra lines in between. Unless those lines are comments

##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,157 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *
+transform_clause_for_join(cypher_parsestate *cpstate, cypher_clause *clause,
+                         RangeTblEntry **rte, ParseNamespaceItem **nsitem,
+                         Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void
+get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+             RangeTblEntry *r_rte, List **res_colnames,
+             List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+
+static RangeTblEntry *
+transform_cypher_optional_match_clause(cypher_parsestate *cpstate, cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+
+    JoinExpr* j = makeNode(JoinExpr);
+    
+    List *res_colnames = NIL, *res_colvars = NIL;
+
+    Alias *l_alias, *r_alias;
+
+    int i;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);
+    r_alias = makeAlias(CYPHER_OPT_RIGHT_ALIAS, NIL);
+
+    j->larg = transform_clause_for_join(cpstate, clause->prev, &l_rte,
+                                        &l_nsitem, l_alias);
+    pstate->p_namespace = lappend(pstate->p_namespace, l_nsitem);
+
+    prevclause = clause->prev;
+    clause->prev = NULL;
+    self->optional = true;
+    cpstate->p_opt_match = true;
+    pstate->p_lateral_active = true;
+
+    j->rarg = transform_clause_for_join(cpstate, clause, &r_rte,
+                                        &r_nsitem, r_alias);
+
+    cpstate->p_opt_match = false;
+    pstate->p_lateral_active = false;
+    self->optional = true;
+    clause->prev = prevclause;
+
+    pstate->p_namespace = NIL;
+
+    j->quals = makeBoolConst(true, false);
+    j->alias = makeAlias(PREV_CYPHER_CLAUSE_ALIAS, NIL);
+
+    get_res_cols(pstate, l_rte, r_rte, &res_colnames, &res_colvars);
+
+    rte = addRangeTableEntryForJoin(pstate, res_colnames, j->jointype,
+                                    res_colvars, j->alias, true);
+
+    j->rtindex = RTERangeTablePosn(pstate, rte, NULL);
+
+    for (i = list_length(pstate->p_joinexprs) + 1; i < j->rtindex; i++)
+        pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
+    pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
+    Assert(list_length(pstate->p_joinexprs) == j->rtindex);
+
+    pstate->p_joinlist = lappend(pstate->p_joinlist, j);
+
+    nsitem = palloc(sizeof(*nsitem));
+    nsitem->p_rte = rte;
+    nsitem->p_rel_visible = true;
+    nsitem->p_cols_visible = true;
+    nsitem->p_lateral_only = false;
+    nsitem->p_lateral_ok = true;
+    pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
+

Review comment:
       You don't need more than 1 line in between lines of code




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug edited a comment on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug edited a comment on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021739645


   @jrgemignani Updated! :)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021745041


   Fixed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021739645


   Updated! :)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021743475


   Wait...


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] jrgemignani commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
jrgemignani commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021733658


   Please resolve the conflicts listed above.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r790492956



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1371,6 +1536,33 @@ static Query *transform_cypher_match_pattern(cypher_parsestate *cpstate,
     return query;
 }
 
+/*
+ * Function to make a target list from an RTE. Borrowed from AgensGraph and PG
+ */
+static List *makeTargetListFromJoin(ParseState *pstate, RangeTblEntry *rte)

Review comment:
       OK Thanks




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] JoshInnis commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
JoshInnis commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r789834516



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,153 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *transform_clause_for_join(cypher_parsestate *cpstate,
+                                       cypher_clause *clause,
+                                       RangeTblEntry **rte,
+                                       ParseNamespaceItem **nsitem,
+                                       Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+                         RangeTblEntry *r_rte, List **res_colnames,
+                         List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+/*
+ * transform_cypher_optional_match_clause
+ *      Transform the previous clauses and OPTIONAL MATCH clauses to be LATERAL LEFT JOIN
+ *      to construct a result value.
+ */
+static RangeTblEntry *transform_cypher_optional_match_clause(cypher_parsestate *cpstate,
+                                                             cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+    JoinExpr* j = makeNode(JoinExpr);
+    List *res_colnames = NIL, *res_colvars = NIL;
+    Alias *l_alias, *r_alias;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);
+    r_alias = makeAlias(CYPHER_OPT_RIGHT_ALIAS, NIL);
+
+    j->larg = transform_clause_for_join(cpstate, clause->prev, &l_rte,
+                                        &l_nsitem, l_alias);
+    pstate->p_namespace = lappend(pstate->p_namespace, l_nsitem);
+
+    prevclause = clause->prev;
+    clause->prev = NULL;
+    self->optional = true;
+    cpstate->p_opt_match = true;
+    pstate->p_lateral_active = true;
+
+    j->rarg = transform_clause_for_join(cpstate, clause, &r_rte,
+                                        &r_nsitem, r_alias);
+
+    cpstate->p_opt_match = false;
+    pstate->p_lateral_active = false;
+    self->optional = true;
+    clause->prev = prevclause;
+
+    pstate->p_namespace = NIL;
+
+    j->quals = makeBoolConst(true, false);
+    j->alias = makeAlias(PREV_CYPHER_CLAUSE_ALIAS, NIL);
+
+    get_res_cols(pstate, l_rte, r_rte, &res_colnames, &res_colvars);
+
+    rte = addRangeTableEntryForJoin(pstate, res_colnames, j->jointype,
+                                    res_colvars, j->alias, true);
+
+    j->rtindex = RTERangeTablePosn(pstate, rte, NULL);
+
+    for (int i = list_length(pstate->p_joinexprs) + 1; i < j->rtindex; i++)
+        pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
+    pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
+    Assert(list_length(pstate->p_joinexprs) == j->rtindex);
+
+    pstate->p_joinlist = lappend(pstate->p_joinlist, j);
+
+    nsitem = palloc(sizeof(*nsitem));
+    nsitem->p_rte = rte;
+    nsitem->p_rel_visible = true;

Review comment:
       The underlying rels do not need to be visible




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021772940


   @jrgemignani 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug removed a comment on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug removed a comment on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1021739645


   @jrgemignani Updated! :)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] jrgemignani merged pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
jrgemignani merged pull request #175:
URL: https://github.com/apache/incubator-age/pull/175


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] emotionbug commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
emotionbug commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r790492529



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,153 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *transform_clause_for_join(cypher_parsestate *cpstate,
+                                       cypher_clause *clause,
+                                       RangeTblEntry **rte,
+                                       ParseNamespaceItem **nsitem,
+                                       Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+                         RangeTblEntry *r_rte, List **res_colnames,
+                         List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+/*
+ * transform_cypher_optional_match_clause
+ *      Transform the previous clauses and OPTIONAL MATCH clauses to be LATERAL LEFT JOIN
+ *      to construct a result value.
+ */
+static RangeTblEntry *transform_cypher_optional_match_clause(cypher_parsestate *cpstate,
+                                                             cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+    JoinExpr* j = makeNode(JoinExpr);
+    List *res_colnames = NIL, *res_colvars = NIL;
+    Alias *l_alias, *r_alias;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);
+    r_alias = makeAlias(CYPHER_OPT_RIGHT_ALIAS, NIL);
+
+    j->larg = transform_clause_for_join(cpstate, clause->prev, &l_rte,
+                                        &l_nsitem, l_alias);
+    pstate->p_namespace = lappend(pstate->p_namespace, l_nsitem);
+
+    prevclause = clause->prev;
+    clause->prev = NULL;
+    self->optional = true;
+    cpstate->p_opt_match = true;
+    pstate->p_lateral_active = true;
+
+    j->rarg = transform_clause_for_join(cpstate, clause, &r_rte,
+                                        &r_nsitem, r_alias);
+
+    cpstate->p_opt_match = false;
+    pstate->p_lateral_active = false;
+    self->optional = true;
+    clause->prev = prevclause;
+
+    pstate->p_namespace = NIL;
+
+    j->quals = makeBoolConst(true, false);
+    j->alias = makeAlias(PREV_CYPHER_CLAUSE_ALIAS, NIL);
+
+    get_res_cols(pstate, l_rte, r_rte, &res_colnames, &res_colvars);
+
+    rte = addRangeTableEntryForJoin(pstate, res_colnames, j->jointype,
+                                    res_colvars, j->alias, true);
+
+    j->rtindex = RTERangeTablePosn(pstate, rte, NULL);
+
+    for (int i = list_length(pstate->p_joinexprs) + 1; i < j->rtindex; i++)
+        pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
+    pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
+    Assert(list_length(pstate->p_joinexprs) == j->rtindex);
+
+    pstate->p_joinlist = lappend(pstate->p_joinlist, j);
+
+    nsitem = palloc(sizeof(*nsitem));
+    nsitem->p_rte = rte;
+    nsitem->p_rel_visible = true;

Review comment:
       Aha... `Relation name is visible?` We don't need that. thanks.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] JoshInnis commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
JoshInnis commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r789824264



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,153 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *transform_clause_for_join(cypher_parsestate *cpstate,
+                                       cypher_clause *clause,
+                                       RangeTblEntry **rte,
+                                       ParseNamespaceItem **nsitem,
+                                       Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+                         RangeTblEntry *r_rte, List **res_colnames,
+                         List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+/*
+ * transform_cypher_optional_match_clause
+ *      Transform the previous clauses and OPTIONAL MATCH clauses to be LATERAL LEFT JOIN
+ *      to construct a result value.
+ */
+static RangeTblEntry *transform_cypher_optional_match_clause(cypher_parsestate *cpstate,
+                                                             cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+    JoinExpr* j = makeNode(JoinExpr);
+    List *res_colnames = NIL, *res_colvars = NIL;
+    Alias *l_alias, *r_alias;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);

Review comment:
       The left alias is for the previous clause, perhaps the alias should be PREV_CYPHER_CLAUSE_ALIAS, for consistency.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] JoshInnis commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
JoshInnis commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r789823039



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1335,6 +1340,153 @@ static Query *transform_cypher_match(cypher_parsestate *cpstate,
         cpstate, transform_cypher_match_pattern, clause, self->where);
 }
 
+static Node *transform_clause_for_join(cypher_parsestate *cpstate,
+                                       cypher_clause *clause,
+                                       RangeTblEntry **rte,
+                                       ParseNamespaceItem **nsitem,
+                                       Alias* alias)
+{
+    ParseState *pstate = (ParseState *)cpstate;
+    ParseNamespaceItem *tmp;
+    RangeTblRef *rtr;
+
+    *rte = transform_cypher_clause_as_subquery(cpstate,
+                                               transform_cypher_clause,
+                                               clause, alias, false);
+
+    tmp = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
+    tmp->p_rte = *rte;
+    tmp->p_rel_visible = true;
+    tmp->p_cols_visible = true;
+    tmp->p_lateral_only = false;
+    tmp->p_lateral_ok = true;
+    *nsitem = tmp;
+
+    rtr = makeNode(RangeTblRef);
+    rtr->rtindex = RTERangeTablePosn(pstate, *rte, NULL);
+
+    return (Node *) rtr;
+}
+
+static void get_res_cols(ParseState *pstate, RangeTblEntry *l_rte,
+                         RangeTblEntry *r_rte, List **res_colnames,
+                         List **res_colvars)
+{
+    List *l_colnames, *l_colvars;
+    List *r_colnames, *r_colvars;
+    ListCell *r_lname, *r_lvar;
+    List *colnames = NIL;
+    List *colvars = NIL;
+
+    expandRTE(l_rte, RTERangeTablePosn(pstate, l_rte, NULL), 0, -1, false,
+              &l_colnames, &l_colvars);
+    expandRTE(r_rte, RTERangeTablePosn(pstate, r_rte, NULL), 0, -1, false,
+              &r_colnames, &r_colvars);
+
+    *res_colnames = list_concat(*res_colnames, l_colnames);
+    *res_colvars = list_concat(*res_colvars, l_colvars);
+
+    forboth(r_lname, r_colnames, r_lvar, r_colvars)
+    {
+        char *r_colname = strVal(lfirst(r_lname));
+        ListCell *lname;
+        ListCell *lvar;
+        Var *var = NULL;
+
+        forboth(lname, *res_colnames, lvar, *res_colvars)
+        {
+            char *colname = strVal(lfirst(lname));
+
+            if (strcmp(r_colname, colname) == 0)
+            {
+                var = lfirst(lvar);
+                break;
+            }
+        }
+
+        if (var == NULL)
+        {
+            colnames = lappend(colnames, lfirst(r_lname));
+            colvars = lappend(colvars, lfirst(r_lvar));
+        }
+    }
+
+    *res_colnames = list_concat(*res_colnames, colnames);
+    *res_colvars = list_concat(*res_colvars, colvars);
+}
+
+/*
+ * transform_cypher_optional_match_clause
+ *      Transform the previous clauses and OPTIONAL MATCH clauses to be LATERAL LEFT JOIN
+ *      to construct a result value.
+ */
+static RangeTblEntry *transform_cypher_optional_match_clause(cypher_parsestate *cpstate,
+                                                             cypher_clause *clause)
+{
+    cypher_clause *prevclause;
+    cypher_match *self = (cypher_match *)clause->self;
+    RangeTblEntry *rte;
+    RangeTblEntry *l_rte, *r_rte;
+    ParseNamespaceItem *l_nsitem, *r_nsitem;
+    ParseState *pstate = (ParseState *) cpstate;
+    JoinExpr* j = makeNode(JoinExpr);
+    List *res_colnames = NIL, *res_colvars = NIL;
+    Alias *l_alias, *r_alias;
+    ParseNamespaceItem *nsitem;
+
+    j->jointype = JOIN_LEFT;
+
+    l_alias = makeAlias(CYPHER_OPT_LEFT_ALIAS, NIL);
+    r_alias = makeAlias(CYPHER_OPT_RIGHT_ALIAS, NIL);
+
+    j->larg = transform_clause_for_join(cpstate, clause->prev, &l_rte,
+                                        &l_nsitem, l_alias);
+    pstate->p_namespace = lappend(pstate->p_namespace, l_nsitem);
+
+    prevclause = clause->prev;
+    clause->prev = NULL;
+    self->optional = true;
+    cpstate->p_opt_match = true;
+    pstate->p_lateral_active = true;
+
+    j->rarg = transform_clause_for_join(cpstate, clause, &r_rte,
+                                        &r_nsitem, r_alias);
+
+    cpstate->p_opt_match = false;
+    pstate->p_lateral_active = false;
+    self->optional = true;
+    clause->prev = prevclause;
+
+    pstate->p_namespace = NIL;
+
+    j->quals = makeBoolConst(true, false);
+    j->alias = makeAlias(PREV_CYPHER_CLAUSE_ALIAS, NIL);

Review comment:
       i->quals and j->alias can be left NULL. PREV_CYPHER_CLAUSE_ALIAS is for the previous clause that gets transformed in a subquery, not the current query.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] JoshInnis commented on a change in pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
JoshInnis commented on a change in pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#discussion_r789814345



##########
File path: src/backend/parser/cypher_clause.c
##########
@@ -1371,6 +1536,33 @@ static Query *transform_cypher_match_pattern(cypher_parsestate *cpstate,
     return query;
 }
 
+/*
+ * Function to make a target list from an RTE. Borrowed from AgensGraph and PG
+ */
+static List *makeTargetListFromJoin(ParseState *pstate, RangeTblEntry *rte)

Review comment:
       please change to make_target_list_from_join




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-age] jrgemignani commented on pull request #175: feat: Implement `OPTIONAL MATCH`

Posted by GitBox <gi...@apache.org>.
jrgemignani commented on pull request #175:
URL: https://github.com/apache/incubator-age/pull/175#issuecomment-1017795284


   There are some minor formatting (coding standard) issues that need to be addressed.
   
   Additionally, I would like to see some more commenting of functions.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@age.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org