Skip to content

Commit 4be9aff

Browse files
authored
[FLINK-22349][table-api] Throw Exception for unsupported Zone ID instead of using wrong value
This closes apache#15678
1 parent 293739d commit 4be9aff

8 files changed

Lines changed: 62 additions & 11 deletions

File tree

docs/layouts/shortcodes/generated/table_config_configuration.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<td><h5>table.local-time-zone</h5><br> <span class="label label-primary">Batch</span> <span class="label label-primary">Streaming</span></td>
3131
<td style="word-wrap: break-word;">"default"</td>
3232
<td>String</td>
33-
<td>The local time zone defines current session time zone id. It is used when converting to/from &lt;code&gt;TIMESTAMP WITH LOCAL TIME ZONE&lt;/code&gt;. Internally, timestamps with local time zone are always represented in the UTC time zone. However, when converting to data types that don't include a time zone (e.g. TIMESTAMP, TIME, or simply STRING), the session time zone is used during conversion. The input of option is either an abbreviation such as "PST", a full name such as "America/Los_Angeles", or a custom timezone id such as "GMT-8:00".</td>
33+
<td>The local time zone defines current session time zone id. It is used when converting to/from &lt;code&gt;TIMESTAMP WITH LOCAL TIME ZONE&lt;/code&gt;. Internally, timestamps with local time zone are always represented in the UTC time zone. However, when converting to data types that don't include a time zone (e.g. TIMESTAMP, TIME, or simply STRING), the session time zone is used during conversion. The input of option is either a full name such as "America/Los_Angeles", or a custom timezone id such as "GMT-8:00".</td>
3434
</tr>
3535
<tr>
3636
<td><h5>table.planner</h5><br> <span class="label label-primary">Batch</span> <span class="label label-primary">Streaming</span></td>

flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/TableConfig.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import java.util.HashMap;
3535
import java.util.Map;
3636

37+
import static java.time.ZoneId.SHORT_IDS;
38+
3739
/**
3840
* Configuration for the current {@link TableEnvironment} session to adjust Table & SQL API
3941
* programs.
@@ -113,6 +115,7 @@ public void setSqlDialect(SqlDialect sqlDialect) {
113115
*/
114116
public ZoneId getLocalTimeZone() {
115117
String zone = configuration.getString(TableConfigOptions.LOCAL_TIME_ZONE);
118+
validateTimeZone(zone);
116119
return TableConfigOptions.LOCAL_TIME_ZONE.defaultValue().equals(zone)
117120
? ZoneId.systemDefault()
118121
: ZoneId.of(zone);
@@ -166,9 +169,24 @@ public ZoneId getLocalTimeZone() {
166169
* @see org.apache.flink.table.types.logical.LocalZonedTimestampType
167170
*/
168171
public void setLocalTimeZone(ZoneId zoneId) {
172+
validateTimeZone(zoneId.toString());
169173
configuration.setString(TableConfigOptions.LOCAL_TIME_ZONE, zoneId.toString());
170174
}
171175

176+
/** Validates user configured time zone. */
177+
private void validateTimeZone(String zone) {
178+
final String zoneId = zone.toUpperCase();
179+
if (zoneId.startsWith("UTC+")
180+
|| zoneId.startsWith("UTC-")
181+
|| SHORT_IDS.containsKey(zoneId)) {
182+
throw new IllegalArgumentException(
183+
String.format(
184+
"The supported Zone ID is either a full name such as 'America/Los_Angeles',"
185+
+ " or a custom timezone id such as 'GMT-8:00', but configured Zone ID is '%s'.",
186+
zone));
187+
}
188+
}
189+
172190
/** Returns the NULL check. If enabled, all fields need to be checked for NULL first. */
173191
public Boolean getNullCheck() {
174192
return nullCheck;

flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/config/TableConfigOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private TableConfigOptions() {}
8989
"The local time zone defines current session time zone id. It is used when converting to/from "
9090
+ "<code>TIMESTAMP WITH LOCAL TIME ZONE</code>. Internally, timestamps with local time zone are always represented in the UTC time zone. "
9191
+ "However, when converting to data types that don't include a time zone (e.g. TIMESTAMP, TIME, or simply STRING), "
92-
+ "the session time zone is used during conversion. The input of option is either an abbreviation such as \"PST\", a full name "
92+
+ "the session time zone is used during conversion. The input of option is either a full name "
9393
+ "such as \"America/Los_Angeles\", or a custom timezone id such as \"GMT-8:00\".");
9494

9595
@Documentation.TableOption(execMode = Documentation.ExecMode.BATCH_STREAMING)

flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/api/TableConfigTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
import org.apache.flink.configuration.Configuration;
2222

23+
import org.junit.Rule;
2324
import org.junit.Test;
25+
import org.junit.rules.ExpectedException;
2426

2527
import java.time.Duration;
2628
import java.time.ZoneId;
@@ -29,6 +31,9 @@
2931

3032
/** Tests for {@link TableConfig}. */
3133
public class TableConfigTest {
34+
35+
@Rule public ExpectedException expectedException = ExpectedException.none();
36+
3237
private static TableConfig configByMethod = new TableConfig();
3338
private static TableConfig configByConfiguration = new TableConfig();
3439
private static Configuration configuration = new Configuration();
@@ -63,6 +68,34 @@ public void testSetAndGetLocalTimeZone() {
6368
assertEquals(ZoneId.of("Asia/Shanghai"), configByConfiguration.getLocalTimeZone());
6469
}
6570

71+
@Test
72+
public void testSetInvalidLocalTimeZone() {
73+
expectedException.expectMessage(
74+
"The supported Zone ID is either a full name such as 'America/Los_Angeles',"
75+
+ " or a custom timezone id such as 'GMT-8:00', but configured Zone ID is 'UTC-10:00'.");
76+
configByMethod.setLocalTimeZone(ZoneId.of("UTC-10:00"));
77+
}
78+
79+
@Test
80+
public void testGetInvalidLocalTimeZone() {
81+
configuration.setString("table.local-time-zone", "UTC+8");
82+
configByConfiguration.addConfiguration(configuration);
83+
expectedException.expectMessage(
84+
"The supported Zone ID is either a full name such as 'America/Los_Angeles',"
85+
+ " or a custom timezone id such as 'GMT-8:00', but configured Zone ID is 'UTC+8'.");
86+
configByConfiguration.getLocalTimeZone();
87+
}
88+
89+
@Test
90+
public void testGetInvalidAbbreviationLocalTimeZone() {
91+
configuration.setString("table.local-time-zone", "PST");
92+
configByConfiguration.addConfiguration(configuration);
93+
expectedException.expectMessage(
94+
"The supported Zone ID is either a full name such as 'America/Los_Angeles',"
95+
+ " or a custom timezone id such as 'GMT-8:00', but configured Zone ID is 'PST'.");
96+
configByConfiguration.getLocalTimeZone();
97+
}
98+
6699
@Test
67100
public void testSetAndGetIdleStateRetention() {
68101
configuration.setString("table.exec.state.ttl", "1 h");

flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/util/python/PythonTableUtilsTest.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ class PythonTableUtilsTest {
3636
val originalZone = TimeZone.getDefault
3737
try {
3838
// Daylight Saving Time Test
39-
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("PST", ZoneId.SHORT_IDS)))
39+
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles")))
4040

41-
// 2018-03-11 01:59:59.0 PST
41+
// 2018-03-11 01:59:59.0 America/Los_Angeles
4242
testOffset(DateTimeUtils.timestampStringToUnixDate("2018-03-11 01:59:59.0"), -28800000)
4343

44-
// 2018-03-11 03:00:00.0 PST
44+
// 2018-03-11 03:00:00.0 America/Los_Angeles
4545
testOffset(DateTimeUtils.timestampStringToUnixDate("2018-03-11 03:00:00.0"), -25200000)
4646

47-
// 2018-11-04 00:59:59.0 PST
47+
// 2018-11-04 00:59:59.0 America/Los_Angeles
4848
testOffset(DateTimeUtils.timestampStringToUnixDate("2018-11-04 00:59:59.0"), -25200000)
4949

50-
// 2018-11-04 02:00:00.0 PST
50+
// 2018-11-04 02:00:00.0 America/Los_Angeles
5151
testOffset(DateTimeUtils.timestampStringToUnixDate("2018-11-04 02:00:00.0"), -28800000)
5252
} finally {
5353
TimeZone.setDefault(originalZone)

flink-table/flink-table-runtime-blink/src/main/java/org/apache/flink/table/runtime/operators/window/assigners/TumblingWindowAssigner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public static TumblingWindowAssigner of(Duration size) {
100100
* windows start at 0:15:00,1:15:00,2:15:00,etc.
101101
*
102102
* <p>Rather than that,if you are living in somewhere which is not using UTC±00:00 time, such as
103-
* China which is using UTC+08:00,and you want a time window with size of one day, and window
103+
* China which is using GMT+08:00,and you want a time window with size of one day, and window
104104
* begins at every 00:00:00 of local time,you may use {@code of(Time.days(1),Time.hours(-8))}.
105105
* The parameter of offset is {@code Time.hours(-8))} since UTC+08:00 is 8 hours earlier than
106106
* UTC time.

flink-table/flink-table-runtime-blink/src/main/java/org/apache/flink/table/runtime/util/TimeWindowUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class TimeWindowUtil {
4343
/**
4444
* Convert a epoch mills to timestamp mills which can describe a locate date time.
4545
*
46-
* <p>For example: The timestamp string of epoch mills 5 in UTC+8 is 1970-01-01 08:00:05, the
46+
* <p>For example: The timestamp string of epoch mills 5 in GMT+8:00 is 1970-01-01 08:00:05, the
4747
* timestamp mills is 8 * 60 * 60 * 1000 + 5.
4848
*
4949
* @param epochMills the epoch mills.

flink-table/flink-table-runtime-blink/src/test/java/org/apache/flink/table/runtime/operators/aggregate/window/SlicingWindowAggOperatorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,8 @@ public void testProcessingTimeTumblingWindows() throws Exception {
692692

693693
final SliceAssigner assigner =
694694
SliceAssigners.tumbling(-1, shiftTimeZone, Duration.ofHours(5));
695-
// the assigned windows should like as following, e.g. the given timeZone is UTC+8:
696-
// local windows(timestamp in UTC+8) <=> epoch windows(timestamp in UTC+0)
695+
// the assigned windows should like as following, e.g. the given timeZone is GMT+8:00:
696+
// local windows(timestamp in GMT+8:00) <=> epoch windows(timestamp in UTC)
697697
// [1970-01-01 00:00, 1970-01-01 05:00] <=> [1969-12-31 16:00, 1969-12-31 21:00]
698698
// [1970-01-01 05:00, 1970-01-01 10:00] <=> [1969-12-31 21:00, 1970-01-01 02:00]
699699

0 commit comments

Comments
 (0)