Coverage Report

Created: 2026-04-17 17:49

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 "exprs/function/cast/cast_to_timestamptz_impl.hpp"
30
31
namespace doris {
32
33
template <CastModeType Mode>
34
class CastToImpl<Mode, DataTypeString, DataTypeTimeStampTz> : public CastToBase {
35
public:
36
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
37
                        uint32_t result, size_t input_rows_count,
38
4
                        const NullMap::value_type* null_map = nullptr) const override {
39
4
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
40
4
                *block.get_by_position(arguments[0]).column);
41
42
4
        auto to_type = block.get_by_position(result).type;
43
4
        auto serde = remove_nullable(to_type)->get_serde();
44
4
        MutableColumnPtr column_to;
45
46
4
        DataTypeSerDe::FormatOptions options;
47
4
        options.timezone = &context->state()->timezone_obj();
48
49
4
        if constexpr (Mode == CastModeType::NonStrictMode) {
50
2
            auto to_nullable_type = make_nullable(to_type);
51
2
            column_to = to_nullable_type->create_column();
52
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
53
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
54
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
55
2
            column_to = to_type->create_column();
56
2
            RETURN_IF_ERROR(
57
2
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
58
2
        }
59
60
3
        block.get_by_position(result).column = std::move(column_to);
61
4
        return Status::OK();
62
4
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE0ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmPKh
Line
Count
Source
38
2
                        const NullMap::value_type* null_map = nullptr) const override {
39
2
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
40
2
                *block.get_by_position(arguments[0]).column);
41
42
2
        auto to_type = block.get_by_position(result).type;
43
2
        auto serde = remove_nullable(to_type)->get_serde();
44
2
        MutableColumnPtr column_to;
45
46
2
        DataTypeSerDe::FormatOptions options;
47
2
        options.timezone = &context->state()->timezone_obj();
48
49
        if constexpr (Mode == CastModeType::NonStrictMode) {
50
            auto to_nullable_type = make_nullable(to_type);
51
            column_to = to_nullable_type->create_column();
52
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
53
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
54
2
        } else if constexpr (Mode == CastModeType::StrictMode) {
55
2
            column_to = to_type->create_column();
56
2
            RETURN_IF_ERROR(
57
2
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
58
2
        }
59
60
1
        block.get_by_position(result).column = std::move(column_to);
61
2
        return Status::OK();
62
2
    }
_ZNK5doris10CastToImplILNS_12CastModeTypeE1ENS_14DataTypeStringENS_19DataTypeTimeStampTzEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmPKh
Line
Count
Source
38
2
                        const NullMap::value_type* null_map = nullptr) const override {
39
2
        const auto& col_from = assert_cast<const DataTypeString::ColumnType&>(
40
2
                *block.get_by_position(arguments[0]).column);
41
42
2
        auto to_type = block.get_by_position(result).type;
43
2
        auto serde = remove_nullable(to_type)->get_serde();
44
2
        MutableColumnPtr column_to;
45
46
2
        DataTypeSerDe::FormatOptions options;
47
2
        options.timezone = &context->state()->timezone_obj();
48
49
2
        if constexpr (Mode == CastModeType::NonStrictMode) {
50
2
            auto to_nullable_type = make_nullable(to_type);
51
2
            column_to = to_nullable_type->create_column();
52
2
            auto& nullable_col_to = assert_cast<ColumnNullable&>(*column_to);
53
2
            RETURN_IF_ERROR(serde->from_string_batch(col_from, nullable_col_to, options));
54
        } else if constexpr (Mode == CastModeType::StrictMode) {
55
            column_to = to_type->create_column();
56
            RETURN_IF_ERROR(
57
                    serde->from_string_strict_mode_batch(col_from, *column_to, options, null_map));
58
        }
59
60
2
        block.get_by_position(result).column = std::move(column_to);
61
2
        return Status::OK();
62
2
    }
63
};
64
65
template <>
66
class CastToImpl<CastModeType::StrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
67
        : public CastToBase {
68
public:
69
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
70
                        uint32_t result, size_t input_rows_count,
71
2
                        const NullMap::value_type* null_map = nullptr) const override {
72
2
        const auto& col_from =
73
2
                assert_cast<const ColumnDateTimeV2&>(*block.get_by_position(arguments[0]).column)
74
2
                        .get_data();
75
76
2
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
77
2
        auto& col_to_data = col_to->get_data();
78
2
        const auto& local_time_zone = context->state()->timezone_obj();
79
80
2
        const auto dt_scale = block.get_by_position(arguments[0]).type->get_scale();
81
2
        const auto tz_scale = block.get_by_position(result).type->get_scale();
82
83
6
        for (int i = 0; i < input_rows_count; ++i) {
84
5
            if (null_map && null_map[i]) {
85
0
                continue;
86
0
            }
87
88
5
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
89
5
            TimestampTzValue tz_value;
90
91
5
            if (!tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
92
1
                return Status::InternalError(
93
1
                        "can not cast from  datetime : {} to timestamptz in timezone : {}",
94
1
                        from_dt.to_string(), context->state()->timezone());
95
1
            }
96
97
4
            col_to_data[i] = tz_value;
98
4
        }
99
1
        block.get_by_position(result).column = std::move(col_to);
100
1
        return Status::OK();
101
2
    }
102
};
103
104
template <>
105
class CastToImpl<CastModeType::NonStrictMode, DataTypeDateTimeV2, DataTypeTimeStampTz>
106
        : public CastToBase {
107
public:
108
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
109
                        uint32_t result, size_t input_rows_count,
110
2
                        const NullMap::value_type*) const override {
111
2
        const auto& col_from =
112
2
                assert_cast<const ColumnDateTimeV2&>(*block.get_by_position(arguments[0]).column)
113
2
                        .get_data();
114
115
2
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
116
2
        auto& col_to_data = col_to->get_data();
117
2
        auto col_null = ColumnBool::create(input_rows_count, 0);
118
2
        auto& col_null_map = col_null->get_data();
119
2
        const auto& local_time_zone = context->state()->timezone_obj();
120
121
2
        const auto dt_scale = block.get_by_position(arguments[0]).type->get_scale();
122
2
        const auto tz_scale = block.get_by_position(result).type->get_scale();
123
124
10
        for (int i = 0; i < input_rows_count; ++i) {
125
8
            DateV2Value<DateTimeV2ValueType> from_dt {col_from[i]};
126
8
            TimestampTzValue tz_value {};
127
128
8
            if (tz_value.from_datetime(from_dt, local_time_zone, dt_scale, tz_scale)) {
129
7
                col_to_data[i] = tz_value;
130
7
            } else {
131
1
                col_null_map[i] = true;
132
1
            }
133
8
        }
134
135
2
        block.get_by_position(result).column =
136
2
                ColumnNullable::create(std::move(col_to), std::move(col_null));
137
2
        return Status::OK();
138
2
    }
139
};
140
141
template <>
142
class CastToImpl<CastModeType::StrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
143
        : public CastToBase {
144
public:
145
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
146
                        uint32_t result, size_t input_rows_count,
147
0
                        const NullMap::value_type* null_map = nullptr) const override {
148
0
        const auto& col_from =
149
0
                assert_cast<const ColumnTimeStampTz&>(*block.get_by_position(arguments[0]).column)
150
0
                        .get_data();
151
152
0
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
153
0
        auto& col_to_data = col_to->get_data();
154
0
        const auto& local_time_zone = context->state()->timezone_obj();
155
156
0
        const auto from_scale = block.get_by_position(arguments[0]).type->get_scale();
157
0
        const auto to_scale = block.get_by_position(result).type->get_scale();
158
159
0
        for (int i = 0; i < input_rows_count; ++i) {
160
0
            if (null_map && null_map[i]) {
161
0
                continue;
162
0
            }
163
164
0
            const auto& from_tz = col_from[i];
165
0
            auto& to_tz = col_to_data[i];
166
167
0
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
168
0
                return Status::InternalError(
169
0
                        "can not cast from  timestamptz : {} to timestamptz in timezone : {}",
170
0
                        TimestampTzValue {from_tz}.to_string(local_time_zone, from_scale),
171
0
                        context->state()->timezone());
172
0
            }
173
0
        }
174
0
        block.get_by_position(result).column = std::move(col_to);
175
0
        return Status::OK();
176
0
    }
177
};
178
179
template <>
180
class CastToImpl<CastModeType::NonStrictMode, DataTypeTimeStampTz, DataTypeTimeStampTz>
181
        : public CastToBase {
182
public:
183
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
184
                        uint32_t result, size_t input_rows_count,
185
0
                        const NullMap::value_type*) const override {
186
0
        const auto& col_from =
187
0
                assert_cast<const ColumnTimeStampTz&>(*block.get_by_position(arguments[0]).column)
188
0
                        .get_data();
189
190
0
        auto col_to = ColumnTimeStampTz::create(input_rows_count);
191
0
        auto& col_to_data = col_to->get_data();
192
0
        auto col_null = ColumnBool::create(input_rows_count, 0);
193
0
        auto& col_null_map = col_null->get_data();
194
195
0
        const auto from_scale = block.get_by_position(arguments[0]).type->get_scale();
196
0
        const auto to_scale = block.get_by_position(result).type->get_scale();
197
198
0
        for (int i = 0; i < input_rows_count; ++i) {
199
0
            const auto& from_tz = col_from[i];
200
0
            auto& to_tz = col_to_data[i];
201
202
0
            if (!transform_date_scale(to_scale, from_scale, to_tz, from_tz)) {
203
0
                col_null_map[i] = true;
204
0
                to_tz = TimestampTzValue(MIN_DATETIME_V2);
205
0
            }
206
0
        }
207
208
0
        block.get_by_position(result).column =
209
0
                ColumnNullable::create(std::move(col_to), std::move(col_null));
210
0
        return Status::OK();
211
0
    }
212
};
213
214
} // namespace doris