Improve error detection in geo_filter parsing

Relates to #5370
This commit is contained in:
Boaz Leskes 2014-03-09 08:53:29 +01:00
parent fbb8c0fafa
commit bb63b3fa61
7 changed files with 127 additions and 8 deletions

View File

@ -53,7 +53,7 @@ import static org.elasticsearch.index.query.support.QueryParsers.wrapSmartNameFi
public class GeoPolygonFilterParser implements FilterParser { public class GeoPolygonFilterParser implements FilterParser {
public static final String NAME = "geo_polygon"; public static final String NAME = "geo_polygon";
public static final String POINTS = "points"; public static final String POINTS = "points";
@Inject @Inject
public GeoPolygonFilterParser() { public GeoPolygonFilterParser() {
@ -91,13 +91,15 @@ public class GeoPolygonFilterParser implements FilterParser {
if (token == XContentParser.Token.FIELD_NAME) { if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName(); currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_ARRAY) { } else if (token == XContentParser.Token.START_ARRAY) {
if(POINTS.equals(currentFieldName)) { if (POINTS.equals(currentFieldName)) {
while((token = parser.nextToken()) != Token.END_ARRAY) { while ((token = parser.nextToken()) != Token.END_ARRAY) {
shell.add(GeoPoint.parse(parser)); shell.add(GeoPoint.parse(parser));
} }
} else { } else {
throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]"); throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]");
} }
} else {
throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support token type [" + token.name() + "] under [" + currentFieldName + "]");
} }
} }
} else if (token.isValue()) { } else if (token.isValue()) {
@ -113,20 +115,22 @@ public class GeoPolygonFilterParser implements FilterParser {
} else { } else {
throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]"); throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]");
} }
} else {
throw new QueryParsingException(parseContext.index(), "[geo_polygon] unexpected token type [" + token.name() + "]");
} }
} }
if (shell.isEmpty()) { if (shell.isEmpty()) {
throw new QueryParsingException(parseContext.index(), "no points defined for geo_polygon filter"); throw new QueryParsingException(parseContext.index(), "no points defined for geo_polygon filter");
} else { } else {
if(shell.size() < 3) { if (shell.size() < 3) {
throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter"); throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter");
} }
GeoPoint start = shell.get(0); GeoPoint start = shell.get(0);
if(!start.equals(shell.get(shell.size()-1))) { if (!start.equals(shell.get(shell.size() - 1))) {
shell.add(start); shell.add(start);
} }
if(shell.size() < 4) { if (shell.size() < 4) {
throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter"); throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter");
} }
} }

View File

@ -2038,6 +2038,29 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.points()[2].lon(), closeTo(-90, 0.00001)); assertThat(filter.points()[2].lon(), closeTo(-90, 0.00001));
} }
@Test
public void testGeoPolygonFilterParsingExceptions() throws IOException {
String[] brokenFiles = new String[]{
"/org/elasticsearch/index/query/geo_polygon_exception_1.json",
"/org/elasticsearch/index/query/geo_polygon_exception_2.json",
"/org/elasticsearch/index/query/geo_polygon_exception_3.json",
"/org/elasticsearch/index/query/geo_polygon_exception_4.json",
"/org/elasticsearch/index/query/geo_polygon_exception_5.json"
};
for (String brokenFile : brokenFiles) {
IndexQueryParserService queryParser = queryParser();
String query = copyToStringFromClasspath(brokenFile);
try {
queryParser.parse(query).query();
fail("parsing a broken geo_polygon filter didn't fail as expected while parsing: " + brokenFile);
} catch (QueryParsingException e) {
// success!
}
}
}
@Test @Test
public void testGeoPolygonFilter1() throws IOException { public void testGeoPolygonFilter1() throws IOException {
IndexQueryParserService queryParser = queryParser(); IndexQueryParserService queryParser = queryParser();
@ -2181,7 +2204,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
Query parsedQuery = queryParser.parse(query).query(); Query parsedQuery = queryParser.parse(query).query();
assertThat((double) (parsedQuery.getBoost()), Matchers.closeTo(3.0, 1.e-7)); assertThat((double) (parsedQuery.getBoost()), Matchers.closeTo(3.0, 1.e-7));
} }
@Test @Test
public void testBadTypeMatchQuery() throws Exception { public void testBadTypeMatchQuery() throws Exception {
IndexQueryParserService queryParser = queryParser(); IndexQueryParserService queryParser = queryParser();
@ -2193,7 +2216,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
expectedException = qpe; expectedException = qpe;
} }
assertThat(expectedException, notNullValue()); assertThat(expectedException, notNullValue());
} }
@Test @Test
public void testMultiMatchQuery() throws Exception { public void testMultiMatchQuery() throws Exception {

View File

@ -0,0 +1,20 @@
{
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_polygon": {
"location": {
"points": {
"points": [
[-70, 40],
[-80, 30],
[-90, 20]
]
}
}
}
}
}
}

View File

@ -0,0 +1,22 @@
{
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_polygon": {
"location": {
"points": [
[-70, 40],
[-80, 30],
[-90, 20]
],
"something_else": {
}
}
}
}
}
}

View File

@ -0,0 +1,12 @@
{
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_polygon": {
"location": ["WRONG"]
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_polygon": {
"location": {
"points": [
[-70, 40],
[-80, 30],
[-90, 20]
]
},
"bla": true
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_polygon": {
"location": {
"points": [
[-70, 40],
[-80, 30],
[-90, 20]
]
},
"bla": ["array"]
}
}
}
}