ESQL: Tests for large concat and many evals (#100159)

This commit is contained in:
Nik Everett 2023-10-03 14:41:40 -04:00 committed by GitHub
parent 48ea474953
commit 9620512a89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 119 additions and 13 deletions

View file

@ -52,6 +52,9 @@ appender.rolling_old.strategy.action.condition.nested_condition.type = IfAccumul
appender.rolling_old.strategy.action.condition.nested_condition.exceeds = 2GB
################################################
logger.esql.name = org.elasticsearch.xpack.esql
logger.esql.level = trace
rootLogger.level = info
rootLogger.appenderRef.console.ref = console
rootLogger.appenderRef.rolling.ref = rolling

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="440" height="76" viewbox="0 0 440 76"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 46h5m68 0h10m32 0h10m68 0h50m-5 0q-5 0-5-5v-26q0-5 5-5h120q5 0 5 5v26q0 5-5 5m-83 0h10m68 0h40m-185 0q5 0 5 5v10q0 5 5 5h160q5 0 5-5v-10q0-5 5-5m5 0h10m32 0h5"/><rect class="s" x="5" y="20" width="68" height="36"/><text class="k" x="15" y="46">CASE</text><rect class="s" x="83" y="20" width="32" height="36" rx="7"/><text class="syn" x="93" y="46">(</text><rect class="s" x="125" y="20" width="68" height="36" rx="7"/><text class="k" x="135" y="46">arg1</text><rect class="s" x="243" y="20" width="32" height="36" rx="7"/><text class="syn" x="253" y="46">,</text><rect class="s" x="285" y="20" width="68" height="36" rx="7"/><text class="k" x="295" y="46">arg2</text><rect class="s" x="403" y="20" width="32" height="36" rx="7"/><text class="syn" x="413" y="46">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="360" height="46" viewbox="0 0 360 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m68 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="68" height="36"/><text class="k" x="15" y="31">CASE</text><rect class="s" x="83" y="5" width="32" height="36" rx="7"/><text class="syn" x="93" y="31">(</text><rect class="s" x="125" y="5" width="68" height="36" rx="7"/><text class="k" x="135" y="31">arg1</text><rect class="s" x="203" y="5" width="32" height="36" rx="7"/><text class="syn" x="213" y="31">,</text><rect class="s" x="245" y="5" width="68" height="36" rx="7"/><text class="k" x="255" y="31">arg2</text><rect class="s" x="323" y="5" width="32" height="36" rx="7"/><text class="syn" x="333" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="488" height="76" viewbox="0 0 488 76"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 46h5m116 0h10m32 0h10m68 0h50m-5 0q-5 0-5-5v-26q0-5 5-5h120q5 0 5 5v26q0 5-5 5m-83 0h10m68 0h40m-185 0q5 0 5 5v10q0 5 5 5h160q5 0 5-5v-10q0-5 5-5m5 0h10m32 0h5"/><rect class="s" x="5" y="20" width="116" height="36"/><text class="k" x="15" y="46">COALESCE</text><rect class="s" x="131" y="20" width="32" height="36" rx="7"/><text class="syn" x="141" y="46">(</text><rect class="s" x="173" y="20" width="68" height="36" rx="7"/><text class="k" x="183" y="46">arg1</text><rect class="s" x="291" y="20" width="32" height="36" rx="7"/><text class="syn" x="301" y="46">,</text><rect class="s" x="333" y="20" width="68" height="36" rx="7"/><text class="k" x="343" y="46">arg2</text><rect class="s" x="451" y="20" width="32" height="36" rx="7"/><text class="syn" x="461" y="46">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="408" height="46" viewbox="0 0 408 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m116 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="116" height="36"/><text class="k" x="15" y="31">COALESCE</text><rect class="s" x="131" y="5" width="32" height="36" rx="7"/><text class="syn" x="141" y="31">(</text><rect class="s" x="173" y="5" width="68" height="36" rx="7"/><text class="k" x="183" y="31">arg1</text><rect class="s" x="251" y="5" width="32" height="36" rx="7"/><text class="syn" x="261" y="31">,</text><rect class="s" x="293" y="5" width="68" height="36" rx="7"/><text class="k" x="303" y="31">arg2</text><rect class="s" x="371" y="5" width="32" height="36" rx="7"/><text class="syn" x="381" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="464" height="76" viewbox="0 0 464 76"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 46h5m92 0h10m32 0h10m68 0h50m-5 0q-5 0-5-5v-26q0-5 5-5h120q5 0 5 5v26q0 5-5 5m-83 0h10m68 0h40m-185 0q5 0 5 5v10q0 5 5 5h160q5 0 5-5v-10q0-5 5-5m5 0h10m32 0h5"/><rect class="s" x="5" y="20" width="92" height="36"/><text class="k" x="15" y="46">CONCAT</text><rect class="s" x="107" y="20" width="32" height="36" rx="7"/><text class="syn" x="117" y="46">(</text><rect class="s" x="149" y="20" width="68" height="36" rx="7"/><text class="k" x="159" y="46">arg1</text><rect class="s" x="267" y="20" width="32" height="36" rx="7"/><text class="syn" x="277" y="46">,</text><rect class="s" x="309" y="20" width="68" height="36" rx="7"/><text class="k" x="319" y="46">arg2</text><rect class="s" x="427" y="20" width="32" height="36" rx="7"/><text class="syn" x="437" y="46">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="384" height="46" viewbox="0 0 384 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m92 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="92" height="36"/><text class="k" x="15" y="31">CONCAT</text><rect class="s" x="107" y="5" width="32" height="36" rx="7"/><text class="syn" x="117" y="31">(</text><rect class="s" x="149" y="5" width="68" height="36" rx="7"/><text class="k" x="159" y="31">arg1</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">,</text><rect class="s" x="269" y="5" width="68" height="36" rx="7"/><text class="k" x="279" y="31">arg2</text><rect class="s" x="347" y="5" width="32" height="36" rx="7"/><text class="syn" x="357" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="432" height="46" viewbox="0 0 432 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m140 0h10m32 0h10m68 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="140" height="36"/><text class="k" x="15" y="31">DATE_PARSE</text><rect class="s" x="155" y="5" width="32" height="36" rx="7"/><text class="syn" x="165" y="31">(</text><rect class="s" x="197" y="5" width="68" height="36" rx="7"/><text class="k" x="207" y="31">arg1</text><rect class="s" x="275" y="5" width="32" height="36" rx="7"/><text class="syn" x="285" y="31">,</text><rect class="s" x="317" y="5" width="68" height="36" rx="7"/><text class="k" x="327" y="31">arg2</text><rect class="s" x="395" y="5" width="32" height="36" rx="7"/><text class="syn" x="405" y="31">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="588" height="46" viewbox="0 0 588 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m140 0h10m32 0h10m152 0h10m32 0h10m140 0h10m32 0h5"/><rect class="s" x="5" y="5" width="140" height="36"/><text class="k" x="15" y="31">DATE_PARSE</text><rect class="s" x="155" y="5" width="32" height="36" rx="7"/><text class="syn" x="165" y="31">(</text><rect class="s" x="197" y="5" width="152" height="36" rx="7"/><text class="k" x="207" y="31">datePattern</text><rect class="s" x="359" y="5" width="32" height="36" rx="7"/><text class="syn" x="369" y="31">,</text><rect class="s" x="401" y="5" width="140" height="36" rx="7"/><text class="k" x="411" y="31">dateString</text><rect class="s" x="551" y="5" width="32" height="36" rx="7"/><text class="syn" x="561" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="500" height="76" viewbox="0 0 500 76"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 46h5m116 0h10m32 0h10m80 0h50m-5 0q-5 0-5-5v-26q0-5 5-5h120q5 0 5 5v26q0 5-5 5m-83 0h10m68 0h40m-185 0q5 0 5 5v10q0 5 5 5h160q5 0 5-5v-10q0-5 5-5m5 0h10m32 0h5"/><rect class="s" x="5" y="20" width="116" height="36"/><text class="k" x="15" y="46">GREATEST</text><rect class="s" x="131" y="20" width="32" height="36" rx="7"/><text class="syn" x="141" y="46">(</text><rect class="s" x="173" y="20" width="80" height="36" rx="7"/><text class="k" x="183" y="46">first</text><rect class="s" x="303" y="20" width="32" height="36" rx="7"/><text class="syn" x="313" y="46">,</text><rect class="s" x="345" y="20" width="68" height="36" rx="7"/><text class="k" x="355" y="46">rest</text><rect class="s" x="463" y="20" width="32" height="36" rx="7"/><text class="syn" x="473" y="46">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="420" height="46" viewbox="0 0 420 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m116 0h10m32 0h10m80 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="116" height="36"/><text class="k" x="15" y="31">GREATEST</text><rect class="s" x="131" y="5" width="32" height="36" rx="7"/><text class="syn" x="141" y="31">(</text><rect class="s" x="173" y="5" width="80" height="36" rx="7"/><text class="k" x="183" y="31">first</text><rect class="s" x="263" y="5" width="32" height="36" rx="7"/><text class="syn" x="273" y="31">,</text><rect class="s" x="305" y="5" width="68" height="36" rx="7"/><text class="k" x="315" y="31">rest</text><rect class="s" x="383" y="5" width="32" height="36" rx="7"/><text class="syn" x="393" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="464" height="76" viewbox="0 0 464 76"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 46h5m80 0h10m32 0h10m80 0h50m-5 0q-5 0-5-5v-26q0-5 5-5h120q5 0 5 5v26q0 5-5 5m-83 0h10m68 0h40m-185 0q5 0 5 5v10q0 5 5 5h160q5 0 5-5v-10q0-5 5-5m5 0h10m32 0h5"/><rect class="s" x="5" y="20" width="80" height="36"/><text class="k" x="15" y="46">LEAST</text><rect class="s" x="95" y="20" width="32" height="36" rx="7"/><text class="syn" x="105" y="46">(</text><rect class="s" x="137" y="20" width="80" height="36" rx="7"/><text class="k" x="147" y="46">first</text><rect class="s" x="267" y="20" width="32" height="36" rx="7"/><text class="syn" x="277" y="46">,</text><rect class="s" x="309" y="20" width="68" height="36" rx="7"/><text class="k" x="319" y="46">rest</text><rect class="s" x="427" y="20" width="32" height="36" rx="7"/><text class="syn" x="437" y="46">)</text></svg>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="384" height="46" viewbox="0 0 384 46"><defs><style type="text/css">#guide .c{fill:none;stroke:#222222;}#guide .k{fill:#000000;font-family:Roboto Mono,Sans-serif;font-size:20px;}#guide .s{fill:#e4f4ff;stroke:#222222;}#guide .syn{fill:#8D8D8D;font-family:Roboto Mono,Sans-serif;font-size:20px;}</style></defs><path class="c" d="M0 31h5m80 0h10m32 0h10m80 0h10m32 0h10m68 0h10m32 0h5"/><rect class="s" x="5" y="5" width="80" height="36"/><text class="k" x="15" y="31">LEAST</text><rect class="s" x="95" y="5" width="32" height="36" rx="7"/><text class="syn" x="105" y="31">(</text><rect class="s" x="137" y="5" width="80" height="36" rx="7"/><text class="k" x="147" y="31">first</text><rect class="s" x="227" y="5" width="32" height="36" rx="7"/><text class="syn" x="237" y="31">,</text><rect class="s" x="269" y="5" width="68" height="36" rx="7"/><text class="k" x="279" y="31">rest</text><rect class="s" x="347" y="5" width="32" height="36" rx="7"/><text class="syn" x="357" y="31">)</text></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

@ -70,10 +70,17 @@ public class ProjectOperator extends AbstractPageMappingOperator {
var block = page.getBlock(source);
blocks[b++] = block;
}
// iterate the blocks to see which one isn't used
closeUnused(page, blocks);
return new Page(page.getPositionCount(), blocks);
}
/**
* Close all {@link Block}s that are in {@code page} but are not in {@code blocks}.
*/
public static void closeUnused(Page page, Block[] blocks) {
List<Releasable> blocksToRelease = new ArrayList<>();
for (int i = 0; i < blockCount; i++) {
for (int i = 0; i < page.getBlockCount(); i++) {
boolean used = false;
var current = page.getBlock(i);
for (int j = 0; j < blocks.length; j++) {
@ -87,7 +94,6 @@ public class ProjectOperator extends AbstractPageMappingOperator {
}
}
Releasables.close(blocksToRelease);
return new Page(page.getPositionCount(), blocks);
}
@Override

View file

@ -18,17 +18,23 @@ import org.elasticsearch.core.TimeValue;
import org.elasticsearch.test.ListMatcher;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.xcontent.json.JsonXContent;
import org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase;
import org.junit.After;
import org.junit.Before;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.elasticsearch.test.ListMatcher.matchesList;
import static org.elasticsearch.test.MapMatcher.assertMap;
import static org.elasticsearch.test.MapMatcher.matchesMap;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
/**
* Tests that run ESQL queries that have, in the past, used so much memory they
@ -58,7 +64,11 @@ public class HeapAttackIT extends ESRestTestCase {
*/
public void testSortByManyLongsTooMuchMemory() throws IOException {
initManyLongs();
ResponseException e = expectThrows(ResponseException.class, () -> sortByManyLongs(5000));
assertCircuitBreaks(() -> sortByManyLongs(5000));
}
private void assertCircuitBreaks(ThrowingRunnable r) throws IOException {
ResponseException e = expectThrows(ResponseException.class, r);
Map<?, ?> map = XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(e.getResponse().getEntity()), false);
assertMap(
map,
@ -139,6 +149,73 @@ public class HeapAttackIT extends ESRestTestCase {
return query.append("\\n");
}
public void testSmallConcat() throws IOException {
initSingleDocIndex();
Map<?, ?> map = XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(concat(2).getEntity()), false);
ListMatcher columns = matchesList().item(matchesMap().entry("name", "a").entry("type", "long"))
.item(matchesMap().entry("name", "str").entry("type", "keyword"));
ListMatcher values = matchesList().item(List.of(1, "1".repeat(100)));
assertMap(map, matchesMap().entry("columns", columns).entry("values", values));
}
public void testHugeConcat() throws IOException {
initSingleDocIndex();
assertCircuitBreaks(() -> concat(10));
}
private Response concat(int evals) throws IOException {
StringBuilder query = new StringBuilder();
query.append("{\"query\":\"FROM single | EVAL str = TO_STRING(a)");
for (int e = 0; e < evals; e++) {
query.append("\n| EVAL str=CONCAT(")
.append(IntStream.range(0, 10).mapToObj(i -> "str").collect(Collectors.joining(", ")))
.append(")");
}
query.append("\"}");
Request request = new Request("POST", "/_query");
request.setJsonEntity(query.toString().replace("\n", "\\n"));
return client().performRequest(request);
}
public void testManyEval() throws IOException {
initManyLongs();
Map<?, ?> map = XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(manyEval(1).getEntity()), false);
ListMatcher columns = matchesList();
columns = columns.item(matchesMap().entry("name", "a").entry("type", "long"));
columns = columns.item(matchesMap().entry("name", "b").entry("type", "long"));
columns = columns.item(matchesMap().entry("name", "c").entry("type", "long"));
columns = columns.item(matchesMap().entry("name", "d").entry("type", "long"));
columns = columns.item(matchesMap().entry("name", "e").entry("type", "long"));
for (int i = 0; i < 10; i++) {
columns = columns.item(matchesMap().entry("name", "i0" + i).entry("type", "long"));
}
assertMap(map, matchesMap().entry("columns", columns).entry("values", hasSize(10_000)));
}
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/99826")
public void testTooManyEval() throws IOException {
initManyLongs();
assertCircuitBreaks(() -> manyEval(1000));
}
private Response manyEval(int evalLines) throws IOException {
StringBuilder query = new StringBuilder();
query.append("{\"query\":\"FROM manylongs");
for (int e = 0; e < evalLines; e++) {
query.append("\n| EVAL ");
for (int i = 0; i < 10; i++) {
if (i != 0) {
query.append(", ");
}
query.append("i").append(e).append(i).append(" = ").append(e * 10 + i).append(" + a + b");
}
}
query.append("\n| LIMIT 10000\"}");
Request request = new Request("POST", "/_query");
request.setJsonEntity(query.toString().replace("\n", "\\n"));
return client().performRequest(request);
}
private void initManyLongs() throws IOException {
logger.info("loading many documents with longs");
StringBuilder bulk = new StringBuilder();
@ -156,14 +233,26 @@ public class HeapAttackIT extends ESRestTestCase {
}
}
}
Request request = new Request("POST", "/manylongs/_bulk");
initIndex("manylongs", bulk.toString());
}
private void initSingleDocIndex() throws IOException {
logger.info("loading many documents with a single document");
initIndex("single", """
{"create":{}}
{"a":1}
""");
}
private void initIndex(String name, String bulk) throws IOException {
Request request = new Request("POST", "/" + name + "/_bulk");
request.addParameter("refresh", "true");
request.addParameter("filter_path", "errors");
request.setJsonEntity(bulk.toString());
Response response = client().performRequest(request);
assertThat(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8), equalTo("{\"errors\":false}"));
request = new Request("POST", "/manylongs/_forcemerge");
request = new Request("POST", "/" + name + "/_forcemerge");
request.addParameter("max_num_segments", "1");
response = client().performRequest(request);
assertThat(
@ -171,11 +260,17 @@ public class HeapAttackIT extends ESRestTestCase {
equalTo("{\"_shards\":{\"total\":2,\"successful\":1,\"failed\":0}}")
);
request = new Request("POST", "/manylongs/_refresh");
request = new Request("POST", "/" + name + "/_refresh");
response = client().performRequest(request);
assertThat(
EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8),
equalTo("{\"_shards\":{\"total\":2,\"successful\":1,\"failed\":0}}")
);
}
@Before
@After
public void assertRequestBreakerEmpty() throws Exception {
EsqlSpecTestCase.assertRequestBreakerEmpty();
}
}

View file

@ -30,6 +30,7 @@ import org.elasticsearch.compute.operator.MvExpandOperator;
import org.elasticsearch.compute.operator.Operator;
import org.elasticsearch.compute.operator.Operator.OperatorFactory;
import org.elasticsearch.compute.operator.OutputOperator.OutputOperatorFactory;
import org.elasticsearch.compute.operator.ProjectOperator;
import org.elasticsearch.compute.operator.RowOperator.RowOperatorFactory;
import org.elasticsearch.compute.operator.ShowOperator;
import org.elasticsearch.compute.operator.SinkOperator;
@ -333,6 +334,7 @@ public class LocalExecutionPlanner {
for (int i = 0; i < blocks.length; i++) {
blocks[i] = p.getBlock(mappedPosition[i]);
}
ProjectOperator.closeUnused(p, blocks);
return new Page(blocks);
} : Function.identity();