Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,17 @@ private boolean matchesProperties(final Vertex vertex, final Result currentResul
expectedValue = evaluator.evaluate((Expression) expectedValue, currentResult, context);
}

// Resolve parameter references (e.g., $id -> actual value from context)
// Resolve ParameterReference objects (e.g., {user_name: $username} -> actual value from context)
if (expectedValue instanceof CypherASTBuilder.ParameterReference) {
final String paramName = ((CypherASTBuilder.ParameterReference) expectedValue).getName();
if (context.getInputParameters() != null) {
final Object paramValue = context.getInputParameters().get(paramName);
if (paramValue != null)
expectedValue = paramValue;
Comment on lines +517 to +518
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

If paramValue is null (meaning the parameter was not found or explicitly set to null), expectedValue will remain a CypherASTBuilder.ParameterReference object. This can lead to incorrect comparisons later in the matchesProperties method, as a ParameterReference object will be compared directly against a vertex property value, or potentially cause a ClassCastException if subsequent logic expects a String or null. The expectedValue should be set to null if the parameter resolves to null.

Suggested change
if (paramValue != null)
expectedValue = paramValue;
expectedValue = paramValue;

}
}

// Resolve parameter references stored as strings (legacy "$paramName" format)
if (expectedValue instanceof String) {
final String strValue = (String) expectedValue;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,38 @@ void manyParametersInIdQuery() {
}
}

/**
* Regression test for: MATCH (n:LABEL {prop: $param}) returns nothing when using inline
* node-pattern property filters with parameters, while the equivalent literal query works.
* The parser stores the parameter as a ParameterReference object in the properties map,
* and MatchNodeStep.matchesProperties() was not resolving it before comparing.
*/
@Test
void inlineNodePatternParameterMatching() {
final Database database = new DatabaseFactory("./target/testparams4").create();
try {
database.getSchema().getOrCreateVertexType("USER_RIGHTS");

database.transaction(() ->
database.command("opencypher", "CREATE (n:USER_RIGHTS {user_name: \"random_username_123\"}) RETURN n"));

// Inline property filter with a string parameter should return the node
final ResultSet result = database.query("opencypher",
"MATCH (n:USER_RIGHTS {user_name: $username}) RETURN n",
Map.of("username", "random_username_123"));

int count = 0;
while (result.hasNext()) {
result.next();
count++;
}
assertThat(count).isEqualTo(1);
} finally {
database.drop();
FileUtils.deleteRecursively(new File("./target/testparams4"));
}
}

@BeforeEach
@AfterEach
void clean() {
Expand Down
Loading