Skip to content

ESQL: Forbid "load" unmapped_fields for certain commands#144115

Merged
elasticsearchmachine merged 10 commits intoelastic:mainfrom
astefan:forbid_unmapped_fields_load
Mar 13, 2026
Merged

ESQL: Forbid "load" unmapped_fields for certain commands#144115
elasticsearchmachine merged 10 commits intoelastic:mainfrom
astefan:forbid_unmapped_fields_load

Conversation

@astefan
Copy link
Copy Markdown
Contributor

@astefan astefan commented Mar 12, 2026

Addresses #142367. AI-assisted PR.

@astefan astefan added the :Analytics/ES|QL AKA ESQL label Mar 13, 2026
@astefan astefan marked this pull request as ready for review March 13, 2026 06:48
@elasticsearchmachine elasticsearchmachine added the Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) label Mar 13, 2026
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

Copy link
Copy Markdown
Contributor

@alex-spies alex-spies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @astefan ! Generally LGTM. However, one error message triggers wrongly, namely subqueries trigger the FORK error message, too (see below for more details). Also, some of the positive tests appear to be duplicated.

Please, go ahead and merge at your own discretion after addressing comments :)

);

assumeFalse(
"FORK is not supported with unmapped_fields=\"load\"",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We could add a comment pointing to #142033?
Also applies elsewhere where this PR disables testing of some queries with load.

Comment on lines +1051 to +1052
public void testForkDisallowedWithUnmappedFieldsLoad() {
assumeTrue("Requires OPTIONAL_FIELDS_V2", EsqlCapabilities.Cap.OPTIONAL_FIELDS_V2.isEnabled());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: that could be moved to the AnalyzerUnmappedTests. They have utilities that auto-disable tests that require load, namely setUnmappedLoad which prepends a query with SET unmapped_fields="load" and skips the test if that's disabled.


/**
* {@code unmapped_fields="load"} does not yet support branching commands (FORK, LOOKUP JOIN, subqueries/views).
* See https://github.com/elastic/elasticsearch/issues/142367
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: implementing support is a separate follow-up issue, namely #142033

private static void checkLoadModeDisallowedCommands(LogicalPlan plan, Failures failures) {
plan.forEachDown(p -> {
if (p instanceof Fork) {
failures.add(fail(p, "FORK is not supported with unmapped_fields=\"load\""));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for actual subqueries, we'll get the FORK is not supported message, too, because subqueries use UnionAll which is a subclass of Fork.

if (right instanceof Filter filter) {
right = filter.child();
}
return right instanceof EsRelation relation && relation.indexMode() == IndexMode.LOOKUP;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is correct, but we may have more complex right branches in the near future.

A simpler approach is to just check the whole plan for EsRelation instances with IndexMode.LOOKUP, as these relations are used exclusively for indices we perform lookups from.

assertThat(pukesf2.getName(), is("does_not_exist2"));
}
}
"""), "Subqueries and views are not supported with unmapped_fields=\"load\"");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verificationFailure just checks that the error message is contained, not that other error messages aren't also triggered.

Looking at the actual failures while debugging this test, I get this:

Found 5 problems
line 1:34: FORK is not supported with unmapped_fields="load"
line 2:5: Subqueries and views are not supported with unmapped_fields="load"
line 5:5: Subqueries and views are not supported with unmapped_fields="load"
line 7:5: Subqueries and views are not supported with unmapped_fields="load"
line 9:7: LOOKUP JOIN is not supported with unmapped_fields="load"

The first failure does not apply here and is wrongly triggered, see my comment above.

assumeTrue("Requires subquery in FROM command support", EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled());

// A single subquery without a main index is merged into the main query during analysis,
// so there is no Subquery node in the plan and no branching — this is allowed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++, that's correct!

Comment on lines +3863 to +3866
FROM test
| EVAL language_code = languages
| LOOKUP JOIN languages_lookup ON language_code
| FORK (WHERE emp_no > 1) (WHERE emp_no < 100)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query is duplicated. Let's extract that into a String that is re-used.

It's correct that we assert both failures, though.

FROM test
| INLINE STATS c = COUNT(*) BY emp_no
"""));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: asserting the plan structure generally makes sense if we already add a positive test. And/or leaving a comment TODO: golden tests so we pick this up later.

public void testLoadModeAllowsInlineStats() {
analyzeStatement(setUnmappedLoad("""
FROM test
| INLINE STATS c = COUNT(*) BY emp_no
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not-so nit: we already have inline stats + nullify tests above, e.g. testInlineStats. The same is true for fork. Let's double check which of the positive tests with nullify already exist and remove them from this PR.

@astefan astefan added the auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label Mar 13, 2026
@elasticsearchmachine elasticsearchmachine merged commit 44da1f7 into elastic:main Mar 13, 2026
36 checks passed
@astefan astefan deleted the forbid_unmapped_fields_load branch March 13, 2026 15:07
szybia added a commit to szybia/elasticsearch that referenced this pull request Mar 13, 2026
…elocations

* upstream/main: (72 commits)
  [Test] Randomly disable sequence numbers in CcrTimeSeriesDataStreamsIT (elastic#143930)
  Fix AsyncSearchIndexServiceTests.testCircuitBreaker failure (elastic#144058)
  Refine GenerativeIT some more, this time with accounting for some added (elastic#144220)
  ESQL: Physical Planning on the Lookup Node (elastic#143707)
  Mute org.elasticsearch.xpack.esql.CsvIT test {csv-spec:approximation.Approximate stats by with zero variance} elastic#144240
  Trigger counter metrics in test for delta temporality measurements (elastic#144193)
  fix capabiltiy approximation_v3 (elastic#144230)
  [ci] Add PR pipeline for testing ipv6 and fix tests not working with ipv6 (elastic#140473)
  update (elastic#144095)
  Make from/to optional in TBUCKET when Kibana timestamp filter is present (elastic#144057)
  Extract reroute behavior from create-index request classes (elastic#144140)
  ESQL: Fix release build only failures (elastic#144122)
  ES|QL query approximation: move sample correction to data node (elastic#144005)
  Add indexing pressure tracking to OTLP endpoints (elastic#144009)
  Fix replica writes after _seq_no doc values are pruned (elastic#144180)
  allow tests to configure supportsLoadingConfig (elastic#144061)
  [ES|QL] Unmute testGiantTextFieldInSubqueryIntermediateResultsWithSort (elastic#144126)
  [ESQL][DOCS] Add CPS page (unpublished for moment) (elastic#144206)
  ESQL: Forbid "load" unmapped_fields for certain commands (elastic#144115)
  Add CCS Remote Views Detection (elastic#143384)
  ...
michalborek pushed a commit to michalborek/elasticsearch that referenced this pull request Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Analytics/ES|QL AKA ESQL auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >non-issue Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants