瀏覽代碼

Handle special regex cases for version fields (#132511)

It is possible that the runAutomaton created is `null` as its one of the
following cases:

 - none: meaning no matches
 - all: meaning all matches
 - single: meaning its just a single term (not actually regex)

Each of these can be handled directly.
Benjamin Trent 2 月之前
父節點
當前提交
b20eaf3e59

+ 5 - 0
docs/changelog/132511.yaml

@@ -0,0 +1,5 @@
+pr: 132511
+summary: Handle special regex cases for version fields
+area: Search
+type: bug
+issues: []

+ 11 - 0
x-pack/plugin/mapper-version/src/main/java/org/elasticsearch/xpack/versionfield/VersionStringFieldMapper.java

@@ -198,6 +198,17 @@ public class VersionStringFieldMapper extends FieldMapper {
                         @Override
                         protected AcceptStatus accept(BytesRef term) throws IOException {
                             BytesRef decoded = VersionEncoder.decodeVersion(term);
+                            if (compiled.runAutomaton == null) {
+                                return switch (compiled.type) {
+                                    case SINGLE -> decoded.equals(compiled.term) ? AcceptStatus.YES : AcceptStatus.NO;
+                                    case ALL -> AcceptStatus.YES;
+                                    case NONE -> AcceptStatus.NO;
+                                    default -> {
+                                        assert false : "Unexpected automaton type: " + compiled.type;
+                                        yield AcceptStatus.NO;
+                                    }
+                                };
+                            }
                             boolean accepted = compiled.runAutomaton.run(decoded.bytes, decoded.offset, decoded.length);
                             if (accepted) {
                                 return AcceptStatus.YES;

+ 29 - 0
x-pack/plugin/mapper-version/src/test/java/org/elasticsearch/xpack/versionfield/VersionStringFieldTests.java

@@ -216,6 +216,35 @@ public class VersionStringFieldTests extends ESSingleNodeTestCase {
                 assertEquals("2.1.0-alpha.beta", response.getHits().getHits()[1].getSourceAsMap().get("version"));
             }
         );
+
+        assertResponse(
+            client().prepareSearch(indexName).setQuery(QueryBuilders.regexpQuery("version", ".*").caseInsensitive(true)),
+            response -> {
+                assertEquals(5, response.getHits().getTotalHits().value());
+            }
+        );
+
+        assertResponse(
+            client().prepareSearch(indexName).setQuery(QueryBuilders.regexpQuery("version", "2\\.1\\.0").caseInsensitive(false)),
+            response -> {
+                assertEquals(1, response.getHits().getTotalHits().value());
+            }
+        );
+
+        assertResponse(
+            client().prepareSearch(indexName).setQuery(QueryBuilders.regexpQuery("version", "2\\.1\\.1").caseInsensitive(false)),
+            response -> {
+                assertEquals(0, response.getHits().getTotalHits().value());
+            }
+        );
+
+        // empty regex should not match anything
+        assertResponse(
+            client().prepareSearch(indexName).setQuery(QueryBuilders.regexpQuery("version", "").caseInsensitive(false)),
+            response -> {
+                assertEquals(0, response.getHits().getTotalHits().value());
+            }
+        );
     }
 
     public void testFuzzyQuery() throws Exception {