Skip to content

Commit a2f7a5b

Browse files
Fail with proper error on overflow in from_unixtime (#95)
The exception is due to the value user entered hence should be reported as a TrinoException rather than a GENERIC_INTERNAL_ERROR Co-authored-by: Athul T R <athultr1997@gmail.com>
1 parent d4977a7 commit a2f7a5b

2 files changed

Lines changed: 46 additions & 5 deletions

File tree

core/trino-main/src/main/java/io/trino/operator/scalar/DateTimeFunctions.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,12 @@ public static Slice currentTimeZone(ConnectorSession session)
127127
public static long fromUnixTime(ConnectorSession session, @SqlType(StandardTypes.DOUBLE) double unixTime)
128128
{
129129
// TODO (https://github.com/trinodb/trino/issues/5781)
130-
return packDateTimeWithZone(Math.round(unixTime * 1000), session.getTimeZoneKey());
130+
try {
131+
return packDateTimeWithZone(Math.round(unixTime * 1000), session.getTimeZoneKey());
132+
}
133+
catch (IllegalArgumentException e) {
134+
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
135+
}
131136
}
132137

133138
@ScalarFunction("from_unixtime")
@@ -137,19 +142,24 @@ public static long fromUnixTime(@SqlType(StandardTypes.DOUBLE) double unixTime,
137142
TimeZoneKey timeZoneKey;
138143
try {
139144
timeZoneKey = getTimeZoneKeyForOffset(toIntExact(hoursOffset * 60 + minutesOffset));
145+
return packDateTimeWithZone(Math.round(unixTime * 1000), timeZoneKey);
140146
}
141147
catch (IllegalArgumentException e) {
142148
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
143149
}
144-
return packDateTimeWithZone(Math.round(unixTime * 1000), timeZoneKey);
145150
}
146151

147152
@ScalarFunction("from_unixtime")
148153
@LiteralParameters("x")
149154
@SqlType("timestamp(3) with time zone")
150155
public static long fromUnixTime(@SqlType(StandardTypes.DOUBLE) double unixTime, @SqlType("varchar(x)") Slice zoneId)
151156
{
152-
return packDateTimeWithZone(Math.round(unixTime * 1000), zoneId.toStringUtf8());
157+
try {
158+
return packDateTimeWithZone(Math.round(unixTime * 1000), zoneId.toStringUtf8());
159+
}
160+
catch (IllegalArgumentException e) {
161+
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
162+
}
153163
}
154164

155165
@ScalarFunction("from_unixtime_nanos")
@@ -172,7 +182,12 @@ public static LongTimestampWithTimeZone fromLong(@LiteralParameter("s") long sca
172182
epochSeconds -= 1;
173183
picosOfSecond += PICOSECONDS_PER_SECOND;
174184
}
175-
return DateTimes.longTimestampWithTimeZone(epochSeconds, picosOfSecond, session.getTimeZoneKey().getZoneId());
185+
try {
186+
return DateTimes.longTimestampWithTimeZone(epochSeconds, picosOfSecond, session.getTimeZoneKey().getZoneId());
187+
}
188+
catch (ArithmeticException e) {
189+
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
190+
}
176191
}
177192

178193
@LiteralParameters({"p", "s"})
@@ -216,7 +231,12 @@ public static long fromISO8601Timestamp(ConnectorSession session, @SqlType("varc
216231
DateTimeFormatter formatter = ISODateTimeFormat.dateTimeParser()
217232
.withChronology(getChronology(session.getTimeZoneKey()))
218233
.withOffsetParsed();
219-
return packDateTimeWithZone(parseDateTimeHelper(formatter, iso8601DateTime.toStringUtf8()));
234+
try {
235+
return packDateTimeWithZone(parseDateTimeHelper(formatter, iso8601DateTime.toStringUtf8()));
236+
}
237+
catch (IllegalArgumentException e) {
238+
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
239+
}
220240
}
221241

222242
@ScalarFunction("from_iso8601_timestamp_nanos")

core/trino-main/src/test/java/io/trino/operator/scalar/TestDateTimeFunctions.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ public void testFromUnixTime()
128128

129129
assertThat(assertions.function("from_unixtime", "980172245.888"))
130130
.matches("TIMESTAMP '2001-01-22 03:04:05.888 Pacific/Apia'");
131+
132+
assertTrinoExceptionThrownBy(assertions.function("from_unixtime", "123456789123456789")::evaluate)
133+
.hasErrorCode(INVALID_FUNCTION_ARGUMENT)
134+
.hasMessage("Millis overflow: 9223372036854775807");
131135
}
132136

133137
@Test
@@ -195,6 +199,10 @@ public void testFromUnixTimeNanos()
195199

196200
assertThat(assertions.function("from_unixtime_nanos", "DECIMAL '-12345678900123456789.500'"))
197201
.matches("TIMESTAMP '1578-10-13 17:18:03.876543210 Pacific/Apia'");
202+
203+
assertTrinoExceptionThrownBy(assertions.function("from_unixtime_nanos", "DECIMAL '123456789123456789000000000'")::evaluate)
204+
.hasErrorCode(INVALID_FUNCTION_ARGUMENT)
205+
.hasMessage("long overflow");
198206
}
199207

200208
@Test
@@ -212,6 +220,11 @@ public void testFromUnixTimeWithOffset()
212220

213221
assertTrinoExceptionThrownBy(assertions.function("from_unixtime", "0", "-100", "100")::evaluate)
214222
.hasErrorCode(INVALID_FUNCTION_ARGUMENT);
223+
224+
// test millisecond overflow
225+
assertTrinoExceptionThrownBy(assertions.function("from_unixtime", "123456789123456789", "1", "1")::evaluate)
226+
.hasErrorCode(INVALID_FUNCTION_ARGUMENT)
227+
.hasMessage("Millis overflow: 9223372036854775807");
215228
}
216229

217230
@Test
@@ -234,6 +247,10 @@ public void testFromUnixTimeWithTimeZone()
234247

235248
assertThat(assertions.function("from_unixtime", "7200", "'America/Los_Angeles'"))
236249
.matches("TIMESTAMP '1969-12-31 18:00:00.000 America/Los_Angeles'");
250+
251+
assertTrinoExceptionThrownBy(assertions.function("from_unixtime", "123456789123456789", "'Asia/Kolkata'")::evaluate)
252+
.hasErrorCode(INVALID_FUNCTION_ARGUMENT)
253+
.hasMessage("Millis overflow: 9223372036854775807");
237254
}
238255

239256
@Test
@@ -260,6 +277,10 @@ public void testFromISO8601()
260277

261278
assertThat(assertions.function("from_iso8601_date", "'2001-08-22'"))
262279
.matches("DATE '2001-08-22'");
280+
281+
assertTrinoExceptionThrownBy(assertions.function("from_iso8601_timestamp", "'115023-03-21T10:45:30.00Z'")::evaluate)
282+
.hasErrorCode(INVALID_FUNCTION_ARGUMENT)
283+
.hasMessage("Millis overflow: 3567614928330000");
263284
}
264285

265286
@Test

0 commit comments

Comments
 (0)