Skip to content

support openCypher-like relationsiop-type edge alternation#2468

Open
eeshwarg wants to merge 1 commit into
apache:masterfrom
eeshwarg:relationship-type-alternation
Open

support openCypher-like relationsiop-type edge alternation#2468
eeshwarg wants to merge 1 commit into
apache:masterfrom
eeshwarg:relationship-type-alternation

Conversation

@eeshwarg

@eeshwarg eeshwarg commented Jul 7, 2026

Copy link
Copy Markdown

Apache AGE's MATCH grammar rejects openCypher's relationship-type alternation syntax - MATCH ()-[:A|B]->() fails at parse time with syntax error at or near "|". For example, a query like SELECT * FROM cypher('kg_s7', $$ MATCH (p)-[:WORKS_AT|REPORTS_TO]->(c) RETURN c $$) AS (c agtype); throws a syntax error. A workaround for this today is to run something like SELECT * FROM cypher('kg_s7', $$ MATCH (p)-[r]->(c) WHERE type(r) IN ['WORKS_AT','REPORTS_TO'] RETURN c $$) AS (c agtype);.

This change enables support for relationship-type alternation in accordance with the openCypher standard. Changes are made in the grammar, AST and during transformation from the AST to Postgres Query struct by adding the types to the quals list.

Variable-length relationship patterns with alternation ([:A|B*1..2]) are explicitly rejected with ERRCODE_FEATURE_NOT_SUPPORTED.

Testing:

  • Added regress test with cases with directed/undirected edges, and variable length edges

Future work:

  • openCypher also supports node-type alternation (like n:Person|Customer), which could be added to AGE in a future PR

Apache AGE's MATCH grammar rejects openCypher's relationship-type alternation syntax -
`MATCH ()-[:A|B]->()` fails at parse time with `syntax error at or near "|"`. For example,
a query like `SELECT * FROM cypher('kg_s7', $$ MATCH (p)-[:WORKS_AT|REPORTS_TO]->(c) RETURN c $$) AS (c agtype);`
throws a syntax error. A workaround for this today is to run something like
`SELECT * FROM cypher('kg_s7', $$ MATCH (p)-[r]->(c) WHERE type(r) IN ['WORKS_AT','REPORTS_TO'] RETURN c $$) AS (c agtype);`.

This change enables support for relationship-type alternation in accordance with the openCypher
standard. Changes are made in the grammar, AST and during transformation from the AST to Postgres
`Query` struct by adding the types to the `quals` list.

Variable-length relationship patterns with alternation `([:A|B*1..2])` are explicitly rejected
with `ERRCODE_FEATURE_NOT_SUPPORTED`.

Testing:
- Added regress test with cases with directed/undirected edges, and variable length edges

Future work:
- openCypher also support node-type alternation (like n:Person|Customer), which could be
added to AGE in a future PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds openCypher-compatible relationship-type alternation in MATCH patterns (e.g. ()-[:A|B]->()), by extending the Cypher grammar/AST and injecting an additional edge-label filter qual during transformation to a PostgreSQL Query. It also explicitly rejects variable-length edges combined with alternation.

Changes:

  • Extend the grammar and cypher_relationship AST node to represent multi-label edge patterns like [:A|B|C].
  • During MATCH transformation, inject a synthetic qual restricting matched edges to the alternation’s label-id set.
  • Add regression coverage for directed/undirected alternation, unknown labels, and the VLE rejection case.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/include/nodes/cypher_nodes.h Adds labels list to cypher_relationship to represent relationship-type alternation.
src/backend/parser/cypher_gram.y Parses `[:A
src/backend/parser/cypher_clause.c Injects an IN qual over _extract_label_id(edge.id) for alternation; rejects alternation with VLE.
src/backend/nodes/cypher_outfuncs.c Serializes the new labels field for cypher_relationship.
regress/sql/cypher_match_rel_label_alternation.sql Adds regression test cases covering alternation behavior and the VLE rejection.
regress/expected/cypher_match_rel_label_alternation.out Expected output for the new regression test.
Makefile Registers the new regression test in REGRESS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5349 to +5352
if (id_consts == NIL)
{
return make_bool_a_const(false);
}
Comment on lines +5791 to +5793
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("variable length relationships with type alternation is not yet supported"),
parser_errposition(&cpstate->pstate, rel->location)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants