Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions muted-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,6 @@ tests:
- class: org.elasticsearch.xpack.esql.heap_attack.HeapAttackIT
method: testLookupExplosionNoFetch
issue: https://github.com/elastic/elasticsearch/issues/127365
- class: org.elasticsearch.xpack.esql.qa.single_node.GenerativeIT
method: test
issue: https://github.com/elastic/elasticsearch/issues/127536
- class: org.elasticsearch.xpack.inference.action.filter.ShardBulkInferenceActionFilterIT
method: testRestart {p0=false p1=false}
issue: https://github.com/elastic/elasticsearch/issues/127592
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private static String grok(List<Column> previousOutput) {
result.append(randomIdentifier());
} else {
String fieldName = randomRawName(previousOutput);
if (fieldName.isEmpty()) { // it's a bug, managed later, skipping for now
if (fieldName == null) {
fieldName = randomIdentifier();
}
result.append(fieldName);
Expand Down Expand Up @@ -191,7 +191,7 @@ private static String dissect(List<Column> previousOutput) {
result.append(randomIdentifier());
} else {
String fieldName = randomRawName(previousOutput);
if (fieldName.isEmpty()) { // it's a bug, managed later, skipping for now
if (fieldName == null) {
fieldName = randomIdentifier();
}
result.append(fieldName);
Expand All @@ -210,6 +210,9 @@ private static String keep(List<Column> previousOutput) {
proj.add("*");
} else {
String name = randomName(previousOutput);
if (name == null) {
continue;
}
if (name.length() > 1 && name.startsWith("`") == false && randomIntBetween(0, 100) < 10) {
if (randomBoolean()) {
name = name.substring(0, randomIntBetween(1, name.length() - 1)) + "*";
Expand All @@ -220,31 +223,42 @@ private static String keep(List<Column> previousOutput) {
proj.add(name);
}
}
if (proj.isEmpty()) {
return "";
}
return " | keep " + proj.stream().collect(Collectors.joining(", "));
}

private static String randomName(List<Column> previousOutput) {
String result = randomRawName(previousOutput);
if ((randomBoolean() && result.contains("*") == false)) {
if (result == null) {
return null;
}
if (randomBoolean() && result.contains("*") == false) {
result = "`" + result + "`";
}
return result;
}

/**
* Returns a field name from a list of columns.
* Could be null if none of the fields can be considered
*/
private static String randomRawName(List<Column> previousOutput) {
// we need to exclude <all-fields-projected>
// https://github.com/elastic/elasticsearch/issues/121741
String result = randomFrom(previousOutput.stream().filter(x -> x.name().equals("<all-fields-projected>") == false).toList()).name();
var list = previousOutput.stream().filter(EsqlQueryGenerator::fieldCanBeUsed).toList();
if (list.isEmpty()) {
return null;
}
String result = randomFrom(list).name();
return result;
}

/**
* Returns a field that can be used for grouping.
* Can return null
*/
private static String randomGroupableName(List<Column> previousOutput) {
// we need to exclude <all-fields-projected>
// https://github.com/elastic/elasticsearch/issues/121741
var candidates = previousOutput.stream()
.filter(EsqlQueryGenerator::groupable)
.filter(x -> x.name().equals("<all-fields-projected>") == false)
.toList();
var candidates = previousOutput.stream().filter(EsqlQueryGenerator::groupable).filter(EsqlQueryGenerator::fieldCanBeUsed).toList();
if (candidates.isEmpty()) {
return null;
}
Expand All @@ -260,13 +274,12 @@ private static boolean groupable(Column col) {
|| col.type.equals("version");
}

/**
* returns a field that can be sorted.
* Null if no fields are sortable.
*/
private static String randomSortableName(List<Column> previousOutput) {
// we need to exclude <all-fields-projected>
// https://github.com/elastic/elasticsearch/issues/121741
var candidates = previousOutput.stream()
.filter(EsqlQueryGenerator::sortable)
.filter(x -> x.name().equals("<all-fields-projected>") == false)
.toList();
var candidates = previousOutput.stream().filter(EsqlQueryGenerator::sortable).filter(EsqlQueryGenerator::fieldCanBeUsed).toList();
if (candidates.isEmpty()) {
return null;
}
Expand All @@ -290,10 +303,18 @@ private static String rename(List<Column> previousOutput) {
for (Column column : previousOutput) {
nameToType.put(column.name, column.type);
}
List<String> names = new ArrayList<>(previousOutput.stream().map(Column::name).collect(Collectors.toList()));
List<String> names = new ArrayList<>(
previousOutput.stream().filter(EsqlQueryGenerator::fieldCanBeUsed).map(Column::name).collect(Collectors.toList())
);
if (names.isEmpty()) {
return "";
}
for (int i = 0; i < n; i++) {
if (names.isEmpty()) {
break;
}
var name = randomFrom(names);
if (name.equals("<all-fields-projected>") || nameToType.get(name).endsWith("_range")) {
if (nameToType.get(name).endsWith("_range")) {
// ranges are not fully supported yet
continue;
}
Expand All @@ -306,9 +327,6 @@ private static String rename(List<Column> previousOutput) {
} else {
newName = names.get(randomIntBetween(0, names.size() - 1));
}
if (newName.equals("<all-fields-projected>")) { // it's a bug, managed as an error later
continue;
}
nameToType.put(newName, nameToType.get(name));
if (randomBoolean() && name.startsWith("`") == false) {
name = "`" + name + "`";
Expand All @@ -332,6 +350,9 @@ private static String drop(List<Column> previousOutput) {
Set<String> proj = new HashSet<>();
for (int i = 0; i < n; i++) {
String name = randomRawName(previousOutput);
if (name == null) {
continue;
}
if (name.length() > 1 && name.startsWith("`") == false && randomIntBetween(0, 100) < 10) {
if (randomBoolean()) {
name = name.substring(0, randomIntBetween(1, name.length() - 1)) + "*";
Expand All @@ -343,6 +364,9 @@ private static String drop(List<Column> previousOutput) {
}
proj.add(name);
}
if (proj.isEmpty()) {
return "";
}
return " | drop " + proj.stream().collect(Collectors.joining(", "));
}

Expand All @@ -363,7 +387,11 @@ private static String sort(List<Column> previousOutput) {
}

private static String mvExpand(List<Column> previousOutput) {
return " | mv_expand " + randomName(previousOutput);
String toExpand = randomName(previousOutput);
if (toExpand == null) {
return ""; // no columns to expand
}
return " | mv_expand " + toExpand;
}

private static String eval(List<Column> previousOutput) {
Expand All @@ -376,6 +404,9 @@ private static String eval(List<Column> previousOutput) {
name = randomIdentifier();
} else {
name = randomName(previousOutput);
if (name == null) {
name = randomIdentifier();
}
}
String expression = expression(previousOutput);
if (i > 0) {
Expand All @@ -390,7 +421,10 @@ private static String eval(List<Column> previousOutput) {
}

private static String stats(List<Column> previousOutput) {
List<Column> nonNull = previousOutput.stream().filter(x -> x.type().equals("null") == false).collect(Collectors.toList());
List<Column> nonNull = previousOutput.stream()
.filter(EsqlQueryGenerator::fieldCanBeUsed)
.filter(x -> x.type().equals("null") == false)
.collect(Collectors.toList());
if (nonNull.isEmpty()) {
return ""; // cannot do any stats, just skip
}
Expand All @@ -402,6 +436,9 @@ private static String stats(List<Column> previousOutput) {
name = randomIdentifier();
} else {
name = randomName(previousOutput);
if (name == null) {
name = randomIdentifier();
}
}
String expression = agg(nonNull);
if (i > 0) {
Expand Down Expand Up @@ -433,6 +470,9 @@ private static String agg(List<Column> previousOutput) {
}
// all types
name = randomName(previousOutput);
if (name == null) {
return "count(*)";
}
return switch (randomIntBetween(0, 2)) {
case 0 -> "count(*)";
case 1 -> "count(" + name + ")";
Expand Down Expand Up @@ -529,4 +569,12 @@ private static String randomIdentifier() {
return randomAlphaOfLength(randomIntBetween(8, 12));
}

private static boolean fieldCanBeUsed(Column field) {
return (
// https://github.com/elastic/elasticsearch/issues/121741
field.name().equals("<all-fields-projected>")
// this is a known pathological case, no need to test it for now
|| field.name().equals("<no-fields>")) == false;
}

}