This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 0ac3c60757 [core] fix that auto-created tags without dashes cannot be
expired (#5786)
0ac3c60757 is described below
commit 0ac3c60757902ddb0d32e579f7b3e9464cfa5e0f
Author: zhoulii <[email protected]>
AuthorDate: Fri Jul 11 14:07:35 2025 +0800
[core] fix that auto-created tags without dashes cannot be expired (#5786)
---
.../org/apache/paimon/tag/TagPeriodHandler.java | 59 +++++++-------
.../org/apache/paimon/tag/TagAutoManagerTest.java | 18 +++++
.../apache/paimon/tag/TagPeriodHandlerTest.java | 94 ++++++++++++++++++++++
3 files changed, 141 insertions(+), 30 deletions(-)
diff --git
a/paimon-core/src/main/java/org/apache/paimon/tag/TagPeriodHandler.java
b/paimon-core/src/main/java/org/apache/paimon/tag/TagPeriodHandler.java
index 2d0df61b6a..abd7375cb9 100644
--- a/paimon-core/src/main/java/org/apache/paimon/tag/TagPeriodHandler.java
+++ b/paimon-core/src/main/java/org/apache/paimon/tag/TagPeriodHandler.java
@@ -27,7 +27,6 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
-import java.time.format.SignStyle;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
@@ -41,62 +40,62 @@ public interface TagPeriodHandler {
DateTimeFormatter HOUR_FORMATTER =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
.appendLiteral('-')
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
+ .appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
+ .appendValue(DAY_OF_MONTH, 2)
.appendLiteral(" ")
- .appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NORMAL)
+ .appendValue(HOUR_OF_DAY, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter HOUR_FORMATTER_WITHOUT_DASHES =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
+ .appendValue(MONTH_OF_YEAR, 2)
+ .appendValue(DAY_OF_MONTH, 2)
.appendLiteral(" ")
- .appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NORMAL)
+ .appendValue(HOUR_OF_DAY, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter HOUR_FORMATTER_WITHOUT_DASHES_AND_SPACES =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
- .appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
+ .appendValue(MONTH_OF_YEAR, 2)
+ .appendValue(DAY_OF_MONTH, 2)
+ .appendValue(HOUR_OF_DAY, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter MINUTE_FORMATTER =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
- .appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NORMAL)
- .appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
+ .appendValue(MONTH_OF_YEAR, 2)
+ .appendValue(DAY_OF_MONTH, 2)
+ .appendValue(HOUR_OF_DAY, 2)
+ .appendValue(MINUTE_OF_HOUR, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter DAY_FORMATTER =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
.appendLiteral('-')
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
+ .appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
+ .appendValue(DAY_OF_MONTH, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
DateTimeFormatter DAY_FORMATTER_WITHOUT_DASHES =
new DateTimeFormatterBuilder()
- .appendValue(YEAR, 1, 10, SignStyle.NORMAL)
- .appendValue(MONTH_OF_YEAR, 2, 2, SignStyle.NORMAL)
- .appendValue(DAY_OF_MONTH, 2, 2, SignStyle.NORMAL)
+ .appendValue(YEAR, 4)
+ .appendValue(MONTH_OF_YEAR, 2)
+ .appendValue(DAY_OF_MONTH, 2)
.toFormatter()
- .withResolverStyle(ResolverStyle.LENIENT);
+ .withResolverStyle(ResolverStyle.STRICT);
void validateDelay(Duration delay);
diff --git
a/paimon-core/src/test/java/org/apache/paimon/tag/TagAutoManagerTest.java
b/paimon-core/src/test/java/org/apache/paimon/tag/TagAutoManagerTest.java
index 089a639c50..0d888225dc 100644
--- a/paimon-core/src/test/java/org/apache/paimon/tag/TagAutoManagerTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/tag/TagAutoManagerTest.java
@@ -501,6 +501,24 @@ public class TagAutoManagerTest extends
PrimaryKeyTableTestBase {
assertThrows(RuntimeException.class, () ->
table.createTag("2023-07-18", 1));
}
+ @Test
+ public void testAutoExpireTagWithoutDashes() {
+ Options options = new Options();
+ options.set(TAG_AUTOMATIC_CREATION, TagCreationMode.WATERMARK);
+ options.set(TAG_CREATION_PERIOD, TagCreationPeriod.DAILY);
+ options.set(TAG_PERIOD_FORMATTER, TagPeriodFormatter.WITHOUT_DASHES);
+ options.set(TAG_NUM_RETAINED_MAX, 1);
+ FileStoreTable table = this.table.copy(options.toMap());
+ TableCommitImpl commit =
table.newCommit(commitUser).ignoreEmptyCommit(false);
+ TagManager tagManager = table.store().newTagManager();
+
+ commit.commit(new ManifestCommittable(0,
utcMills("2023-07-18T12:12:00")));
+ assertThat(tagManager.allTagNames()).containsOnly("20230717");
+
+ commit.commit(new ManifestCommittable(1,
utcMills("2023-07-19T12:12:00")));
+ assertThat(tagManager.allTagNames()).containsOnly("20230718");
+ }
+
private long localZoneMills(String timestamp) {
return LocalDateTime.parse(timestamp)
.atZone(ZoneId.systemDefault())
diff --git
a/paimon-core/src/test/java/org/apache/paimon/tag/TagPeriodHandlerTest.java
b/paimon-core/src/test/java/org/apache/paimon/tag/TagPeriodHandlerTest.java
new file mode 100644
index 0000000000..0bc8ba5e7a
--- /dev/null
+++ b/paimon-core/src/test/java/org/apache/paimon/tag/TagPeriodHandlerTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.tag;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+import static org.apache.paimon.CoreOptions.TagPeriodFormatter.WITHOUT_DASHES;
+import static
org.apache.paimon.CoreOptions.TagPeriodFormatter.WITHOUT_DASHES_AND_SPACES;
+import static org.apache.paimon.CoreOptions.TagPeriodFormatter.WITH_DASHES;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/** Test for TagPeriodHandler. */
+public class TagPeriodHandlerTest {
+
+ @Test
+ public void testDailyTagPeriodHandler() {
+ TagPeriodHandler.DailyTagPeriodHandler dailyTagPeriodHandler =
+ new TagPeriodHandler.DailyTagPeriodHandler(WITH_DASHES);
+ assertThat(dailyTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 0, 0)))
+ .isEqualTo("2023-01-01");
+ assertThat(dailyTagPeriodHandler.tagToTime("2023-01-01"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 0, 0));
+ assertThat(dailyTagPeriodHandler.isAutoTag("2023-01-01")).isTrue();
+ assertThat(dailyTagPeriodHandler.isAutoTag("20230101")).isFalse();
+
+ dailyTagPeriodHandler = new
TagPeriodHandler.DailyTagPeriodHandler(WITHOUT_DASHES);
+ assertThat(dailyTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 0, 0)))
+ .isEqualTo("20230101");
+ assertThat(dailyTagPeriodHandler.tagToTime("20230101"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 0, 0));
+ assertThat(dailyTagPeriodHandler.isAutoTag("20230101")).isTrue();
+ assertThat(dailyTagPeriodHandler.isAutoTag("2023-01-01")).isFalse();
+ }
+
+ @Test
+ public void testHourlyTagPeriodHandler() {
+ TagPeriodHandler.HourlyTagPeriodHandler hourlyTagPeriodHandler =
+ new TagPeriodHandler.HourlyTagPeriodHandler(WITH_DASHES);
+ assertThat(hourlyTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 1, 0)))
+ .isEqualTo("2023-01-01 01");
+ assertThat(hourlyTagPeriodHandler.tagToTime("2023-01-01 01"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 1, 0));
+ assertThat(hourlyTagPeriodHandler.isAutoTag("2023-01-01 01")).isTrue();
+ assertThat(hourlyTagPeriodHandler.isAutoTag("20230101 01")).isFalse();
+
+ hourlyTagPeriodHandler = new
TagPeriodHandler.HourlyTagPeriodHandler(WITHOUT_DASHES);
+ assertThat(hourlyTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 1, 0)))
+ .isEqualTo("20230101 01");
+ assertThat(hourlyTagPeriodHandler.tagToTime("20230101 01"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 1, 0));
+ assertThat(hourlyTagPeriodHandler.isAutoTag("20230101 01")).isTrue();
+ assertThat(hourlyTagPeriodHandler.isAutoTag("2023-01-01
01")).isFalse();
+
+ hourlyTagPeriodHandler =
+ new
TagPeriodHandler.HourlyTagPeriodHandler(WITHOUT_DASHES_AND_SPACES);
+ assertThat(hourlyTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 1, 0)))
+ .isEqualTo("2023010101");
+ assertThat(hourlyTagPeriodHandler.tagToTime("2023010101"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 1, 0));
+ assertThat(hourlyTagPeriodHandler.isAutoTag("2023010101")).isTrue();
+ assertThat(hourlyTagPeriodHandler.isAutoTag("20230101 01")).isFalse();
+ }
+
+ @Test
+ public void testPeriodDurationTagPeriodHandler() {
+ TagPeriodHandler.PeriodDurationTagPeriodHandler
periodDurationTagPeriodHandler =
+ new
TagPeriodHandler.PeriodDurationTagPeriodHandler(Duration.ofMinutes(5));
+
assertThat(periodDurationTagPeriodHandler.timeToTag(LocalDateTime.of(2023, 1,
1, 1, 1)))
+ .isEqualTo("202301010101");
+ assertThat(periodDurationTagPeriodHandler.tagToTime("202301010101"))
+ .isEqualTo(LocalDateTime.of(2023, 1, 1, 1, 1));
+
assertThat(periodDurationTagPeriodHandler.isAutoTag("202301010101")).isTrue();
+ assertThat(periodDurationTagPeriodHandler.isAutoTag("20230101
0101")).isFalse();
+ }
+}