1 | /* | |
2 | * Copyright OpenSearch Contributors | |
3 | * SPDX-License-Identifier: Apache-2.0 | |
4 | */ | |
5 | ||
6 | ||
7 | package org.opensearch.sql.expression.datetime; | |
8 | ||
9 | import static java.time.temporal.ChronoUnit.MONTHS; | |
10 | import static org.opensearch.sql.data.type.ExprCoreType.DATE; | |
11 | import static org.opensearch.sql.data.type.ExprCoreType.DATETIME; | |
12 | import static org.opensearch.sql.data.type.ExprCoreType.DOUBLE; | |
13 | import static org.opensearch.sql.data.type.ExprCoreType.INTEGER; | |
14 | import static org.opensearch.sql.data.type.ExprCoreType.INTERVAL; | |
15 | import static org.opensearch.sql.data.type.ExprCoreType.LONG; | |
16 | import static org.opensearch.sql.data.type.ExprCoreType.STRING; | |
17 | import static org.opensearch.sql.data.type.ExprCoreType.TIME; | |
18 | import static org.opensearch.sql.data.type.ExprCoreType.TIMESTAMP; | |
19 | import static org.opensearch.sql.expression.function.FunctionDSL.define; | |
20 | import static org.opensearch.sql.expression.function.FunctionDSL.impl; | |
21 | import static org.opensearch.sql.expression.function.FunctionDSL.nullMissingHandling; | |
22 | import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_LONG_YEAR; | |
23 | import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_SHORT_YEAR; | |
24 | import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_LONG_YEAR; | |
25 | import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_SHORT_YEAR; | |
26 | import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_STRICT_WITH_TZ; | |
27 | ||
28 | import java.math.BigDecimal; | |
29 | import java.math.RoundingMode; | |
30 | import java.text.DecimalFormat; | |
31 | import java.time.DateTimeException; | |
32 | import java.time.Instant; | |
33 | import java.time.LocalDate; | |
34 | import java.time.LocalDateTime; | |
35 | import java.time.LocalTime; | |
36 | import java.time.ZoneId; | |
37 | import java.time.ZoneOffset; | |
38 | import java.time.ZonedDateTime; | |
39 | import java.time.format.DateTimeFormatter; | |
40 | import java.time.format.DateTimeParseException; | |
41 | import java.time.format.TextStyle; | |
42 | import java.util.Locale; | |
43 | import java.util.TimeZone; | |
44 | import java.util.concurrent.TimeUnit; | |
45 | import javax.annotation.Nullable; | |
46 | import lombok.experimental.UtilityClass; | |
47 | import org.opensearch.sql.data.model.ExprDateValue; | |
48 | import org.opensearch.sql.data.model.ExprDatetimeValue; | |
49 | import org.opensearch.sql.data.model.ExprDoubleValue; | |
50 | import org.opensearch.sql.data.model.ExprIntegerValue; | |
51 | import org.opensearch.sql.data.model.ExprLongValue; | |
52 | import org.opensearch.sql.data.model.ExprNullValue; | |
53 | import org.opensearch.sql.data.model.ExprStringValue; | |
54 | import org.opensearch.sql.data.model.ExprTimeValue; | |
55 | import org.opensearch.sql.data.model.ExprTimestampValue; | |
56 | import org.opensearch.sql.data.model.ExprValue; | |
57 | import org.opensearch.sql.data.type.ExprCoreType; | |
58 | import org.opensearch.sql.exception.ExpressionEvaluationException; | |
59 | import org.opensearch.sql.exception.SemanticCheckException; | |
60 | import org.opensearch.sql.expression.function.BuiltinFunctionName; | |
61 | import org.opensearch.sql.expression.function.BuiltinFunctionRepository; | |
62 | import org.opensearch.sql.expression.function.DefaultFunctionResolver; | |
63 | import org.opensearch.sql.expression.function.FunctionName; | |
64 | import org.opensearch.sql.utils.DateTimeUtils; | |
65 | ||
66 | /** | |
67 | * The definition of date and time functions. | |
68 | * 1) have the clear interface for function define. | |
69 | * 2) the implementation should rely on ExprValue. | |
70 | */ | |
71 | @UtilityClass | |
72 | @SuppressWarnings("unchecked") | |
73 | public class DateTimeFunction { | |
74 | // The number of days from year zero to year 1970. | |
75 | private static final Long DAYS_0000_TO_1970 = (146097 * 5L) - (30L * 365L + 7L); | |
76 | ||
77 | // MySQL doesn't process any datetime/timestamp values which are greater than | |
78 | // 32536771199.999999, or equivalent '3001-01-18 23:59:59.999999' UTC | |
79 | private static final Double MYSQL_MAX_TIMESTAMP = 32536771200d; | |
80 | ||
81 | /** | |
82 | * Register Date and Time Functions. | |
83 | * | |
84 | * @param repository {@link BuiltinFunctionRepository}. | |
85 | */ | |
86 | public void register(BuiltinFunctionRepository repository) { | |
87 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(adddate()); |
88 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(convert_tz()); |
89 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(curtime()); |
90 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(curdate()); |
91 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(current_date()); |
92 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(current_time()); |
93 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(current_timestamp()); |
94 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(date()); |
95 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(datetime()); |
96 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(date_add()); |
97 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(date_sub()); |
98 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(day()); |
99 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(dayName()); |
100 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(dayOfMonth()); |
101 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(dayOfWeek()); |
102 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(dayOfYear()); |
103 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(from_days()); |
104 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(from_unixtime()); |
105 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(hour()); |
106 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(localtime()); |
107 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(localtimestamp()); |
108 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(makedate()); |
109 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(maketime()); |
110 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(microsecond()); |
111 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(minute()); |
112 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(month()); |
113 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(monthName()); |
114 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → KILLED |
repository.register(now()); |
115 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(period_add()); |
116 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(period_diff()); |
117 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(quarter()); |
118 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(second()); |
119 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(subdate()); |
120 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(sysdate()); |
121 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(time()); |
122 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(time_to_sec()); |
123 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(timestamp()); |
124 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(date_format()); |
125 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(to_days()); |
126 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(unix_timestamp()); |
127 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(week()); |
128 |
1
1. register : removed call to org/opensearch/sql/expression/function/BuiltinFunctionRepository::register → SURVIVED |
repository.register(year()); |
129 | } | |
130 | ||
131 | /** | |
132 | * Specify a start date and add a temporal amount to the date. | |
133 | * The return type depends on the date type and the interval unit. Detailed supported signatures: | |
134 | * (STRING/DATE/DATETIME/TIMESTAMP, INTERVAL) -> DATETIME | |
135 | * (DATE, LONG) -> DATE | |
136 | * (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | |
137 | */ | |
138 | private DefaultFunctionResolver add_date(FunctionName functionName) { | |
139 |
1
1. add_date : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::add_date → KILLED |
return define(functionName, |
140 | impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), | |
141 | DATETIME, STRING, INTERVAL), | |
142 | impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), DATETIME, DATE, INTERVAL), | |
143 | impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), | |
144 | DATETIME, DATETIME, INTERVAL), | |
145 | impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), | |
146 | DATETIME, TIMESTAMP, INTERVAL), | |
147 | impl(nullMissingHandling(DateTimeFunction::exprAddDateDays), DATE, DATE, LONG), | |
148 | impl(nullMissingHandling(DateTimeFunction::exprAddDateDays), DATETIME, DATETIME, LONG), | |
149 | impl(nullMissingHandling(DateTimeFunction::exprAddDateDays), DATETIME, TIMESTAMP, LONG), | |
150 | impl(nullMissingHandling(DateTimeFunction::exprAddDateDays), DATETIME, STRING, LONG) | |
151 | ); | |
152 | } | |
153 | ||
154 | private DefaultFunctionResolver adddate() { | |
155 |
1
1. adddate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::adddate → KILLED |
return add_date(BuiltinFunctionName.ADDDATE.getName()); |
156 | } | |
157 | ||
158 | /** | |
159 | * Converts date/time from a specified timezone to another specified timezone. | |
160 | * The supported signatures: | |
161 | * (DATETIME, STRING, STRING) -> DATETIME | |
162 | * (STRING, STRING, STRING) -> DATETIME | |
163 | */ | |
164 | private DefaultFunctionResolver convert_tz() { | |
165 |
1
1. convert_tz : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::convert_tz → KILLED |
return define(BuiltinFunctionName.CONVERT_TZ.getName(), |
166 | impl(nullMissingHandling(DateTimeFunction::exprConvertTZ), | |
167 | DATETIME, DATETIME, STRING, STRING), | |
168 | impl(nullMissingHandling(DateTimeFunction::exprConvertTZ), | |
169 | DATETIME, STRING, STRING, STRING) | |
170 | ); | |
171 | } | |
172 | ||
173 | private DefaultFunctionResolver curdate(FunctionName functionName) { | |
174 |
1
1. curdate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::curdate → KILLED |
return define(functionName, |
175 |
1
1. lambda$curdate$8f844d55$1 : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::lambda$curdate$8f844d55$1 → KILLED |
impl(() -> new ExprDateValue(formatNow(null).toLocalDate()), DATE) |
176 | ); | |
177 | } | |
178 | ||
179 | private DefaultFunctionResolver curdate() { | |
180 |
1
1. curdate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::curdate → KILLED |
return curdate(BuiltinFunctionName.CURDATE.getName()); |
181 | } | |
182 | ||
183 | /** | |
184 | * Synonym for @see `now`. | |
185 | */ | |
186 | private DefaultFunctionResolver curtime(FunctionName functionName) { | |
187 |
1
1. curtime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::curtime → KILLED |
return define(functionName, |
188 |
1
1. lambda$curtime$8f844d55$1 : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::lambda$curtime$8f844d55$1 → KILLED |
impl(() -> new ExprTimeValue(formatNow(null).toLocalTime()), TIME) |
189 | ); | |
190 | } | |
191 | ||
192 | private DefaultFunctionResolver curtime() { | |
193 |
1
1. curtime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::curtime → KILLED |
return curtime(BuiltinFunctionName.CURTIME.getName()); |
194 | } | |
195 | ||
196 | private DefaultFunctionResolver current_date() { | |
197 |
1
1. current_date : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::current_date → KILLED |
return curdate(BuiltinFunctionName.CURRENT_DATE.getName()); |
198 | } | |
199 | ||
200 | private DefaultFunctionResolver current_time() { | |
201 |
1
1. current_time : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::current_time → KILLED |
return curtime(BuiltinFunctionName.CURRENT_TIME.getName()); |
202 | } | |
203 | ||
204 | private DefaultFunctionResolver current_timestamp() { | |
205 |
1
1. current_timestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::current_timestamp → KILLED |
return now(BuiltinFunctionName.CURRENT_TIMESTAMP.getName()); |
206 | } | |
207 | ||
208 | /** | |
209 | * Extracts the date part of a date and time value. | |
210 | * Also to construct a date type. The supported signatures: | |
211 | * STRING/DATE/DATETIME/TIMESTAMP -> DATE | |
212 | */ | |
213 | private DefaultFunctionResolver date() { | |
214 |
1
1. date : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::date → KILLED |
return define(BuiltinFunctionName.DATE.getName(), |
215 | impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING), | |
216 | impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE), | |
217 | impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATETIME), | |
218 | impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIMESTAMP)); | |
219 | } | |
220 | ||
221 | /** | |
222 | * Specify a datetime with time zone field and a time zone to convert to. | |
223 | * Returns a local date time. | |
224 | * (STRING, STRING) -> DATETIME | |
225 | * (STRING) -> DATETIME | |
226 | */ | |
227 | private DefaultFunctionResolver datetime() { | |
228 |
1
1. datetime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::datetime → KILLED |
return define(BuiltinFunctionName.DATETIME.getName(), |
229 | impl(nullMissingHandling(DateTimeFunction::exprDateTime), | |
230 | DATETIME, STRING, STRING), | |
231 | impl(nullMissingHandling(DateTimeFunction::exprDateTimeNoTimezone), | |
232 | DATETIME, STRING) | |
233 | ); | |
234 | } | |
235 | ||
236 | private DefaultFunctionResolver date_add() { | |
237 |
1
1. date_add : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::date_add → KILLED |
return add_date(BuiltinFunctionName.DATE_ADD.getName()); |
238 | } | |
239 | ||
240 | /** | |
241 | * Specify a start date and subtract a temporal amount to the date. | |
242 | * The return type depends on the date type and the interval unit. Detailed supported signatures: | |
243 | * (STRING/DATE/DATETIME/TIMESTAMP, INTERVAL) -> DATETIME | |
244 | * (DATE, LONG) -> DATE | |
245 | * (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | |
246 | */ | |
247 | private DefaultFunctionResolver sub_date(FunctionName functionName) { | |
248 |
1
1. sub_date : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::sub_date → KILLED |
return define(functionName, |
249 | impl(nullMissingHandling(DateTimeFunction::exprSubDateInterval), | |
250 | DATETIME, STRING, INTERVAL), | |
251 | impl(nullMissingHandling(DateTimeFunction::exprSubDateInterval), DATETIME, DATE, INTERVAL), | |
252 | impl(nullMissingHandling(DateTimeFunction::exprSubDateInterval), | |
253 | DATETIME, DATETIME, INTERVAL), | |
254 | impl(nullMissingHandling(DateTimeFunction::exprSubDateInterval), | |
255 | DATETIME, TIMESTAMP, INTERVAL), | |
256 | impl(nullMissingHandling(DateTimeFunction::exprSubDateDays), DATE, DATE, LONG), | |
257 | impl(nullMissingHandling(DateTimeFunction::exprSubDateDays), DATETIME, DATETIME, LONG), | |
258 | impl(nullMissingHandling(DateTimeFunction::exprSubDateDays), DATETIME, TIMESTAMP, LONG), | |
259 | impl(nullMissingHandling(DateTimeFunction::exprSubDateDays), DATETIME, STRING, LONG) | |
260 | ); | |
261 | } | |
262 | ||
263 | private DefaultFunctionResolver date_sub() { | |
264 |
1
1. date_sub : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::date_sub → KILLED |
return sub_date(BuiltinFunctionName.DATE_SUB.getName()); |
265 | } | |
266 | ||
267 | /** | |
268 | * DAY(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). | |
269 | */ | |
270 | private DefaultFunctionResolver day() { | |
271 |
1
1. day : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::day → KILLED |
return define(BuiltinFunctionName.DAY.getName(), |
272 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), | |
273 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), | |
274 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP), | |
275 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING) | |
276 | ); | |
277 | } | |
278 | ||
279 | /** | |
280 | * DAYNAME(STRING/DATE/DATETIME/TIMESTAMP). | |
281 | * return the name of the weekday for date, including Monday, Tuesday, Wednesday, | |
282 | * Thursday, Friday, Saturday and Sunday. | |
283 | */ | |
284 | private DefaultFunctionResolver dayName() { | |
285 |
1
1. dayName : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::dayName → KILLED |
return define(BuiltinFunctionName.DAYNAME.getName(), |
286 | impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATE), | |
287 | impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATETIME), | |
288 | impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, TIMESTAMP), | |
289 | impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, STRING) | |
290 | ); | |
291 | } | |
292 | ||
293 | /** | |
294 | * DAYOFMONTH(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). | |
295 | */ | |
296 | private DefaultFunctionResolver dayOfMonth() { | |
297 |
1
1. dayOfMonth : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::dayOfMonth → KILLED |
return define(BuiltinFunctionName.DAYOFMONTH.getName(), |
298 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), | |
299 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), | |
300 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP), | |
301 | impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING) | |
302 | ); | |
303 | } | |
304 | ||
305 | /** | |
306 | * DAYOFWEEK(STRING/DATE/DATETIME/TIMESTAMP). | |
307 | * return the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday). | |
308 | */ | |
309 | private DefaultFunctionResolver dayOfWeek() { | |
310 |
1
1. dayOfWeek : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::dayOfWeek → KILLED |
return define(BuiltinFunctionName.DAYOFWEEK.getName(), |
311 | impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATE), | |
312 | impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATETIME), | |
313 | impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, TIMESTAMP), | |
314 | impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, STRING) | |
315 | ); | |
316 | } | |
317 | ||
318 | /** | |
319 | * DAYOFYEAR(STRING/DATE/DATETIME/TIMESTAMP). | |
320 | * return the day of the year for date (1-366). | |
321 | */ | |
322 | private DefaultFunctionResolver dayOfYear() { | |
323 |
1
1. dayOfYear : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::dayOfYear → KILLED |
return define(BuiltinFunctionName.DAYOFYEAR.getName(), |
324 | impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATE), | |
325 | impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATETIME), | |
326 | impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, TIMESTAMP), | |
327 | impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, STRING) | |
328 | ); | |
329 | } | |
330 | ||
331 | /** | |
332 | * FROM_DAYS(LONG). return the date value given the day number N. | |
333 | */ | |
334 | private DefaultFunctionResolver from_days() { | |
335 |
1
1. from_days : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::from_days → KILLED |
return define(BuiltinFunctionName.FROM_DAYS.getName(), |
336 | impl(nullMissingHandling(DateTimeFunction::exprFromDays), DATE, LONG)); | |
337 | } | |
338 | ||
339 | private DefaultFunctionResolver from_unixtime() { | |
340 |
1
1. from_unixtime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::from_unixtime → KILLED |
return define(BuiltinFunctionName.FROM_UNIXTIME.getName(), |
341 | impl(nullMissingHandling(DateTimeFunction::exprFromUnixTime), DATETIME, DOUBLE), | |
342 | impl(nullMissingHandling(DateTimeFunction::exprFromUnixTimeFormat), | |
343 | STRING, DOUBLE, STRING)); | |
344 | } | |
345 | ||
346 | /** | |
347 | * HOUR(STRING/TIME/DATETIME/TIMESTAMP). return the hour value for time. | |
348 | */ | |
349 | private DefaultFunctionResolver hour() { | |
350 |
1
1. hour : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::hour → KILLED |
return define(BuiltinFunctionName.HOUR.getName(), |
351 | impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, STRING), | |
352 | impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIME), | |
353 | impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, DATETIME), | |
354 | impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIMESTAMP) | |
355 | ); | |
356 | } | |
357 | ||
358 | private DefaultFunctionResolver localtime() { | |
359 |
1
1. localtime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::localtime → KILLED |
return now(BuiltinFunctionName.LOCALTIME.getName()); |
360 | } | |
361 | ||
362 | private DefaultFunctionResolver localtimestamp() { | |
363 |
1
1. localtimestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::localtimestamp → KILLED |
return now(BuiltinFunctionName.LOCALTIMESTAMP.getName()); |
364 | } | |
365 | ||
366 | /** | |
367 | * NOW() returns a constant time that indicates the time at which the statement began to execute. | |
368 | * `fsp` argument support is removed until refactoring to avoid bug where `now()`, `now(x)` and | |
369 | * `now(y) return different values. | |
370 | */ | |
371 | private DefaultFunctionResolver now(FunctionName functionName) { | |
372 |
1
1. now : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::now → KILLED |
return define(functionName, |
373 |
1
1. lambda$now$8f844d55$1 : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::lambda$now$8f844d55$1 → KILLED |
impl(() -> new ExprDatetimeValue(formatNow(null)), DATETIME) |
374 | ); | |
375 | } | |
376 | ||
377 | private DefaultFunctionResolver now() { | |
378 |
1
1. now : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::now → KILLED |
return now(BuiltinFunctionName.NOW.getName()); |
379 | } | |
380 | ||
381 | private DefaultFunctionResolver makedate() { | |
382 |
1
1. makedate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::makedate → KILLED |
return define(BuiltinFunctionName.MAKEDATE.getName(), |
383 | impl(nullMissingHandling(DateTimeFunction::exprMakeDate), DATE, DOUBLE, DOUBLE)); | |
384 | } | |
385 | ||
386 | private DefaultFunctionResolver maketime() { | |
387 |
1
1. maketime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::maketime → KILLED |
return define(BuiltinFunctionName.MAKETIME.getName(), |
388 | impl(nullMissingHandling(DateTimeFunction::exprMakeTime), TIME, DOUBLE, DOUBLE, DOUBLE)); | |
389 | } | |
390 | ||
391 | /** | |
392 | * MICROSECOND(STRING/TIME/DATETIME/TIMESTAMP). return the microsecond value for time. | |
393 | */ | |
394 | private DefaultFunctionResolver microsecond() { | |
395 |
1
1. microsecond : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::microsecond → KILLED |
return define(BuiltinFunctionName.MICROSECOND.getName(), |
396 | impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, STRING), | |
397 | impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIME), | |
398 | impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, DATETIME), | |
399 | impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIMESTAMP) | |
400 | ); | |
401 | } | |
402 | ||
403 | /** | |
404 | * MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time. | |
405 | */ | |
406 | private DefaultFunctionResolver minute() { | |
407 |
1
1. minute : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::minute → KILLED |
return define(BuiltinFunctionName.MINUTE.getName(), |
408 | impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, STRING), | |
409 | impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIME), | |
410 | impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, DATETIME), | |
411 | impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIMESTAMP) | |
412 | ); | |
413 | } | |
414 | ||
415 | /** | |
416 | * MONTH(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-12). | |
417 | */ | |
418 | private DefaultFunctionResolver month() { | |
419 |
1
1. month : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::month → KILLED |
return define(BuiltinFunctionName.MONTH.getName(), |
420 | impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATE), | |
421 | impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATETIME), | |
422 | impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, TIMESTAMP), | |
423 | impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, STRING) | |
424 | ); | |
425 | } | |
426 | ||
427 | /** | |
428 | * MONTHNAME(STRING/DATE/DATETIME/TIMESTAMP). return the full name of the month for date. | |
429 | */ | |
430 | private DefaultFunctionResolver monthName() { | |
431 |
1
1. monthName : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::monthName → KILLED |
return define(BuiltinFunctionName.MONTHNAME.getName(), |
432 | impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATE), | |
433 | impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATETIME), | |
434 | impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, TIMESTAMP), | |
435 | impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, STRING) | |
436 | ); | |
437 | } | |
438 | ||
439 | /** | |
440 | * Add N months to period P (in the format YYMM or YYYYMM). Returns a value in the format YYYYMM. | |
441 | * (INTEGER, INTEGER) -> INTEGER | |
442 | */ | |
443 | private DefaultFunctionResolver period_add() { | |
444 |
1
1. period_add : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::period_add → KILLED |
return define(BuiltinFunctionName.PERIOD_ADD.getName(), |
445 | impl(nullMissingHandling(DateTimeFunction::exprPeriodAdd), INTEGER, INTEGER, INTEGER) | |
446 | ); | |
447 | } | |
448 | ||
449 | /** | |
450 | * Returns the number of months between periods P1 and P2. | |
451 | * P1 and P2 should be in the format YYMM or YYYYMM. | |
452 | * (INTEGER, INTEGER) -> INTEGER | |
453 | */ | |
454 | private DefaultFunctionResolver period_diff() { | |
455 |
1
1. period_diff : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::period_diff → KILLED |
return define(BuiltinFunctionName.PERIOD_DIFF.getName(), |
456 | impl(nullMissingHandling(DateTimeFunction::exprPeriodDiff), INTEGER, INTEGER, INTEGER) | |
457 | ); | |
458 | } | |
459 | ||
460 | /** | |
461 | * QUARTER(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-4). | |
462 | */ | |
463 | private DefaultFunctionResolver quarter() { | |
464 |
1
1. quarter : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::quarter → KILLED |
return define(BuiltinFunctionName.QUARTER.getName(), |
465 | impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATE), | |
466 | impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATETIME), | |
467 | impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, TIMESTAMP), | |
468 | impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, STRING) | |
469 | ); | |
470 | } | |
471 | ||
472 | /** | |
473 | * SECOND(STRING/TIME/DATETIME/TIMESTAMP). return the second value for time. | |
474 | */ | |
475 | private DefaultFunctionResolver second() { | |
476 |
1
1. second : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::second → KILLED |
return define(BuiltinFunctionName.SECOND.getName(), |
477 | impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, STRING), | |
478 | impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIME), | |
479 | impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, DATETIME), | |
480 | impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIMESTAMP) | |
481 | ); | |
482 | } | |
483 | ||
484 | private DefaultFunctionResolver subdate() { | |
485 |
1
1. subdate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::subdate → KILLED |
return sub_date(BuiltinFunctionName.SUBDATE.getName()); |
486 | } | |
487 | ||
488 | /** | |
489 | * Extracts the time part of a date and time value. | |
490 | * Also to construct a time type. The supported signatures: | |
491 | * STRING/DATE/DATETIME/TIME/TIMESTAMP -> TIME | |
492 | */ | |
493 | private DefaultFunctionResolver time() { | |
494 |
1
1. time : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::time → KILLED |
return define(BuiltinFunctionName.TIME.getName(), |
495 | impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, STRING), | |
496 | impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATE), | |
497 | impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATETIME), | |
498 | impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, TIME), | |
499 | impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, TIMESTAMP)); | |
500 | } | |
501 | ||
502 | /** | |
503 | * TIME_TO_SEC(STRING/TIME/DATETIME/TIMESTAMP). return the time argument, converted to seconds. | |
504 | */ | |
505 | private DefaultFunctionResolver time_to_sec() { | |
506 |
1
1. time_to_sec : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::time_to_sec → KILLED |
return define(BuiltinFunctionName.TIME_TO_SEC.getName(), |
507 | impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, STRING), | |
508 | impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIME), | |
509 | impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIMESTAMP), | |
510 | impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, DATETIME) | |
511 | ); | |
512 | } | |
513 | ||
514 | /** | |
515 | * Extracts the timestamp of a date and time value. | |
516 | * Also to construct a date type. The supported signatures: | |
517 | * STRING/DATE/DATETIME/TIMESTAMP -> DATE | |
518 | */ | |
519 | private DefaultFunctionResolver timestamp() { | |
520 |
1
1. timestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::timestamp → KILLED |
return define(BuiltinFunctionName.TIMESTAMP.getName(), |
521 | impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, STRING), | |
522 | impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, DATE), | |
523 | impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, DATETIME), | |
524 | impl(nullMissingHandling(DateTimeFunction::exprTimestamp), TIMESTAMP, TIMESTAMP)); | |
525 | } | |
526 | ||
527 | /** | |
528 | * TO_DAYS(STRING/DATE/DATETIME/TIMESTAMP). return the day number of the given date. | |
529 | */ | |
530 | private DefaultFunctionResolver to_days() { | |
531 |
1
1. to_days : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::to_days → KILLED |
return define(BuiltinFunctionName.TO_DAYS.getName(), |
532 | impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, STRING), | |
533 | impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, TIMESTAMP), | |
534 | impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, DATE), | |
535 | impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, DATETIME)); | |
536 | } | |
537 | ||
538 | private DefaultFunctionResolver unix_timestamp() { | |
539 |
1
1. unix_timestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unix_timestamp → KILLED |
return define(BuiltinFunctionName.UNIX_TIMESTAMP.getName(), |
540 | impl(DateTimeFunction::unixTimeStamp, LONG), | |
541 | impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DATE), | |
542 | impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DATETIME), | |
543 | impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, TIMESTAMP), | |
544 | impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DOUBLE) | |
545 | ); | |
546 | } | |
547 | ||
548 | /** | |
549 | * WEEK(DATE[,mode]). return the week number for date. | |
550 | */ | |
551 | private DefaultFunctionResolver week() { | |
552 |
1
1. week : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::week → KILLED |
return define(BuiltinFunctionName.WEEK.getName(), |
553 | impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATE), | |
554 | impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATETIME), | |
555 | impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, TIMESTAMP), | |
556 | impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, STRING), | |
557 | impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, DATE, INTEGER), | |
558 | impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, DATETIME, INTEGER), | |
559 | impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, TIMESTAMP, INTEGER), | |
560 | impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, STRING, INTEGER) | |
561 | ); | |
562 | } | |
563 | ||
564 | /** | |
565 | * YEAR(STRING/DATE/DATETIME/TIMESTAMP). return the year for date (1000-9999). | |
566 | */ | |
567 | private DefaultFunctionResolver year() { | |
568 |
1
1. year : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::year → KILLED |
return define(BuiltinFunctionName.YEAR.getName(), |
569 | impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATE), | |
570 | impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATETIME), | |
571 | impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, TIMESTAMP), | |
572 | impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, STRING) | |
573 | ); | |
574 | } | |
575 | ||
576 | /** | |
577 | * Formats date according to format specifier. First argument is date, second is format. | |
578 | * Detailed supported signatures: | |
579 | * (STRING, STRING) -> STRING | |
580 | * (DATE, STRING) -> STRING | |
581 | * (DATETIME, STRING) -> STRING | |
582 | * (TIMESTAMP, STRING) -> STRING | |
583 | */ | |
584 | private DefaultFunctionResolver date_format() { | |
585 |
1
1. date_format : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::date_format → KILLED |
return define(BuiltinFunctionName.DATE_FORMAT.getName(), |
586 | impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), | |
587 | STRING, STRING, STRING), | |
588 | impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), | |
589 | STRING, DATE, STRING), | |
590 | impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), | |
591 | STRING, DATETIME, STRING), | |
592 | impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), | |
593 | STRING, TIMESTAMP, STRING) | |
594 | ); | |
595 | } | |
596 | ||
597 | /** | |
598 | * ADDDATE function implementation for ExprValue. | |
599 | * | |
600 | * @param date ExprValue of String/Date/Datetime/Timestamp type. | |
601 | * @param expr ExprValue of Interval type, the temporal amount to add. | |
602 | * @return Datetime resulted from expr added to date. | |
603 | */ | |
604 | private ExprValue exprAddDateInterval(ExprValue date, ExprValue expr) { | |
605 | ExprValue exprValue = new ExprDatetimeValue(date.datetimeValue().plus(expr.intervalValue())); | |
606 |
2
1. exprAddDateInterval : negated conditional → KILLED 2. exprAddDateInterval : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprAddDateInterval → KILLED |
return (exprValue.timeValue().toSecondOfDay() == 0 ? new ExprDateValue(exprValue.dateValue()) |
607 | : exprValue); | |
608 | } | |
609 | ||
610 | /** | |
611 | * ADDDATE function implementation for ExprValue. | |
612 | * | |
613 | * @param date ExprValue of String/Date/Datetime/Timestamp type. | |
614 | * @param days ExprValue of Long type, representing the number of days to add. | |
615 | * @return Date/Datetime resulted from days added to date. | |
616 | */ | |
617 | private ExprValue exprAddDateDays(ExprValue date, ExprValue days) { | |
618 | ExprValue exprValue = new ExprDatetimeValue(date.datetimeValue().plusDays(days.longValue())); | |
619 |
2
1. exprAddDateDays : negated conditional → KILLED 2. exprAddDateDays : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprAddDateDays → KILLED |
return (exprValue.timeValue().toSecondOfDay() == 0 ? new ExprDateValue(exprValue.dateValue()) |
620 | : exprValue); | |
621 | } | |
622 | ||
623 | /** | |
624 | * CONVERT_TZ function implementation for ExprValue. | |
625 | * Returns null for time zones outside of +13:00 and -12:00. | |
626 | * | |
627 | * @param startingDateTime ExprValue of DateTime that is being converted from | |
628 | * @param fromTz ExprValue of time zone, representing the time to convert from. | |
629 | * @param toTz ExprValue of time zone, representing the time to convert to. | |
630 | * @return DateTime that has been converted to the to_tz timezone. | |
631 | */ | |
632 | private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, ExprValue toTz) { | |
633 |
1
1. exprConvertTZ : negated conditional → KILLED |
if (startingDateTime.type() == ExprCoreType.STRING) { |
634 | startingDateTime = exprDateTimeNoTimezone(startingDateTime); | |
635 | } | |
636 | try { | |
637 | ZoneId convertedFromTz = ZoneId.of(fromTz.stringValue()); | |
638 | ZoneId convertedToTz = ZoneId.of(toTz.stringValue()); | |
639 | ||
640 | // isValidMySqlTimeZoneId checks if the timezone is within the range accepted by | |
641 | // MySQL standard. | |
642 |
1
1. exprConvertTZ : negated conditional → KILLED |
if (!DateTimeUtils.isValidMySqlTimeZoneId(convertedFromTz) |
643 |
1
1. exprConvertTZ : negated conditional → KILLED |
|| !DateTimeUtils.isValidMySqlTimeZoneId(convertedToTz)) { |
644 |
1
1. exprConvertTZ : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprConvertTZ → KILLED |
return ExprNullValue.of(); |
645 | } | |
646 | ZonedDateTime zonedDateTime = | |
647 | startingDateTime.datetimeValue().atZone(convertedFromTz); | |
648 |
1
1. exprConvertTZ : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprConvertTZ → KILLED |
return new ExprDatetimeValue( |
649 | zonedDateTime.withZoneSameInstant(convertedToTz).toLocalDateTime()); | |
650 | ||
651 | ||
652 | // Catches exception for invalid timezones. | |
653 | // ex. "+0:00" is an invalid timezone and would result in this exception being thrown. | |
654 | } catch (ExpressionEvaluationException | DateTimeException e) { | |
655 |
1
1. exprConvertTZ : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprConvertTZ → KILLED |
return ExprNullValue.of(); |
656 | } | |
657 | } | |
658 | ||
659 | /** | |
660 | * Date implementation for ExprValue. | |
661 | * | |
662 | * @param exprValue ExprValue of Date type or String type. | |
663 | * @return ExprValue. | |
664 | */ | |
665 | private ExprValue exprDate(ExprValue exprValue) { | |
666 |
1
1. exprDate : negated conditional → KILLED |
if (exprValue instanceof ExprStringValue) { |
667 |
1
1. exprDate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDate → KILLED |
return new ExprDateValue(exprValue.stringValue()); |
668 | } else { | |
669 |
1
1. exprDate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDate → KILLED |
return new ExprDateValue(exprValue.dateValue()); |
670 | } | |
671 | } | |
672 | ||
673 | /** | |
674 | * DateTime implementation for ExprValue. | |
675 | * | |
676 | * @param dateTime ExprValue of String type. | |
677 | * @param timeZone ExprValue of String type (or null). | |
678 | * @return ExprValue of date type. | |
679 | */ | |
680 | private ExprValue exprDateTime(ExprValue dateTime, ExprValue timeZone) { | |
681 | String defaultTimeZone = TimeZone.getDefault().getID(); | |
682 | ||
683 | ||
684 | try { | |
685 | LocalDateTime ldtFormatted = | |
686 | LocalDateTime.parse(dateTime.stringValue(), DATE_TIME_FORMATTER_STRICT_WITH_TZ); | |
687 |
1
1. exprDateTime : negated conditional → KILLED |
if (timeZone.isNull()) { |
688 |
1
1. exprDateTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDateTime → KILLED |
return new ExprDatetimeValue(ldtFormatted); |
689 | } | |
690 | ||
691 | // Used if datetime field is invalid format. | |
692 | } catch (DateTimeParseException e) { | |
693 |
1
1. exprDateTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDateTime → KILLED |
return ExprNullValue.of(); |
694 | } | |
695 | ||
696 | ExprValue convertTZResult; | |
697 | ExprDatetimeValue ldt; | |
698 | String toTz; | |
699 | ||
700 | try { | |
701 | ZonedDateTime zdtWithZoneOffset = | |
702 | ZonedDateTime.parse(dateTime.stringValue(), DATE_TIME_FORMATTER_STRICT_WITH_TZ); | |
703 | ZoneId fromTZ = zdtWithZoneOffset.getZone(); | |
704 | ||
705 | ldt = new ExprDatetimeValue(zdtWithZoneOffset.toLocalDateTime()); | |
706 | toTz = String.valueOf(fromTZ); | |
707 | } catch (DateTimeParseException e) { | |
708 | ldt = new ExprDatetimeValue(dateTime.stringValue()); | |
709 | toTz = defaultTimeZone; | |
710 | } | |
711 | convertTZResult = exprConvertTZ( | |
712 | ldt, | |
713 | new ExprStringValue(toTz), | |
714 | timeZone); | |
715 | ||
716 |
1
1. exprDateTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDateTime → KILLED |
return convertTZResult; |
717 | } | |
718 | ||
719 | /** | |
720 | * DateTime implementation for ExprValue without a timezone to convert to. | |
721 | * | |
722 | * @param dateTime ExprValue of String type. | |
723 | * @return ExprValue of date type. | |
724 | */ | |
725 | private ExprValue exprDateTimeNoTimezone(ExprValue dateTime) { | |
726 |
1
1. exprDateTimeNoTimezone : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDateTimeNoTimezone → KILLED |
return exprDateTime(dateTime, ExprNullValue.of()); |
727 | } | |
728 | ||
729 | /** | |
730 | * Name of the Weekday implementation for ExprValue. | |
731 | * | |
732 | * @param date ExprValue of Date/String type. | |
733 | * @return ExprValue. | |
734 | */ | |
735 | private ExprValue exprDayName(ExprValue date) { | |
736 |
1
1. exprDayName : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDayName → KILLED |
return new ExprStringValue( |
737 | date.dateValue().getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault())); | |
738 | } | |
739 | ||
740 | /** | |
741 | * Day of Month implementation for ExprValue. | |
742 | * | |
743 | * @param date ExprValue of Date/String type. | |
744 | * @return ExprValue. | |
745 | */ | |
746 | private ExprValue exprDayOfMonth(ExprValue date) { | |
747 |
1
1. exprDayOfMonth : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDayOfMonth → KILLED |
return new ExprIntegerValue(date.dateValue().getDayOfMonth()); |
748 | } | |
749 | ||
750 | /** | |
751 | * Day of Week implementation for ExprValue. | |
752 | * | |
753 | * @param date ExprValue of Date/String type. | |
754 | * @return ExprValue. | |
755 | */ | |
756 | private ExprValue exprDayOfWeek(ExprValue date) { | |
757 |
3
1. exprDayOfWeek : Replaced integer modulus with multiplication → KILLED 2. exprDayOfWeek : Replaced integer addition with subtraction → KILLED 3. exprDayOfWeek : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDayOfWeek → KILLED |
return new ExprIntegerValue((date.dateValue().getDayOfWeek().getValue() % 7) + 1); |
758 | } | |
759 | ||
760 | /** | |
761 | * Day of Year implementation for ExprValue. | |
762 | * | |
763 | * @param date ExprValue of Date/String type. | |
764 | * @return ExprValue. | |
765 | */ | |
766 | private ExprValue exprDayOfYear(ExprValue date) { | |
767 |
1
1. exprDayOfYear : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprDayOfYear → KILLED |
return new ExprIntegerValue(date.dateValue().getDayOfYear()); |
768 | } | |
769 | ||
770 | /** | |
771 | * From_days implementation for ExprValue. | |
772 | * | |
773 | * @param exprValue Day number N. | |
774 | * @return ExprValue. | |
775 | */ | |
776 | private ExprValue exprFromDays(ExprValue exprValue) { | |
777 |
2
1. exprFromDays : Replaced long subtraction with addition → KILLED 2. exprFromDays : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromDays → KILLED |
return new ExprDateValue(LocalDate.ofEpochDay(exprValue.longValue() - DAYS_0000_TO_1970)); |
778 | } | |
779 | ||
780 | private ExprValue exprFromUnixTime(ExprValue time) { | |
781 |
2
1. exprFromUnixTime : changed conditional boundary → KILLED 2. exprFromUnixTime : negated conditional → KILLED |
if (0 > time.doubleValue()) { |
782 |
1
1. exprFromUnixTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTime → KILLED |
return ExprNullValue.of(); |
783 | } | |
784 | // According to MySQL documentation: | |
785 | // effective maximum is 32536771199.999999, which returns '3001-01-18 23:59:59.999999' UTC. | |
786 | // Regardless of platform or version, a greater value for first argument than the effective | |
787 | // maximum returns 0. | |
788 |
2
1. exprFromUnixTime : changed conditional boundary → KILLED 2. exprFromUnixTime : negated conditional → KILLED |
if (MYSQL_MAX_TIMESTAMP <= time.doubleValue()) { |
789 |
1
1. exprFromUnixTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTime → KILLED |
return ExprNullValue.of(); |
790 | } | |
791 |
1
1. exprFromUnixTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTime → KILLED |
return new ExprDatetimeValue(exprFromUnixTimeImpl(time)); |
792 | } | |
793 | ||
794 | private LocalDateTime exprFromUnixTimeImpl(ExprValue time) { | |
795 |
1
1. exprFromUnixTimeImpl : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTimeImpl → KILLED |
return LocalDateTime.ofInstant( |
796 | Instant.ofEpochSecond((long)Math.floor(time.doubleValue())), | |
797 | ZoneId.of("UTC")) | |
798 |
2
1. exprFromUnixTimeImpl : Replaced double modulus with multiplication → KILLED 2. exprFromUnixTimeImpl : Replaced double multiplication with division → KILLED |
.withNano((int)((time.doubleValue() % 1) * 1E9)); |
799 | } | |
800 | ||
801 | private ExprValue exprFromUnixTimeFormat(ExprValue time, ExprValue format) { | |
802 | var value = exprFromUnixTime(time); | |
803 |
1
1. exprFromUnixTimeFormat : negated conditional → KILLED |
if (value.equals(ExprNullValue.of())) { |
804 |
1
1. exprFromUnixTimeFormat : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTimeFormat → KILLED |
return ExprNullValue.of(); |
805 | } | |
806 |
1
1. exprFromUnixTimeFormat : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprFromUnixTimeFormat → KILLED |
return DateTimeFormatterUtil.getFormattedDate(value, format); |
807 | } | |
808 | ||
809 | /** | |
810 | * Hour implementation for ExprValue. | |
811 | * | |
812 | * @param time ExprValue of Time/String type. | |
813 | * @return ExprValue. | |
814 | */ | |
815 | private ExprValue exprHour(ExprValue time) { | |
816 |
1
1. exprHour : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprHour → KILLED |
return new ExprIntegerValue(time.timeValue().getHour()); |
817 | } | |
818 | ||
819 | /** | |
820 | * Following MySQL, function receives arguments of type double and rounds them before use. | |
821 | * Furthermore: | |
822 | * - zero year interpreted as 2000 | |
823 | * - negative year is not accepted | |
824 | * - @dayOfYear should be greater than 1 | |
825 | * - if @dayOfYear is greater than 365/366, calculation goes to the next year(s) | |
826 | * | |
827 | * @param yearExpr year | |
828 | * @param dayOfYearExp day of the @year, starting from 1 | |
829 | * @return Date - ExprDateValue object with LocalDate | |
830 | */ | |
831 | private ExprValue exprMakeDate(ExprValue yearExpr, ExprValue dayOfYearExp) { | |
832 | var year = Math.round(yearExpr.doubleValue()); | |
833 | var dayOfYear = Math.round(dayOfYearExp.doubleValue()); | |
834 | // We need to do this to comply with MySQL | |
835 |
4
1. exprMakeDate : changed conditional boundary → KILLED 2. exprMakeDate : changed conditional boundary → KILLED 3. exprMakeDate : negated conditional → KILLED 4. exprMakeDate : negated conditional → KILLED |
if (0 >= dayOfYear || 0 > year) { |
836 |
1
1. exprMakeDate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMakeDate → KILLED |
return ExprNullValue.of(); |
837 | } | |
838 |
1
1. exprMakeDate : negated conditional → KILLED |
if (0 == year) { |
839 | year = 2000; | |
840 | } | |
841 |
2
1. exprMakeDate : Replaced long subtraction with addition → KILLED 2. exprMakeDate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMakeDate → KILLED |
return new ExprDateValue(LocalDate.ofYearDay((int)year, 1).plusDays(dayOfYear - 1)); |
842 | } | |
843 | ||
844 | /** | |
845 | * Following MySQL, function receives arguments of type double. @hour and @minute are rounded, | |
846 | * while @second used as is, including fraction part. | |
847 | * @param hourExpr hour | |
848 | * @param minuteExpr minute | |
849 | * @param secondExpr second | |
850 | * @return Time - ExprTimeValue object with LocalTime | |
851 | */ | |
852 | private ExprValue exprMakeTime(ExprValue hourExpr, ExprValue minuteExpr, ExprValue secondExpr) { | |
853 | var hour = Math.round(hourExpr.doubleValue()); | |
854 | var minute = Math.round(minuteExpr.doubleValue()); | |
855 | var second = secondExpr.doubleValue(); | |
856 |
6
1. exprMakeTime : changed conditional boundary → KILLED 2. exprMakeTime : changed conditional boundary → KILLED 3. exprMakeTime : changed conditional boundary → KILLED 4. exprMakeTime : negated conditional → KILLED 5. exprMakeTime : negated conditional → KILLED 6. exprMakeTime : negated conditional → KILLED |
if (0 > hour || 0 > minute || 0 > second) { |
857 |
1
1. exprMakeTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMakeTime → KILLED |
return ExprNullValue.of(); |
858 | } | |
859 |
1
1. exprMakeTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMakeTime → KILLED |
return new ExprTimeValue(LocalTime.parse(String.format("%02d:%02d:%012.9f", |
860 | hour, minute, second), DateTimeFormatter.ISO_TIME)); | |
861 | } | |
862 | ||
863 | /** | |
864 | * Microsecond implementation for ExprValue. | |
865 | * | |
866 | * @param time ExprValue of Time/String type. | |
867 | * @return ExprValue. | |
868 | */ | |
869 | private ExprValue exprMicrosecond(ExprValue time) { | |
870 |
1
1. exprMicrosecond : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMicrosecond → KILLED |
return new ExprIntegerValue( |
871 | TimeUnit.MICROSECONDS.convert(time.timeValue().getNano(), TimeUnit.NANOSECONDS)); | |
872 | } | |
873 | ||
874 | /** | |
875 | * Minute implementation for ExprValue. | |
876 | * | |
877 | * @param time ExprValue of Time/String type. | |
878 | * @return ExprValue. | |
879 | */ | |
880 | private ExprValue exprMinute(ExprValue time) { | |
881 |
1
1. exprMinute : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMinute → KILLED |
return new ExprIntegerValue(time.timeValue().getMinute()); |
882 | } | |
883 | ||
884 | /** | |
885 | * Month for date implementation for ExprValue. | |
886 | * | |
887 | * @param date ExprValue of Date/String type. | |
888 | * @return ExprValue. | |
889 | */ | |
890 | private ExprValue exprMonth(ExprValue date) { | |
891 |
1
1. exprMonth : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMonth → KILLED |
return new ExprIntegerValue(date.dateValue().getMonthValue()); |
892 | } | |
893 | ||
894 | /** | |
895 | * Name of the Month implementation for ExprValue. | |
896 | * | |
897 | * @param date ExprValue of Date/String type. | |
898 | * @return ExprValue. | |
899 | */ | |
900 | private ExprValue exprMonthName(ExprValue date) { | |
901 |
1
1. exprMonthName : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprMonthName → KILLED |
return new ExprStringValue( |
902 | date.dateValue().getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault())); | |
903 | } | |
904 | ||
905 | private LocalDate parseDatePeriod(Integer period) { | |
906 | var input = period.toString(); | |
907 | // MySQL undocumented: if year is not specified or has 1 digit - 2000/200x is assumed | |
908 |
2
1. parseDatePeriod : changed conditional boundary → KILLED 2. parseDatePeriod : negated conditional → KILLED |
if (input.length() <= 5) { |
909 | input = String.format("200%05d", period); | |
910 | } | |
911 | try { | |
912 |
1
1. parseDatePeriod : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::parseDatePeriod → KILLED |
return LocalDate.parse(input, DATE_FORMATTER_SHORT_YEAR); |
913 | } catch (DateTimeParseException ignored) { | |
914 | // nothing to do, try another format | |
915 | } | |
916 | try { | |
917 |
1
1. parseDatePeriod : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::parseDatePeriod → KILLED |
return LocalDate.parse(input, DATE_FORMATTER_LONG_YEAR); |
918 | } catch (DateTimeParseException ignored) { | |
919 | return null; | |
920 | } | |
921 | } | |
922 | ||
923 | /** | |
924 | * Adds N months to period P (in the format YYMM or YYYYMM). | |
925 | * Returns a value in the format YYYYMM. | |
926 | * | |
927 | * @param period Period in the format YYMM or YYYYMM. | |
928 | * @param months Amount of months to add. | |
929 | * @return ExprIntegerValue. | |
930 | */ | |
931 | private ExprValue exprPeriodAdd(ExprValue period, ExprValue months) { | |
932 | // We should add a day to make string parsable and remove it afterwards | |
933 |
2
1. exprPeriodAdd : Replaced integer multiplication with division → KILLED 2. exprPeriodAdd : Replaced integer addition with subtraction → KILLED |
var input = period.integerValue() * 100 + 1; // adds 01 to end of the string |
934 | var parsedDate = parseDatePeriod(input); | |
935 |
1
1. exprPeriodAdd : negated conditional → KILLED |
if (parsedDate == null) { |
936 |
1
1. exprPeriodAdd : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprPeriodAdd → KILLED |
return ExprNullValue.of(); |
937 | } | |
938 | var res = DATE_FORMATTER_LONG_YEAR.format(parsedDate.plusMonths(months.integerValue())); | |
939 |
1
1. exprPeriodAdd : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprPeriodAdd → KILLED |
return new ExprIntegerValue(Integer.parseInt( |
940 |
1
1. exprPeriodAdd : Replaced integer subtraction with addition → KILLED |
res.substring(0, res.length() - 2))); // Remove the day part, .eg. 20070101 -> 200701 |
941 | } | |
942 | ||
943 | /** | |
944 | * Returns the number of months between periods P1 and P2. | |
945 | * P1 and P2 should be in the format YYMM or YYYYMM. | |
946 | * | |
947 | * @param period1 Period in the format YYMM or YYYYMM. | |
948 | * @param period2 Period in the format YYMM or YYYYMM. | |
949 | * @return ExprIntegerValue. | |
950 | */ | |
951 | private ExprValue exprPeriodDiff(ExprValue period1, ExprValue period2) { | |
952 |
2
1. exprPeriodDiff : Replaced integer multiplication with division → KILLED 2. exprPeriodDiff : Replaced integer addition with subtraction → KILLED |
var parsedDate1 = parseDatePeriod(period1.integerValue() * 100 + 1); |
953 |
2
1. exprPeriodDiff : Replaced integer multiplication with division → KILLED 2. exprPeriodDiff : Replaced integer addition with subtraction → KILLED |
var parsedDate2 = parseDatePeriod(period2.integerValue() * 100 + 1); |
954 |
2
1. exprPeriodDiff : negated conditional → KILLED 2. exprPeriodDiff : negated conditional → KILLED |
if (parsedDate1 == null || parsedDate2 == null) { |
955 |
1
1. exprPeriodDiff : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprPeriodDiff → KILLED |
return ExprNullValue.of(); |
956 | } | |
957 |
1
1. exprPeriodDiff : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprPeriodDiff → KILLED |
return new ExprIntegerValue(MONTHS.between(parsedDate2, parsedDate1)); |
958 | } | |
959 | ||
960 | /** | |
961 | * Quarter for date implementation for ExprValue. | |
962 | * | |
963 | * @param date ExprValue of Date/String type. | |
964 | * @return ExprValue. | |
965 | */ | |
966 | private ExprValue exprQuarter(ExprValue date) { | |
967 | int month = date.dateValue().getMonthValue(); | |
968 |
5
1. exprQuarter : Replaced integer division with multiplication → KILLED 2. exprQuarter : Replaced integer modulus with multiplication → KILLED 3. exprQuarter : Replaced integer addition with subtraction → KILLED 4. exprQuarter : negated conditional → KILLED 5. exprQuarter : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprQuarter → KILLED |
return new ExprIntegerValue((month / 3) + ((month % 3) == 0 ? 0 : 1)); |
969 | } | |
970 | ||
971 | /** | |
972 | * Second implementation for ExprValue. | |
973 | * | |
974 | * @param time ExprValue of Time/String type. | |
975 | * @return ExprValue. | |
976 | */ | |
977 | private ExprValue exprSecond(ExprValue time) { | |
978 |
1
1. exprSecond : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprSecond → KILLED |
return new ExprIntegerValue(time.timeValue().getSecond()); |
979 | } | |
980 | ||
981 | /** | |
982 | * SUBDATE function implementation for ExprValue. | |
983 | * | |
984 | * @param date ExprValue of String/Date/Datetime/Timestamp type. | |
985 | * @param days ExprValue of Long type, representing the number of days to subtract. | |
986 | * @return Date/Datetime resulted from days subtracted to date. | |
987 | */ | |
988 | private ExprValue exprSubDateDays(ExprValue date, ExprValue days) { | |
989 | ExprValue exprValue = new ExprDatetimeValue(date.datetimeValue().minusDays(days.longValue())); | |
990 |
2
1. exprSubDateDays : negated conditional → KILLED 2. exprSubDateDays : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprSubDateDays → KILLED |
return (exprValue.timeValue().toSecondOfDay() == 0 ? new ExprDateValue(exprValue.dateValue()) |
991 | : exprValue); | |
992 | } | |
993 | ||
994 | /** | |
995 | * SUBDATE function implementation for ExprValue. | |
996 | * | |
997 | * @param date ExprValue of String/Date/Datetime/Timestamp type. | |
998 | * @param expr ExprValue of Interval type, the temporal amount to subtract. | |
999 | * @return Datetime resulted from expr subtracted to date. | |
1000 | */ | |
1001 | private ExprValue exprSubDateInterval(ExprValue date, ExprValue expr) { | |
1002 | ExprValue exprValue = new ExprDatetimeValue(date.datetimeValue().minus(expr.intervalValue())); | |
1003 |
2
1. exprSubDateInterval : negated conditional → KILLED 2. exprSubDateInterval : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprSubDateInterval → KILLED |
return (exprValue.timeValue().toSecondOfDay() == 0 ? new ExprDateValue(exprValue.dateValue()) |
1004 | : exprValue); | |
1005 | } | |
1006 | ||
1007 | /** | |
1008 | * SYSDATE() returns the time at which it executes. | |
1009 | */ | |
1010 | private DefaultFunctionResolver sysdate() { | |
1011 |
1
1. sysdate : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::sysdate → KILLED |
return define(BuiltinFunctionName.SYSDATE.getName(), |
1012 |
1
1. lambda$sysdate$19cc14d4$1 : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::lambda$sysdate$19cc14d4$1 → KILLED |
impl(() -> new ExprDatetimeValue(formatNow(null)), DATETIME), |
1013 |
1
1. lambda$sysdate$12c7dc48$1 : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::lambda$sysdate$12c7dc48$1 → KILLED |
impl((v) -> new ExprDatetimeValue(formatNow(v.integerValue())), DATETIME, INTEGER) |
1014 | ); | |
1015 | } | |
1016 | ||
1017 | /** | |
1018 | * Time implementation for ExprValue. | |
1019 | * | |
1020 | * @param exprValue ExprValue of Time type or String. | |
1021 | * @return ExprValue. | |
1022 | */ | |
1023 | private ExprValue exprTime(ExprValue exprValue) { | |
1024 |
1
1. exprTime : negated conditional → KILLED |
if (exprValue instanceof ExprStringValue) { |
1025 |
1
1. exprTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprTime → KILLED |
return new ExprTimeValue(exprValue.stringValue()); |
1026 | } else { | |
1027 |
1
1. exprTime : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprTime → KILLED |
return new ExprTimeValue(exprValue.timeValue()); |
1028 | } | |
1029 | } | |
1030 | ||
1031 | /** | |
1032 | * Timestamp implementation for ExprValue. | |
1033 | * | |
1034 | * @param exprValue ExprValue of Timestamp type or String type. | |
1035 | * @return ExprValue. | |
1036 | */ | |
1037 | private ExprValue exprTimestamp(ExprValue exprValue) { | |
1038 |
1
1. exprTimestamp : negated conditional → KILLED |
if (exprValue instanceof ExprStringValue) { |
1039 |
1
1. exprTimestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprTimestamp → KILLED |
return new ExprTimestampValue(exprValue.stringValue()); |
1040 | } else { | |
1041 |
1
1. exprTimestamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprTimestamp → KILLED |
return new ExprTimestampValue(exprValue.timestampValue()); |
1042 | } | |
1043 | } | |
1044 | ||
1045 | /** | |
1046 | * Time To Sec implementation for ExprValue. | |
1047 | * | |
1048 | * @param time ExprValue of Time/String type. | |
1049 | * @return ExprValue. | |
1050 | */ | |
1051 | private ExprValue exprTimeToSec(ExprValue time) { | |
1052 |
1
1. exprTimeToSec : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprTimeToSec → KILLED |
return new ExprLongValue(time.timeValue().toSecondOfDay()); |
1053 | } | |
1054 | ||
1055 | /** | |
1056 | * To_days implementation for ExprValue. | |
1057 | * | |
1058 | * @param date ExprValue of Date/String type. | |
1059 | * @return ExprValue. | |
1060 | */ | |
1061 | private ExprValue exprToDays(ExprValue date) { | |
1062 |
2
1. exprToDays : Replaced long addition with subtraction → KILLED 2. exprToDays : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprToDays → KILLED |
return new ExprLongValue(date.dateValue().toEpochDay() + DAYS_0000_TO_1970); |
1063 | } | |
1064 | ||
1065 | /** | |
1066 | * Week for date implementation for ExprValue. | |
1067 | * | |
1068 | * @param date ExprValue of Date/Datetime/Timestamp/String type. | |
1069 | * @param mode ExprValue of Integer type. | |
1070 | */ | |
1071 | private ExprValue exprWeek(ExprValue date, ExprValue mode) { | |
1072 |
1
1. exprWeek : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprWeek → KILLED |
return new ExprIntegerValue( |
1073 | CalendarLookup.getWeekNumber(mode.integerValue(), date.dateValue())); | |
1074 | } | |
1075 | ||
1076 | private ExprValue unixTimeStamp() { | |
1077 |
1
1. unixTimeStamp : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStamp → KILLED |
return new ExprLongValue(Instant.now().getEpochSecond()); |
1078 | } | |
1079 | ||
1080 | private ExprValue unixTimeStampOf(ExprValue value) { | |
1081 | var res = unixTimeStampOfImpl(value); | |
1082 |
1
1. unixTimeStampOf : negated conditional → KILLED |
if (res == null) { |
1083 |
1
1. unixTimeStampOf : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOf → KILLED |
return ExprNullValue.of(); |
1084 | } | |
1085 |
2
1. unixTimeStampOf : changed conditional boundary → SURVIVED 2. unixTimeStampOf : negated conditional → KILLED |
if (res < 0) { |
1086 | // According to MySQL returns 0 if year < 1970, don't return negative values as java does. | |
1087 |
1
1. unixTimeStampOf : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOf → KILLED |
return new ExprDoubleValue(0); |
1088 | } | |
1089 |
2
1. unixTimeStampOf : changed conditional boundary → KILLED 2. unixTimeStampOf : negated conditional → KILLED |
if (res >= MYSQL_MAX_TIMESTAMP) { |
1090 | // Return 0 also for dates > '3001-01-19 03:14:07.999999' UTC (32536771199.999999 sec) | |
1091 |
1
1. unixTimeStampOf : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOf → KILLED |
return new ExprDoubleValue(0); |
1092 | } | |
1093 |
1
1. unixTimeStampOf : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOf → KILLED |
return new ExprDoubleValue(res); |
1094 | } | |
1095 | ||
1096 | private Double unixTimeStampOfImpl(ExprValue value) { | |
1097 | // Also, according to MySQL documentation: | |
1098 | // The date argument may be a DATE, DATETIME, or TIMESTAMP ... | |
1099 | switch ((ExprCoreType)value.type()) { | |
1100 |
2
1. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED 2. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
case DATE: return value.dateValue().toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + 0d; |
1101 |
1
1. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
case DATETIME: return value.datetimeValue().toEpochSecond(ZoneOffset.UTC) |
1102 |
2
1. unixTimeStampOfImpl : Replaced double division with multiplication → KILLED 2. unixTimeStampOfImpl : Replaced double addition with subtraction → KILLED |
+ value.datetimeValue().getNano() / 1E9; |
1103 |
1
1. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
case TIMESTAMP: return value.timestampValue().getEpochSecond() |
1104 |
2
1. unixTimeStampOfImpl : Replaced double division with multiplication → SURVIVED 2. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED |
+ value.timestampValue().getNano() / 1E9; |
1105 | default: | |
1106 | // ... or a number in YYMMDD, YYMMDDhhmmss, YYYYMMDD, or YYYYMMDDhhmmss format. | |
1107 | // If the argument includes a time part, it may optionally include a fractional | |
1108 | // seconds part. | |
1109 | ||
1110 | var format = new DecimalFormat("0.#"); | |
1111 |
1
1. unixTimeStampOfImpl : removed call to java/text/DecimalFormat::setMinimumFractionDigits → SURVIVED |
format.setMinimumFractionDigits(0); |
1112 |
1
1. unixTimeStampOfImpl : removed call to java/text/DecimalFormat::setMaximumFractionDigits → KILLED |
format.setMaximumFractionDigits(6); |
1113 | String input = format.format(value.doubleValue()); | |
1114 | double fraction = 0; | |
1115 |
1
1. unixTimeStampOfImpl : negated conditional → KILLED |
if (input.contains(".")) { |
1116 | // Keeping fraction second part and adding it to the result, don't parse it | |
1117 | // Because `toEpochSecond` returns only `long` | |
1118 | // input = 12345.6789 becomes input = 12345 and fraction = 0.6789 | |
1119 |
1
1. unixTimeStampOfImpl : Replaced double subtraction with addition → KILLED |
fraction = value.doubleValue() - Math.round(Math.ceil(value.doubleValue())); |
1120 | input = input.substring(0, input.indexOf('.')); | |
1121 | } | |
1122 | try { | |
1123 | var res = LocalDateTime.parse(input, DATE_TIME_FORMATTER_SHORT_YEAR); | |
1124 |
2
1. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED 2. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
return res.toEpochSecond(ZoneOffset.UTC) + fraction; |
1125 | } catch (DateTimeParseException ignored) { | |
1126 | // nothing to do, try another format | |
1127 | } | |
1128 | try { | |
1129 | var res = LocalDateTime.parse(input, DATE_TIME_FORMATTER_LONG_YEAR); | |
1130 |
2
1. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED 2. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
return res.toEpochSecond(ZoneOffset.UTC) + fraction; |
1131 | } catch (DateTimeParseException ignored) { | |
1132 | // nothing to do, try another format | |
1133 | } | |
1134 | try { | |
1135 | var res = LocalDate.parse(input, DATE_FORMATTER_SHORT_YEAR); | |
1136 |
2
1. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED 2. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
return res.toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + 0d; |
1137 | } catch (DateTimeParseException ignored) { | |
1138 | // nothing to do, try another format | |
1139 | } | |
1140 | try { | |
1141 | var res = LocalDate.parse(input, DATE_FORMATTER_LONG_YEAR); | |
1142 |
2
1. unixTimeStampOfImpl : Replaced double addition with subtraction → SURVIVED 2. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
return res.toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + 0d; |
1143 | } catch (DateTimeParseException ignored) { | |
1144 |
1
1. unixTimeStampOfImpl : replaced Double return value with 0 for org/opensearch/sql/expression/datetime/DateTimeFunction::unixTimeStampOfImpl → KILLED |
return null; |
1145 | } | |
1146 | } | |
1147 | } | |
1148 | ||
1149 | /** | |
1150 | * Week for date implementation for ExprValue. | |
1151 | * When mode is not specified default value mode 0 is used for default_week_format. | |
1152 | * | |
1153 | * @param date ExprValue of Date/Datetime/Timestamp/String type. | |
1154 | * @return ExprValue. | |
1155 | */ | |
1156 | private ExprValue exprWeekWithoutMode(ExprValue date) { | |
1157 |
1
1. exprWeekWithoutMode : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprWeekWithoutMode → KILLED |
return exprWeek(date, new ExprIntegerValue(0)); |
1158 | } | |
1159 | ||
1160 | /** | |
1161 | * Year for date implementation for ExprValue. | |
1162 | * | |
1163 | * @param date ExprValue of Date/String type. | |
1164 | * @return ExprValue. | |
1165 | */ | |
1166 | private ExprValue exprYear(ExprValue date) { | |
1167 |
1
1. exprYear : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::exprYear → KILLED |
return new ExprIntegerValue(date.dateValue().getYear()); |
1168 | } | |
1169 | ||
1170 | /** | |
1171 | * Prepare LocalDateTime value. Truncate fractional second part according to the argument. | |
1172 | * @param fsp argument is given to specify a fractional seconds precision from 0 to 6, | |
1173 | * the return value includes a fractional seconds part of that many digits. | |
1174 | * @return LocalDateTime object. | |
1175 | */ | |
1176 | private LocalDateTime formatNow(@Nullable Integer fsp) { | |
1177 | var res = LocalDateTime.now(); | |
1178 |
1
1. formatNow : negated conditional → KILLED |
if (fsp == null) { |
1179 | fsp = 0; | |
1180 | } | |
1181 | var defaultPrecision = 9; // There are 10^9 nanoseconds in one second | |
1182 |
4
1. formatNow : changed conditional boundary → SURVIVED 2. formatNow : changed conditional boundary → KILLED 3. formatNow : negated conditional → KILLED 4. formatNow : negated conditional → KILLED |
if (fsp < 0 || fsp > 6) { // Check that the argument is in the allowed range [0, 6] |
1183 | throw new IllegalArgumentException( | |
1184 | String.format("Invalid `fsp` value: %d, allowed 0 to 6", fsp)); | |
1185 | } | |
1186 | var nano = new BigDecimal(res.getNano()) | |
1187 |
1
1. formatNow : Replaced integer subtraction with addition → SURVIVED |
.setScale(fsp - defaultPrecision, RoundingMode.DOWN).intValue(); |
1188 |
1
1. formatNow : replaced return value with null for org/opensearch/sql/expression/datetime/DateTimeFunction::formatNow → KILLED |
return res.withNano(nano); |
1189 | } | |
1190 | } | |
Mutations | ||
87 |
1.1 |
|
88 |
1.1 |
|
89 |
1.1 |
|
90 |
1.1 |
|
91 |
1.1 |
|
92 |
1.1 |
|
93 |
1.1 |
|
94 |
1.1 |
|
95 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
98 |
1.1 |
|
99 |
1.1 |
|
100 |
1.1 |
|
101 |
1.1 |
|
102 |
1.1 |
|
103 |
1.1 |
|
104 |
1.1 |
|
105 |
1.1 |
|
106 |
1.1 |
|
107 |
1.1 |
|
108 |
1.1 |
|
109 |
1.1 |
|
110 |
1.1 |
|
111 |
1.1 |
|
112 |
1.1 |
|
113 |
1.1 |
|
114 |
1.1 |
|
115 |
1.1 |
|
116 |
1.1 |
|
117 |
1.1 |
|
118 |
1.1 |
|
119 |
1.1 |
|
120 |
1.1 |
|
121 |
1.1 |
|
122 |
1.1 |
|
123 |
1.1 |
|
124 |
1.1 |
|
125 |
1.1 |
|
126 |
1.1 |
|
127 |
1.1 |
|
128 |
1.1 |
|
139 |
1.1 |
|
155 |
1.1 |
|
165 |
1.1 |
|
174 |
1.1 |
|
175 |
1.1 |
|
180 |
1.1 |
|
187 |
1.1 |
|
188 |
1.1 |
|
193 |
1.1 |
|
197 |
1.1 |
|
201 |
1.1 |
|
205 |
1.1 |
|
214 |
1.1 |
|
228 |
1.1 |
|
237 |
1.1 |
|
248 |
1.1 |
|
264 |
1.1 |
|
271 |
1.1 |
|
285 |
1.1 |
|
297 |
1.1 |
|
310 |
1.1 |
|
323 |
1.1 |
|
335 |
1.1 |
|
340 |
1.1 |
|
350 |
1.1 |
|
359 |
1.1 |
|
363 |
1.1 |
|
372 |
1.1 |
|
373 |
1.1 |
|
378 |
1.1 |
|
382 |
1.1 |
|
387 |
1.1 |
|
395 |
1.1 |
|
407 |
1.1 |
|
419 |
1.1 |
|
431 |
1.1 |
|
444 |
1.1 |
|
455 |
1.1 |
|
464 |
1.1 |
|
476 |
1.1 |
|
485 |
1.1 |
|
494 |
1.1 |
|
506 |
1.1 |
|
520 |
1.1 |
|
531 |
1.1 |
|
539 |
1.1 |
|
552 |
1.1 |
|
568 |
1.1 |
|
585 |
1.1 |
|
606 |
1.1 2.2 |
|
619 |
1.1 2.2 |
|
633 |
1.1 |
|
642 |
1.1 |
|
643 |
1.1 |
|
644 |
1.1 |
|
648 |
1.1 |
|
655 |
1.1 |
|
666 |
1.1 |
|
667 |
1.1 |
|
669 |
1.1 |
|
687 |
1.1 |
|
688 |
1.1 |
|
693 |
1.1 |
|
716 |
1.1 |
|
726 |
1.1 |
|
736 |
1.1 |
|
747 |
1.1 |
|
757 |
1.1 2.2 3.3 |
|
767 |
1.1 |
|
777 |
1.1 2.2 |
|
781 |
1.1 2.2 |
|
782 |
1.1 |
|
788 |
1.1 2.2 |
|
789 |
1.1 |
|
791 |
1.1 |
|
795 |
1.1 |
|
798 |
1.1 2.2 |
|
803 |
1.1 |
|
804 |
1.1 |
|
806 |
1.1 |
|
816 |
1.1 |
|
835 |
1.1 2.2 3.3 4.4 |
|
836 |
1.1 |
|
838 |
1.1 |
|
841 |
1.1 2.2 |
|
856 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
857 |
1.1 |
|
859 |
1.1 |
|
870 |
1.1 |
|
881 |
1.1 |
|
891 |
1.1 |
|
901 |
1.1 |
|
908 |
1.1 2.2 |
|
912 |
1.1 |
|
917 |
1.1 |
|
933 |
1.1 2.2 |
|
935 |
1.1 |
|
936 |
1.1 |
|
939 |
1.1 |
|
940 |
1.1 |
|
952 |
1.1 2.2 |
|
953 |
1.1 2.2 |
|
954 |
1.1 2.2 |
|
955 |
1.1 |
|
957 |
1.1 |
|
968 |
1.1 2.2 3.3 4.4 5.5 |
|
978 |
1.1 |
|
990 |
1.1 2.2 |
|
1003 |
1.1 2.2 |
|
1011 |
1.1 |
|
1012 |
1.1 |
|
1013 |
1.1 |
|
1024 |
1.1 |
|
1025 |
1.1 |
|
1027 |
1.1 |
|
1038 |
1.1 |
|
1039 |
1.1 |
|
1041 |
1.1 |
|
1052 |
1.1 |
|
1062 |
1.1 2.2 |
|
1072 |
1.1 |
|
1077 |
1.1 |
|
1082 |
1.1 |
|
1083 |
1.1 |
|
1085 |
1.1 2.2 |
|
1087 |
1.1 |
|
1089 |
1.1 2.2 |
|
1091 |
1.1 |
|
1093 |
1.1 |
|
1100 |
1.1 2.2 |
|
1101 |
1.1 |
|
1102 |
1.1 2.2 |
|
1103 |
1.1 |
|
1104 |
1.1 2.2 |
|
1111 |
1.1 |
|
1112 |
1.1 |
|
1115 |
1.1 |
|
1119 |
1.1 |
|
1124 |
1.1 2.2 |
|
1130 |
1.1 2.2 |
|
1136 |
1.1 2.2 |
|
1142 |
1.1 2.2 |
|
1144 |
1.1 |
|
1157 |
1.1 |
|
1167 |
1.1 |
|
1178 |
1.1 |
|
1182 |
1.1 2.2 3.3 4.4 |
|
1187 |
1.1 |
|
1188 |
1.1 |