Skip to content

Commit f705ed4

Browse files
more tests and comments
1 parent 95a461f commit f705ed4

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -992,12 +992,15 @@ public void testMultipleBatchesWithLookupJoin() throws IOException {
992992
createIndex("idx" + i, false);
993993
}
994994
bulkLoadTestDataLookupMode(10);
995-
var query = requestObjectBuilder().query(format(null, "from * | lookup join {} on integer | sort integer", testIndexName()));
996-
Map<String, Object> result = runEsql(query);
997-
var columns = as(result.get("columns"), List.class);
998-
assertEquals(20, columns.size());
999-
var values = as(result.get("values"), List.class);
1000-
assertEquals(10, values.size());
995+
// lookup join with and without sort
996+
for (String sort : List.of("", "| sort integer")) {
997+
var query = requestObjectBuilder().query(format(null, "from * | lookup join {} on integer {}", testIndexName(), sort));
998+
Map<String, Object> result = runEsql(query);
999+
var columns = as(result.get("columns"), List.class);
1000+
assertEquals(20, columns.size());
1001+
var values = as(result.get("values"), List.class);
1002+
assertEquals(10, values.size());
1003+
}
10011004
// clean up
10021005
for (int i = 1; i <= 20; i++) {
10031006
assertThat(deleteIndex("idx" + i).isAcknowledged(), is(true));

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/ReplaceMissingFieldWithNull.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ else if (plan instanceof Project project) {
8181
Alias nullAlias = nullLiteral.get(f.dataType());
8282
// save the first field as null (per datatype)
8383
if (nullAlias == null) {
84-
Alias alias = joinAttributes.isEmpty()
85-
? new Alias(f.source(), f.name(), Literal.of(f, null), f.id())
86-
: new Alias(f.source(), f.name(), Literal.of(f, null));
84+
// In case of batch executions on data nodes and join exists, SearchStats may not always be available for all,
85+
// fields, creating a new alias for null with the same id as the field id can potentially cause planEval to add a
86+
// duplicated ChannelSet to a layout, and Layout.builder().build() could throw a NullPointerException.
87+
// As a workaround, assign a new alias id to the null alias when join exists and SearchStats is not available.
88+
Alias alias = new Alias(f.source(), f.name(), Literal.of(f, null), joinAttributes.isEmpty() ? f.id() : null);
8789
nullLiteral.put(dt, alias);
8890
projection = alias.toAttribute();
8991
}

0 commit comments

Comments
 (0)