Browse Source

Filter unsupported relation for range query builder (#26620)

kel 8 years ago
parent
commit
0f2a11695e

+ 13 - 0
core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java

@@ -115,10 +115,20 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
             String relationString = in.readOptionalString();
             if (relationString != null) {
                 relation = ShapeRelation.getRelationByName(relationString);
+                if (relation != null && !isRelationAllowed(relation)) {
+                    throw new IllegalArgumentException(
+                        "[range] query does not support relation [" + relationString + "]");
+                }
             }
         }
     }
 
+    private boolean isRelationAllowed(ShapeRelation relation) {
+        return relation == ShapeRelation.INTERSECTS
+            || relation == ShapeRelation.CONTAINS
+            || relation == ShapeRelation.WITHIN;
+    }
+
     @Override
     protected void doWriteTo(StreamOutput out) throws IOException {
         out.writeString(this.fieldName);
@@ -317,6 +327,9 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
         if (this.relation == null) {
             throw new IllegalArgumentException(relation + " is not a valid relation");
         }
+        if (!isRelationAllowed(this.relation)) {
+            throw new IllegalArgumentException("[range] query does not support relation [" + relation + "]");
+        }
         return this;
     }
 

+ 26 - 0
core/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java

@@ -31,6 +31,7 @@ import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TermRangeQuery;
 import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.common.ParsingException;
+import org.elasticsearch.common.geo.ShapeRelation;
 import org.elasticsearch.common.lucene.BytesRefs;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
@@ -535,4 +536,29 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
         ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(json));
         assertEquals("[range] query doesn't support multiple fields, found [age] and [" + DATE_FIELD_NAME + "]", e.getMessage());
     }
+
+    public void testParseRelation() {
+        String json =
+            "{\n" +
+                "    \"range\": {\n" +
+                "      \"age\": {\n" +
+                "        \"gte\": 30,\n" +
+                "        \"lte\": 40,\n" +
+                "        \"relation\": \"disjoint\"\n" +
+                "      }" +
+                "    }\n" +
+                "  }";
+        String fieldName = randomAlphaOfLengthBetween(1, 20);
+        IllegalArgumentException e1 = expectThrows(IllegalArgumentException.class, () -> parseQuery(json));
+        assertEquals("[range] query does not support relation [disjoint]", e1.getMessage());
+        RangeQueryBuilder builder = new RangeQueryBuilder(fieldName);
+        IllegalArgumentException e2 = expectThrows(IllegalArgumentException.class, ()->builder.relation("disjoint"));
+        assertEquals("[range] query does not support relation [disjoint]", e2.getMessage());
+        builder.relation("contains");
+        assertEquals(ShapeRelation.CONTAINS, builder.relation());
+        builder.relation("within");
+        assertEquals(ShapeRelation.WITHIN, builder.relation());
+        builder.relation("intersects");
+        assertEquals(ShapeRelation.INTERSECTS, builder.relation());
+    }
 }