|
13 | 13 | import org.elasticsearch.common.lucene.BytesRefs;
|
14 | 14 | import org.elasticsearch.common.util.Maps;
|
15 | 15 | import org.elasticsearch.xpack.core.enrich.EnrichPolicy;
|
| 16 | +import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; |
16 | 17 | import org.elasticsearch.xpack.esql.capabilities.PostOptimizationVerificationAware;
|
17 | 18 | import org.elasticsearch.xpack.esql.capabilities.TelemetryAware;
|
18 | 19 | import org.elasticsearch.xpack.esql.common.Failures;
|
@@ -48,6 +49,7 @@ public class Enrich extends UnaryPlan
|
48 | 49 | implements
|
49 | 50 | GeneratingPlan<Enrich>,
|
50 | 51 | PostOptimizationVerificationAware,
|
| 52 | + PostAnalysisVerificationAware, |
51 | 53 | TelemetryAware,
|
52 | 54 | SortAgnostic,
|
53 | 55 | ExecutesOn {
|
@@ -284,6 +286,36 @@ private void checkForPlansForbiddenBeforeRemoteEnrich(Failures failures) {
|
284 | 286 | fails.forEach(f -> failures.add(fail(this, "ENRICH with remote policy can't be executed after [" + f.text() + "]" + f.source())));
|
285 | 287 | }
|
286 | 288 |
|
| 289 | + /** |
| 290 | + * Remote ENRICH (and any remote operation in fact) is not compatible with MV_EXPAND + LIMIT. Consider: |
| 291 | + * `FROM *:events | SORT @timestamp | LIMIT 2 | MV_EXPAND ip | ENRICH _remote:clientip_policy ON ip` |
| 292 | + * Semantically, this must take two top events and then expand them. However, this can not be executed remotely, |
| 293 | + * because this means that we have to take top 2 events on each node, then expand them, then apply Enrich, |
| 294 | + * then bring them to the coordinator - but then we can not select top 2 of them - because that would be pre-expand! |
| 295 | + * We do not know which expanded rows are coming from the true top rows and which are coming from "false" top rows |
| 296 | + * which should have been thrown out. This is only possible to execute if MV_EXPAND executes on the coordinator |
| 297 | + * - which contradicts remote Enrich. |
| 298 | + * This could be fixed by the optimizer by moving MV_EXPAND past ENRICH, at least in some cases, but currently we do not do that. |
| 299 | + */ |
| 300 | + private void checkMvExpandAfterLimit(Failures failures) { |
| 301 | + this.forEachDown(MvExpand.class, u -> { |
| 302 | + u.forEachDown(p -> { |
| 303 | + if (p instanceof Limit || p instanceof TopN) { |
| 304 | + failures.add(fail(this, "MV_EXPAND after LIMIT is incompatible with remote ENRICH")); |
| 305 | + } |
| 306 | + }); |
| 307 | + }); |
| 308 | + |
| 309 | + } |
| 310 | + |
| 311 | + @Override |
| 312 | + public void postAnalysisVerification(Failures failures) { |
| 313 | + if (this.mode == Mode.REMOTE) { |
| 314 | + checkMvExpandAfterLimit(failures); |
| 315 | + } |
| 316 | + |
| 317 | + } |
| 318 | + |
287 | 319 | @Override
|
288 | 320 | public void postOptimizationVerification(Failures failures) {
|
289 | 321 | if (this.mode == Mode.REMOTE) {
|
|
0 commit comments