Skip to content

Conversation

@anderson4j
Copy link
Collaborator

@anderson4j anderson4j commented Oct 28, 2025

Implements similar logic that we used for paths like
MATCH (n:A)-[: to complete rels, to also work for node completions in paths like:
MATCH (n:A)-[r:R]->(:

Also uses the new lastRule property on the parsing result to get the latest node/rel pattern before the caret in both rel/node completions to avoid taking just "last pattern in parent ctx" failing on queries like MATCH (n:A)-[r:R]->(:^)-[r2:R2]->(:

Closes DEV-197

@changeset-bot
Copy link

changeset-bot bot commented Oct 28, 2025

⚠️ No Changeset found

Latest commit: e18ee73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@anderson4j anderson4j added the auto completion Issues related to the auto-completion label Oct 28, 2025
// and returns the "labels" of rels/nodes going out/in of the node/rel in the graph schema
function walkLabelTree(
relsFromLabels: Map<string, Set<string>>,
labelToConnectedLabelsMap: Map<string, Set<string>>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can use this identically if it is
Map<label, Set> (rel completion)
Map<rel types, Set>, (node completion)

I struggle to find a nice name that covers both. Maybe I should add the above comment into the code to help clarify things that way?

Copy link
Collaborator

Choose a reason for hiding this comment

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

In the grammar/database, they're just called "labels" right? Even if they can also be relationship types. It's not perfect, but at least somewhat consistent.

An idea for a better name for the labelToConnectedLabelsMap be to call it labelSegments ? I feel it makes it clear it's part of a path/patterns but not the full thing?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a thought: is there a risk anywhere in our logic around people using the same names for a Reltype or label?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have some ideas on how we maybe could make this data structure better or more efficient, but I think we can wait until the feature matures to consider that refactoring

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

About interference between rels/nodes with the same labels. Short answer - I see no risk

Longer:
We check for variable name/reference offset (really offset should be enough..) when fetching labels for a variable, so other variables will not interfere here -> the labels object on each symbol should be correct regardless of labels of other variables, even if the labels are the same.

Copy link
Collaborator Author

@anderson4j anderson4j Nov 4, 2025

Choose a reason for hiding this comment

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

Regarding the naming. Im not sure of labelSegments... First thought is that seeing a collection called labelSegments I would think "list of segments", not map to list... but then if we use it like labelSegments.get(myLabel) I suppose that makes it clear that it's a map... I checked with ChatGPT and it proposed connectedLabelsMap, which I quite like. Or maybe even just connectedLabels

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm happy to go with connectedLabels 👍

{ label: 'CATCHES', kind: CompletionItemKind.TypeParameter },
{ label: 'TRAINS', kind: CompletionItemKind.TypeParameter },
{ label: 'IS_IN', kind: CompletionItemKind.TypeParameter },
//Limitation: Only take preceding node into account
Copy link
Collaborator Author

@anderson4j anderson4j Oct 29, 2025

Choose a reason for hiding this comment

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

If we keep slicing the query at the cursor we won't even have access to the fact that a "Pokemon" node follows the rel we are completing

Comment on lines 67 to 68
test('Simple node completion pattern', () => {
const query = 'MATCH (t:Trainer)-[r:CATCHES]->(:';
Copy link
Collaborator

Choose a reason for hiding this comment

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

It'd be nice to add a few more test cases (longer pattern, different relationships). Kind of like we have for the rel types?

Copy link
Collaborator

Choose a reason for hiding this comment

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

And for example showing tests of the limitations with regards to directionality

Copy link
Collaborator Author

@anderson4j anderson4j Nov 4, 2025

Choose a reason for hiding this comment

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

I think directionality is covered by existing tests (like this one, you see the "limitation" comment inside), so im not sure if we need more tests that explicitly state the limitation?

Comment on lines 41 to 43
if (query.length > offset) {
query = query.slice(0, offset);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this not done in the auto completion function now?

Copy link
Collaborator Author

@anderson4j anderson4j Nov 4, 2025

Choose a reason for hiding this comment

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

Oh right, I fixed it here first when I thought id merge it in quickly, but then things came up and I did a separate PR with it.

Forgot to merge main to this, but you're right I should now remove this, good spot!

// and returns the "labels" of rels/nodes going out/in of the node/rel in the graph schema
function walkLabelTree(
relsFromLabels: Map<string, Set<string>>,
labelToConnectedLabelsMap: Map<string, Set<string>>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the grammar/database, they're just called "labels" right? Even if they can also be relationship types. It's not perfect, but at least somewhat consistent.

An idea for a better name for the labelToConnectedLabelsMap be to call it labelSegments ? I feel it makes it clear it's part of a path/patterns but not the full thing?

}

// limitation: not direction-aware (ignores <- vs ->)
// limitation: not checking relationship variable reuse
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// limitation: not checking relationship variable reuse
// limitation: not checking node label repetition

// and returns the "labels" of rels/nodes going out/in of the node/rel in the graph schema
function walkLabelTree(
relsFromLabels: Map<string, Set<string>>,
labelToConnectedLabelsMap: Map<string, Set<string>>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a thought: is there a risk anywhere in our logic around people using the same names for a Reltype or label?

Comment on lines 121 to 124
let currentRelEntry = nodesFromRelsSet.get(rel.relType);
if (!currentRelEntry) {
nodesFromRelsSet.set(rel.relType, new Set());
currentRelEntry = nodesFromRelsSet.get(rel.relType);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it'd be cleaned to do a .has check first, and avoid the mutation of currentRelEntry

// and returns the "labels" of rels/nodes going out/in of the node/rel in the graph schema
function walkLabelTree(
relsFromLabels: Map<string, Set<string>>,
labelToConnectedLabelsMap: Map<string, Set<string>>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have some ideas on how we maybe could make this data structure better or more efficient, but I think we can wait until the feature matures to consider that refactoring

Copy link
Collaborator

@OskarDamkjaer OskarDamkjaer left a comment

Choose a reason for hiding this comment

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

Would be nice to have a simple undirected match test

MATCH (t:Trainer)-[r:CATCHES]-(:';

and I think it could be good for a longer path as well

@anderson4j anderson4j merged commit e7d209f into main Nov 5, 2025
8 checks passed
@anderson4j anderson4j deleted the nodeSACompletions branch November 5, 2025 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto completion Issues related to the auto-completion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants