Coverage Report

Created: 2026-10-28 17:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/cast/cast_to_timestamptz.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include "core/assert_cast.h"
21
#include "core/data_type/data_type_date_or_datetime_v2.h"
22
#include "core/data_type/data_type_timestamp_ns.h"
23
#include "core/data_type/data_type_timestamptz.h"
24
#include "core/data_type/primitive_type.h"
25
#include "core/types.h"
26
#include "core/value/timestamptz_value.h"
27
#include "core/value/vdatetime_value.h"
28
#include "exprs/function/cast/cast_base.h"
29
#include "exprs/function/cast/cast_to_datetimev2_impl.hpp"
30
#include "exprs/function/cast/cast_to_timestamptz_impl.hpp"
31
#include "runtime/runtime_state.h"
32
33
namespace doris {
34
35
template <CastModeType Mode>
36
class CastToImpl<Mode, DataTypeString, DataTypeTimeStampTz> : public CastToBase {
37
public:
38
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
39
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
40
4
                        const NullMap::value_type* parent_null_map = nullptr) const override {
41
4
        const auto& col_from =
42
4
                assert_cast<const DataTypeString::ColumnType&>(*source_column.column);
43
44
4
        auto to_type = target_column.type;
45
4
        auto serde = remove_nullable(to_type)->get_serde();
46
4
        MutableColumnPtr column_to;
47
48
4
        DataTypeSerDe::FormatOptions options;
49
4
        options.timezone = &state->timezone_obj();
50
51
4
        if constexpr (Mode == CastModeType::NonStrictMode) {
52
2
            auto to_nullable_type = make_nullable(to_type);
53
2
            column_to = to_nullable_type->create_column();
54
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
55
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
56
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
57
2
            column_to = to_type->create_column();
58
2
            RETURN_IF_ERROR(serde->from_string_strict_mode_batch(col_from, *column_to, options,
59
2
                                                                 parent_null_map));
60
2
        }
61
62
3
        target_column.column = std::move(column_to);
63
4
        return Status::OK();
64
4
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE0ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_12RuntimeStateERKNS_21ColumnWithTypeAndNameERS7_mPKh
Line
Count
Source
40
2
                        const NullMap::value_type* parent_null_map = nullptr) const override {
41
2
        const auto& col_from =
42
2
                assert_cast<const DataTypeString::ColumnType&>(*source_column.column);
43
44
2
        auto to_type = target_column.type;
45
2
        auto serde = remove_nullable(to_type)->get_serde();
46
2
        MutableColumnPtr column_to;
47
48
2
        DataTypeSerDe::FormatOptions options;
49
2
        options.timezone = &state->timezone_obj();
50
51
        if constexpr (Mode == CastModeType::NonStrictMode) {
52
            auto to_nullable_type = make_nullable(to_type);
53
            column_to = to_nullable_type->create_column();
54
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
55
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
56
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
57
2
            column_to = to_type->create_column();
58
2
            RETURN_IF_ERROR(serde->from_string_strict_mode_batch(col_from, *column_to, options,
59
2
                                                                 parent_null_map));
60
2
        }
61
62
1
        target_column.column = std::move(column_to);
63
2
        return Status::OK();
64
2
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE1ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_12RuntimeStateERKNS_21ColumnWithTypeAndNameERS7_mPKh
Line
Count
Source
40
2
                        const NullMap::value_type* parent_null_map = nullptr) const override {
41
2
        const auto& col_from =
42
2
                assert_cast<const DataTypeString::ColumnType&>(*source_column.column);
43
44
2
        auto to_type = target_column.type;
45
2
        auto serde = remove_nullable(to_type)->get_serde();
46
2
        MutableColumnPtr column_to;
47
48
2
        DataTypeSerDe::FormatOptions options;
49
2
        options.timezone = &state->timezone_obj();
50
51
2
        if constexpr (Mode == CastModeType::NonStrictMode) {
52
2
            auto to_nullable_type = make_nullable(to_type);
53
2
            column_to = to_nullable_type->create_column();
54
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
55
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
56
        } else if constexpr (Mode == CastModeType::StrictMode) {
57
            column_to = to_type->create_column();
58
            RETURN_IF_ERROR(serde->from_string_strict_mode_batch(col_from, *column_to, options,
59
                                                                 parent_null_map));
60
        }
61
62
2
        target_column.column = std::move(column_to);
63
2
        return Status::OK();
64
2
    }
65
};
66
67
template <>
68
class CastToImpl<CastModeType::StrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
69
        : public CastToBase {
70
public:
71
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
72
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
73
6
                        const NullMap::value_type* parent_null_map = nullptr) const override {
74
6
        const auto& col_from =
75
6
                assert_cast<const ColumnDateTimeV2&>(*source_column.column).get_data();
76
77
6
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
78
6
        auto& col_to_data = col_to->get_data();
79
6
        const auto& local_time_zone = state->timezone_obj();
80
81
6
        const auto dt_scale = source_column.type->get_scale();
82
6
        const auto tz_scale = target_column.type->get_scale();
83
84
13
        for (int i = 0; i < input_rows_count; ++i) {
85
10
            if (parent_null_map && parent_null_map[i]) {
86
1
                continue;
87
1
            }
88
89
9
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
90
9
            TimestampTzValue tz_value;
91
92
9
            if (!tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
93
3
                return Status::InvalidArgument(
94
3
                        "can not cast from  datetime : {} to timestamptz in timezone : {}",
95
3
                        from_dt.to_string(), state->timezone());
96
3
            }
97
98
6
            col_to_data[i] = tz_value;
99
6
        }
100
3
        target_column.column = std::move(col_to);
101
3
        return Status::OK();
102
6
    }
103
};
104
105
template <>
106
class CastToImpl<CastModeType::NonStrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
107
        : public CastToBase {
108
public:
109
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
110
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
111
3
                        const NullMap::value_type* parent_null_map = nullptr) const override {
112
3
        const auto& col_from =
113
3
                assert_cast<const ColumnDateTimeV2&>(*source_column.column).get_data();
114
115
3
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
116
3
        auto& col_to_data = col_to->get_data();
117
3
        auto col_null = ColumnBool::create(input_rows_count, 0);
118
3
        auto& col_null_map = col_null->get_data();
119
3
        const auto& local_time_zone = state->timezone_obj();
120
121
3
        const auto dt_scale = source_column.type->get_scale();
122
3
        const auto tz_scale = target_column.type->get_scale();
123
124
14
        for (int i = 0; i < input_rows_count; ++i) {
125
11
            if (parent_null_map && parent_null_map[i]) {
126
1
                continue;
127
1
            }
128
10
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
129
10
            TimestampTzValue tz_value {};
130
131
10
            if (tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
132
8
                col_to_data[i] = tz_value;
133
8
            } else {
134
2
                col_null_map[i] = true;
135
2
            }
136
10
        }
137
138
3
        target_column.column = ColumnNullable::create(std::move(col_to), std::move(col_null));
139
3
        return Status::OK();
140
3
    }
141
};
142
143
template <CastModeType CastMode>
144
class CastToImpl<CastMode, DataTypeTimeStampNs, DataTypeTimeStampTz> : public CastToBase {
145
public:
146
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
147
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
148
1
                        const NullMap::value_type* parent_null_map = nullptr) const override {
149
1
        const auto& col_from =
150
1
                assert_cast<const ColumnTimeStampNs&>(*source_column.column).get_data();
151
1
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
152
1
        auto col_null = ColumnBool::create(input_rows_count, 0);
153
1
        const auto& local_time_zone = state->timezone_obj();
154
1
        const auto target_scale = target_column.type->get_scale();
155
156
6
        for (size_t i = 0; i < input_rows_count; ++i) {
157
5
            if (parent_null_map && parent_null_map[i]) {
158
0
                continue;
159
0
            }
160
5
            DateV2Value<DateTimeV2ValueType> rounded_datetime;
161
5
            TimestampTzValue target;
162
5
            const bool converted =
163
5
                    transform_date_scale(target_scale, TimeStampNsValue::FRACTIONAL_DIGITS,
164
5
                                         rounded_datetime, col_from[i]) &&
165
5
                    target.from_datetime(rounded_datetime, local_time_zone, target_scale,
166
5
                                         target_scale);
167
5
            if (!converted) {
168
0
                if constexpr (CastMode == CastModeType::StrictMode) {
169
0
                    return Status::InvalidArgument(
170
0
                            "can not cast TIMESTAMP_NS {} to timestamptz in timezone {}",
171
0
                            col_from[i].to_string(), state->timezone());
172
0
                }
173
0
                col_null->get_data()[i] = true;
174
0
                continue;
175
0
            }
176
5
            col_to->get_data()[i] = target;
177
5
        }
178
179
1
        if constexpr (CastMode == CastModeType::StrictMode) {
180
0
            target_column.column = std::move(col_to);
181
1
        } else {
182
1
            target_column.column = ColumnNullable::create(std::move(col_to), std::move(col_null));
183
1
        }
184
1
        return Status::OK();
185
1
    }
Unexecuted instantiation: _ZNK5doris10CastToImplILNS_12CastModeTypeE0ENS_19DataTypeTimeStampNsENS_19DataTypeTimeStampTzEE12execute_implEPNS_12RuntimeStateERKNS_21ColumnWithTypeAndNameERS7_mPKh
_ZNK5doris10CastToImplILNS_12CastModeTypeE1ENS_19DataTypeTimeStampNsENS_19DataTypeTimeStampTzEE12execute_implEPNS_12RuntimeStateERKNS_21ColumnWithTypeAndNameERS7_mPKh
Line
Count
Source
148
1
                        const NullMap::value_type* parent_null_map = nullptr) const override {
149
1
        const auto& col_from =
150
1
                assert_cast<const ColumnTimeStampNs&>(*source_column.column).get_data();
151
1
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
152
1
        auto col_null = ColumnBool::create(input_rows_count, 0);
153
1
        const auto& local_time_zone = state->timezone_obj();
154
1
        const auto target_scale = target_column.type->get_scale();
155
156
6
        for (size_t i = 0; i < input_rows_count; ++i) {
157
5
            if (parent_null_map && parent_null_map[i]) {
158
0
                continue;
159
0
            }
160
5
            DateV2Value<DateTimeV2ValueType> rounded_datetime;
161
5
            TimestampTzValue target;
162
5
            const bool converted =
163
5
                    transform_date_scale(target_scale, TimeStampNsValue::FRACTIONAL_DIGITS,
164
5
                                         rounded_datetime, col_from[i]) &&
165
5
                    target.from_datetime(rounded_datetime, local_time_zone, target_scale,
166
5
                                         target_scale);
167
5
            if (!converted) {
168
                if constexpr (CastMode == CastModeType::StrictMode) {
169
                    return Status::InvalidArgument(
170
                            "can not cast TIMESTAMP_NS {} to timestamptz in timezone {}",
171
                            col_from[i].to_string(), state->timezone());
172
                }
173
0
                col_null->get_data()[i] = true;
174
0
                continue;
175
0
            }
176
5
            col_to->get_data()[i] = target;
177
5
        }
178
179
        if constexpr (CastMode == CastModeType::StrictMode) {
180
            target_column.column = std::move(col_to);
181
1
        } else {
182
1
            target_column.column = ColumnNullable::create(std::move(col_to), std::move(col_null));
183
1
        }
184
1
        return Status::OK();
185
1
    }
186
};
187
188
template <>
189
class CastToImpl<CastModeType::StrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
190
        : public CastToBase {
191
public:
192
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
193
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
194
5
                        const NullMap::value_type* parent_null_map = nullptr) const override {
195
5
        const auto& col_from =
196
5
                assert_cast<const ColumnTimeStampTz&>(*source_column.column).get_data();
197
198
5
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
199
5
        auto& col_to_data = col_to->get_data();
200
201
5
        const auto from_scale = source_column.type->get_scale();
202
5
        const auto to_scale = target_column.type->get_scale();
203
204
8
        for (int i = 0; i < input_rows_count; ++i) {
205
6
            if (parent_null_map && parent_null_map[i]) {
206
1
                continue;
207
1
            }
208
209
5
            const auto& from_tz = col_from[i];
210
5
            auto& to_tz = col_to_data[i];
211
212
5
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
213
                // Error reporting must not format an overflowing timestamp in a session
214
                // timezone whose local year may itself be outside the supported range.
215
3
                return Status::InvalidArgument(
216
3
                        "can not cast from  timestamptz : {} UTC to timestamptz in timezone : {}",
217
3
                        from_tz.utc_dt().to_string(from_scale), state->timezone());
218
3
            }
219
5
        }
220
2
        target_column.column = std::move(col_to);
221
2
        return Status::OK();
222
5
    }
223
};
224
225
template <>
226
class CastToImpl<CastModeType::NonStrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
227
        : public CastToBase {
228
public:
229
    Status execute_impl(RuntimeState* state, const ColumnWithTypeAndName& source_column,
230
                        ColumnWithTypeAndName& target_column, size_t input_rows_count,
231
2
                        const NullMap::value_type* parent_null_map = nullptr) const override {
232
2
        const auto& col_from =
233
2
                assert_cast<const ColumnTimeStampTz&>(*source_column.column).get_data();
234
235
2
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
236
2
        auto& col_to_data = col_to->get_data();
237
2
        auto col_null = ColumnBool::create(input_rows_count, 0);
238
2
        auto& col_null_map = col_null->get_data();
239
240
2
        const auto from_scale = source_column.type->get_scale();
241
2
        const auto to_scale = target_column.type->get_scale();
242
243
6
        for (int i = 0; i < input_rows_count; ++i) {
244
4
            if (parent_null_map && parent_null_map[i]) {
245
1
                continue;
246
1
            }
247
3
            const auto& from_tz = col_from[i];
248
3
            auto& to_tz = col_to_data[i];
249
250
3
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
251
2
                col_null_map[i] = true;
252
2
                to_tz = TimestampTzValue(MIN_DATETIME_V2);
253
2
            }
254
3
        }
255
256
2
        target_column.column = ColumnNullable::create(std::move(col_to), std::move(col_null));
257
2
        return Status::OK();
258
2
    }
259
};
260
261
} // namespace doris