fix: Cypher -> WITH-carried node variable becomes null after anonymous CREATE or MERGE#4029
Conversation
…s CREATE or MERGE Anonymous node patterns (no variable) in CREATE/MERGE fell back to "n" as a default variable name and overwrote any `n` already bound in the row by an upstream MATCH/WITH. Guard the setProperty calls so only named node patterns bind a result slot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
🟢 Coverage 100.00% diff coverage · -8.56% coverage variation
Metric Results Coverage variation ✅ -8.56% coverage variation Diff coverage ✅ 100.00% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (bdbf985) 120168 88733 73.84% Head commit (371efb9) 151425 (+31257) 98857 (+10124) 65.28% (-8.56%) 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 (#4029) 8 8 100.00% 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.
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where anonymous CREATE and MERGE operations in OpenCypher would incorrectly overwrite existing variables in the result set. The fix ensures that properties are only set on the result if a variable is explicitly defined in the node pattern. A new regression test suite has been added to verify the fix. Reviewer feedback suggests refactoring the code to use a local variable for the node pattern's variable name to improve readability and performance by avoiding redundant method calls.
| // Only check for already-bound variable when explicitly named by the user. | ||
| // Anonymous MERGE nodes (no variable) should always search for matches. | ||
| if (nodePattern.getVariable() != null) { | ||
| final Object existing = baseResult.getProperty(variable); | ||
| final Object existing = baseResult.getProperty(nodePattern.getVariable()); |
There was a problem hiding this comment.
Capturing the variable name in a local variable improves readability and avoids redundant calls to nodePattern.getVariable(), especially since it is used multiple times throughout this method.
final String variable = nodePattern.getVariable();
// Only check for already-bound variable when explicitly named by the user.
// Anonymous MERGE nodes (no variable) should always search for matches.
if (variable != null) {
final Object existing = baseResult.getProperty(variable);| if (nodePattern.getVariable() != null) | ||
| r.setProperty(nodePattern.getVariable(), v); |
| if (nodePattern.getVariable() != null) | ||
| baseResult.setProperty(nodePattern.getVariable(), vertex); |
Code Review - PR #4029: Fix Cypher WITH-carried node variable becoming null after anonymous CREATE/MERGEOverviewThis PR fixes a real and well-understood bug: anonymous node patterns (no variable) in Bug Fix Correctness - Looks GoodThe core changes in both Before: final String variable = nodePattern.getVariable() != null ? nodePattern.getVariable() : "n";
result.setProperty(variable, vertex);After: if (nodePattern.getVariable() != null)
result.setProperty(nodePattern.getVariable(), vertex);The hardcoded I also verified that:
Test CoverageFive regression tests are a solid set and cover the meaningful variants. A few observations: Missing schema pre-creation for This may work in practice, but it is inconsistent with the established test pattern and could be fragile if that auto-creation behavior ever changes. Consider adding: database.getSchema().createVertexType("Temp4019");to Lambda workaround: Control tests are valuable: Code StyleThe fix follows the project's conventions correctly:
Summary
The fix itself is solid. The only actionable suggestion is to add 🤖 Generated with Claude Code |
…9 in test setUp Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code ReviewOverviewThis PR fixes a correctness bug where anonymous node patterns (no variable) in Correctness - the fix is right
The internal One readability note: In Test CoverageThe 5 regression tests cover the core cases well. A couple of gaps worth considering:
StyleThe test class has a multi-paragraph Javadoc block comment (lines 38-44). Per project guidelines, comment blocks should be one short line at most. A single-sentence class-level comment (or none at all, since the class name is descriptive) would be preferred. SummaryThe fix is correct, clean, and well-targeted. The two missing test cases (scalar alias + MERGE, and ON CREATE SET with anonymous node) are worth adding for completeness, but they do not affect the correctness of the fix itself. The existing tests cover the reported issue thoroughly. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4029 +/- ##
==========================================
- Coverage 64.83% 64.25% -0.59%
==========================================
Files 1597 1597
Lines 120168 120170 +2
Branches 25587 25589 +2
==========================================
- Hits 77916 77219 -697
- Misses 31466 32280 +814
+ Partials 10786 10671 -115 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…l after anonymous CREATE or MERGE (ArcadeData#4029)
… 2.64.1 to 2.65.0 [skip ci] Bumps [com.google.api.grpc:proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.64.1 to 2.65.0. Release notes *Sourced from [com.google.api.grpc:proto-google-common-protos's releases](https://github.com/googleapis/sdk-platform-java/releases).* > v2.65.0 > ------- > > [2.65.0](googleapis/sdk-platform-java@v2.64.2...v2.65.0) (2026-01-12) > ------------------------------------------------------------------------------------------------ > > ### Features > > * add org.json:json to third-party-dependencies pom ([ArcadeData#4047](https://redirect.github.com/googleapis/sdk-platform-java/issues/4047)) ([ffa432e](googleapis/sdk-platform-java@ffa432e)), closes [ArcadeData#4046](https://redirect.github.com/googleapis/sdk-platform-java/issues/4046) > * remove dependency management of graal-sdk ([ArcadeData#4033](https://redirect.github.com/googleapis/sdk-platform-java/issues/4033)) ([ad05c34](googleapis/sdk-platform-java@ad05c34)) > > ### Bug Fixes > > * add api\_version breadcrumb to client docs ([ArcadeData#4018](https://redirect.github.com/googleapis/sdk-platform-java/issues/4018)) ([a2b2179](googleapis/sdk-platform-java@a2b2179)) > * Create a single S2AChannelCredentials per application ([ArcadeData#3989](https://redirect.github.com/googleapis/sdk-platform-java/issues/3989)) ([3758b43](googleapis/sdk-platform-java@3758b43)) > * provide API to share the same background executor for channel po… ([ArcadeData#4030](https://redirect.github.com/googleapis/sdk-platform-java/issues/4030)) ([178182c](googleapis/sdk-platform-java@178182c)) > > ### Dependencies > > * update dependencies.txt for grpc-gcp to 1.9.0 ([ArcadeData#4025](https://redirect.github.com/googleapis/sdk-platform-java/issues/4025)) ([b68791d](googleapis/sdk-platform-java@b68791d)) > * update google api dependencies ([ArcadeData#3917](https://redirect.github.com/googleapis/sdk-platform-java/issues/3917)) ([480cf13](googleapis/sdk-platform-java@480cf13)) > * update google.http-client.version to 2.0.3 ([ArcadeData#4054](https://redirect.github.com/googleapis/sdk-platform-java/issues/4054)) ([b9a8c89](googleapis/sdk-platform-java@b9a8c89)) > > ### Documentation > > * Fix retry guide link in javadocs ([ArcadeData#4029](https://redirect.github.com/googleapis/sdk-platform-java/issues/4029)) ([b43f77c](googleapis/sdk-platform-java@b43f77c)) > > v2.65.0-rc1 > ----------- > > [2.65.0-rc1](googleapis/sdk-platform-java@v2.64.2...v2.65.0-rc1) (2025-12-11) > -------------------------------------------------------------------------------------------------------- > > ### Features > > * feat: Upgrade protobuf runtime and gen code to 4.33. ([googleapis/sdk-platform-java#4000](https://redirect.github.com/googleapis/sdk-platform-java/pull/4000)) (<googleapis/sdk-platform-java@ac25015>) > * feat: configure rc releases to be on prerelease mode (<googleapis/sdk-platform-java@e9055b0>) > > ### Bug Fixes > > * fix: add rc versioning scheme (<googleapis/sdk-platform-java@2939320>) > > ### Dependencies > > * deps: update auth to 1.42.0-rc1 and http-client to 2.1.0-rc1 ([googleapis/sdk-platform-java#4014](https://redirect.github.com/googleapis/sdk-platform-java/pull/4014)) (<googleapis/sdk-platform-java@0e01361>) > * deps: Upgrade grpc to 1.76.2 ([googleapis/sdk-platform-java#4006](https://redirect.github.com/googleapis/sdk-platform-java/pull/4006)(https://redirect.github.com/googleapis/sdk-platform-java/commit/a8060a263ba34556b8d4d347a57625849a6859bc)) > * deps: update google api dependencies ([googleapis/sdk-platform-java#3917](https://redirect.github.com/googleapis/sdk-platform-java/pull/3917)(https://redirect.github.com/googleapis/sdk-platform-java/commit/480cf13148687c53c4af3da9d48490aeb5bf4b88)) > > v2.64.2 > ------- > > [2.64.2](googleapis/sdk-platform-java@v2.64.1...v2.64.2) (2025-12-10) > ------------------------------------------------------------------------------------------------ ... (truncated) Changelog *Sourced from [com.google.api.grpc:proto-google-common-protos's changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md).* > [2.65.0](googleapis/sdk-platform-java@v2.64.2...v2.65.0) (2026-01-12) > ------------------------------------------------------------------------------------------------ > > ### Features > > * add org.json:json to third-party-dependencies pom ([ArcadeData#4047](https://redirect.github.com/googleapis/sdk-platform-java/issues/4047)) ([ffa432e](googleapis/sdk-platform-java@ffa432e)), closes [ArcadeData#4046](https://redirect.github.com/googleapis/sdk-platform-java/issues/4046) > * remove dependency management of graal-sdk ([ArcadeData#4033](https://redirect.github.com/googleapis/sdk-platform-java/issues/4033)) ([ad05c34](googleapis/sdk-platform-java@ad05c34)) > > ### Bug Fixes > > * add api\_version breadcrumb to client docs ([ArcadeData#4018](https://redirect.github.com/googleapis/sdk-platform-java/issues/4018)) ([a2b2179](googleapis/sdk-platform-java@a2b2179)) > * Create a single S2AChannelCredentials per application ([ArcadeData#3989](https://redirect.github.com/googleapis/sdk-platform-java/issues/3989)) ([3758b43](googleapis/sdk-platform-java@3758b43)) > * provide API to share the same background executor for channel po… ([ArcadeData#4030](https://redirect.github.com/googleapis/sdk-platform-java/issues/4030)) ([178182c](googleapis/sdk-platform-java@178182c)) > > ### Dependencies > > * update dependencies.txt for grpc-gcp to 1.9.0 ([ArcadeData#4025](https://redirect.github.com/googleapis/sdk-platform-java/issues/4025)) ([b68791d](googleapis/sdk-platform-java@b68791d)) > * update google api dependencies ([ArcadeData#3917](https://redirect.github.com/googleapis/sdk-platform-java/issues/3917)) ([480cf13](googleapis/sdk-platform-java@480cf13)) > * update google.http-client.version to 2.0.3 ([ArcadeData#4054](https://redirect.github.com/googleapis/sdk-platform-java/issues/4054)) ([b9a8c89](googleapis/sdk-platform-java@b9a8c89)) > > ### Documentation > > * Fix retry guide link in javadocs ([ArcadeData#4029](https://redirect.github.com/googleapis/sdk-platform-java/issues/4029)) ([b43f77c](googleapis/sdk-platform-java@b43f77c)) > > [2.64.2](googleapis/sdk-platform-java@v2.64.1...v2.64.2) (2025-12-10) > ------------------------------------------------------------------------------------------------ > > ### Bug Fixes > > * add per-service api\_version to gapic\_metadata ([ArcadeData#3984](https://redirect.github.com/googleapis/sdk-platform-java/issues/3984)) ([d589306](googleapis/sdk-platform-java@d589306)) > > ### Dependencies > > * Upgrade auth to 1.41.0. ([ArcadeData#4008](https://redirect.github.com/googleapis/sdk-platform-java/issues/4008)) ([833b3e5](googleapis/sdk-platform-java@833b3e5)) > * upgrade grpc to 1.76.1 ([ArcadeData#3993](https://redirect.github.com/googleapis/sdk-platform-java/issues/3993)) ([958611e](googleapis/sdk-platform-java@958611e)) > * Upgrade grpc to 1.76.2 ([ArcadeData#4006](https://redirect.github.com/googleapis/sdk-platform-java/issues/4006)) ([a8060a2](googleapis/sdk-platform-java@a8060a2)) Commits * [`972f87a`](googleapis/sdk-platform-java@972f87a) chore(main): release 2.65.0 ([ArcadeData#4058](https://redirect.github.com/googleapis/sdk-platform-java/issues/4058)) * [`74a2dd6`](googleapis/sdk-platform-java@74a2dd6) chore: update googleapis commit at Wed Dec 10 02:37:02 UTC 2025 ([ArcadeData#4013](https://redirect.github.com/googleapis/sdk-platform-java/issues/4013)) * [`b9a8c89`](googleapis/sdk-platform-java@b9a8c89) deps: update google.http-client.version to 2.0.3 ([ArcadeData#4054](https://redirect.github.com/googleapis/sdk-platform-java/issues/4054)) * [`93cbb09`](googleapis/sdk-platform-java@93cbb09) chore(deps): update upper bound dependencies file ([ArcadeData#4052](https://redirect.github.com/googleapis/sdk-platform-java/issues/4052)) * [`aa4a7f7`](googleapis/sdk-platform-java@aa4a7f7) build: Update macOS version in nightly workflow ([ArcadeData#4048](https://redirect.github.com/googleapis/sdk-platform-java/issues/4048)) * [`ffa432e`](googleapis/sdk-platform-java@ffa432e) feat: add org.json:json to third-party-dependencies pom ([ArcadeData#4047](https://redirect.github.com/googleapis/sdk-platform-java/issues/4047)) * [`3758b43`](googleapis/sdk-platform-java@3758b43) fix: Create a single S2AChannelCredentials per application ([ArcadeData#3989](https://redirect.github.com/googleapis/sdk-platform-java/issues/3989)) * [`178182c`](googleapis/sdk-platform-java@178182c) fix: provide API to share the same background executor for channel po… ([ArcadeData#4030](https://redirect.github.com/googleapis/sdk-platform-java/issues/4030)) * [`ad05c34`](googleapis/sdk-platform-java@ad05c34) feat: remove dependency management of graal-sdk ([ArcadeData#4033](https://redirect.github.com/googleapis/sdk-platform-java/issues/4033)) * [`6f59f7c`](googleapis/sdk-platform-java@6f59f7c) tests: Use fixed copyright year in tests. ([ArcadeData#4036](https://redirect.github.com/googleapis/sdk-platform-java/issues/4036)) * Additional commits viewable in [compare view](googleapis/sdk-platform-java@v2.64.1...v2.65.0) [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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)
…l after anonymous CREATE or MERGE (ArcadeData#4029)
…l after anonymous CREATE or MERGE (ArcadeData#4029)
…l after anonymous CREATE or MERGE (ArcadeData#4029)
$(cat <<'EOF'
Summary
Fixes #4019.
Anonymous node patterns (no variable) in
CREATEandMERGEused"n"as a hardcoded fallback variable name and stored the newly created vertex at that result-row key, silently overwriting anynalready bound by an upstreamMATCH/WITH.CreateStep.java(createPath, single-node branch): removed the"n"default; the created vertex is only bound to the row when the pattern has an explicit variable.MergeStep.java(mergeSingleNodeAll): same fix for both the match path and the create path.Test plan
Issue4019WithNodeVarNullAfterCreateMergeTest- 5 regression tests covering all cases from the issue report:MATCH (n) WITH n CREATE (:Temp)- node var survives anonymous CREATEMATCH (n) WITH n MERGE (:Temp)- node var survives anonymous MERGEMATCH (n) WITH n, 1 AS x CREATE (:Temp)- both node var and scalar surviveWITH nwithout any write (was already correct - control)OpenCypherCreateTest,OpenCypherMergeTest,OpenCypherMergeActionsTest,OpenCypherSetTest- no regressions🤖 Generated with Claude Code
EOF
)