Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -206,11 +206,31 @@ protected SimpleNode[] getCacheableElements() {

@Override
public boolean isIndexAware(final IndexSearchInfo info) {
// For nested properties like "tags.id", we need to handle the case where isBaseIdentifier() returns false
// due to the presence of a suffix/modifier. We'll check both cases:
// 1. Simple identifiers: left.isBaseIdentifier() == true (e.g., "tags")
// 2. Nested identifiers: Compare the full string representation (e.g., "tags.id")

String fieldName = null;

if (left.isBaseIdentifier()) {
if (info.getField().equals(left.getDefaultAlias().getStringValue())) {
return right.isEarlyCalculated(info.getContext());
// Simple identifier - use default alias
fieldName = left.getDefaultAlias().getStringValue();
} else {
// Might be a nested property - try using the string representation
String leftStr = left.toString();
// Check if this looks like a simple property path (alphanumeric with dots)
if (leftStr.matches("[a-zA-Z_][a-zA-Z0-9_.]*")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The regular expression used to validate the property path is both too restrictive and too permissive.

  1. Too restrictive: It doesn't handle quoted identifiers (using backticks), which are necessary for property names with special characters like hyphens (e.g., `my-property`.name). This will cause index lookups to fail for such valid property paths.
  2. Too permissive: It allows multiple consecutive dots (e.g., tags..id), which is not a valid property path syntax.

A more accurate validation might be needed here. Using a more robust regular expression or parsing the path to validate each segment would make this more reliable.

fieldName = leftStr;
}
}

if (fieldName != null && info.getField().equals(fieldName)) {
// CONTAINSANY operator only works with BY-ITEM indexes, not regular list indexes
if (info.isIndexByItem() && right != null)
return right.isEarlyCalculated(info.getContext());
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void listOfEmbeddedDocumentIndexByItem() {
database.command("sql", "INSERT INTO doc SET nums = [{'@type':'num','a':1},{'@type':'num','a':2}]");
});

// Query the indexed data
// Query the indexed data via CONTAINS
database.transaction(() -> {
ResultSet result = database.query("sql", "SELECT FROM doc WHERE nums.a CONTAINS 1");
long count = result.stream().count();
Expand All @@ -161,5 +161,17 @@ void listOfEmbeddedDocumentIndexByItem() {
.next().getProperty("executionPlan").toString();
assertThat(explain).contains("FETCH FROM INDEX");
});

// Query the indexed data via CONTAINSANY
database.transaction(() -> {
ResultSet result = database.query("sql", "SELECT FROM doc WHERE nums.a CONTAINSANY [1]");
long count = result.stream().count();
assertThat(count).isEqualTo(1);

// Verify index is being used
String explain = database.query("sql", "EXPLAIN SELECT FROM doc WHERE nums.a CONTAINSANY [1]")
.next().getProperty("executionPlan").toString();
assertThat(explain).contains("FETCH FROM INDEX");
});
}
}
Loading