morrySnow commented on code in PR #64026:
URL: https://github.com/apache/doris/pull/64026#discussion_r3457959211


##########
regression-test/suites/partition_p0/dynamic_partition/test_dynamic_partition_timestamptz_timezone.groovy:
##########
@@ -0,0 +1,125 @@
+// 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.
+
+suite("test_dynamic_partition_timestamptz_timezone") {
+    sql "drop table if exists test_dp_timestamptz_shanghai"
+    sql "drop table if exists test_dp_timestamptz_utc"
+
+    // Table A: TIMESTAMPTZ dynamic partition with Asia/Shanghai timezone
+    // A DAY boundary at Asia/Shanghai midnight should map to 16:00 UTC
+    // (Asia/Shanghai is UTC+8, no DST).
+    sql """
+        CREATE TABLE test_dp_timestamptz_shanghai (
+            k1 TIMESTAMPTZ NOT NULL,
+            v1 INT
+        )
+        DUPLICATE KEY(k1)
+        PARTITION BY RANGE(k1) ()
+        DISTRIBUTED BY HASH(k1) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "dynamic_partition.enable" = "true",
+            "dynamic_partition.time_unit" = "DAY",
+            "dynamic_partition.time_zone" = "Asia/Shanghai",
+            "dynamic_partition.start" = "-1",
+            "dynamic_partition.end" = "1",
+            "dynamic_partition.prefix" = "p",
+            "dynamic_partition.buckets" = "1",
+            "dynamic_partition.create_history_partition" = "true"
+        )
+    """
+
+    // Table B: TIMESTAMPTZ dynamic partition with UTC timezone (reference)
+    // A DAY boundary at UTC midnight should map to 00:00 UTC.
+    sql """
+        CREATE TABLE test_dp_timestamptz_utc (
+            k1 TIMESTAMPTZ NOT NULL,
+            v1 INT
+        )
+        DUPLICATE KEY(k1)
+        PARTITION BY RANGE(k1) ()
+        DISTRIBUTED BY HASH(k1) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "dynamic_partition.enable" = "true",
+            "dynamic_partition.time_unit" = "DAY",
+            "dynamic_partition.time_zone" = "UTC",
+            "dynamic_partition.start" = "-1",
+            "dynamic_partition.end" = "1",
+            "dynamic_partition.prefix" = "p",
+            "dynamic_partition.buckets" = "1",
+            "dynamic_partition.create_history_partition" = "true"
+        )
+    """
+
+    def createShanghai = sql "SHOW CREATE TABLE test_dp_timestamptz_shanghai"
+    def createUtc = sql "SHOW CREATE TABLE test_dp_timestamptz_utc"
+    logger.info("Shanghai create: ${createShanghai}")
+    logger.info("UTC create: ${createUtc}")
+
+    def shStr = createShanghai[0][1]
+    def utcStr = createUtc[0][1]
+
+    // Verify that both tables have their dynamic_partition.time_zone set 
correctly
+    assertTrue(shStr.contains('"dynamic_partition.time_zone" = 
"Asia/Shanghai"'),
+        "Shanghai table should have time_zone=Asia/Shanghai")
+    assertTrue(utcStr.contains('"dynamic_partition.time_zone" = "UTC"'),
+        "UTC table should have time_zone=UTC")
+
+    // Verify both tables have the expected number of partitions (yesterday, 
today, tomorrow)
+    def partsShanghai = sql "SHOW PARTITIONS FROM test_dp_timestamptz_shanghai"
+    def partsUtc = sql "SHOW PARTITIONS FROM test_dp_timestamptz_utc"
+    logger.info("Shanghai partitions: ${partsShanghai}")
+    logger.info("UTC partitions: ${partsUtc}")
+    assertEquals(3, partsShanghai.size(),
+        "Shanghai table should have 3 partitions (yesterday, today, tomorrow)")
+    assertEquals(3, partsUtc.size(),
+        "UTC table should have 3 partitions (yesterday, today, tomorrow)")
+
+    // Insert data: midnight and afternoon in their respective timezones
+    sql """
+        INSERT INTO test_dp_timestamptz_shanghai VALUES
+        (CAST('2026-06-17 16:00:00 UTC' AS TIMESTAMPTZ), 1),
+        (CAST('2026-06-18 08:00:00 UTC' AS TIMESTAMPTZ), 2)

Review Comment:
   这个 case 创建的是相对当前时间的 dynamic partitions(`start=-1`, `end=1`),但插入值硬编码为 
`2026-06-17/18`。在 2026-06-23 
运行时,表只会有当前日前后一天的分区,这两行会落不到任何分区导致测试失败;在其它日期也同样是时间相关的 flaky 
case。这里需要基于实际生成的分区边界/当前日期构造插入值,或直接验证 `SHOW PARTITIONS` 的边界,而不是固定日期。



##########
fe/fe-core/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java:
##########
@@ -298,25 +300,47 @@ private ArrayList<AddPartitionOp> 
getAddPartitionOp(Database db, OlapTable olapT
                 nowPartitionPrevBorder, 
dynamicPartitionProperty.getTimeUnit());
 
         for (; idx <= dynamicPartitionProperty.getEnd(); idx++) {
-            String prevBorder = DynamicPartitionUtil.getPartitionRangeString(
-                    dynamicPartitionProperty, now, idx, partitionFormat);
-            String nextBorder = DynamicPartitionUtil.getPartitionRangeString(
-                    dynamicPartitionProperty, now, idx + 1, partitionFormat);
-            PartitionValue lowerValue = new PartitionValue(prevBorder);
-            PartitionValue upperValue = new PartitionValue(nextBorder);
-
             boolean isPartitionExists = false;
             Range<PartitionKey> addPartitionKeyRange;
+            PartitionValue lowerValue;
+            PartitionValue upperValue;
+            String prevBorder;
+            String nextBorder;
+            try {
+                prevBorder = DynamicPartitionUtil.getPartitionRangeString(
+                        dynamicPartitionProperty, now, idx, partitionFormat);
+                prevBorder = 
PartitionExprUtil.normalizePartitionValueString(prevBorder, 
partitionColumn.getType(),

Review Comment:
   这里把 `prevBorder` 从 `dynamic_partition.time_zone` 下的本地边界改写成 TIMESTAMPTZ 的 UTC 
字符串,但后面仍用同一个 `prevBorder` 
生成分区名。`DynamicPartitionUtil.getFormattedPartitionName()` 
只是去掉分隔符后截日期,不会按配置时区转回本地时间,所以例如 `Asia/Shanghai` 的日分区本地边界 `2026-06-18 00:00:00` 
会被 normalize 成 `2026-06-17 16:00:00...+00:00`,最终生成 
`p20260617`。建议保留原始本地边界用于命名,只把 normalized 值用于 `PartitionKey` / 
`PartitionKeyDesc`。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to