|
9 | 9 |
|
10 | 10 | import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; |
11 | 11 |
|
| 12 | +import org.elasticsearch.common.network.NetworkAddress; |
12 | 13 | import org.elasticsearch.common.settings.Settings; |
13 | 14 | import org.elasticsearch.core.Tuple; |
14 | 15 | import org.elasticsearch.index.query.QueryBuilder; |
|
54 | 55 | import org.elasticsearch.xpack.ql.type.EsField; |
55 | 56 | import org.junit.Before; |
56 | 57 |
|
| 58 | +import java.util.ArrayList; |
57 | 59 | import java.util.List; |
58 | 60 | import java.util.Map; |
| 61 | +import java.util.stream.Collectors; |
59 | 62 |
|
60 | 63 | import static java.util.Arrays.asList; |
| 64 | +import static org.elasticsearch.common.logging.LoggerMessageFormat.format; |
61 | 65 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.as; |
62 | 66 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.configuration; |
63 | 67 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping; |
@@ -415,6 +419,44 @@ public void testIsNullPushdownFilter() { |
415 | 419 | assertThat(query.query().toString(), is(expected.toString())); |
416 | 420 | } |
417 | 421 |
|
| 422 | + /** |
| 423 | + * Expects |
| 424 | + * LimitExec[500[INTEGER]] |
| 425 | + * \_ExchangeExec[[],false] |
| 426 | + * \_ProjectExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, |
| 427 | + * 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, |
| 428 | + * unsigned_long{f}#16, version{f}#19, wildcard{f}#20]] |
| 429 | + * \_FieldExtractExec[!alias_integer, boolean{f}#4, byte{f}#5, constant_k..][] |
| 430 | + * \_EsQueryExec[test], query[{"esql_single_value":{"field":"ip","next":{"terms":{"ip":["127.0.0.0/24"],"boost":1.0}},"source": |
| 431 | + * "cidr_match(ip, \"127.0.0.0/24\")@1:19"}}][_doc{f}#21], limit[500], sort[] estimatedRowSize[389] |
| 432 | + */ |
| 433 | + public void testCidrMatchPushdownFilter() { |
| 434 | + var allTypeMappingAnalyzer = makeAnalyzer("mapping-ip.json", new EnrichResolution()); |
| 435 | + final String fieldName = "ip_addr"; |
| 436 | + |
| 437 | + int cidrBlockCount = randomIntBetween(1, 10); |
| 438 | + ArrayList<String> cidrBlocks = new ArrayList<>(); |
| 439 | + for (int i = 0; i < cidrBlockCount; i++) { |
| 440 | + cidrBlocks.add(randomCidrBlock()); |
| 441 | + } |
| 442 | + String cidrBlocksString = cidrBlocks.stream().map((s) -> "\"" + s + "\"").collect(Collectors.joining(",")); |
| 443 | + String cidrMatch = format(null, "cidr_match({}, {})", fieldName, cidrBlocksString); |
| 444 | + |
| 445 | + var query = "from test | where " + cidrMatch; |
| 446 | + var plan = plan(query, EsqlTestUtils.TEST_SEARCH_STATS, allTypeMappingAnalyzer); |
| 447 | + |
| 448 | + var limit = as(plan, LimitExec.class); |
| 449 | + var exchange = as(limit.child(), ExchangeExec.class); |
| 450 | + var project = as(exchange.child(), ProjectExec.class); |
| 451 | + var field = as(project.child(), FieldExtractExec.class); |
| 452 | + var queryExec = as(field.child(), EsQueryExec.class); |
| 453 | + assertThat(queryExec.limit().fold(), is(500)); |
| 454 | + |
| 455 | + var expectedInnerQuery = QueryBuilders.termsQuery(fieldName, cidrBlocks); |
| 456 | + var expectedQuery = wrapWithSingleQuery(expectedInnerQuery, fieldName, new Source(1, 18, cidrMatch)); |
| 457 | + assertThat(queryExec.query().toString(), is(expectedQuery.toString())); |
| 458 | + } |
| 459 | + |
418 | 460 | private record OutOfRangeTestCase(String fieldName, String tooLow, String tooHigh) {}; |
419 | 461 |
|
420 | 462 | public void testOutOfRangeFilterPushdown() { |
@@ -621,4 +663,13 @@ private PhysicalPlan physicalPlan(String query, Analyzer analyzer) { |
621 | 663 | protected List<String> filteredWarnings() { |
622 | 664 | return withDefaultLimitWarning(super.filteredWarnings()); |
623 | 665 | } |
| 666 | + |
| 667 | + private String randomCidrBlock() { |
| 668 | + boolean ipv4 = randomBoolean(); |
| 669 | + |
| 670 | + String address = NetworkAddress.format(randomIp(ipv4)); |
| 671 | + int cidrPrefixLength = ipv4 ? randomIntBetween(0, 32) : randomIntBetween(0, 128); |
| 672 | + |
| 673 | + return format(null, "{}/{}", address, cidrPrefixLength); |
| 674 | + } |
624 | 675 | } |
0 commit comments