linhongyu510 commented on code in PR #2559:
URL: https://github.com/apache/age/pull/2559#discussion_r4371915567


##########
src/backend/parser/cypher_clause.c:
##########
@@ -4621,6 +4629,132 @@ static ParseNamespaceItem 
*transform_RangeFunction(cypher_parsestate *cpstate,
     return pnsi;
 }
 
+static const char *find_static_edge_label(List *pattern,
+                                          const char *variable_name)
+{
+    ListCell *path_cell;
+    const char *label = NULL;
+
+    foreach (path_cell, pattern)
+    {
+        cypher_path *path = lfirst(path_cell);
+        ListCell *entity_cell;
+
+        foreach (entity_cell, path->path)
+        {
+            Node *entity = lfirst(entity_cell);
+            cypher_relationship *rel;
+
+            if (!is_ag_node(entity, cypher_relationship))
+                continue;
+
+            rel = (cypher_relationship *)entity;
+            if (rel->name == NULL ||
+                strcmp(rel->name, variable_name) != 0)
+                continue;
+
+            if (rel->varlen != NULL || rel->parsed_label == NULL)
+                return NULL;
+
+            if (label != NULL && strcmp(label, rel->parsed_label) != 0)
+                return NULL;
+
+            label = rel->parsed_label;
+        }
+    }
+
+    return label;
+}
+
+static bool is_redundant_edge_type_qual(List *pattern, Node *qual)
+{
+    cypher_comparison_aexpr *comparison;
+    FuncCall *function;
+    ColumnRef *column;
+    A_Const *constant;
+    String *operator_name;
+    String *function_name;
+    String *variable_name;
+    const char *static_label;
+
+    if (qual == NULL || !is_ag_node(qual, cypher_comparison_aexpr))
+        return false;
+
+    comparison = (cypher_comparison_aexpr *)qual;
+    if (comparison->kind != AEXPR_OP ||
+        list_length(comparison->name) != 1)
+        return false;
+
+    operator_name = linitial(comparison->name);
+    if (!IsA(operator_name, String) ||
+        strcmp(strVal(operator_name), "=") != 0 ||
+        !IsA(comparison->lexpr, FuncCall) ||
+        !IsA(comparison->rexpr, A_Const))
+        return false;
+
+    function = (FuncCall *)comparison->lexpr;
+    constant = (A_Const *)comparison->rexpr;
+    if (list_length(function->funcname) != 1 ||
+        list_length(function->args) != 1 ||
+        constant->isnull ||
+        constant->val.sval.type != T_String)
+        return false;
+
+    function_name = linitial(function->funcname);
+    if (!IsA(function_name, String) ||
+        pg_strcasecmp(strVal(function_name), "type") != 0 ||
+        !IsA(linitial(function->args), ColumnRef))
+        return false;
+
+    column = linitial(function->args);
+    if (list_length(column->fields) != 1 ||
+        !IsA(linitial(column->fields), String))
+        return false;
+
+    variable_name = linitial(column->fields);
+    static_label = find_static_edge_label(pattern, strVal(variable_name));
+
+    return static_label != NULL &&
+           strcmp(static_label, strVal(&constant->val)) == 0;
+}
+
+static Node *simplify_redundant_edge_type_qual(List *pattern, Node *where)
+{
+    BoolExpr *expression;
+    List *args = NIL;
+    ListCell *cell;
+
+    if (where == NULL)
+        return NULL;
+
+    if (is_redundant_edge_type_qual(pattern, where))
+        return NULL;
+
+    if (!IsA(where, BoolExpr))
+        return where;
+
+    expression = (BoolExpr *)where;
+    if (expression->boolop != AND_EXPR)
+        return where;
+
+    foreach (cell, expression->args)
+    {
+        Node *arg = lfirst(cell);
+
+        if (!is_redundant_edge_type_qual(pattern, arg))

Review Comment:
   Done in 917b68ea: `simplify_redundant_edge_type_qual` now recurses into 
nested `AND_EXPR` groups (stopping at `OR_EXPR`/`NOT_EXPR` boundaries to avoid 
over-elision), so `r.v > 0 AND (type(r) = 'P' AND r.v < 4)` elides just like 
the flat form. A `changed` flag rebuilds the outer conjunction when elision 
happens inside a nested group.
   
   Added regress cases for the nested-AND count, its EXPLAIN (type() gone, 
siblings preserved), and a parenthesized OR-group guard confirming the 
predicate is NOT elided there.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to