Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/134851.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 134851
summary: Remove ingest conditionals `_type` deprecation warning
area: Ingest Node
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@

package org.elasticsearch.ingest;

import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.script.DynamicMap;
import org.elasticsearch.script.IngestConditionalScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptException;
Expand All @@ -28,7 +25,6 @@
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;

Expand All @@ -39,16 +35,6 @@
*/
public class ConditionalProcessor extends AbstractProcessor implements WrappingProcessor {

private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(DynamicMap.class);
private static final Map<String, Function<Object, Object>> FUNCTIONS = Map.of("_type", value -> {
deprecationLogger.warn(
DeprecationCategory.INDICES,
"conditional-processor__type",
"[types removal] Looking up doc types [_type] in scripts is deprecated."
);
return value;
});
Comment on lines -43 to -50
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason we wouldn't do:

FUNCTIONS = Map.of("_type", ignored -> "_doc");

and just hardcode it to return _doc?

Copy link
Member

Choose a reason for hiding this comment

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

My guess would be because it already does that in Painless?

Copy link
Contributor Author

@joegallo joegallo Sep 17, 2025

Choose a reason for hiding this comment

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

That'd be a change in the behavior. The behavior has been (for a while, I could track down the PR that changed it, but I'm 95% sure I didn't write it so I don't know what I'm looking for off the top of my head) that the _type is null (in both the conditional and the ordinary script context):

POST _ingest/pipeline/_simulate { "pipeline": { "processors": [ { "script": { "source": "ctx.type_from_script = ctx._type" } }, { "script": { "if": "ctx._type == null", "source": "ctx.type_from_conditional_was_null = true" } } ] }, "docs": [ { "_index": "index", "_id": "id", "_source": { "hello": "world" } } ] } 

results in:

{ "docs" : [ { "doc" : { "_index" : "index", "_version" : "-3", "_id" : "id", "_source" : { "type_from_script" : null, "type_from_conditional_was_null" : true, "hello" : "world" }, "_ingest" : { "timestamp" : "2025-09-17T11:33:43.056173Z" } } } ] } 

Before and after this PR the above script works the same (that is, _type is null), it's just that prior to this PR a deprecation would be generated only for the conditional part of the one script. All this PR does is remove the deprecation warning, other than that doesn't change the behavior of the scripts in question.

Copy link
Contributor Author

@joegallo joegallo Sep 17, 2025

Choose a reason for hiding this comment

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

I haven't found a PR that clearly is the one that makes the _type be null for these, but I have confirmed that if you run 8.0.0 the behavior is the same as I show above. So this has been the behavior since at least February 2022.

Copy link
Member

Choose a reason for hiding this comment

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

Ahh okay, I hadn't realized it was null, so removing it makes sense. Thanks for the clarification.


static final String TYPE = "conditional";

private final Script condition;
Expand Down Expand Up @@ -144,10 +130,7 @@ boolean evaluate(IngestDocument ingestDocument) {
if (factory == null) {
factory = scriptService.compile(condition, IngestConditionalScript.CONTEXT);
}
return factory.newInstance(
condition.getParams(),
new UnmodifiableIngestData(new DynamicMap(ingestDocument.getSourceAndMetadata(), FUNCTIONS))
).execute();
return factory.newInstance(condition.getParams(), new UnmodifiableIngestData(ingestDocument.getSourceAndMetadata())).execute();
}

public Processor getInnerProcessor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,55 +143,6 @@ public void testActsOnImmutableData() throws Exception {
assertMutatingCtxThrows(ctx -> ((List<Object>) ctx.get("listField")).remove("bar"));
}

public void testTypeDeprecation() throws Exception {

ScriptService scriptService = new ScriptService(
Settings.builder().build(),
Map.of(Script.DEFAULT_SCRIPT_LANG, new MockScriptEngine(Script.DEFAULT_SCRIPT_LANG, Map.of(scriptName, ctx -> {
ctx.get("_type");
return true;
}), Map.of())),
new HashMap<>(ScriptModule.CORE_CONTEXTS),
() -> 1L,
TestProjectResolvers.singleProject(randomProjectIdOrDefault())
);

LongSupplier relativeTimeProvider = mock(LongSupplier.class);
when(relativeTimeProvider.getAsLong()).thenReturn(0L, TimeUnit.MILLISECONDS.toNanos(1), 0L, TimeUnit.MILLISECONDS.toNanos(2));
ConditionalProcessor processor = new ConditionalProcessor(
randomAlphaOfLength(10),
"description",
new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptName, Map.of()),
scriptService,
new Processor() {
@Override
public IngestDocument execute(final IngestDocument ingestDocument) {
return ingestDocument;
}

@Override
public String getType() {
return null;
}

@Override
public String getTag() {
return null;
}

@Override
public String getDescription() {
return null;
}
},
relativeTimeProvider
);

IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), Map.of());
execProcessor(processor, ingestDocument, (result, e) -> {});
assertWarnings("[types removal] Looking up doc types [_type] in scripts is deprecated.");
}

public void testPrecompiledError() {
ScriptService scriptService = MockScriptService.singleContext(IngestConditionalScript.CONTEXT, code -> {
throw new ScriptException("bad script", new ParseException("error", 0), List.of(), "", "lang", null);
Expand Down