| 
134 | 134 | import static java.util.Collections.emptyList;  | 
135 | 135 | import static java.util.Collections.singletonList;  | 
136 | 136 | import static org.elasticsearch.xpack.core.enrich.EnrichPolicy.GEO_MATCH_TYPE;  | 
 | 137 | +import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.IMPLICIT_CASTING_DATE_AND_DATE_NANOS;  | 
137 | 138 | import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN;  | 
138 | 139 | import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME;  | 
139 | 140 | import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS;  | 
@@ -175,7 +176,7 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon  | 
175 | 176 |             new ResolveInference(),  | 
176 | 177 |             new ResolveLookupTables(),  | 
177 | 178 |             new ResolveFunctions(),  | 
178 |  | -            new DateMillisToNanosInEsRelation()  | 
 | 179 | +            new DateMillisToNanosInEsRelation(IMPLICIT_CASTING_DATE_AND_DATE_NANOS.isEnabled())  | 
179 | 180 |         ),  | 
180 | 181 |         new Batch<>(  | 
181 | 182 |             "Resolution",  | 
@@ -1819,10 +1820,6 @@ private static boolean canConvertOriginalTypes(MultiTypeEsField multiTypeEsField  | 
1819 | 1820 | 
 
  | 
1820 | 1821 |         private static Expression typeSpecificConvert(ConvertFunction convert, Source source, DataType type, InvalidMappedField mtf) {  | 
1821 | 1822 |             EsField field = new EsField(mtf.getName(), type, mtf.getProperties(), mtf.isAggregatable());  | 
1822 |  | -            return typeSpecificConvert(convert, source, field);  | 
1823 |  | -        }  | 
1824 |  | - | 
1825 |  | -        private static Expression typeSpecificConvert(ConvertFunction convert, Source source, EsField field) {  | 
1826 | 1823 |             FieldAttribute originalFieldAttr = (FieldAttribute) convert.field();  | 
1827 | 1824 |             FieldAttribute resolvedAttr = new FieldAttribute(  | 
1828 | 1825 |                 source,  | 
@@ -1902,23 +1899,42 @@ private static LogicalPlan planWithoutSyntheticAttributes(LogicalPlan plan) {  | 
1902 | 1899 |      * Cast the union typed fields in EsRelation to date_nanos if they are mixed date and date_nanos types.  | 
1903 | 1900 |      */  | 
1904 | 1901 |     private static class DateMillisToNanosInEsRelation extends Rule<LogicalPlan, LogicalPlan> {  | 
 | 1902 | + | 
 | 1903 | +        private final boolean isSnapshot;  | 
 | 1904 | + | 
 | 1905 | +        DateMillisToNanosInEsRelation(boolean isSnapshot) {  | 
 | 1906 | +            this.isSnapshot = isSnapshot;  | 
 | 1907 | +        }  | 
 | 1908 | + | 
1905 | 1909 |         @Override  | 
1906 | 1910 |         public LogicalPlan apply(LogicalPlan plan) {  | 
1907 |  | -            return plan.transformUp(EsRelation.class, relation -> {  | 
1908 |  | -                if (relation.indexMode() == IndexMode.LOOKUP) {  | 
1909 |  | -                    return relation;  | 
1910 |  | -                }  | 
1911 |  | -                return relation.transformExpressionsUp(FieldAttribute.class, f -> {  | 
1912 |  | -                    if (f.field() instanceof InvalidMappedField imf && imf.types().stream().allMatch(DataType::isDate)) {  | 
1913 |  | -                        HashMap<ResolveUnionTypes.TypeResolutionKey, Expression> typeResolutions = new HashMap<>();  | 
1914 |  | -                        var convert = new ToDateNanos(f.source(), f);  | 
1915 |  | -                        imf.types().forEach(type -> typeResolutions(f, convert, type, imf, typeResolutions));  | 
1916 |  | -                        var resolvedField = ResolveUnionTypes.resolvedMultiTypeEsField(f, typeResolutions);  | 
1917 |  | -                        return new FieldAttribute(f.source(), f.parentName(), f.name(), resolvedField, f.nullable(), f.id(), f.synthetic());  | 
 | 1911 | +            if (isSnapshot) {  | 
 | 1912 | +                return plan.transformUp(EsRelation.class, relation -> {  | 
 | 1913 | +                    if (relation.indexMode() == IndexMode.LOOKUP) {  | 
 | 1914 | +                        return relation;  | 
1918 | 1915 |                     }  | 
1919 |  | -                    return f;  | 
 | 1916 | +                    return relation.transformExpressionsUp(FieldAttribute.class, f -> {  | 
 | 1917 | +                        if (f.field() instanceof InvalidMappedField imf && imf.types().stream().allMatch(DataType::isDate)) {  | 
 | 1918 | +                            HashMap<ResolveUnionTypes.TypeResolutionKey, Expression> typeResolutions = new HashMap<>();  | 
 | 1919 | +                            var convert = new ToDateNanos(f.source(), f);  | 
 | 1920 | +                            imf.types().forEach(type -> typeResolutions(f, convert, type, imf, typeResolutions));  | 
 | 1921 | +                            var resolvedField = ResolveUnionTypes.resolvedMultiTypeEsField(f, typeResolutions);  | 
 | 1922 | +                            return new FieldAttribute(  | 
 | 1923 | +                                f.source(),  | 
 | 1924 | +                                f.parentName(),  | 
 | 1925 | +                                f.name(),  | 
 | 1926 | +                                resolvedField,  | 
 | 1927 | +                                f.nullable(),  | 
 | 1928 | +                                f.id(),  | 
 | 1929 | +                                f.synthetic()  | 
 | 1930 | +                            );  | 
 | 1931 | +                        }  | 
 | 1932 | +                        return f;  | 
 | 1933 | +                    });  | 
1920 | 1934 |                 });  | 
1921 |  | -            });  | 
 | 1935 | +            } else {  | 
 | 1936 | +                return plan;  | 
 | 1937 | +            }  | 
1922 | 1938 |         }  | 
1923 | 1939 |     }  | 
1924 | 1940 | 
 
  | 
 | 
0 commit comments