|
54 | 54 | import org.elasticsearch.xpack.ql.type.EsField; |
55 | 55 | import org.junit.Before; |
56 | 56 |
|
| 57 | +import java.util.ArrayList; |
57 | 58 | import java.util.List; |
58 | 59 | import java.util.Map; |
| 60 | +import java.util.stream.Collectors; |
59 | 61 |
|
60 | 62 | import static java.util.Arrays.asList; |
61 | 63 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.as; |
@@ -415,6 +417,47 @@ public void testIsNullPushdownFilter() { |
415 | 417 | assertThat(query.query().toString(), is(expected.toString())); |
416 | 418 | } |
417 | 419 |
|
| 420 | + /** |
| 421 | + * Expects |
| 422 | + * LimitExec[500[INTEGER]] |
| 423 | + * \_ExchangeExec[[],false] |
| 424 | + * \_ProjectExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, |
| 425 | + * half_float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, |
| 426 | + * unsigned_long{f}#16, version{f}#19, wildcard{f}#20]] |
| 427 | + * \_FieldExtractExec[!alias_integer, boolean{f}#4, byte{f}#5, constant_k..][] |
| 428 | + * \_EsQueryExec[test], query[{"esql_single_value":{"field":"ip","next":{"terms":{"ip":["127.0.0.0/24"],"boost":1.0}},"source": |
| 429 | + * "cidr_match(ip, \"127.0.0.0/24\")@1:19"}}][_doc{f}#21], limit[500], sort[] estimatedRowSize[389] |
| 430 | + */ |
| 431 | + public void testCidrMatchPushdownFilter() { |
| 432 | + var allTypeMappingAnalyzer = makeAnalyzer("mapping-all-types.json", new EnrichResolution()); |
| 433 | + |
| 434 | + int cidrBlockCount = randomIntBetween(1, 10); |
| 435 | + ArrayList<String> cidrBlocks = new ArrayList<>(); |
| 436 | + for (int i = 0; i < cidrBlockCount; i++) { |
| 437 | + cidrBlocks.add("127.0." + i + ".0/24"); |
| 438 | + } |
| 439 | + String cidrBlocksString = cidrBlocks.stream().map((s) -> "\"" + s + "\"").collect(Collectors.joining(",")); |
| 440 | + String cidrMatch = "cidr_match(ip, " + cidrBlocksString + ")"; |
| 441 | + |
| 442 | + var query = "from test | where " + cidrMatch; |
| 443 | + var plan = plan(query, EsqlTestUtils.TEST_SEARCH_STATS, allTypeMappingAnalyzer); |
| 444 | + |
| 445 | + var limit = as(plan, LimitExec.class); |
| 446 | + var exchange = as(limit.child(), ExchangeExec.class); |
| 447 | + var project = as(exchange.child(), ProjectExec.class); |
| 448 | + var field = as(project.child(), FieldExtractExec.class); |
| 449 | + var queryExec = as(field.child(), EsQueryExec.class); |
| 450 | + assertThat(queryExec.limit().fold(), is(500)); |
| 451 | + |
| 452 | + assertThat(queryExec.query(), is(instanceOf(SingleValueQuery.Builder.class))); |
| 453 | + var actualLuceneQuery = (SingleValueQuery.Builder) queryExec.query(); |
| 454 | + assertThat(actualLuceneQuery.field(), equalTo("ip")); |
| 455 | + assertThat(actualLuceneQuery.source().text(), equalTo(cidrMatch)); |
| 456 | + |
| 457 | + var expectedInnerQuery = QueryBuilders.termsQuery("ip", cidrBlocks); |
| 458 | + assertThat(actualLuceneQuery.next(), equalTo(expectedInnerQuery)); |
| 459 | + } |
| 460 | + |
418 | 461 | private record OutOfRangeTestCase(String fieldName, String tooLow, String tooHigh) {}; |
419 | 462 |
|
420 | 463 | public void testOutOfRangeFilterPushdown() { |
|
0 commit comments