Skip to content

#4000 fix(cypher): SET propagates to all aliases bound to the same node - #4004

Merged
robfrank merged 2 commits into
mainfrom
fix/4000-cypher-set-stale-alias
Apr 28, 2026
Merged

#4000 fix(cypher): SET propagates to all aliases bound to the same node#4004
robfrank merged 2 commits into
mainfrom
fix/4000-cypher-set-stale-alias

Conversation

@robfrank

Copy link
Copy Markdown
Collaborator

Summary

Fixes #4000.

When two Cypher variables are bound to the same node, a SET through one alias left the other alias stale in the same result row:

MATCH (n:Person {name:'Alice'}), (m:Person {name:'Alice'})
SET n.age = 35
RETURN n.age AS n_age, m.age AS m_age
-- Was returning: 35, 30  (m stale)
-- Now returns:   35, 35  (both consistent)

Root cause: SetStep.java called doc.modify() to get a MutableDocument, saved it, then updated only the single variable named in the SET item. Any other result-row entries pointing to the same underlying node (by RID) kept their old immutable snapshot.

Fix: Added propagateUpdateToSameNodeAliases() - after saving the mutated document, it scans every property in the result row and replaces any Document whose getIdentity() matches the original RID with the updated document. Applied in applyPropertySet, applyReplaceMap, and applyMergeMap.

Test plan

  • setThroughOneAliasPropagatestoOtherAliasOnSameNode - reproduces the main issue (two aliases in same MATCH)
  • setThroughOneAliasPropagatestoOtherAliasOnSameNodeFullNode - reproduces the stronger WITH+MATCH reproducer from the issue
  • All 15 tests in OpenCypherSetTest pass
  • Full OpenCypher suite: 5390 tests, 0 new failures

🤖 Generated with Claude Code

@codacy-production

codacy-production Bot commented Apr 27, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Coverage 83.33% diff coverage · -8.36% coverage variation

Metric Results
Coverage variation -8.36% coverage variation
Diff coverage 83.33% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (4ad4748) 120048 88335 73.58%
Head commit (93c62af) 151301 (+31253) 98678 (+10343) 65.22% (-8.36%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#4004) 18 15 83.33%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism to propagate node updates across all aliases within a result row in OpenCypher queries, ensuring consistency when multiple references point to the same node. This is implemented via a new propagateUpdateToSameNodeAliases method in SetStep.java and verified with new test cases. The review feedback identifies that this propagation logic is missing from the applyLabels method, which could lead to stale data when labels are changed, and suggests an optimization to the propagation loop to avoid redundant property updates.

mutableDoc.save();

if (variableToUpdate != null)
propagateUpdateToSameNodeAliases(result, doc, mutableDoc);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The applyLabels method (starting at line 261) is missing this propagation logic. When a vertex's labels are updated in ArcadeDB, it often results in the creation of a new vertex instance and the deletion of the old one (especially if the underlying type changes). Without calling propagateUpdateToSameNodeAliases in applyLabels, any other aliases in the same result row will continue to point to the old, deleted vertex instance. This will lead to stale data or errors in subsequent query steps. Please ensure that applyLabels also propagates the update to all aliases bound to the same node.

Comment thread engine/src/main/java/com/arcadedb/query/opencypher/executor/steps/SetStep.java Outdated
@codecov

codecov Bot commented Apr 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 61.11111% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.18%. Comparing base (4ad4748) to head (93c62af).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...adedb/query/opencypher/executor/steps/SetStep.java 61.11% 3 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4004      +/-   ##
==========================================
- Coverage   64.59%   64.18%   -0.41%     
==========================================
  Files        1597     1597              
  Lines      120048   120062      +14     
  Branches    25551    25556       +5     
==========================================
- Hits        77545    77066     -479     
- Misses      31743    32342     +599     
+ Partials    10760    10654     -106     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

When multiple variables point to the same node, SET through one alias now
updates all aliases in the result row by matching on RID, preventing stale
snapshots from being returned.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@robfrank
robfrank force-pushed the fix/4000-cypher-set-stale-alias branch from 0944d41 to 70f5632 Compare April 27, 2026 22:36
…node aliases

When SET n:Label causes a vertex type change, the old vertex is deleted
and a new one created. Only the named variable was updated; other aliases
pointing to the same node kept a stale reference to the deleted vertex.
Fix: use propagateUpdateToSameNodeAliases in applyLabels instead of a
direct setProperty call. Also skip redundant setProperty when the alias
already holds the updated document instance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@robfrank
robfrank merged commit 983da3f into main Apr 28, 2026
108 of 115 checks passed
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Apr 28, 2026
robfrank added a commit that referenced this pull request May 12, 2026
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
…studio [skip ci]

Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.58.2 to 1.59.1.
Release notes

*Sourced from [`@​playwright/test`'s releases](https://github.com/microsoft/playwright/releases).*

> v1.59.1
> -------
>
> ### Bug Fixes
>
> * **[Windows]** Reverted hiding console window when spawning browser processes, which caused regressions including broken `codegen`, `--ui` and `show` commands ([#39990](https://redirect.github.com/microsoft/playwright/issues/39990))
>
> v1.59.0
> -------
>
> 🎬 Screencast
> ------------
>
> New [page.screencast](https://playwright.dev/docs/api/class-page#page-screencast) API provides a unified interface for capturing page content with:
>
> * Screencast recordings
> * Action annotations
> * Visual overlays
> * Real-time frame capture
> * Agentic video receipts
>
> **Screencast recording** — record video with precise start/stop control, as an alternative to the [`recordVideo`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-video) option:
>
> ```
> await page.screencast.start({ path: 'video.webm' });
> // ... perform actions ...
> await page.screencast.stop();
> ```
>
> **Action annotations** — enable built-in visual annotations that highlight interacted elements and display action titles during recording:
>
> ```
> await page.screencast.showActions({ position: 'top-right' });
> ```
>
> [screencast.showActions()](https://playwright.dev/docs/api/class-screencast#screencast-show-actions) accepts `position` (`'top-left'`, `'top'`, `'top-right'`, `'bottom-left'`, `'bottom'`, `'bottom-right'`), `duration` (ms per annotation), and `fontSize` (px). Returns a disposable to stop showing actions.
>
> Action annotations can also be enabled in test fixtures via the `video` option:
>
> ```
> // playwright.config.ts
> export default defineConfig({
>   use: {
>     video: {
>       mode: 'on',
>       show: {
>         actions: { position: 'top-left' },
>         test: { position: 'top-right' },
>       },
> </tr></table>
> ```

... (truncated)


Commits

* [`d466ac5`](microsoft/playwright@d466ac5) chore: mark v1.59.1 ([#40005](https://redirect.github.com/microsoft/playwright/issues/40005))
* [`530e7e5`](microsoft/playwright@530e7e5) cherry-pick([ArcadeData#4004](https://redirect.github.com/microsoft/playwright/issues/4004)): fix(cli): kill-all should kill dashboard
* [`9aa216c`](microsoft/playwright@9aa216c) cherry-pick([#39994](https://redirect.github.com/microsoft/playwright/issues/39994)): Revert "fix(windows): hide console window when spawning ...
* [`01b2b15`](microsoft/playwright@01b2b15) cherry-pick([#39980](https://redirect.github.com/microsoft/playwright/issues/39980)): chore: more release notes fixes
* [`a5cb6c9`](microsoft/playwright@a5cb6c9) cherry-pick([#39972](https://redirect.github.com/microsoft/playwright/issues/39972)): chore: expose browser.bind and browser.unbind APIs
* [`99a17b5`](microsoft/playwright@99a17b5) cherry-pick([#39975](https://redirect.github.com/microsoft/playwright/issues/39975)): chore: support opening .trace files via .link indirection
* [`43607c3`](microsoft/playwright@43607c3) cherry-pick([#39974](https://redirect.github.com/microsoft/playwright/issues/39974)): chore(webkit): update Safari user-agent version to 26.4
* [`62cabe1`](microsoft/playwright@62cabe1) cherry-pick([#39969](https://redirect.github.com/microsoft/playwright/issues/39969)): chore(npm): include all \*.md from lib ([#39970](https://redirect.github.com/microsoft/playwright/issues/39970))
* [`0c65a75`](microsoft/playwright@0c65a75) cherry-pick([#39968](https://redirect.github.com/microsoft/playwright/issues/39968)): chore: screencast.showActions api
* [`f04155b`](microsoft/playwright@f04155b) cherry-pick([#39958](https://redirect.github.com/microsoft/playwright/issues/39958)): chore: release notes for langs v1.59
* Additional commits viewable in [compare view](microsoft/playwright@v1.58.2...v1.59.1)
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
@lvca
lvca deleted the fix/4000-cypher-set-stale-alias branch July 3, 2026 20:18
mergify Bot added a commit that referenced this pull request Jul 26, 2026
…o [skip ci]

Bumps [marked](https://github.com/markedjs/marked) from 18.0.6 to 18.0.7.
Release notes

*Sourced from [marked's releases](https://github.com/markedjs/marked/releases).*

> v18.0.7
> -------
>
> [18.0.7](markedjs/marked@v18.0.6...v18.0.7) (2026-07-21)
> -----------------------------------------------------------------------------------
>
> ### Bug Fixes
>
> * Avoid O(n^2) backtracking in HTML block close and tilde interrupt regexes ([#4014](https://redirect.github.com/markedjs/marked/issues/4014)) ([f945fc5](markedjs/marked@f945fc5)), closes [#3991](https://redirect.github.com/markedjs/marked/issues/3991)
> * Avoid O(n^2) masked source rebuild in inline tokenizer ([#4017](https://redirect.github.com/markedjs/marked/issues/4017)) ([9154f8f](markedjs/marked@9154f8f))
> * keep empty list after blockquote as a sibling block ([#4004](https://redirect.github.com/markedjs/marked/issues/4004)) ([3f144a0](markedjs/marked@3f144a0))
> * preserve code spans adjacent to tildes ([#4012](https://redirect.github.com/markedjs/marked/issues/4012)) ([0de7188](markedjs/marked@0de7188))
> * Recognize setext headings whose first line starts with # ([#4015](https://redirect.github.com/markedjs/marked/issues/4015)) ([f056437](markedjs/marked@f056437)), closes [#1](https://redirect.github.com/markedjs/marked/issues/1)
> * treat a line of only tabs as a blank line between paragraphs ([#4007](https://redirect.github.com/markedjs/marked/issues/4007)) ([bc2f121](markedjs/marked@bc2f121))


Commits

* [`a8971a1`](markedjs/marked@a8971a1) chore(release): 18.0.7 [skip ci]
* [`d899c2e`](markedjs/marked@d899c2e) chore(deps): bump actions/setup-node from 6 to 7 ([#4025](https://redirect.github.com/markedjs/marked/issues/4025))
* [`7fbf82e`](markedjs/marked@7fbf82e) chore(deps-dev): bump semantic-release from 25.0.7 to 25.0.8 ([#4026](https://redirect.github.com/markedjs/marked/issues/4026))
* [`738edf2`](markedjs/marked@738edf2) chore(deps-dev): bump brace-expansion from 5.0.2 to 5.0.6 ([#4027](https://redirect.github.com/markedjs/marked/issues/4027))
* [`9154f8f`](markedjs/marked@9154f8f) fix: Avoid O(n^2) masked source rebuild in inline tokenizer ([#4017](https://redirect.github.com/markedjs/marked/issues/4017))
* [`f945fc5`](markedjs/marked@f945fc5) fix: Avoid O(n^2) backtracking in HTML block close and tilde interrupt regexe...
* [`3f144a0`](markedjs/marked@3f144a0) fix: keep empty list after blockquote as a sibling block ([#4004](https://redirect.github.com/markedjs/marked/issues/4004))
* [`0de7188`](markedjs/marked@0de7188) fix: preserve code spans adjacent to tildes ([#4012](https://redirect.github.com/markedjs/marked/issues/4012))
* [`f056437`](markedjs/marked@f056437) fix: Recognize setext headings whose first line starts with # ([#4015](https://redirect.github.com/markedjs/marked/issues/4015))
* [`12bfa94`](markedjs/marked@12bfa94) chore(deps-dev): bump semantic-release from 25.0.5 to 25.0.7 ([#4020](https://redirect.github.com/markedjs/marked/issues/4020))
* Additional commits viewable in [compare view](markedjs/marked@v18.0.6...v18.0.7)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=marked&package-manager=npm\_and\_yarn&previous-version=18.0.6&new-version=18.0.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
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.

SET may leave other aliases to the same node stale within the same query

1 participant