This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 6ae89db5d5b branch-4.1: [fix](outfile)Preserve DateTimeV2 scale in
OUTFILE CSV. #64344 (#64714)
6ae89db5d5b is described below
commit 6ae89db5d5bddd91a56e8830dcd8ae91d8e07e3a
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Jun 23 14:57:54 2026 +0800
branch-4.1: [fix](outfile)Preserve DateTimeV2 scale in OUTFILE CSV. #64344
(#64714)
Cherry-picked from #64344
Co-authored-by: daidai <[email protected]>
---
.../data_type_serde/data_type_datetimev2_serde.cpp | 2 +-
.../data_type_serde_datetime_v2_test.cpp | 87 ++++++++++++++++
.../data/export_p0/test_export_data_types.out | 25 +++--
.../export_p0/test_outfile_datetimev2_scale.groovy | 110 +++++++++++++++++++++
4 files changed, 210 insertions(+), 14 deletions(-)
diff --git a/be/src/core/data_type_serde/data_type_datetimev2_serde.cpp
b/be/src/core/data_type_serde/data_type_datetimev2_serde.cpp
index 2006a03cc4d..c368ad17662 100644
--- a/be/src/core/data_type_serde/data_type_datetimev2_serde.cpp
+++ b/be/src/core/data_type_serde/data_type_datetimev2_serde.cpp
@@ -329,7 +329,7 @@ Status
DataTypeDateTimeV2SerDe::serialize_one_cell_to_json(const IColumn& column
auto val = assert_cast<const ColumnDateTimeV2&,
TypeCheckOnRelease::DISABLE>(*ptr).get_element(
row_num);
char buf[64];
- char* pos = val.to_string(buf);
+ char* pos = val.to_string(buf, _scale);
bw.write(buf, pos - buf - 1);
if (_nesting_level > 1) {
diff --git a/be/test/core/data_type_serde/data_type_serde_datetime_v2_test.cpp
b/be/test/core/data_type_serde/data_type_serde_datetime_v2_test.cpp
index 456aa6a54d2..3769e5f6946 100644
--- a/be/test/core/data_type_serde/data_type_serde_datetime_v2_test.cpp
+++ b/be/test/core/data_type_serde/data_type_serde_datetime_v2_test.cpp
@@ -25,7 +25,9 @@
#include <cstddef>
#include <iostream>
#include <limits>
+#include <string>
#include <type_traits>
+#include <vector>
#include "core/assert_cast.h"
#include "core/column/column.h"
@@ -217,6 +219,91 @@ TEST_F(DataTypeDateTimeV2SerDeTest, serdes) {
test_func(*serde_time_v2_0, column_time_v2_0);
}
+TEST_F(DataTypeDateTimeV2SerDeTest, SerializeDateTimeV2KeepsScale) {
+ auto column = ColumnDateTimeV2::create();
+
+ auto insert_datetime = [&](int microsecond) {
+ DateV2Value<DateTimeV2ValueType> value;
+ value.unchecked_set_time(2026, 6, 6, 15, 54, 51, microsecond);
+ column->insert_value(value);
+ };
+ insert_datetime(442123);
+ insert_datetime(442000);
+ insert_datetime(0);
+
+ auto serialize_one = [&](int scale, int64_t row_num, int nesting_level =
1) {
+ DataTypeDateTimeV2SerDe serde(scale, nesting_level);
+ DataTypeSerDe::FormatOptions option;
+ auto ser_col = ColumnString::create();
+ VectorBufferWriter buffer_writer(*ser_col);
+ auto st = serde.serialize_one_cell_to_json(*column, row_num,
buffer_writer, option);
+ EXPECT_TRUE(st.ok()) << "Failed to serialize datetimev2 at row " <<
row_num << ": " << st;
+ buffer_writer.commit();
+ return ser_col->get_data_at(0).to_string();
+ };
+
+ auto default_to_string = [](int microsecond) {
+ DateV2Value<DateTimeV2ValueType> value;
+ value.unchecked_set_time(2026, 6, 6, 15, 54, 51, microsecond);
+ char buf[64];
+ value.to_string(buf);
+ return std::string(buf);
+ };
+
+ auto scaled_to_string = [](int microsecond, int scale) {
+ DateV2Value<DateTimeV2ValueType> value;
+ value.unchecked_set_time(2026, 6, 6, 15, 54, 51, microsecond);
+ char buf[64];
+ value.to_string(buf, scale);
+ return std::string(buf);
+ };
+
+ EXPECT_EQ("2026-06-06 15:54:51.120000", default_to_string(120000));
+ EXPECT_EQ("2026-06-06 15:54:51", default_to_string(0));
+ EXPECT_EQ("2026-06-06 15:54:51.120", scaled_to_string(120000, 3));
+ EXPECT_EQ("2026-06-06 15:54:51.000", scaled_to_string(0, 3));
+
+ struct SerializeCase {
+ int scale;
+ const char* full_microsecond;
+ const char* millisecond;
+ const char* zero_microsecond;
+ };
+ const std::vector<SerializeCase> cases = {
+ {0, "2026-06-06 15:54:51", "2026-06-06 15:54:51", "2026-06-06
15:54:51"},
+ {1, "2026-06-06 15:54:51.4", "2026-06-06 15:54:51.4", "2026-06-06
15:54:51.0"},
+ {2, "2026-06-06 15:54:51.44", "2026-06-06 15:54:51.44",
"2026-06-06 15:54:51.00"},
+ {3, "2026-06-06 15:54:51.442", "2026-06-06 15:54:51.442",
"2026-06-06 15:54:51.000"},
+ {4, "2026-06-06 15:54:51.4421", "2026-06-06 15:54:51.4420",
"2026-06-06 15:54:51.0000"},
+ {5, "2026-06-06 15:54:51.44212", "2026-06-06 15:54:51.44200",
+ "2026-06-06 15:54:51.00000"},
+ {6, "2026-06-06 15:54:51.442123", "2026-06-06 15:54:51.442000",
+ "2026-06-06 15:54:51.000000"},
+ };
+
+ for (const auto& c : cases) {
+ EXPECT_EQ(c.full_microsecond, serialize_one(c.scale, 0)) << "scale="
<< c.scale;
+ EXPECT_EQ(c.millisecond, serialize_one(c.scale, 1)) << "scale=" <<
c.scale;
+ EXPECT_EQ(c.zero_microsecond, serialize_one(c.scale, 2)) << "scale="
<< c.scale;
+ }
+
+ EXPECT_EQ("\"2026-06-06 15:54:51.442\"", serialize_one(3, 1, 2));
+
+ DataTypeDateTimeV2SerDe serde(3);
+ DataTypeSerDe::FormatOptions option;
+ option.field_delim = "|";
+ auto ser_col = ColumnString::create();
+ VectorBufferWriter buffer_writer(*ser_col);
+ auto st = serde.serialize_column_to_json(*column, 0, column->size(),
buffer_writer, option);
+ EXPECT_TRUE(st.ok()) << "Failed to serialize datetimev2 column: " << st;
+ buffer_writer.commit();
+ std::string serialized((char*)ser_col->get_chars().data(),
ser_col->get_chars().size());
+ EXPECT_EQ(
+ "2026-06-06 15:54:51.442|2026-06-06 15:54:51.442|"
+ "2026-06-06 15:54:51.000",
+ serialized);
+}
+
// Run with UBSan enabled to catch misalignment errors.
TEST_F(DataTypeDateTimeV2SerDeTest, ArrowMemNotAlignedDate) {
// 1.Prepare the data.
diff --git a/regression-test/data/export_p0/test_export_data_types.out
b/regression-test/data/export_p0/test_export_data_types.out
index f02acd6a3b1..82cae66256e 100644
--- a/regression-test/data/export_p0/test_export_data_types.out
+++ b/regression-test/data/export_p0/test_export_data_types.out
@@ -6,10 +6,10 @@
4 0000-01-01 0000-01-01 2023-04-20T00:00
2023-04-20T00:00 2023-04-20T00:00 2023-04-20T00:00 Beijing
Haidian 4 4 true 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
-- !select_load1 --
-1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 1
1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
-2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120000 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
-3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123000 2023-04-20 00:00:00.123456
Beijing 32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff: [...]
-4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 4
4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
+1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 1 1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
+2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
+3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123 2023-04-20 00:00:00.123456 Beijing
32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff:fff [...]
+4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 4 4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
-- !select_load2 --
1 2023-04-20 2023-04-20 2023-04-20T00:00
2023-04-20T00:00 2023-04-20T00:00 2023-04-20T00:00 Beijing
Haidian 1 1 true 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 1 ::1
@@ -24,14 +24,13 @@
4 0000-01-01 0000-01-01 2023-04-20T00:00
2023-04-20T00:00 2023-04-20T00:00 2023-04-20T00:00 Beijing
Haidian 4 4 true 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 4 ::4
-- !select_load4 --
-1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 1
1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
-2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120000 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
-3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123000 2023-04-20 00:00:00.123456
Beijing 32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff: [...]
-4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 4
4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
+1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 1 1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
+2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
+3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123 2023-04-20 00:00:00.123456 Beijing
32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff:fff [...]
+4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 4 4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
-- !select_load5 --
-1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 1
1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
-2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120000 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
-3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123000 2023-04-20 00:00:00.123456
Beijing 32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff: [...]
-4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00 2023-04-20 00:00:00 Beijing Haidian 4
4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
-
+1 2023-04-20 2023-04-20 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 1 1 1 1 1 1 1.1 1.1 char1
1.000000000 1.000000000 1 0.1 1.00000000 1.0000000000
1 1.0000000000000000000000000000000000000
0.10000000000000000000000000000000000000 0.0.0.1 ::1
+2 9999-12-31 9999-12-31 9999-12-31 23:59:59 9999-12-31
23:59:59 2023-04-20 00:00:00.120 2023-04-20 00:00:00.334400
Haidian -32768 -128 1 -2147483648 -9223372036854775808
-170141183460469231731687303715884105728 1.401298e-45
4.940656458412465e-324 char2 100000000.000000000 100000000.000000000
4 0.1 0.99999999 9999999999.9999999999
99999999999999999999999999999999999999 9.9999999999999999999999999999999999999
0.99999999999999999999999999999999999999 0.0.0.0 ::
+3 2023-04-21 2023-04-21 2023-04-20 12:34:56 2023-04-20
00:00:00 2023-04-20 00:00:00.123 2023-04-20 00:00:00.123456 Beijing
32767 127 1 2147483647 9223372036854775807
170141183460469231731687303715884105727 3.402823e+38 1.797693134862316e+308
char3 999999999.000000000 999999999.000000000 9 0.9
9.99999999 1234567890.0123456789 12345678901234567890123456789012345678
1.2345678901234567890123456789012345678
0.12345678901234567890123456789012345678 255.255.255.255
ffff:ffff:ffff:ffff:ffff:fff [...]
+4 0000-01-01 0000-01-01 2023-04-20 00:00:00 2023-04-20
00:00:00 2023-04-20 00:00:00.000 2023-04-20 00:00:00.000000 Beijing
Haidian 4 4 1 4 4 4 4.4 4.4 char4
4.000000000 4.000000000 4 0.4 4.00000000 4.0000000000
4 4.0000000000000000000000000000000000000
0.40000000000000000000000000000000000000 0.0.0.4 ::4
diff --git
a/regression-test/suites/export_p0/test_outfile_datetimev2_scale.groovy
b/regression-test/suites/export_p0/test_outfile_datetimev2_scale.groovy
new file mode 100644
index 00000000000..dc3d8dfafb1
--- /dev/null
+++ b/regression-test/suites/export_p0/test_outfile_datetimev2_scale.groovy
@@ -0,0 +1,110 @@
+// 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.
+
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Paths
+
+suite("test_outfile_datetimev2_scale") {
+ StringBuilder strBuilder = new StringBuilder()
+ strBuilder.append("curl --location-trusted -u " + context.config.jdbcUser
+ ":" + context.config.jdbcPassword)
+ if
((context.config.otherConfigs.get("enableTLS")?.toString()?.equalsIgnoreCase("true"))
?: false) {
+ strBuilder.append(" https://" + context.config.feHttpAddress +
"/rest/v1/config/fe")
+ strBuilder.append(" --cert " +
context.config.otherConfigs.get("trustCert") + " --cacert " +
context.config.otherConfigs.get("trustCACert") + " --key " +
context.config.otherConfigs.get("trustCAKey"))
+ } else {
+ strBuilder.append(" http://" + context.config.feHttpAddress +
"/rest/v1/config/fe")
+ }
+
+ String command = strBuilder.toString()
+ def process = command.execute()
+ def code = process.waitFor()
+ def err = IOGroovyMethods.getText(new BufferedReader(new
InputStreamReader(process.getErrorStream())))
+ def out = process.getText()
+ logger.info("Request FE Config: code=" + code + ", out=" + out + ", err="
+ err)
+ assertEquals(code, 0)
+ def response = parseJson(out.trim())
+ assertEquals(response.code, 0)
+ assertEquals(response.msg, "success")
+ def configJson = response.data.rows
+ boolean enableOutfileToLocal = false
+ for (Object conf: configJson) {
+ assert conf instanceof Map
+ if (((Map<String, String>) conf).get("Name").toLowerCase() ==
"enable_outfile_to_local") {
+ enableOutfileToLocal = ((Map<String, String>)
conf).get("Value").toLowerCase() == "true"
+ }
+ }
+ if (!enableOutfileToLocal) {
+ logger.warn("Please set enable_outfile_to_local to true to run
test_outfile_datetimev2_scale")
+ return
+ }
+
+ def tableName = "test_outfile_datetimev2_scale"
+ def uuid = UUID.randomUUID().toString()
+ def outFilePath = """/tmp/test_outfile_datetimev2_scale_${uuid}"""
+
+ try {
+ sql """ DROP TABLE IF EXISTS ${tableName} """
+ sql """
+ CREATE TABLE ${tableName} (
+ `id` INT,
+ `dt0` DATETIMEV2(0),
+ `dt3` DATETIMEV2(3),
+ `dt6` DATETIMEV2(6)
+ )
+ DUPLICATE KEY(`id`)
+ DISTRIBUTED BY HASH(`id`) BUCKETS 1
+ PROPERTIES("replication_num" = "1");
+ """
+ sql """
+ INSERT INTO ${tableName} VALUES
+ (1, '2026-06-06 15:54:51', '2026-06-06 15:54:51.442', '2026-06-06
15:54:51.442000');
+ """
+
+ File path = new File(outFilePath)
+ if (!path.exists()) {
+ assert path.mkdirs()
+ } else {
+ throw new IllegalStateException("""${outFilePath} already exists!
""")
+ }
+
+ sql """
+ SELECT * FROM ${tableName} ORDER BY id
+ INTO OUTFILE "file://${outFilePath}/"
+ FORMAT AS CSV
+ PROPERTIES("column_separator" = ",");
+ """
+
+ File[] files = path.listFiles().findAll { it.isFile() &&
it.getName().endsWith(".csv") } as File[]
+ assertEquals(1, files.length)
+
+ List<String> outLines =
Files.readAllLines(Paths.get(files[0].getAbsolutePath()),
StandardCharsets.UTF_8)
+ assertEquals(1, outLines.size())
+ assertEquals("1,2026-06-06 15:54:51,2026-06-06 15:54:51.442,2026-06-06
15:54:51.442000", outLines.get(0))
+ assertFalse(outLines.get(0).contains("2026-06-06
15:54:51.442000,2026-06-06 15:54:51.442000"))
+ } finally {
+ try_sql("DROP TABLE IF EXISTS ${tableName}")
+ File path = new File(outFilePath)
+ if (path.exists()) {
+ for (File f: path.listFiles()) {
+ f.delete()
+ }
+ path.delete()
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]