Skip to content

Commit 16a7835

Browse files
Merge branch 'main' into segrate_merge_executor_disk_space_tests
2 parents 3d4035c + 580831a commit 16a7835

File tree

76 files changed

+1212
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1212
-388
lines changed

docs/changelog/128866.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 128866
2+
summary: Add `age_in_millis` to ILM Explain Response
3+
area: ILM+SLM
4+
type: enhancement
5+
issues:
6+
- 103659

docs/reference/query-languages/esql/README.md

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,95 @@ To help differentiate between the static and generated content, the generated co
105105
% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
106106
```
107107

108+
## Version differentiation in Docs V3
109+
110+
> [!IMPORTANT]
111+
> Starting with 9.0, we no longer publish separate documentation branches for every minor release (`9.0`, `9.1`, `9.2`, etc.).
112+
> This means there won't be a different page for `9.1`, `9.2`, and so on. Instead, all changes landing in subsequent minor releases **will appear on the same page**.
113+
114+
Because we now publish just one docs set off of the `main` branch, we use the [`applies_to` metadata](https://elastic.github.io/docs-builder/syntax/applies/) to differentiate features and their availability across different versions. This is a [cumulative approach](https://elastic.github.io/docs-builder/contribute/#cumulative-docs): instead of creating separate pages for each product and release, we update a **single page** with product- and version-specific details over time.
115+
116+
`applies_to` allows us to clearly communicate when features are introduced, when they transition from preview to GA, and which versions support specific functionality.
117+
118+
This metadata accepts a lifecycle and an optional version.
119+
120+
### Functions and operators
121+
122+
Use the `@FunctionAppliesTo` annotation within the `@FunctionInfo` annotation on function and operator classes to specify the lifecycle and version for functions and operators.
123+
124+
For example, to indicate that a function is in technical preview and applies to version 9.0.0, you would use:
125+
126+
```java
127+
@FunctionInfo(
128+
returnType = "boolean",
129+
appliesTo = {
130+
@FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.PREVIEW, version = "9.0.0")
131+
},
132+
...
133+
)
134+
```
135+
136+
When a feature evolves from preview in `9.0` to GA in `9.2`, add a new entry alongside the existing preview entry and remove the `preview = true` boolean:
137+
138+
```java
139+
@FunctionInfo(
140+
returnType = "boolean",
141+
preview = false, // the preview boolean can be removed (or flipped to false) when the function becomes GA
142+
appliesTo = {
143+
@FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.PREVIEW, version = "9.0.0"),
144+
@FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.GA, version = "9.2.0")
145+
},
146+
...
147+
)
148+
```
149+
150+
We updated [`DocsV3Support.java`](https://github.com/elastic/elasticsearch/blob/main/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java) to generate the `applies_to` metadata correctly for functions and operators.
151+
152+
### Inline `applies_to` metadata
153+
154+
Use [inline annotations](https://elastic.github.io/docs-builder/syntax/applies/#inline-annotations) to specify `applies_to` metadata in descriptions, parameter lists, etc.
155+
156+
For example, the second item in this list is in technical preview as of version 9.2:
157+
158+
```markdown
159+
- Item 1
160+
- Item 2 {applies_to}`stack: preview 9.2.`
161+
```
162+
163+
### Key rules
164+
165+
1. **Use the `preview = true` boolean** for any tech preview feature - this is required for the Kibana inline docs
166+
- **Remove `preview = true`** only when the feature becomes GA on serverless and is _definitely_ going GA in the next minor release
167+
2. **Never delete `appliesTo` entries** - only add new ones as features evolve from preview to GA
168+
3. **Use specific versions** (`9.0.0`, `9.1.0`) when known, or just `PREVIEW` without a version if timing is uncertain
169+
4. **Add `applies_to` to examples** where necessary
170+
171+
> [!IMPORTANT]
172+
> We don't use `applies_to` in the legacy asciidoc system for 8.x and earlier versions.
173+
174+
### Supported lifecycles
175+
176+
- `PREVIEW` - Feature is in technical preview
177+
- `GA` - Feature is generally available
178+
- `DEPRECATED` - Feature is deprecated and will be removed in a future release
179+
- `UNAVAILABLE` - Feature is not available in the current version, but may be available in future releases
180+
181+
> [!NOTE]
182+
> Unreleased version information is automatically sanitized in the docs build output. For example, say you specify `preview 9.3.0`:
183+
> - Before `9.3.0` is released, the live documentation will display "Planned for a future release" instead of the specific version number.
184+
> - This will be updated automatically when the version is released.
185+
108186
## Tutorials
109187

110188
### Adding a new command
111189

112190
When adding a new command, for example adding the `CHANGE_POINT` command, do the following:
113191
1. Create a new file in the `_snippets/commands/layout` directory with the name of the command, for example `change_point.md`.
114-
2. Add the content for the command to the file. See other files in this directory for examples.
115-
3. Add the command to the list in `_snippets/lists/processing-commands.md`.
116-
4. Add an include directive to the `commands/processing-commands.md` file to include the new command.
117-
5. Add tested examples to the `_snippets/commands/examples` directory. See below for details.
192+
2. Ensure to specify what versions the command applies to. See [Version differentiation in Docs V3](#version-differentiation-in-docs-v3) for details. [Example PR](https://github.com/elastic/elasticsearch/pull/130314/files#diff-0ab90b6202c5d9eeea75dc95a7cb71dc4d720230342718bff887816771a5a803R3-R6).
193+
3. Add the content for the command to the file. See other files in this directory for examples.
194+
4. Add the command to the list in `_snippets/lists/processing-commands.md`.
195+
5. Add an include directive to the `commands/processing-commands.md` file to include the new command.
196+
6. Add tested examples to the `_snippets/commands/examples` directory. See below for details.
118197

119198
### Adding examples to commands
120199

docs/reference/query-languages/esql/kibana/definition/commands/change_point.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/categorize.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/240_data_stream_settings.yml

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,6 @@ setup:
327327
index: "my-data-stream-1"
328328
wait_for_status: green
329329

330-
331-
332330
- do:
333331
indices.get_data_stream:
334332
name: my-data-stream-1
@@ -398,3 +396,96 @@ setup:
398396
- match: { .$idx0name.settings.index.number_of_shards: "1" }
399397
- match: { .$idx0name.settings.index.lifecycle.name: "my-policy" }
400398
- match: { .$idx0name.settings.index.lifecycle.prefer_ilm: "true" }
399+
400+
---
401+
"Test null out settings component templates only":
402+
- requires:
403+
cluster_features: [ "logs_stream" ]
404+
reason: requires setting 'logs_stream' to get or set data stream settings
405+
406+
- do:
407+
cluster.put_component_template:
408+
name: settings-template
409+
body:
410+
template:
411+
settings:
412+
lifecycle.name: my-policy
413+
414+
- do:
415+
allowed_warnings:
416+
- "index template [my-component-only-template] has index patterns [my-component-only-data-stream-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-component-only-template] will take precedence during new index creation"
417+
indices.put_index_template:
418+
name: my-component-only-template
419+
body:
420+
index_patterns: [ my-component-only-data-stream-* ]
421+
data_stream: { }
422+
composed_of:
423+
- settings-template
424+
425+
- do:
426+
indices.create_data_stream:
427+
name: my-component-only-data-stream-1
428+
429+
- do:
430+
cluster.health:
431+
index: "my-component-only-data-stream-1"
432+
wait_for_status: green
433+
434+
- do:
435+
indices.get_data_stream:
436+
name: my-component-only-data-stream-1
437+
- match: { data_streams.0.name: my-component-only-data-stream-1 }
438+
- match: { data_streams.0.settings: {} }
439+
- match: { data_streams.0.effective_settings: null }
440+
441+
- do:
442+
indices.put_data_stream_settings:
443+
name: my-component-only-data-stream-1
444+
body:
445+
index:
446+
lifecycle:
447+
name: my-new-policy
448+
prefer_ilm: true
449+
- match: { data_streams.0.name: my-component-only-data-stream-1 }
450+
- match: { data_streams.0.applied_to_data_stream: true }
451+
- length: { data_streams.0.index_settings_results.applied_to_data_stream_and_backing_indices: 2 }
452+
- match: { data_streams.0.settings.index.lifecycle.name: "my-new-policy" }
453+
- match: { data_streams.0.settings.index.lifecycle.prefer_ilm: "true" }
454+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-new-policy" }
455+
- match: { data_streams.0.effective_settings.index.lifecycle.prefer_ilm: "true" }
456+
457+
- do:
458+
indices.put_data_stream_settings:
459+
name: my-component-only-data-stream-1
460+
body:
461+
index:
462+
lifecycle:
463+
name: null
464+
prefer_ilm: null
465+
- match: { data_streams.0.name: my-component-only-data-stream-1 }
466+
- match: { data_streams.0.applied_to_data_stream: true }
467+
- length: { data_streams.0.index_settings_results.applied_to_data_stream_and_backing_indices: 2 }
468+
- match: { data_streams.0.settings.index.lifecycle.name: null }
469+
- match: { data_streams.0.settings.index.lifecycle.prefer_ilm: null }
470+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-policy" }
471+
- match: { data_streams.0.effective_settings.index.lifecycle.prefer_ilm: null }
472+
473+
- do:
474+
indices.get_data_stream_settings:
475+
name: my-component-only-data-stream-1
476+
- match: { data_streams.0.name: my-component-only-data-stream-1 }
477+
- match: { data_streams.0.settings.index.lifecycle.name: null }
478+
- match: { data_streams.0.settings.index.lifecycle.prefer_ilm: null }
479+
- match: { data_streams.0.effective_settings.index.lifecycle.name: "my-policy" }
480+
- match: { data_streams.0.effective_settings.index.lifecycle.prefer_ilm: null }
481+
482+
- do:
483+
indices.get_data_stream:
484+
name: my-component-only-data-stream-1
485+
- set: { data_streams.0.indices.0.index_name: idx0name }
486+
487+
- do:
488+
indices.get_settings:
489+
index: my-component-only-data-stream-1
490+
- match: { .$idx0name.settings.index.lifecycle.name: "my-policy" }
491+
- match: { .$idx0name.settings.index.lifecycle.prefer_ilm: null }

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/MatchOnlyTextFieldMapper.java

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.elasticsearch.common.text.UTF8DecodingReader;
3636
import org.elasticsearch.common.unit.Fuzziness;
3737
import org.elasticsearch.index.IndexVersion;
38+
import org.elasticsearch.index.IndexVersions;
3839
import org.elasticsearch.index.analysis.IndexAnalyzers;
3940
import org.elasticsearch.index.analysis.NamedAnalyzer;
4041
import org.elasticsearch.index.fielddata.FieldDataContext;
@@ -105,8 +106,15 @@ public static class Builder extends FieldMapper.Builder {
105106

106107
private final TextParams.Analyzers analyzers;
107108
private final boolean withinMultiField;
109+
private final boolean storedFieldInBinaryFormat;
108110

109-
public Builder(String name, IndexVersion indexCreatedVersion, IndexAnalyzers indexAnalyzers, boolean withinMultiField) {
111+
public Builder(
112+
String name,
113+
IndexVersion indexCreatedVersion,
114+
IndexAnalyzers indexAnalyzers,
115+
boolean withinMultiField,
116+
boolean storedFieldInBinaryFormat
117+
) {
110118
super(name);
111119
this.indexCreatedVersion = indexCreatedVersion;
112120
this.analyzers = new TextParams.Analyzers(
@@ -116,6 +124,7 @@ public Builder(String name, IndexVersion indexCreatedVersion, IndexAnalyzers ind
116124
indexCreatedVersion
117125
);
118126
this.withinMultiField = withinMultiField;
127+
this.storedFieldInBinaryFormat = storedFieldInBinaryFormat;
119128
}
120129

121130
@Override
@@ -135,7 +144,8 @@ private MatchOnlyTextFieldType buildFieldType(MapperBuilderContext context) {
135144
context.isSourceSynthetic(),
136145
meta.getValue(),
137146
withinMultiField,
138-
multiFieldsBuilder.hasSyntheticSourceCompatibleKeywordField()
147+
multiFieldsBuilder.hasSyntheticSourceCompatibleKeywordField(),
148+
storedFieldInBinaryFormat
139149
);
140150
return ft;
141151
}
@@ -155,8 +165,22 @@ public MatchOnlyTextFieldMapper build(MapperBuilderContext context) {
155165
}
156166
}
157167

168+
private static boolean isSyntheticSourceStoredFieldInBinaryFormat(IndexVersion indexCreatedVersion) {
169+
return indexCreatedVersion.onOrAfter(IndexVersions.MATCH_ONLY_TEXT_STORED_AS_BYTES)
170+
|| indexCreatedVersion.between(
171+
IndexVersions.SYNTHETIC_SOURCE_STORE_ARRAYS_NATIVELY_BACKPORT_8_X,
172+
IndexVersions.UPGRADE_TO_LUCENE_10_0_0
173+
);
174+
}
175+
158176
public static final TypeParser PARSER = new TypeParser(
159-
(n, c) -> new Builder(n, c.indexVersionCreated(), c.getIndexAnalyzers(), c.isWithinMultiField())
177+
(n, c) -> new Builder(
178+
n,
179+
c.indexVersionCreated(),
180+
c.getIndexAnalyzers(),
181+
c.isWithinMultiField(),
182+
isSyntheticSourceStoredFieldInBinaryFormat(c.indexVersionCreated())
183+
)
160184
);
161185

162186
public static class MatchOnlyTextFieldType extends StringFieldType {
@@ -167,6 +191,7 @@ public static class MatchOnlyTextFieldType extends StringFieldType {
167191

168192
private final boolean withinMultiField;
169193
private final boolean hasCompatibleMultiFields;
194+
private final boolean storedFieldInBinaryFormat;
170195

171196
public MatchOnlyTextFieldType(
172197
String name,
@@ -175,14 +200,16 @@ public MatchOnlyTextFieldType(
175200
boolean isSyntheticSource,
176201
Map<String, String> meta,
177202
boolean withinMultiField,
178-
boolean hasCompatibleMultiFields
203+
boolean hasCompatibleMultiFields,
204+
boolean storedFieldInBinaryFormat
179205
) {
180206
super(name, true, false, false, tsi, meta);
181207
this.indexAnalyzer = Objects.requireNonNull(indexAnalyzer);
182208
this.textFieldType = new TextFieldType(name, isSyntheticSource);
183209
this.originalName = isSyntheticSource ? name + "._original" : null;
184210
this.withinMultiField = withinMultiField;
185211
this.hasCompatibleMultiFields = hasCompatibleMultiFields;
212+
this.storedFieldInBinaryFormat = storedFieldInBinaryFormat;
186213
}
187214

188215
public MatchOnlyTextFieldType(String name) {
@@ -193,6 +220,7 @@ public MatchOnlyTextFieldType(String name) {
193220
false,
194221
Collections.emptyMap(),
195222
false,
223+
false,
196224
false
197225
);
198226
}
@@ -451,7 +479,11 @@ protected BytesRef toBytesRef(Object v) {
451479
@Override
452480
public BlockLoader blockLoader(BlockLoaderContext blContext) {
453481
if (textFieldType.isSyntheticSource()) {
454-
return new BytesFromMixedStringsBytesRefBlockLoader(storedFieldNameForSyntheticSource());
482+
if (storedFieldInBinaryFormat) {
483+
return new BlockStoredFieldsReader.BytesFromBytesRefsBlockLoader(storedFieldNameForSyntheticSource());
484+
} else {
485+
return new BytesFromMixedStringsBytesRefBlockLoader(storedFieldNameForSyntheticSource());
486+
}
455487
}
456488
SourceValueFetcher fetcher = SourceValueFetcher.toString(blContext.sourcePaths(name()));
457489
// MatchOnlyText never has norms, so we have to use the field names field
@@ -502,6 +534,7 @@ private String storedFieldNameForSyntheticSource() {
502534
private final boolean storeSource;
503535
private final FieldType fieldType;
504536
private final boolean withinMultiField;
537+
private final boolean storedFieldInBinaryFormat;
505538

506539
private MatchOnlyTextFieldMapper(
507540
String simpleName,
@@ -521,6 +554,7 @@ private MatchOnlyTextFieldMapper(
521554
this.positionIncrementGap = builder.analyzers.positionIncrementGap.getValue();
522555
this.storeSource = storeSource;
523556
this.withinMultiField = builder.withinMultiField;
557+
this.storedFieldInBinaryFormat = builder.storedFieldInBinaryFormat;
524558
}
525559

526560
@Override
@@ -530,7 +564,7 @@ public Map<String, NamedAnalyzer> indexAnalyzers() {
530564

531565
@Override
532566
public FieldMapper.Builder getMergeBuilder() {
533-
return new Builder(leafName(), indexCreatedVersion, indexAnalyzers, withinMultiField).init(this);
567+
return new Builder(leafName(), indexCreatedVersion, indexAnalyzers, withinMultiField, storedFieldInBinaryFormat).init(this);
534568
}
535569

536570
@Override
@@ -547,8 +581,12 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
547581
context.addToFieldNames(fieldType().name());
548582

549583
if (storeSource) {
550-
final var bytesRef = new BytesRef(utfBytes.bytes(), utfBytes.offset(), utfBytes.length());
551-
context.doc().add(new StoredField(fieldType().storedFieldNameForSyntheticSource(), bytesRef));
584+
if (storedFieldInBinaryFormat) {
585+
final var bytesRef = new BytesRef(utfBytes.bytes(), utfBytes.offset(), utfBytes.length());
586+
context.doc().add(new StoredField(fieldType().storedFieldNameForSyntheticSource(), bytesRef));
587+
} else {
588+
context.doc().add(new StoredField(fieldType().storedFieldNameForSyntheticSource(), value.string()));
589+
}
552590
}
553591
}
554592

0 commit comments

Comments
 (0)