From 475b1318baa68b0d6d0855807191d60bbd5cb20a Mon Sep 17 00:00:00 2001 From: "ievgen.degtiarenko" Date: Wed, 25 Jun 2025 08:29:45 +0200 Subject: [PATCH] [8.x] backport SearchContextStats changes --- .../xpack/esql/stats/SearchContextStats.java | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java index 24bd1bd61f938..c308b317529ca 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java @@ -82,12 +82,6 @@ private SearchContextStats(List contexts) { assert contexts != null && contexts.isEmpty() == false; } - @Override - public boolean exists(FieldName field) { - var stat = cache.computeIfAbsent(field.string(), this::makeFieldStats); - return stat.config.exists; - } - private FieldStats makeFieldStats(String field) { var stat = new FieldStats(); stat.config = makeFieldConfig(field); @@ -103,20 +97,19 @@ private FieldConfig makeFieldConfig(String field) { // since if it's missing, deleted documents won't change that for (SearchExecutionContext context : contexts) { if (context.isFieldMapped(field)) { - exists = exists || true; - MappedFieldType type = context.getFieldType(field); - indexed = indexed && type.isIndexed(); - hasDocValues = hasDocValues && type.hasDocValues(); - if (type instanceof TextFieldMapper.TextFieldType t) { - hasExactSubfield = hasExactSubfield && t.canUseSyntheticSourceDelegateForQuerying(); - } else { - hasExactSubfield = false; - } + var type = context.getFieldType(field); + exists |= true; + indexed &= type.isIndexed(); + hasDocValues &= type.hasDocValues(); + hasExactSubfield &= type instanceof TextFieldMapper.TextFieldType t && t.canUseSyntheticSourceDelegateForQuerying(); } else { indexed = false; hasDocValues = false; hasExactSubfield = false; } + if (exists && indexed == false && hasDocValues == false && hasExactSubfield == false) { + break; + } } if (exists == false) { // if it does not exist on any context, no other settings are valid @@ -126,22 +119,34 @@ private FieldConfig makeFieldConfig(String field) { } } + private boolean fastNoCacheFieldExists(String field) { + for (SearchExecutionContext context : contexts) { + if (context.isFieldMapped(field)) { + return true; + } + } + return false; + } + + @Override + public boolean exists(FieldName field) { + var stat = cache.get(field.string()); + return stat != null ? stat.config.exists : fastNoCacheFieldExists(field.string()); + } + @Override public boolean isIndexed(FieldName field) { - var stat = cache.computeIfAbsent(field.string(), this::makeFieldStats); - return stat.config.indexed; + return cache.computeIfAbsent(field.string(), this::makeFieldStats).config.indexed; } @Override public boolean hasDocValues(FieldName field) { - var stat = cache.computeIfAbsent(field.string(), this::makeFieldStats); - return stat.config.hasDocValues; + return cache.computeIfAbsent(field.string(), this::makeFieldStats).config.hasDocValues; } @Override public boolean hasExactSubfield(FieldName field) { - var stat = cache.computeIfAbsent(field.string(), this::makeFieldStats); - return stat.config.hasExactSubfield; + return cache.computeIfAbsent(field.string(), this::makeFieldStats).config.hasExactSubfield; } @Override @@ -231,7 +236,7 @@ public boolean isSingleValue(FieldName field) { var stat = cache.computeIfAbsent(fieldName, this::makeFieldStats); if (stat.singleValue == null) { // there's no such field so no need to worry about multi-value fields - if (exists(field) == false) { + if (stat.config.exists == false) { stat.singleValue = true; } else { // fields are MV per default