mirror of https://github.com/apache/lucene.git
SOLR-10303: Supporting more datatypes via a TemporalAccessor
This commit is contained in:
parent
cf14b4be03
commit
c6fbb27376
|
@ -22,7 +22,10 @@ import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.IsoFields;
|
import java.time.temporal.IsoFields;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.time.temporal.UnsupportedTemporalTypeException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -62,7 +65,7 @@ public class DatePartEvaluator extends NumberEvaluator {
|
||||||
public Number evaluate(Tuple tuple) throws IOException {
|
public Number evaluate(Tuple tuple) throws IOException {
|
||||||
|
|
||||||
Instant instant = null;
|
Instant instant = null;
|
||||||
LocalDateTime date = null;
|
TemporalAccessor date = null;
|
||||||
|
|
||||||
//First evaluate the parameter
|
//First evaluate the parameter
|
||||||
StreamEvaluator streamEvaluator = subEvaluators.get(0);
|
StreamEvaluator streamEvaluator = subEvaluators.get(0);
|
||||||
|
@ -76,8 +79,8 @@ public class DatePartEvaluator extends NumberEvaluator {
|
||||||
instant = (Instant) tupleValue;
|
instant = (Instant) tupleValue;
|
||||||
} else if (tupleValue instanceof Date) {
|
} else if (tupleValue instanceof Date) {
|
||||||
instant = ((Date) tupleValue).toInstant();
|
instant = ((Date) tupleValue).toInstant();
|
||||||
} else if (tupleValue instanceof LocalDateTime) {
|
} else if (tupleValue instanceof TemporalAccessor) {
|
||||||
date = ((LocalDateTime) tupleValue);
|
date = ((TemporalAccessor) tupleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instant != null) {
|
if (instant != null) {
|
||||||
|
@ -110,32 +113,38 @@ public class DatePartEvaluator extends NumberEvaluator {
|
||||||
* @param date
|
* @param date
|
||||||
* @return the evaluated value
|
* @return the evaluated value
|
||||||
*/
|
*/
|
||||||
private Number evaluate(LocalDateTime date) throws IOException {
|
private Number evaluate(TemporalAccessor date) throws IOException {
|
||||||
switch (function) {
|
try {
|
||||||
case year:
|
switch (function) {
|
||||||
return date.getYear();
|
case year:
|
||||||
case month:
|
return date.get(ChronoField.YEAR);
|
||||||
return date.getMonthValue();
|
case month:
|
||||||
case day:
|
return date.get(ChronoField.MONTH_OF_YEAR);
|
||||||
return date.getDayOfMonth();
|
case day:
|
||||||
case dayofyear:
|
return date.get(ChronoField.DAY_OF_MONTH);
|
||||||
return date.getDayOfYear();
|
case dayofyear:
|
||||||
case hour:
|
return date.get(ChronoField.DAY_OF_YEAR);
|
||||||
return date.getHour();
|
case hour:
|
||||||
case minute:
|
return date.get(ChronoField.HOUR_OF_DAY);
|
||||||
return date.getMinute();
|
case minute:
|
||||||
case second:
|
return date.get(ChronoField.MINUTE_OF_HOUR);
|
||||||
return date.getSecond();
|
case second:
|
||||||
case dayofquarter:
|
return date.get(ChronoField.SECOND_OF_MINUTE);
|
||||||
return date.get(IsoFields.DAY_OF_QUARTER);
|
case dayofquarter:
|
||||||
case quarter:
|
return date.get(IsoFields.DAY_OF_QUARTER);
|
||||||
return date.get(IsoFields.QUARTER_OF_YEAR);
|
case quarter:
|
||||||
case week:
|
return date.get(IsoFields.QUARTER_OF_YEAR);
|
||||||
return date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
|
case week:
|
||||||
case epoch:
|
return date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
|
||||||
return date.atZone(ZoneOffset.UTC).toInstant().toEpochMilli();
|
case epoch:
|
||||||
|
if (date instanceof LocalDateTime) {
|
||||||
|
return ((LocalDateTime)date).atZone(ZoneOffset.UTC).toInstant().toEpochMilli();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UnsupportedTemporalTypeException utte) {
|
||||||
|
throw new IOException(String.format(Locale.ROOT, "It is not possible to call '%s' function on %s", function, date.getClass().getName()));
|
||||||
}
|
}
|
||||||
throw new IOException(String.format(Locale.ROOT, "Unsupported function %s called on LocalDateTime %s", function, date.toString()));
|
throw new IOException(String.format(Locale.ROOT, "Unsupported function '%s' called on %s", function, date.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,8 @@ package org.apache.solr.client.solrj.io.stream.eval;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.MonthDay;
|
||||||
|
import java.time.YearMonth;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -72,7 +74,7 @@ public class DatePartEvaluatorTest {
|
||||||
evaluator = factory.constructEvaluator("nope(a)");
|
evaluator = factory.constructEvaluator("nope(a)");
|
||||||
evaluator.evaluate(new Tuple(null));
|
evaluator.evaluate(new Tuple(null));
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertTrue(e.getCause().getCause().getMessage().contains("Invalid date expression nope"));
|
assertTrue(e.getCause().getCause().getMessage().contains("Invalid date expression nope"));
|
||||||
assertTrue(e.getCause().getCause().getMessage().contains("expecting one of [year, month, day"));
|
assertTrue(e.getCause().getCause().getMessage().contains("expecting one of [year, month, day"));
|
||||||
}
|
}
|
||||||
|
@ -80,21 +82,21 @@ public class DatePartEvaluatorTest {
|
||||||
try {
|
try {
|
||||||
evaluator = factory.constructEvaluator("week()");
|
evaluator = factory.constructEvaluator("week()");
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertTrue(e.getCause().getCause().getMessage().contains("Invalid expression week()"));
|
assertTrue(e.getCause().getCause().getMessage().contains("Invalid expression week()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
evaluator = factory.constructEvaluator("week(a, b)");
|
evaluator = factory.constructEvaluator("week(a, b)");
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertTrue(e.getCause().getCause().getMessage().contains("expecting one value but found 2"));
|
assertTrue(e.getCause().getCause().getMessage().contains("expecting one value but found 2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
evaluator = factory.constructEvaluator("Week()");
|
evaluator = factory.constructEvaluator("Week()");
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertTrue(e.getMessage().contains("Invalid evaluator expression Week() - function 'Week' is unknown"));
|
assertTrue(e.getMessage().contains("Invalid evaluator expression Week() - function 'Week' is unknown"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,7 @@ public class DatePartEvaluatorTest {
|
||||||
values.put("a", 12);
|
values.put("a", 12);
|
||||||
Object result = evaluator.evaluate(new Tuple(values));
|
Object result = evaluator.evaluate(new Tuple(values));
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertEquals("Invalid parameter 12 - The parameter must be a string formatted ISO_INSTANT or of type Instant,Date or LocalDateTime.", e.getMessage());
|
assertEquals("Invalid parameter 12 - The parameter must be a string formatted ISO_INSTANT or of type Instant,Date or LocalDateTime.", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@ public class DatePartEvaluatorTest {
|
||||||
values.put("a", "1995-12-31");
|
values.put("a", "1995-12-31");
|
||||||
Object result = evaluator.evaluate(new Tuple(values));
|
Object result = evaluator.evaluate(new Tuple(values));
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertEquals("Invalid parameter 1995-12-31 - The String must be formatted in the ISO_INSTANT date format.", e.getMessage());
|
assertEquals("Invalid parameter 1995-12-31 - The String must be formatted in the ISO_INSTANT date format.", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ public class DatePartEvaluatorTest {
|
||||||
values.put("a", "");
|
values.put("a", "");
|
||||||
Object result = evaluator.evaluate(new Tuple(values));
|
Object result = evaluator.evaluate(new Tuple(values));
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
assertEquals("Invalid parameter - The parameter must be a string formatted ISO_INSTANT or of type Instant,Date or LocalDateTime.", e.getMessage());
|
assertEquals("Invalid parameter - The parameter must be a string formatted ISO_INSTANT or of type Instant,Date or LocalDateTime.", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +222,34 @@ public class DatePartEvaluatorTest {
|
||||||
testFunction("epoch(a)", localDateTime, aDate.getTime());
|
testFunction("epoch(a)", localDateTime, aDate.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLimitedFunctions() throws Exception {
|
||||||
|
|
||||||
|
MonthDay monthDay = MonthDay.of(12,5);
|
||||||
|
testFunction("month(a)", monthDay, 12);
|
||||||
|
testFunction("day(a)", monthDay, 5);
|
||||||
|
|
||||||
|
try {
|
||||||
|
testFunction("year(a)", monthDay, 2017);
|
||||||
|
assertTrue(false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
assertEquals("It is not possible to call 'year' function on java.time.MonthDay", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth yearMonth = YearMonth.of(2018, 4);
|
||||||
|
testFunction("month(a)", yearMonth, 4);
|
||||||
|
testFunction("year(a)", yearMonth, 2018);
|
||||||
|
|
||||||
|
try {
|
||||||
|
testFunction("day(a)", yearMonth, 5);
|
||||||
|
assertTrue(false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
assertEquals("It is not possible to call 'day' function on java.time.YearMonth", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testFunction(String expression, Object value, Number expected) throws Exception {
|
public void testFunction(String expression, Object value, Number expected) throws Exception {
|
||||||
StreamEvaluator evaluator = factory.constructEvaluator(expression);
|
StreamEvaluator evaluator = factory.constructEvaluator(expression);
|
||||||
values.clear();
|
values.clear();
|
||||||
|
|
Loading…
Reference in New Issue