blob: 7b7f1139a52f6b30fa2a5b640bb64e2f17eb226f [file]
// 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.
#pragma once
#include <cctz/time_zone.h>
#include <sys/types.h>
#include <cstdint>
#include <functional>
#include <string>
#include "common/status.h"
#include "vec/runtime/vdatetime_value.h"
namespace doris {
struct StringRef;
namespace vectorized {
struct CastParameters;
}
// TIMESTAMPTZ can be understood as a DATETIME type with timezone conversion functionality.
// Doris automatically handles timezone conversions internally.
// The storage format of TIMESTAMPTZ is the same as DATETIMEV2, both are 8-byte integers
// representing microseconds from 0001-01-01 00:00:00.000000 to 9999-12-31 23:59:59.999999.
// TIMESTAMPTZ does not store timezone information; conversions are performed during read and write
// operations according to the specified timezone.
// This requires that both reading and writing operations need a timezone parameter.
// Therefore, we implement a separate TIMESTAMPTZ type to prevent misuse.
class TimestampTzValue {
public:
using underlying_value = uint64_t;
const static TimestampTzValue DEFAULT_VALUE;
explicit TimestampTzValue(underlying_value u64) : _utc_dt(u64) {}
TimestampTzValue() : _utc_dt(MIN_DATETIME_V2) {}
TimestampTzValue(const DateV2Value<DateTimeV2ValueType>& dt) : _utc_dt(dt) {}
DateV2Value<DateTimeV2ValueType> utc_dt() const { return _utc_dt; }
// Returns an integer value for storage in a column
underlying_value to_date_int_val() const { return _utc_dt.to_date_int_val(); }
// Outputs a string representation with timezone information in the format +03:00
std::string to_string(const cctz::time_zone& local_time_zone, int scale = 6) const;
// Parses a string, CastParameters can control whether strict mode is used
bool from_string(const StringRef& str, const cctz::time_zone* local_time_zone,
vectorized::CastParameters& params, uint32_t to_scale);
// Converts from a datetime value
bool from_datetime(const DateV2Value<DateTimeV2ValueType>& dt,
const cctz::time_zone& local_time_zone, int dt_scale, int tz_scale);
// Converts to a datetime value
bool to_datetime(DateV2Value<DateTimeV2ValueType>& dt, const cctz::time_zone& local_time_zone,
int dt_scale, int tz_scale) const;
// Default column value (since the default value 0 for UInt64 is not a valid datetime)
static underlying_value default_column_value() { return MIN_DATETIME_V2; }
// Check if the datetime part is valid
bool is_valid_date() const { return _utc_dt.is_valid_date(); }
uint16_t year() const { return _utc_dt.year(); }
uint8_t month() const { return _utc_dt.month(); }
uint8_t day() const { return _utc_dt.day(); }
uint8_t hour() const { return _utc_dt.hour(); }
uint8_t minute() const { return _utc_dt.minute(); }
uint8_t second() const { return _utc_dt.second(); }
uint32_t microsecond() const { return _utc_dt.microsecond(); }
int64_t daynr() const { return _utc_dt.daynr(); }
int quarter() const { return _utc_dt.quarter(); }
// Methods needed for time rounding
int64_t datetime_diff_in_seconds(const TimestampTzValue& other) const {
return _utc_dt.datetime_diff_in_seconds(other._utc_dt);
}
template <TimeUnit unit>
bool date_set_interval(const TimeInterval& interval) {
return _utc_dt.date_set_interval<unit>(interval);
}
template <TimeUnit unit>
void unchecked_set_time_unit(uint32_t value) {
_utc_dt.unchecked_set_time_unit<unit>(value);
}
void unchecked_set_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute,
uint8_t second, uint32_t microsecond = 0) {
_utc_dt.unchecked_set_time(year, month, day, hour, minute, second, microsecond);
}
bool check_range_and_set_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
uint8_t minute, uint8_t second, uint32_t microsecond = 0) {
return _utc_dt.check_range_and_set_time(year, month, day, hour, minute, second,
microsecond);
}
void set_int_val(underlying_value value) { _utc_dt.set_int_val(value); }
// Special constant for first day
static const TimestampTzValue FIRST_DAY;
template <TimeUnit unit, bool need_check = true>
bool date_add_interval(const TimeInterval& interval) {
return _utc_dt.date_add_interval<unit, need_check>(interval);
}
// truncate datetime to specified unit
template <TimeUnit unit>
bool datetime_trunc() {
return _utc_dt.datetime_trunc<unit>();
}
void from_unixtime(int64_t timestamp, const cctz::time_zone& ctz) {
_utc_dt.from_unixtime(timestamp, ctz);
}
void set_microsecond(uint64_t microsecond) { _utc_dt.set_microsecond(microsecond); }
void unix_timestamp(int64_t* timestamp, const cctz::time_zone& ctz) const {
_utc_dt.unix_timestamp(timestamp, ctz);
}
// Convert UTC time to local time based on the given timezone
void convert_utc_to_local(const cctz::time_zone& local_time_zone,
DateV2Value<DateTimeV2ValueType>& dt) const;
// Convert local time to UTC time based on the given timezone
void convert_local_to_utc(const cctz::time_zone& local_time_zone,
const DateV2Value<DateTimeV2ValueType>& dt);
TimestampTzValue& operator++() {
++_utc_dt;
return *this;
}
TimestampTzValue& operator--() {
--_utc_dt;
return *this;
}
TimestampTzValue& operator+=(int64_t rhs) {
_utc_dt += rhs;
return *this;
}
TimestampTzValue& operator-=(int64_t rhs) {
_utc_dt -= rhs;
return *this;
}
bool operator==(const TimestampTzValue& rhs) const { return _utc_dt == rhs._utc_dt; }
bool operator!=(const TimestampTzValue& rhs) const { return _utc_dt != rhs._utc_dt; }
bool operator<(const TimestampTzValue& rhs) const { return _utc_dt < rhs._utc_dt; }
bool operator<=(const TimestampTzValue& rhs) const { return _utc_dt <= rhs._utc_dt; }
bool operator>(const TimestampTzValue& rhs) const { return _utc_dt > rhs._utc_dt; }
bool operator>=(const TimestampTzValue& rhs) const { return _utc_dt >= rhs._utc_dt; }
private:
DateV2Value<DateTimeV2ValueType> _utc_dt;
};
inline const TimestampTzValue TimestampTzValue::DEFAULT_VALUE =
TimestampTzValue(DateV2Value<DateTimeV2ValueType>::DEFAULT_VALUE.to_date_int_val());
} // namespace doris
template <>
struct std::hash<doris::TimestampTzValue> {
size_t operator()(const doris::TimestampTzValue& v) const {
auto int_val = v.to_date_int_val();
return doris::HashUtil::hash(&int_val, sizeof(int_val), 0);
}
};