2018-11-10 20:09:07 +00:00
# pragma once
2021-05-06 23:17:39 +00:00
2021-10-02 07:13:14 +00:00
# include <base/types.h>
2019-09-26 15:12:40 +00:00
# include <Core/DecimalFunctions.h>
2018-09-26 00:31:40 +00:00
# include <Common/Exception.h>
2021-12-21 13:41:53 +00:00
# include <Common/DateLUTImpl.h>
# include <Common/DateLUT.h>
2018-09-26 00:31:40 +00:00
# include <Columns/ColumnVector.h>
2019-09-26 15:12:40 +00:00
# include <Columns/ColumnDecimal.h>
2018-09-26 00:31:40 +00:00
# include <Functions/FunctionHelpers.h>
2021-05-17 07:30:42 +00:00
# include <Functions/IFunction.h>
2018-09-26 00:31:40 +00:00
# include <Functions/extractTimeZoneFromFunctionArguments.h>
2019-05-04 12:13:59 +00:00
# include <DataTypes/DataTypeDateTime.h>
2019-11-04 14:06:22 +00:00
# include <DataTypes/DataTypeDateTime64.h>
2018-09-26 00:31:40 +00:00
2021-05-06 23:17:39 +00:00
2018-09-26 00:31:40 +00:00
namespace DB
{
namespace ErrorCodes
{
extern const int ILLEGAL_TYPE_OF_ARGUMENT ;
extern const int ILLEGAL_COLUMN ;
}
/** Transformations.
* Represents two functions - from datetime ( UInt32 ) and from date ( UInt16 ) .
*
* Also , the " factor transformation " F is defined for the T transformation .
* This is a transformation of F such that its value identifies the region of monotonicity for T
* ( for a fixed value of F , the transformation T is monotonic ) .
*
* Or , figuratively , if T is similar to taking the remainder of division , then F is similar to division .
*
* Example : for transformation T " get the day number in the month " ( 2015 - 02 - 03 - > 3 ) ,
* factor - transformation F is " round to the nearest month " ( 2015 - 02 - 03 - > 2015 - 02 - 01 ) .
*/
2020-04-17 13:26:44 +00:00
static inline UInt32 dateIsNotSupported ( const char * name )
{
throw Exception ( " Illegal type Date of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
2018-09-26 00:31:40 +00:00
2022-02-15 23:43:08 +00:00
static inline UInt32 dateTimeIsNotSupported ( const char * name )
{
throw Exception ( " Illegal type DateTime of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
2018-09-26 00:31:40 +00:00
/// This factor transformation will say that the function is monotone everywhere.
struct ZeroTransform
{
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 , const DateLUTImpl & ) { return 0 ; }
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 , const DateLUTImpl & ) { return 0 ; }
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 , const DateLUTImpl & ) { return 0 ; }
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 , const DateLUTImpl & ) { return 0 ; }
} ;
struct ToDateImpl
{
static constexpr auto name = " toDate " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
{
2022-08-25 09:28:15 +00:00
return t < 0 ? 0 : std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
2022-08-17 15:33:36 +00:00
return time_zone . toDayNum ( t ) ;
2018-09-26 00:31:40 +00:00
}
2022-08-14 22:16:35 +00:00
static inline UInt16 execute ( Int32 t , const DateLUTImpl & )
2021-07-15 11:41:52 +00:00
{
2022-08-25 09:28:15 +00:00
return t < 0 ? 0 : std : : min ( t , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & )
{
return d ;
}
2021-07-15 11:40:45 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToDate32Impl
{
static constexpr auto name = " toDate32 " ;
static inline Int32 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return Int32 ( time_zone . toDayNum ( t ) ) ;
}
static inline Int32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
/// Don't saturate.
return Int32 ( time_zone . toDayNum < Int64 > ( t ) ) ;
2021-07-15 11:40:45 +00:00
}
static inline Int32 execute ( Int32 d , const DateLUTImpl & )
{
return d ;
}
static inline Int32 execute ( UInt16 d , const DateLUTImpl & )
{
return d ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfDayImpl
{
static constexpr auto name = " toStartOfDay " ;
2020-04-17 13:26:44 +00:00
//TODO: right now it is hardcoded to produce DateTime only, needs fixing later. See date_and_time_type_details::ResultDataTypeMap for deduction of result type example.
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
2022-08-21 21:02:27 +00:00
if ( t . whole < 0 | | ( t . whole > = 0 & & t . fractional < 0 ) )
2022-08-14 22:16:35 +00:00
return 0 ;
2022-08-25 09:28:15 +00:00
return time_zone . toDate ( std : : min < Int64 > ( t . whole , Int64 ( 0xffffffff ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toDate ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
2022-08-14 22:16:35 +00:00
if ( d < 0 )
return 0 ;
2022-08-23 21:44:08 +00:00
auto date_time = time_zone . fromDayNum ( ExtendedDayNum ( d ) ) ;
2022-08-17 15:33:36 +00:00
if ( date_time < = 0xffffffff )
return date_time ;
else
return time_zone . toDate ( 0xffffffff ) ;
2021-07-15 11:41:52 +00:00
}
2019-02-12 14:18:00 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
2022-08-23 21:44:08 +00:00
auto date_time = time_zone . fromDayNum ( ExtendedDayNum ( d ) ) ;
2022-08-21 21:02:27 +00:00
return date_time < 0xffffffff ? date_time : time_zone . toDate ( 0xffffffff ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToMondayImpl
{
static constexpr auto name = " toMonday " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2020-04-17 13:26:44 +00:00
{
2022-08-21 21:02:27 +00:00
return t < 0 ? 0 : time_zone . toFirstDayNumOfWeek ( ExtendedDayNum (
2022-08-25 09:28:15 +00:00
std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
2020-04-17 13:26:44 +00:00
return time_zone . toFirstDayNumOfWeek ( t ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2021-07-15 11:41:52 +00:00
{
2022-08-25 09:28:15 +00:00
return d < 0 ? 0 : time_zone . toFirstDayNumOfWeek ( ExtendedDayNum ( std : : min ( d , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toFirstDayNumOfWeek ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
2022-09-16 09:37:30 +00:00
return time_zone . toFirstDayNumOfWeek ( time_zone . toDayNum ( t ) ) ;
2022-09-09 13:25:52 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfWeek ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfMonthImpl
{
static constexpr auto name = " toStartOfMonth " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2020-04-17 13:26:44 +00:00
{
2022-08-25 09:28:15 +00:00
return t < 0 ? 0 : time_zone . toFirstDayNumOfMonth ( ExtendedDayNum ( std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
2022-08-17 15:33:36 +00:00
return time_zone . toFirstDayNumOfMonth ( ExtendedDayNum ( time_zone . toDayNum ( t ) ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2021-07-15 11:41:52 +00:00
{
2022-08-25 09:28:15 +00:00
return d < 0 ? 0 : time_zone . toFirstDayNumOfMonth ( ExtendedDayNum ( std : : min ( d , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toFirstDayNumOfMonth ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfMonth ( time_zone . toDayNum ( t ) ) ;
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfMonth ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
2022-02-07 20:38:36 +00:00
struct ToLastDayOfMonthImpl
{
static constexpr auto name = " toLastDayOfMonth " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2022-02-07 20:38:36 +00:00
{
2022-08-22 14:36:10 +00:00
if ( t < 0 )
return 0 ;
/// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value.
2022-08-25 09:28:15 +00:00
return time_zone . toLastDayNumOfMonth ( ExtendedDayNum ( std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( 0xFFF9 ) ) ) ) ;
2022-02-07 20:38:36 +00:00
}
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toLastDayNumOfMonth ( time_zone . toDayNum ( t ) ) ;
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2022-02-07 20:38:36 +00:00
{
2022-08-22 14:36:10 +00:00
if ( d < 0 )
return 0 ;
/// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value.
2022-08-25 09:28:15 +00:00
return time_zone . toLastDayNumOfMonth ( ExtendedDayNum ( std : : min ( d , Int32 ( 0xFFF9 ) ) ) ) ;
2022-02-07 20:38:36 +00:00
}
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2022-08-22 14:36:10 +00:00
/// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value.
return time_zone . toLastDayNumOfMonth ( DayNum ( std : : min ( d , UInt16 ( 0xFFF9 ) ) ) ) ;
2022-02-07 20:38:36 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toLastDayNumOfMonth ( time_zone . toDayNum ( t ) ) ;
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toLastDayNumOfMonth ( ExtendedDayNum ( d ) ) ;
}
2022-02-07 20:38:36 +00:00
using FactorTransform = ZeroTransform ;
} ;
2018-09-26 00:31:40 +00:00
struct ToStartOfQuarterImpl
{
static constexpr auto name = " toStartOfQuarter " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2020-04-17 13:26:44 +00:00
{
2022-08-25 09:28:15 +00:00
return t < 0 ? 0 : time_zone . toFirstDayNumOfQuarter ( ExtendedDayNum ( std : : min < Int64 > ( Int64 ( time_zone . toDayNum ( t ) ) , Int64 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toFirstDayNumOfQuarter ( time_zone . toDayNum ( t ) ) ;
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2021-07-15 11:41:52 +00:00
{
2022-08-25 09:28:15 +00:00
return d < 0 ? 0 : time_zone . toFirstDayNumOfQuarter ( ExtendedDayNum ( std : : min < Int32 > ( d , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toFirstDayNumOfQuarter ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfQuarter ( time_zone . toDayNum ( t ) ) ;
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfQuarter ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfYearImpl
{
static constexpr auto name = " toStartOfYear " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2020-04-17 13:26:44 +00:00
{
2022-08-25 09:28:15 +00:00
return t < 0 ? 0 : time_zone . toFirstDayNumOfYear ( ExtendedDayNum ( std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toFirstDayNumOfYear ( time_zone . toDayNum ( t ) ) ;
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2021-07-15 11:41:52 +00:00
{
2022-08-25 09:28:15 +00:00
return d < 0 ? 0 : time_zone . toFirstDayNumOfYear ( ExtendedDayNum ( std : : min ( d , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toFirstDayNumOfYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfYear ( time_zone . toDayNum ( t ) ) ;
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToTimeImpl
{
2021-11-08 07:19:31 +00:00
/// When transforming to time, the date will be equated to 1970-01-02.
2018-09-26 00:31:40 +00:00
static constexpr auto name = " toTime " ;
2020-04-17 13:26:44 +00:00
static UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
return time_zone . toTime ( t . whole ) + 86400 ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toTime ( t ) + 86400 ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ToDateImpl ;
} ;
struct ToStartOfMinuteImpl
{
static constexpr auto name = " toStartOfMinute " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
2022-08-21 21:02:27 +00:00
if ( t . whole < 0 | | ( t . whole > = 0 & & t . fractional < 0 ) )
2022-08-14 22:16:35 +00:00
return 0 ;
2022-08-25 09:28:15 +00:00
return time_zone . toStartOfMinute ( std : : min < Int64 > ( t . whole , Int64 ( 0xffffffff ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfMinute ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2020-05-06 12:56:03 +00:00
// Rounding towards negative infinity.
// 1.01 => 1.00
// -1.01 => -2
struct ToStartOfSecondImpl
{
static constexpr auto name = " toStartOfSecond " ;
static inline DateTime64 execute ( const DateTime64 & datetime64 , Int64 scale_multiplier , const DateLUTImpl & )
{
auto fractional_with_sign = DecimalUtils : : getFractionalPartWithScaleMultiplier < DateTime64 , true > ( datetime64 , scale_multiplier ) ;
// given that scale is 3, scale_multiplier is 1000
// for DateTime64 value of 123.456:
// 123456 - 456 = 123000
// for DateTime64 value of -123.456:
// -123456 - (1000 + (-456)) = -124000
if ( fractional_with_sign < 0 )
fractional_with_sign + = scale_multiplier ;
return datetime64 - fractional_with_sign ;
}
static inline UInt32 execute ( UInt32 , const DateLUTImpl & )
{
throw Exception ( " Illegal type DateTime of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2020-05-06 12:56:03 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2022-02-13 14:54:03 +00:00
struct ToStartOfMillisecondImpl
{
static constexpr auto name = " toStartOfMillisecond " ;
static inline DateTime64 execute ( const DateTime64 & datetime64 , Int64 scale_multiplier , const DateLUTImpl & )
{
// given that scale is 6, scale_multiplier is 1000000
// for DateTime64 value of 123.456789:
// 123456789 - 789 = 123456000
// for DateTime64 value of -123.456789:
// -123456789 - (1000 + (-789)) = -123457000
2022-02-13 21:04:09 +00:00
if ( scale_multiplier = = 1000 )
{
return datetime64 ;
}
else if ( scale_multiplier < = 1000 )
{
2022-02-13 14:54:03 +00:00
return datetime64 * ( 1000 / scale_multiplier ) ;
}
else
{
auto droppable_part_with_sign = DecimalUtils : : getFractionalPartWithScaleMultiplier < DateTime64 , true > ( datetime64 , scale_multiplier / 1000 ) ;
if ( droppable_part_with_sign < 0 )
droppable_part_with_sign + = scale_multiplier ;
return datetime64 - droppable_part_with_sign ;
}
}
static inline UInt32 execute ( UInt32 , const DateLUTImpl & )
{
throw Exception ( " Illegal type DateTime of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfMicrosecondImpl
{
static constexpr auto name = " toStartOfMicrosecond " ;
static inline DateTime64 execute ( const DateTime64 & datetime64 , Int64 scale_multiplier , const DateLUTImpl & )
{
// @see ToStartOfMillisecondImpl
2022-02-13 21:04:09 +00:00
if ( scale_multiplier = = 1000000 )
{
return datetime64 ;
}
else if ( scale_multiplier < = 1000000 )
{
2022-02-13 14:54:03 +00:00
return datetime64 * ( 1000000 / scale_multiplier ) ;
}
else
{
auto droppable_part_with_sign = DecimalUtils : : getFractionalPartWithScaleMultiplier < DateTime64 , true > ( datetime64 , scale_multiplier / 1000000 ) ;
if ( droppable_part_with_sign < 0 )
droppable_part_with_sign + = scale_multiplier ;
return datetime64 - droppable_part_with_sign ;
}
}
static inline UInt32 execute ( UInt32 , const DateLUTImpl & )
{
throw Exception ( " Illegal type DateTime of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfNanosecondImpl
{
static constexpr auto name = " toStartOfNanosecond " ;
static inline DateTime64 execute ( const DateTime64 & datetime64 , Int64 scale_multiplier , const DateLUTImpl & )
{
// @see ToStartOfMillisecondImpl
2022-02-13 21:04:09 +00:00
if ( scale_multiplier = = 1000000000 )
{
2022-02-13 14:54:03 +00:00
return datetime64 ;
}
2022-02-13 21:04:09 +00:00
else if ( scale_multiplier < = 1000000000 )
{
2022-02-13 14:54:03 +00:00
return datetime64 * ( 1000000000 / scale_multiplier ) ;
}
else
{
throw Exception ( " Illegal type of argument for function " + std : : string ( name ) + " , DateTime64 expected " , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
}
static inline UInt32 execute ( UInt32 , const DateLUTImpl & )
{
throw Exception ( " Illegal type DateTime of argument for function " + std : : string ( name ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2022-04-22 02:49:59 +00:00
struct ToStartOfFiveMinutesImpl
2018-09-26 00:31:40 +00:00
{
2022-04-22 02:49:59 +00:00
static constexpr auto name = " toStartOfFiveMinutes " ;
2018-09-26 00:31:40 +00:00
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
2022-04-22 02:49:59 +00:00
return time_zone . toStartOfFiveMinutes ( t . whole ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
2022-04-22 02:49:59 +00:00
return time_zone . toStartOfFiveMinutes ( t ) ;
2018-09-26 00:31:40 +00:00
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2019-02-06 22:50:04 +00:00
struct ToStartOfTenMinutesImpl
{
static constexpr auto name = " toStartOfTenMinutes " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfTenMinutes ( t . whole ) ;
}
2019-02-06 22:50:04 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfTenMinutes ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2019-02-06 22:50:04 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2018-09-26 00:31:40 +00:00
struct ToStartOfFifteenMinutesImpl
{
static constexpr auto name = " toStartOfFifteenMinutes " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfFifteenMinutes ( t . whole ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfFifteenMinutes ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
2022-04-15 22:20:47 +00:00
/// Round to start of half-an-hour length interval with unspecified offset. This transform is specific for Metrica web analytics system.
2018-09-26 00:31:40 +00:00
struct TimeSlotImpl
{
static constexpr auto name = " timeSlot " ;
2020-04-17 13:26:44 +00:00
//static inline DecimalUtils::DecimalComponents<DateTime64> execute(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl &)
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & )
{
return t . whole / 1800 * 1800 ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & )
{
return t / 1800 * 1800 ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfHourImpl
{
static constexpr auto name = " toStartOfHour " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
2022-08-21 21:02:27 +00:00
if ( t . whole < 0 | | ( t . whole > = 0 & & t . fractional < 0 ) )
return 0 ;
2022-08-25 09:28:15 +00:00
return time_zone . toStartOfHour ( std : : min < Int64 > ( t . whole , Int64 ( 0xffffffff ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toStartOfHour ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2022-09-21 12:58:57 +00:00
static inline DecimalUtils : : DecimalComponents < DateTime64 > execute_extended_result ( const DecimalUtils : : DecimalComponents < DateTime64 > & t , const DateLUTImpl & time_zone )
{
return { time_zone . toStartOfHour ( Int64 ( t . whole ) ) , 0 } ;
}
2022-09-22 07:07:04 +00:00
static inline UInt32 execute_extended_result ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToYearImpl
{
static constexpr auto name = " toYear " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toYear ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toYear ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToQuarterImpl
{
static constexpr auto name = " toQuarter " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toQuarter ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toQuarter ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toQuarter ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toQuarter ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToStartOfYearImpl ;
} ;
struct ToMonthImpl
{
static constexpr auto name = " toMonth " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toMonth ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toMonth ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toMonth ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toMonth ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToStartOfYearImpl ;
} ;
struct ToDayOfMonthImpl
{
static constexpr auto name = " toDayOfMonth " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfMonth ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfMonth ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfMonth ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toDayOfMonth ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToStartOfMonthImpl ;
} ;
struct ToDayOfWeekImpl
{
static constexpr auto name = " toDayOfWeek " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfWeek ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfWeek ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfWeek ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toDayOfWeek ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToMondayImpl ;
} ;
struct ToDayOfYearImpl
{
static constexpr auto name = " toDayOfYear " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfYear ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfYear ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toDayOfYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toDayOfYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToStartOfYearImpl ;
} ;
struct ToHourImpl
{
static constexpr auto name = " toHour " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toHour ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toHour ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ToDateImpl ;
} ;
2021-02-02 15:35:45 +00:00
struct TimezoneOffsetImpl
2021-02-02 03:01:20 +00:00
{
static constexpr auto name = " timezoneOffset " ;
2020-04-17 13:26:44 +00:00
static inline time_t execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . timezoneOffset ( t ) ;
}
2021-02-02 03:01:20 +00:00
static inline time_t execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . timezoneOffset ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline time_t execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2021-02-02 03:01:20 +00:00
static inline time_t execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2021-02-02 15:35:45 +00:00
using FactorTransform = ToTimeImpl ;
2021-02-02 03:01:20 +00:00
} ;
2018-09-26 00:31:40 +00:00
struct ToMinuteImpl
{
static constexpr auto name = " toMinute " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toMinute ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toMinute ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ToStartOfHourImpl ;
} ;
struct ToSecondImpl
{
static constexpr auto name = " toSecond " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toSecond ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toSecond ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 , const DateLUTImpl & )
{
return dateIsNotSupported ( name ) ;
}
using FactorTransform = ToStartOfMinuteImpl ;
} ;
struct ToISOYearImpl
{
static constexpr auto name = " toISOYear " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toISOYear ( time_zone . toDayNum ( t ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toISOYear ( time_zone . toDayNum ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toISOYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toISOYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToStartOfISOYearImpl
{
static constexpr auto name = " toStartOfISOYear " ;
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2020-04-17 13:26:44 +00:00
{
2022-09-16 08:40:15 +00:00
return t < 0 ? 0 : time_zone . toFirstDayNumOfISOYear ( ExtendedDayNum ( std : : min ( Int32 ( time_zone . toDayNum ( t ) ) , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2020-04-17 13:26:44 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toFirstDayNumOfISOYear ( time_zone . toDayNum ( t ) ) ;
}
2022-09-09 13:25:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
2021-07-15 11:41:52 +00:00
{
2022-09-16 08:40:15 +00:00
return d < 0 ? 0 : time_zone . toFirstDayNumOfISOYear ( ExtendedDayNum ( std : : min ( d , Int32 ( DATE_LUT_MAX_DAY_NUM ) ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toFirstDayNumOfISOYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
2022-09-15 12:48:09 +00:00
static inline Int64 execute_extended_result ( Int64 t , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfISOYear ( time_zone . toDayNum ( t ) ) ;
}
2022-09-15 12:48:09 +00:00
static inline Int32 execute_extended_result ( Int32 d , const DateLUTImpl & time_zone )
2022-09-09 13:25:52 +00:00
{
return time_zone . toFirstDayNumOfISOYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
using FactorTransform = ZeroTransform ;
} ;
struct ToISOWeekImpl
{
static constexpr auto name = " toISOWeek " ;
2020-04-17 13:26:44 +00:00
static inline UInt8 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toISOWeek ( time_zone . toDayNum ( t ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toISOWeek ( time_zone . toDayNum ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt8 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toISOWeek ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt8 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toISOWeek ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ToISOYearImpl ;
} ;
struct ToRelativeYearNumImpl
{
static constexpr auto name = " toRelativeYearNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toYear ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toYear ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toYear ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toYear ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeQuarterNumImpl
{
static constexpr auto name = " toRelativeQuarterNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toRelativeQuarterNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeQuarterNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeQuarterNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toRelativeQuarterNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeMonthNumImpl
{
static constexpr auto name = " toRelativeMonthNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toRelativeMonthNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeMonthNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeMonthNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toRelativeMonthNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeWeekNumImpl
{
static constexpr auto name = " toRelativeWeekNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toRelativeWeekNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeWeekNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeWeekNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toRelativeWeekNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeDayNumImpl
{
static constexpr auto name = " toRelativeDayNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toDayNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt16 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toDayNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt16 execute ( Int32 d , const DateLUTImpl & )
{
return static_cast < ExtendedDayNum > ( d ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt16 execute ( UInt16 d , const DateLUTImpl & )
{
return static_cast < DayNum > ( d ) ;
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeHourNumImpl
{
static constexpr auto name = " toRelativeHourNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toRelativeHourNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeHourNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeHourNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toRelativeHourNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeMinuteNumImpl
{
static constexpr auto name = " toRelativeMinuteNum " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( Int64 t , const DateLUTImpl & time_zone )
2018-09-26 00:31:40 +00:00
{
return time_zone . toRelativeMinuteNum ( t ) ;
}
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeMinuteNum ( static_cast < time_t > ( t ) ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . toRelativeMinuteNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toRelativeMinuteNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToRelativeSecondNumImpl
{
static constexpr auto name = " toRelativeSecondNum " ;
2020-04-17 13:26:44 +00:00
static inline Int64 execute ( Int64 t , const DateLUTImpl & )
{
return t ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & )
{
return t ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
return time_zone . fromDayNum ( ExtendedDayNum ( d ) ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . fromDayNum ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToYYYYMMImpl
{
static constexpr auto name = " toYYYYMM " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMM ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMM ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMM ( ExtendedDayNum ( d ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMM ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToYYYYMMDDImpl
{
static constexpr auto name = " toYYYYMMDD " ;
2020-04-17 13:26:44 +00:00
static inline UInt32 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMMDD ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMMDD ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt32 execute ( Int32 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMMDD ( ExtendedDayNum ( d ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt32 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMMDD ( DayNum ( d ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
struct ToYYYYMMDDhhmmssImpl
{
static constexpr auto name = " toYYYYMMDDhhmmss " ;
2020-04-17 13:26:44 +00:00
static inline UInt64 execute ( Int64 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMMDDhhmmss ( t ) ;
}
2018-09-26 00:31:40 +00:00
static inline UInt64 execute ( UInt32 t , const DateLUTImpl & time_zone )
{
return time_zone . toNumYYYYMMDDhhmmss ( t ) ;
}
2021-07-15 11:41:52 +00:00
static inline UInt64 execute ( Int32 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMMDDhhmmss ( time_zone . toDate ( ExtendedDayNum ( d ) ) ) ;
2021-07-15 11:41:52 +00:00
}
2018-09-26 00:31:40 +00:00
static inline UInt64 execute ( UInt16 d , const DateLUTImpl & time_zone )
{
2021-11-08 07:19:31 +00:00
return time_zone . toNumYYYYMMDDhhmmss ( time_zone . toDate ( DayNum ( d ) ) ) ;
2018-09-26 00:31:40 +00:00
}
using FactorTransform = ZeroTransform ;
} ;
2022-09-15 12:48:09 +00:00
template < typename FromType , typename ToType , typename Transform , bool is_extended_result = false >
2018-09-26 00:31:40 +00:00
struct Transformer
{
2019-10-30 13:59:38 +00:00
template < typename FromTypeVector , typename ToTypeVector >
static void vector ( const FromTypeVector & vec_from , ToTypeVector & vec_to , const DateLUTImpl & time_zone , const Transform & transform )
2018-09-26 00:31:40 +00:00
{
size_t size = vec_from . size ( ) ;
vec_to . resize ( size ) ;
for ( size_t i = 0 ; i < size ; + + i )
2022-09-15 12:48:09 +00:00
if constexpr ( is_extended_result )
vec_to [ i ] = transform . execute_extended_result ( vec_from [ i ] , time_zone ) ;
2022-09-09 13:25:52 +00:00
else
vec_to [ i ] = transform . execute ( vec_from [ i ] , time_zone ) ;
2018-09-26 00:31:40 +00:00
}
} ;
2022-09-15 12:48:09 +00:00
template < typename FromDataType , typename ToDataType , typename Transform , bool is_extended_result = false >
2018-09-26 00:31:40 +00:00
struct DateTimeTransformImpl
{
2021-05-06 23:17:39 +00:00
static ColumnPtr execute (
const ColumnsWithTypeAndName & arguments , const DataTypePtr & result_type , size_t /*input_rows_count*/ , const Transform & transform = { } )
2018-09-26 00:31:40 +00:00
{
2022-09-15 12:48:09 +00:00
using Op = Transformer < typename FromDataType : : FieldType , typename ToDataType : : FieldType , Transform , is_extended_result > ;
2018-09-26 00:31:40 +00:00
2020-10-17 14:23:37 +00:00
const ColumnPtr source_col = arguments [ 0 ] . column ;
2019-10-30 13:59:38 +00:00
if ( const auto * sources = checkAndGetColumn < typename FromDataType : : ColumnType > ( source_col . get ( ) ) )
2018-09-26 00:31:40 +00:00
{
2020-10-17 14:23:37 +00:00
auto mutable_result_col = result_type - > createColumn ( ) ;
2019-10-30 13:59:38 +00:00
auto * col_to = assert_cast < typename ToDataType : : ColumnType * > ( mutable_result_col . get ( ) ) ;
2021-05-14 20:07:08 +00:00
WhichDataType result_data_type ( result_type ) ;
2021-05-14 21:46:17 +00:00
if ( result_data_type . isDateTime ( ) | | result_data_type . isDateTime64 ( ) )
2021-05-14 20:07:08 +00:00
{
const auto & time_zone = dynamic_cast < const TimezoneMixin & > ( * result_type ) . getTimeZone ( ) ;
Op : : vector ( sources - > getData ( ) , col_to - > getData ( ) , time_zone , transform ) ;
}
else
{
2021-06-28 16:56:15 +00:00
size_t time_zone_argument_position = 1 ;
if constexpr ( std : : is_same_v < ToDataType , DataTypeDateTime64 > )
time_zone_argument_position = 2 ;
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments ( arguments , time_zone_argument_position , 0 ) ;
Op : : vector ( sources - > getData ( ) , col_to - > getData ( ) , time_zone , transform ) ;
2021-05-14 20:07:08 +00:00
}
2019-10-30 13:59:38 +00:00
2020-10-17 14:23:37 +00:00
return mutable_result_col ;
2018-09-26 00:31:40 +00:00
}
else
{
2020-10-17 14:23:37 +00:00
throw Exception ( " Illegal column " + arguments [ 0 ] . column - > getName ( )
2018-09-26 00:31:40 +00:00
+ " of first argument of function " + Transform : : name ,
ErrorCodes : : ILLEGAL_COLUMN ) ;
}
}
} ;
}