Coverage Report

Created: 2026-03-16 16:04

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_timestamptz.h"
23
#include "core/data_type/primitive_type.h"
24
#include "core/types.h"
25
#include "core/value/timestamptz_value.h"
26
#include "core/value/vdatetime_value.h"
27
#include "exprs/function/cast/cast_base.h"
28
#include "exprs/function/cast/cast_to_datetimev2_impl.hpp"
29
#include "util/io_helper.h"
30
31
namespace doris {
32
33
struct CastToTimstampTz {
34
    static inline bool from_string(const StringRef& from, TimestampTzValue& to,
35
                                   CastParameters& params, const cctz::time_zone* local_time_zone,
36
                                   uint32_t to_scale);
37
};
38
39
inline bool CastToTimstampTz::from_string(const StringRef& from, TimestampTzValue& to,
40
                                          CastParameters& params,
41
                                          const cctz::time_zone* local_time_zone,
42
103
                                          uint32_t to_scale) {
43
103
    return to.from_string(from, local_time_zone, params, to_scale);
44
103
}
45
46
template <CastModeType Mode>
47
class CastToImpl<Mode, DataTypeString, DataTypeTimeStampTz> : public CastToBase {
48
public:
49
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
50
                        uint32_t result, size_t input_rows_count,
51
4
                        const NullMap::value_type* null_map = nullptr) const override {
52
4
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
53
4
                *block.get_by_position(arguments[0]).column);
54
55
4
        auto to_type = block.get_by_position(result).type;
56
4
        auto serde = remove_nullable(to_type)->get_serde();
57
4
        MutableColumnPtr column_to;
58
59
4
        DataTypeSerDe::FormatOptions options;
60
4
        options.timezone = &context->state()->timezone_obj();
61
62
4
        if constexpr (Mode == CastModeType::NonStrictMode) {
63
2
            auto to_nullable_type = make_nullable(to_type);
64
2
            column_to = to_nullable_type->create_column();
65
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
66
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
67
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
68
2
            column_to = to_type->create_column();
69
2
            RETURN_IF_ERROR(
70
2
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
71
2
        }
72
73
3
        block.get_by_position(result).column = std::move(column_to);
74
4
        return Status::OK();
75
4
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE0ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmPKh
Line
Count
Source
51
2
                        const NullMap::value_type* null_map = nullptr) const override {
52
2
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
53
2
                *block.get_by_position(arguments[0]).column);
54
55
2
        auto to_type = block.get_by_position(result).type;
56
2
        auto serde = remove_nullable(to_type)->get_serde();
57
2
        MutableColumnPtr column_to;
58
59
2
        DataTypeSerDe::FormatOptions options;
60
2
        options.timezone = &context->state()->timezone_obj();
61
62
        if constexpr (Mode == CastModeType::NonStrictMode) {
63
            auto to_nullable_type = make_nullable(to_type);
64
            column_to = to_nullable_type->create_column();
65
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
66
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
67
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
68
2
            column_to = to_type->create_column();
69
2
            RETURN_IF_ERROR(
70
2
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
71
2
        }
72
73
1
        block.get_by_position(result).column = std::move(column_to);
74
2
        return Status::OK();
75
2
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE1ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmPKh
Line
Count
Source
51
2
                        const NullMap::value_type* null_map = nullptr) const override {
52
2
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
53
2
                *block.get_by_position(arguments[0]).column);
54
55
2
        auto to_type = block.get_by_position(result).type;
56
2
        auto serde = remove_nullable(to_type)->get_serde();
57
2
        MutableColumnPtr column_to;
58
59
2
        DataTypeSerDe::FormatOptions options;
60
2
        options.timezone = &context->state()->timezone_obj();
61
62
2
        if constexpr (Mode == CastModeType::NonStrictMode) {
63
2
            auto to_nullable_type = make_nullable(to_type);
64
2
            column_to = to_nullable_type->create_column();
65
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
66
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
67
        } else if constexpr (Mode == CastModeType::StrictMode) {
68
            column_to = to_type->create_column();
69
            RETURN_IF_ERROR(
70
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
71
        }
72
73
2
        block.get_by_position(result).column = std::move(column_to);
74
2
        return Status::OK();
75
2
    }
76
};
77
78
template <>
79
class CastToImpl<CastModeType::StrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
80
        : public CastToBase {
81
public:
82
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
83
                        uint32_t result, size_t input_rows_count,
84
2
                        const NullMap::value_type* null_map = nullptr) const override {
85
2
        const auto& col_from =
86
2
                assert_cast<const ColumnDateTimeV2&>(*block.get_by_position(arguments[0]).column)
87
2
                        .get_data();
88
89
2
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
90
2
        auto& col_to_data = col_to->get_data();
91
2
        const auto& local_time_zone = context->state()->timezone_obj();
92
93
2
        const auto dt_scale = block.get_by_position(arguments[0]).type->get_scale();
94
2
        const auto tz_scale = block.get_by_position(result).type->get_scale();
95
96
6
        for (int i = 0; i < input_rows_count; ++i) {
97
5
            if (null_map && null_map[i]) {
98
0
                continue;
99
0
            }
100
101
5
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
102
5
            TimestampTzValue tz_value;
103
104
5
            if (!tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
105
1
                return Status::InternalError(
106
1
                        "can not cast from  datetime : {} to timestamptz in timezone : {}",
107
1
                        from_dt.to_string(), context->state()->timezone());
108
1
            }
109
110
4
            col_to_data[i] = tz_value;
111
4
        }
112
1
        block.get_by_position(result).column = std::move(col_to);
113
1
        return Status::OK();
114
2
    }
115
};
116
117
template <>
118
class CastToImpl<CastModeType::NonStrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
119
        : public CastToBase {
120
public:
121
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
122
                        uint32_t result, size_t input_rows_count,
123
2
                        const NullMap::value_type*) const override {
124
2
        const auto& col_from =
125
2
                assert_cast<const ColumnDateTimeV2&>(*block.get_by_position(arguments[0]).column)
126
2
                        .get_data();
127
128
2
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
129
2
        auto& col_to_data = col_to->get_data();
130
2
        auto col_null = ColumnBool::create(input_rows_count, 0);
131
2
        auto& col_null_map = col_null->get_data();
132
2
        const auto& local_time_zone = context->state()->timezone_obj();
133
134
2
        const auto dt_scale = block.get_by_position(arguments[0]).type->get_scale();
135
2
        const auto tz_scale = block.get_by_position(result).type->get_scale();
136
137
10
        for (int i = 0; i < input_rows_count; ++i) {
138
8
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
139
8
            TimestampTzValue tz_value {};
140
141
8
            if (tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
142
7
                col_to_data[i] = tz_value;
143
7
            } else {
144
1
                col_null_map[i] = true;
145
1
            }
146
8
        }
147
148
2
        block.get_by_position(result).column =
149
2
                ColumnNullable::create(std::move(col_to), std::move(col_null));
150
2
        return Status::OK();
151
2
    }
152
};
153
154
template <>
155
class CastToImpl<CastModeType::StrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
156
        : public CastToBase {
157
public:
158
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
159
                        uint32_t result, size_t input_rows_count,
160
0
                        const NullMap::value_type* null_map = nullptr) const override {
161
0
        const auto& col_from =
162
0
                assert_cast<const ColumnTimeStampTz&>(*block.get_by_position(arguments[0]).column)
163
0
                        .get_data();
164
165
0
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
166
0
        auto& col_to_data = col_to->get_data();
167
0
        const auto& local_time_zone = context->state()->timezone_obj();
168
169
0
        const auto from_scale = block.get_by_position(arguments[0]).type->get_scale();
170
0
        const auto to_scale = block.get_by_position(result).type->get_scale();
171
172
0
        for (int i = 0; i < input_rows_count; ++i) {
173
0
            if (null_map && null_map[i]) {
174
0
                continue;
175
0
            }
176
177
0
            const auto& from_tz = col_from[i];
178
0
            auto& to_tz = col_to_data[i];
179
180
0
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
181
0
                return Status::InternalError(
182
0
                        "can not cast from  timestamptz : {} to timestamptz in timezone : {}",
183
0
                        TimestampTzValue {from_tz}.to_string(local_time_zone, from_scale),
184
0
                        context->state()->timezone());
185
0
            }
186
0
        }
187
0
        block.get_by_position(result).column = std::move(col_to);
188
0
        return Status::OK();
189
0
    }
190
};
191
192
template <>
193
class CastToImpl<CastModeType::NonStrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
194
        : public CastToBase {
195
public:
196
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
197
                        uint32_t result, size_t input_rows_count,
198
0
                        const NullMap::value_type*) const override {
199
0
        const auto& col_from =
200
0
                assert_cast<const ColumnTimeStampTz&>(*block.get_by_position(arguments[0]).column)
201
0
                        .get_data();
202
203
0
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
204
0
        auto& col_to_data = col_to->get_data();
205
0
        auto col_null = ColumnBool::create(input_rows_count, 0);
206
0
        auto& col_null_map = col_null->get_data();
207
208
0
        const auto from_scale = block.get_by_position(arguments[0]).type->get_scale();
209
0
        const auto to_scale = block.get_by_position(result).type->get_scale();
210
211
0
        for (int i = 0; i < input_rows_count; ++i) {
212
0
            const auto& from_tz = col_from[i];
213
0
            auto& to_tz = col_to_data[i];
214
215
0
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
216
0
                col_null_map[i] = true;
217
0
                to_tz = TimestampTzValue(MIN_DATETIME_V2);
218
0
            }
219
0
        }
220
221
0
        block.get_by_position(result).column =
222
0
                ColumnNullable::create(std::move(col_to), std::move(col_null));
223
0
        return Status::OK();
224
0
    }
225
};
226
227
namespace CastWrapper {
228
inline WrapperType create_timestamptz_wrapper(FunctionContext* context,
229
0
                                              const DataTypePtr& from_type) {
230
0
    std::shared_ptr<CastToBase> cast_to_timestamptz;
231
232
0
    auto make_timestamptz_wrapper = [&](const auto& types) -> bool {
233
0
        using Types = std::decay_t<decltype(types)>;
234
0
        using FromDataType = typename Types::LeftType;
235
        if constexpr (CastUtil::IsBaseCastFromType<FromDataType> ||
236
0
                      IsTimeStampTzType<FromDataType>) {
237
0
            if (context->enable_strict_mode()) {
238
0
                cast_to_timestamptz = std::make_shared<
239
0
                        CastToImpl<CastModeType::StrictMode, FromDataType, DataTypeTimeStampTz>>();
240
0
            } else {
241
0
                cast_to_timestamptz =
242
0
                        std::make_shared<CastToImpl<CastModeType::NonStrictMode, FromDataType,
243
0
                                                    DataTypeTimeStampTz>>();
244
0
            }
245
0
            return true;
246
        } else {
247
            return false;
248
        }
249
0
    };
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE2EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE3EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE4EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE5EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE6EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE7EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE8EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeNumberILNS_13PrimitiveTypeE9EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_15DataTypeDecimalILNS_13PrimitiveTypeE28EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_15DataTypeDecimalILNS_13PrimitiveTypeE29EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_15DataTypeDecimalILNS_13PrimitiveTypeE20EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_15DataTypeDecimalILNS_13PrimitiveTypeE30EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_15DataTypeDecimalILNS_13PrimitiveTypeE35EEEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_12DataTypeDateEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeDateV2EvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_18DataTypeDateTimeV2EvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_16DataTypeDateTimeEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeTimeV2EvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_19DataTypeTimeStampTzEvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_12DataTypeIPv4EvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_12DataTypeIPv6EvEEEEbSB_
Unexecuted instantiation: _ZZN5doris11CastWrapper26create_timestamptz_wrapperEPNS_15FunctionContextERKSt10shared_ptrIKNS_9IDataTypeEEENKUlRKT_E_clINS_8TypePairINS_14DataTypeStringEvEEEEbSB_
250
251
0
    if (!call_on_index_and_data_type<void>(from_type->get_primitive_type(),
252
0
                                           make_timestamptz_wrapper)) {
253
0
        return create_unsupport_wrapper(
254
0
                fmt::format("CAST AS timestamptz not supported {}", from_type->get_name()));
255
0
    }
256
257
0
    return [cast_to_timestamptz](FunctionContext* context, Block& block,
258
0
                                 const ColumnNumbers& arguments, uint32_t result,
259
0
                                 size_t input_rows_count,
260
0
                                 const NullMap::value_type* null_map = nullptr) {
261
0
        return cast_to_timestamptz->execute_impl(context, block, arguments, result,
262
0
                                                 input_rows_count, null_map);
263
0
    };
264
0
}
265
266
}; // namespace CastWrapper
267
268
} // namespace doris