Skip to content

Commit

Permalink
[ESQL] merge the two date utils classes (elastic#111718)
Browse files Browse the repository at this point in the history
Merge org.elasticsearch.xpack.esql.core.type.DateUtils and org.elasticsearch.xpack.esql.core.util.DateUtils into one class. This makes it a little easier to find stuff. There's an argument to be made that we should merge all of this into org.elasticsearch.common.time.DateUtils, but I didn't go that far in this PR.
  • Loading branch information
not-napoleon committed Aug 12, 2024
1 parent 2d7724b commit c7f2225
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;

import java.io.IOException;
import java.time.DateTimeException;
Expand All @@ -22,6 +21,7 @@
import java.util.Objects;

import static java.util.Arrays.asList;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;

// BETWEEN or range - is a mix of gt(e) AND lt(e)
public class Range extends ScalarFunction {
Expand Down Expand Up @@ -118,10 +118,10 @@ protected boolean areBoundariesInvalid() {
if (DataType.isDateTime(value.dataType()) || DataType.isDateTime(lower.dataType()) || DataType.isDateTime(upper.dataType())) {
try {
if (upperValue instanceof String upperString) {
upperValue = DateUtils.asDateTime(upperString);
upperValue = asDateTime(upperString);
}
if (lowerValue instanceof String lowerString) {
lowerValue = DateUtils.asDateTime(lowerString);
lowerValue = asDateTime(lowerString);
}
} catch (DateTimeException e) {
// one of the patterns is not a normal date, it could be a date math expression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.xpack.esql.core.InvalidArgumentException;
import org.elasticsearch.xpack.esql.core.util.DateUtils;
import org.elasticsearch.xpack.versionfield.Version;

import java.io.IOException;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

//FIXME: this class comes from sql-proto
// find a way to share it across or potentially just copy it over
final class StringUtils {
public final class StringUtils {

public static final String EMPTY = "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.time.OffsetTime;
import java.time.Period;
import java.time.ZoneId;
Expand All @@ -23,6 +24,7 @@
import java.util.concurrent.TimeUnit;

import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
Expand All @@ -34,6 +36,24 @@
public class DateUtils {

public static final ZoneId UTC = ZoneId.of("Z");
private static final DateTimeFormatter DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL = new DateTimeFormatterBuilder().append(ISO_LOCAL_DATE)
.optionalStart()
.appendLiteral('T')
.append(ISO_LOCAL_TIME)
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.toFormatter(Locale.ROOT)
.withZone(UTC);
private static final DateTimeFormatter DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE = new DateTimeFormatterBuilder().append(ISO_LOCAL_DATE)
.optionalStart()
.appendLiteral(' ')
.append(ISO_LOCAL_TIME)
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.toFormatter(Locale.ROOT)
.withZone(UTC);

public static final String EMPTY = "";

Expand Down Expand Up @@ -146,4 +166,41 @@ public static String toString(Object value) {
private static String indent(long timeUnit) {
return timeUnit < 10 ? "0" + timeUnit : Long.toString(timeUnit);
}

/**
* Creates a datetime from the millis since epoch (thus the time-zone is UTC).
*/
public static ZonedDateTime asDateTime(long millis) {
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), UTC);
}

public static long asMillis(ZonedDateTime zonedDateTime) {
return zonedDateTime.toInstant().toEpochMilli();
}

/**
* Parses the given string into a DateTime using UTC as a default timezone.
*/
public static ZonedDateTime asDateTime(String dateFormat) {
int separatorIdx = dateFormat.indexOf('-'); // Find the first `-` date separator
if (separatorIdx == 0) { // first char = `-` denotes a negative year
separatorIdx = dateFormat.indexOf('-', 1); // Find the first `-` date separator past the negative year
}
// Find the second `-` date separator and move 3 places past the dayOfYear to find the time separator
// e.g. 2020-06-01T10:20:30....
// ^
// +3 = ^
separatorIdx = dateFormat.indexOf('-', separatorIdx + 1) + 3;

// Avoid index out of bounds - it will lead to DateTimeParseException anyways
if (separatorIdx >= dateFormat.length() || dateFormat.charAt(separatorIdx) == 'T') {
return DateFormatters.from(DATE_OPTIONAL_TIME_FORMATTER_T_LITERAL.parse(dateFormat)).withZoneSameInstant(UTC);
} else {
return DateFormatters.from(DATE_OPTIONAL_TIME_FORMATTER_WHITESPACE.parse(dateFormat)).withZoneSameInstant(UTC);
}
}

public static String toString(ZonedDateTime dateTime) {
return org.elasticsearch.xpack.esql.core.type.StringUtils.toString(dateTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;
import org.elasticsearch.xpack.esql.core.util.DateUtils;

import java.time.ZoneId;
import java.time.ZonedDateTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION;
import static org.elasticsearch.xpack.esql.core.type.DataTypeConverter.commonType;
import static org.elasticsearch.xpack.esql.core.type.DataTypeConverter.converterFor;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;

public class DataTypeConversionTests extends ESTestCase {

Expand All @@ -56,7 +56,7 @@ public void testConversionToString() {
assertNull(conversion.convert(null));
assertEquals("1973-11-29T21:33:09.101Z", conversion.convert(asDateTime(123456789101L)));
assertEquals("1966-02-02T02:26:50.899Z", conversion.convert(asDateTime(-123456789101L)));
assertEquals("2020-05-01T10:20:30.123456789Z", conversion.convert(DateUtils.asDateTime("2020-05-01T10:20:30.123456789Z")));
assertEquals("2020-05-01T10:20:30.123456789Z", conversion.convert(asDateTime("2020-05-01T10:20:30.123456789Z")));
}
}

Expand Down Expand Up @@ -102,7 +102,7 @@ public void testConversionToLong() {
assertEquals(123456789101L, conversion.convert(asDateTime(123456789101L)));
assertEquals(-123456789101L, conversion.convert(asDateTime(-123456789101L)));
// Nanos are ignored, only millis are used
assertEquals(1588328430123L, conversion.convert(DateUtils.asDateTime("2020-05-01T10:20:30.123456789Z")));
assertEquals(1588328430123L, conversion.convert(asDateTime("2020-05-01T10:20:30.123456789Z")));
}
{
Converter conversion = converterFor(KEYWORD, to);
Expand Down Expand Up @@ -213,7 +213,7 @@ public void testConversionToFloat() {
assertEquals(1.23456789101E11f, (float) conversion.convert(asDateTime(123456789101L)), 0);
assertEquals(-1.23456789101E11f, (float) conversion.convert(asDateTime(-123456789101L)), 0);
// Nanos are ignored, only millis are used
assertEquals(1.5883284E12f, conversion.convert(DateUtils.asDateTime("2020-05-01T10:20:30.123456789Z")));
assertEquals(1.5883284E12f, conversion.convert(asDateTime("2020-05-01T10:20:30.123456789Z")));
}
{
Converter conversion = converterFor(KEYWORD, to);
Expand Down Expand Up @@ -260,7 +260,7 @@ public void testConversionToDouble() {
assertEquals(1.23456789101E11, (double) conversion.convert(asDateTime(123456789101L)), 0);
assertEquals(-1.23456789101E11, (double) conversion.convert(asDateTime(-123456789101L)), 0);
// Nanos are ignored, only millis are used
assertEquals(1.588328430123E12, conversion.convert(DateUtils.asDateTime("2020-05-01T10:20:30.123456789Z")));
assertEquals(1.588328430123E12, conversion.convert(asDateTime("2020-05-01T10:20:30.123456789Z")));
}
{
Converter conversion = converterFor(KEYWORD, to);
Expand Down Expand Up @@ -429,7 +429,7 @@ public void testConversionToInt() {
assertEquals(223456789, conversion.convert(asDateTime(223456789L)));
assertEquals(-123456789, conversion.convert(asDateTime(-123456789L)));
// Nanos are ignored, only millis are used
assertEquals(62123, conversion.convert(DateUtils.asDateTime("1970-01-01T00:01:02.123456789Z")));
assertEquals(62123, conversion.convert(asDateTime("1970-01-01T00:01:02.123456789Z")));
Exception e = expectThrows(InvalidArgumentException.class, () -> conversion.convert(asDateTime(Long.MAX_VALUE)));
assertEquals("[" + Long.MAX_VALUE + "] out of [integer] range", e.getMessage());
}
Expand Down Expand Up @@ -462,7 +462,7 @@ public void testConversionToShort() {
assertEquals((short) 12345, conversion.convert(asDateTime(12345L)));
assertEquals((short) -12345, conversion.convert(asDateTime(-12345L)));
// Nanos are ignored, only millis are used
assertEquals((short) 1123, conversion.convert(DateUtils.asDateTime("1970-01-01T00:00:01.123456789Z")));
assertEquals((short) 1123, conversion.convert(asDateTime("1970-01-01T00:00:01.123456789Z")));
Exception e = expectThrows(InvalidArgumentException.class, () -> conversion.convert(asDateTime(Integer.MAX_VALUE)));
assertEquals("[" + Integer.MAX_VALUE + "] out of [short] range", e.getMessage());
}
Expand Down Expand Up @@ -495,7 +495,7 @@ public void testConversionToByte() {
assertEquals((byte) 123, conversion.convert(asDateTime(123L)));
assertEquals((byte) -123, conversion.convert(asDateTime(-123L)));
// Nanos are ignored, only millis are used
assertEquals((byte) 123, conversion.convert(DateUtils.asDateTime("1970-01-01T00:00:00.123456789Z")));
assertEquals((byte) 123, conversion.convert(asDateTime("1970-01-01T00:00:00.123456789Z")));
Exception e = expectThrows(InvalidArgumentException.class, () -> conversion.convert(asDateTime(Integer.MAX_VALUE)));
assertEquals("[" + Integer.MAX_VALUE + "] out of [byte] range", e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
import org.elasticsearch.xpack.esql.core.expression.predicate.Range;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;
import org.elasticsearch.xpack.esql.core.type.EsField;
import org.elasticsearch.xpack.esql.core.util.DateUtils;
import org.elasticsearch.xpack.esql.core.util.StringUtils;
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals;
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import java.time.Period;
import java.time.temporal.TemporalAmount;

import static org.elasticsearch.xpack.esql.core.type.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongAddExact;
import static org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.EsqlArithmeticOperation.OperationSymbol.ADD;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import java.time.temporal.TemporalAmount;

import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongSubtractExact;
import static org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.EsqlArithmeticOperation.OperationSymbol.SUB;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardPattern;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;
import org.elasticsearch.xpack.esql.core.util.DateUtils;
import org.elasticsearch.xpack.esql.core.util.StringUtils;
import org.elasticsearch.xpack.esql.expression.Order;
import org.elasticsearch.xpack.esql.expression.UnresolvedNamePattern;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.elasticsearch.xpack.esql.core.expression.Literal;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;
import org.elasticsearch.xpack.esql.core.util.DateUtils;
import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
import org.elasticsearch.xpack.esql.expression.function.scalar.AbstractConfigurationFunctionTestCase;
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.elasticsearch.xpack.esql.core.expression.Literal;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.DateUtils;
import org.elasticsearch.xpack.esql.core.util.DateUtils;
import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
import org.elasticsearch.xpack.esql.expression.function.scalar.AbstractConfigurationFunctionTestCase;
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import java.util.function.BinaryOperator;
import java.util.function.Supplier;

import static org.elasticsearch.xpack.esql.core.type.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.asLongUnsigned;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import java.util.function.Supplier;

import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.type.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asDateTime;
import static org.elasticsearch.xpack.esql.core.util.DateUtils.asMillis;
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.ZERO_AS_UNSIGNED_LONG;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
Expand Down

0 comments on commit c7f2225

Please sign in to comment.