Skip to content

Conversation

@seanjSO
Copy link

@seanjSO seanjSO commented Jan 29, 2026

this is a first take implementation that still needs some cleanup and love; I need to do a big stare-down at the identifier matching to make sure all is copacetic, but so far, the responses for this match up with my cypher queries for my demo dataset.

still need to ensure the following:

  • a leading optional match does not cause a failure and is treated effectively like a plain match
    • check this based on previous frames? ie., if no previous frame, the optional match is the initial query so skip the aggregation step
  • tests for query translations once the implementation is on the right track

test queries:

single traversal w/ optional match

match (u:User) where u.name contains 'ADMIN'
    optional match (u)-[:MemberOf]->(g) where g.name contains 'DOMAIN ADMINS'
    return u, g

expands to:

WITH s0 AS (
  SELECT
    (n0.id, n0.kind_ids, n0.properties) ::nodecomposite AS n0
  FROM node n0
  WHERE ( (n0.properties ->> 'name') LIKE '%ADMIN%') AND n0.kind_ids operator (pg_catalog.&&) array [25]::int2 []
), s1 AS (
  SELECT
    (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties) ::edgecomposite AS e0
    , s0.n0 AS n0
    , (n1.id, n1.kind_ids, n1.properties) ::nodecomposite AS n1
  FROM s0
  JOIN edge e0
  ON (s0.n0) .id = e0.start_id
  JOIN node n1
  ON n1.id = e0.end_id
  WHERE ( (n1.properties ->> 'name') LIKE '%DOMAIN ADMINS%') AND e0.kind_id = any (array [94]::int2 [])
), s2 AS (
  SELECT
    s0.n0 AS n0
    , s1.e0 AS e0
    , s1.n1 AS n1
  FROM s0
  LEFT OUTER JOIN s1
  ON (s0.n0 = s1.n0)
)
SELECT
  s2.n0 AS u
  , s2.n1 AS g
FROM s2;

returns an 8x2 with 5 g values nulled

multiple-traversal w/ multiple optional match

match (u:User) where u.name contains 'ADMIN'
	optional match (u)-[:MemberOf]->(g) where g.name contains 'ADMINS'
	optional match (g)-[:GenericAll]->(item) where item.name contains 'ADMIN' or item.name contains 'OWNER'
	return u.name, g.name, labels(item), item.name

expands to:

WITH s0 AS (
  SELECT
    (n0.id, n0.kind_ids, n0.properties) ::nodecomposite AS n0
  FROM node n0
  WHERE ( (n0.properties ->> 'name') LIKE '%ADMIN%') AND n0.kind_ids operator (pg_catalog.&&) array [25]::int2 []
), s1 AS (
  SELECT
    (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties) ::edgecomposite AS e0
    , s0.n0 AS n0
    , (n1.id, n1.kind_ids, n1.properties) ::nodecomposite AS n1
  FROM s0
  JOIN edge e0
  ON (s0.n0) .id = e0.start_id
  JOIN node n1
  ON n1.id = e0.end_id
  WHERE ( (n1.properties ->> 'name') LIKE '%ADMINS%') AND e0.kind_id = any (array [94]::int2 [])
), s2 AS (
  SELECT
    s0.n0 AS n0
    , s1.e0 AS e0
    , s1.n1 AS n1
  FROM s0
  LEFT OUTER JOIN s1
  ON (s0.n0 = s1.n0)
), s3 AS (
  SELECT
    s2.e0 AS e0
    , (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties) ::edgecomposite AS e1
    , s2.n0 AS n0
    , s2.n1 AS n1
    , (n2.id, n2.kind_ids, n2.properties) ::nodecomposite AS n2
  FROM s2
  JOIN edge e1
  ON (s2.n1) .id = e1.start_id
  JOIN node n2
  ON n2.id = e1.end_id
  WHERE ( (n2.properties ->> 'name') LIKE '%ADMIN%' OR (n2.properties ->> 'name') LIKE '%OWNER%') AND e1.kind_id = any (array [90]::int2 [])
), s4 AS (
  SELECT
    s2.e0 AS e0
    , s2.n0 AS n0
    , s2.n1 AS n1
    , s3.e1 AS e1
    , s3.n2 AS n2
  FROM s2
  LEFT OUTER JOIN s3
  ON (s2.n1 = s3.n1) AND (s2.n0 = s3.n0) AND (s2.e0 = s3.e0)
)
SELECT
  ( (s4.n0) .properties -> 'name')
  , ( (s4.n1) .properties -> 'name')
  , (s4.n2) .kind_ids
  , ( (s4.n2) .properties -> 'name')
FROM s4;

returns a 56x4 with 5 g values nulled, 7 item values nulled

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch seanj/BED-6696

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@seanjSO seanjSO self-assigned this Jan 29, 2026
@seanjSO seanjSO force-pushed the seanj/BED-6696 branch 3 times, most recently from 03f8dc4 to 5ff19ed Compare January 30, 2026 20:15
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