diff --git a/docs/changelog/127797.yaml b/docs/changelog/127797.yaml deleted file mode 100644 index 8fca3da004130..0000000000000 --- a/docs/changelog/127797.yaml +++ /dev/null @@ -1,6 +0,0 @@ -pr: 127797 -summary: "Date nanos implicit casting in union types option #2" -area: ES|QL -type: enhancement -issues: - - 110009 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java index f48c95397dcab..1b48ffd22b491 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java @@ -134,6 +134,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.elasticsearch.xpack.core.enrich.EnrichPolicy.GEO_MATCH_TYPE; +import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.IMPLICIT_CASTING_DATE_AND_DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN; import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; @@ -175,7 +176,7 @@ public class Analyzer extends ParameterizedRuleExecutor( "Resolution", @@ -1819,10 +1820,6 @@ private static boolean canConvertOriginalTypes(MultiTypeEsField multiTypeEsField private static Expression typeSpecificConvert(ConvertFunction convert, Source source, DataType type, InvalidMappedField mtf) { EsField field = new EsField(mtf.getName(), type, mtf.getProperties(), mtf.isAggregatable()); - return typeSpecificConvert(convert, source, field); - } - - private static Expression typeSpecificConvert(ConvertFunction convert, Source source, EsField field) { FieldAttribute originalFieldAttr = (FieldAttribute) convert.field(); FieldAttribute resolvedAttr = new FieldAttribute( source, @@ -1902,23 +1899,42 @@ private static LogicalPlan planWithoutSyntheticAttributes(LogicalPlan plan) { * Cast the union typed fields in EsRelation to date_nanos if they are mixed date and date_nanos types. */ private static class DateMillisToNanosInEsRelation extends Rule { + + private final boolean isSnapshot; + + DateMillisToNanosInEsRelation(boolean isSnapshot) { + this.isSnapshot = isSnapshot; + } + @Override public LogicalPlan apply(LogicalPlan plan) { - return plan.transformUp(EsRelation.class, relation -> { - if (relation.indexMode() == IndexMode.LOOKUP) { - return relation; - } - return relation.transformExpressionsUp(FieldAttribute.class, f -> { - if (f.field() instanceof InvalidMappedField imf && imf.types().stream().allMatch(DataType::isDate)) { - HashMap typeResolutions = new HashMap<>(); - var convert = new ToDateNanos(f.source(), f); - imf.types().forEach(type -> typeResolutions(f, convert, type, imf, typeResolutions)); - var resolvedField = ResolveUnionTypes.resolvedMultiTypeEsField(f, typeResolutions); - return new FieldAttribute(f.source(), f.parentName(), f.name(), resolvedField, f.nullable(), f.id(), f.synthetic()); + if (isSnapshot) { + return plan.transformUp(EsRelation.class, relation -> { + if (relation.indexMode() == IndexMode.LOOKUP) { + return relation; } - return f; + return relation.transformExpressionsUp(FieldAttribute.class, f -> { + if (f.field() instanceof InvalidMappedField imf && imf.types().stream().allMatch(DataType::isDate)) { + HashMap typeResolutions = new HashMap<>(); + var convert = new ToDateNanos(f.source(), f); + imf.types().forEach(type -> typeResolutions(f, convert, type, imf, typeResolutions)); + var resolvedField = ResolveUnionTypes.resolvedMultiTypeEsField(f, typeResolutions); + return new FieldAttribute( + f.source(), + f.parentName(), + f.name(), + resolvedField, + f.nullable(), + f.id(), + f.synthetic() + ); + } + return f; + }); }); - }); + } else { + return plan; + } } }