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)
$(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
)