mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Add new function toLastDayOfMonth
This commit is contained in:
parent
15bcbb97e5
commit
57ff05b6e6
@ -393,6 +393,13 @@ This is a generalization of other functions named `toStartOf*`. For example,
|
|||||||
`toStartOfInterval(t, INTERVAL 1 day)` returns the same as `toStartOfDay(t)`,
|
`toStartOfInterval(t, INTERVAL 1 day)` returns the same as `toStartOfDay(t)`,
|
||||||
`toStartOfInterval(t, INTERVAL 15 minute)` returns the same as `toStartOfFifteenMinutes(t)` etc.
|
`toStartOfInterval(t, INTERVAL 15 minute)` returns the same as `toStartOfFifteenMinutes(t)` etc.
|
||||||
|
|
||||||
|
## toLastDayOfMonth {#toLastDayOfMonth}
|
||||||
|
|
||||||
|
Rounds up a date or date with time to the last day of the month.
|
||||||
|
Returns the date.
|
||||||
|
|
||||||
|
Alias: `LAST_DAY`.
|
||||||
|
|
||||||
## toTime {#totime}
|
## toTime {#totime}
|
||||||
|
|
||||||
Converts a date with time to a certain fixed date, while preserving the time.
|
Converts a date with time to a certain fixed date, while preserving the time.
|
||||||
|
@ -360,6 +360,27 @@ public:
|
|||||||
return toDayNum(LUTIndex(i - (lut[i].day_of_month - 1)));
|
return toDayNum(LUTIndex(i - (lut[i].day_of_month - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Round up to last day of month.
|
||||||
|
template <typename DateOrTime>
|
||||||
|
inline Time toLastDayOfMonth(DateOrTime v) const
|
||||||
|
{
|
||||||
|
const LUTIndex i = toLUTIndex(v);
|
||||||
|
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||||
|
return lut_saturated[i - lut[i].day_of_month + lut[i].days_in_month].date;
|
||||||
|
else
|
||||||
|
return lut[i - lut[i].day_of_month + lut[i].days_in_month].date;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DateOrTime>
|
||||||
|
inline auto toLastDayNumOfMonth(DateOrTime v) const
|
||||||
|
{
|
||||||
|
const LUTIndex i = toLUTIndex(v);
|
||||||
|
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||||
|
return toDayNum(LUTIndexWithSaturation(i - lut[i].day_of_month + lut[i].days_in_month));
|
||||||
|
else
|
||||||
|
return toDayNum(LUTIndex(i - lut[i].day_of_month + lut[i].days_in_month));
|
||||||
|
}
|
||||||
|
|
||||||
/// Round down to start of quarter.
|
/// Round down to start of quarter.
|
||||||
template <typename DateOrTime>
|
template <typename DateOrTime>
|
||||||
inline auto toFirstDayNumOfQuarter(DateOrTime v) const
|
inline auto toFirstDayNumOfQuarter(DateOrTime v) const
|
||||||
|
@ -142,6 +142,8 @@ TEST(DateLUTTest, TimeValuesInMiddleOfRange)
|
|||||||
EXPECT_EQ(lut.addYears(time, 10), 1884270011 /*time_t*/);
|
EXPECT_EQ(lut.addYears(time, 10), 1884270011 /*time_t*/);
|
||||||
EXPECT_EQ(lut.timeToString(time), "2019-09-16 19:20:11" /*std::string*/);
|
EXPECT_EQ(lut.timeToString(time), "2019-09-16 19:20:11" /*std::string*/);
|
||||||
EXPECT_EQ(lut.dateToString(time), "2019-09-16" /*std::string*/);
|
EXPECT_EQ(lut.dateToString(time), "2019-09-16" /*std::string*/);
|
||||||
|
EXPECT_EQ(lut.toLastDayOfMonth(time), 1569790800 /*time_t*/);
|
||||||
|
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(18169) /*DayNum*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -202,6 +204,8 @@ TEST(DateLUTTest, TimeValuesAtLeftBoderOfRange)
|
|||||||
EXPECT_EQ(lut.addYears(time, 10), 315532800 /*time_t*/);
|
EXPECT_EQ(lut.addYears(time, 10), 315532800 /*time_t*/);
|
||||||
EXPECT_EQ(lut.timeToString(time), "1970-01-01 00:00:00" /*std::string*/);
|
EXPECT_EQ(lut.timeToString(time), "1970-01-01 00:00:00" /*std::string*/);
|
||||||
EXPECT_EQ(lut.dateToString(time), "1970-01-01" /*std::string*/);
|
EXPECT_EQ(lut.dateToString(time), "1970-01-01" /*std::string*/);
|
||||||
|
EXPECT_EQ(lut.toLastDayOfMonth(time), 2592000 /*time_t*/);
|
||||||
|
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(30) /*DayNum*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
||||||
@ -264,6 +268,8 @@ TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
|||||||
|
|
||||||
EXPECT_EQ(lut.timeToString(time), "2106-01-31 01:17:53" /*std::string*/);
|
EXPECT_EQ(lut.timeToString(time), "2106-01-31 01:17:53" /*std::string*/);
|
||||||
EXPECT_EQ(lut.dateToString(time), "2106-01-31" /*std::string*/);
|
EXPECT_EQ(lut.dateToString(time), "2106-01-31" /*std::string*/);
|
||||||
|
EXPECT_EQ(lut.toLastDayOfMonth(time), 4294339200 /*time_t*/); // 2016-01-01
|
||||||
|
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(49703));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,6 +174,30 @@ struct ToStartOfMonthImpl
|
|||||||
using FactorTransform = ZeroTransform;
|
using FactorTransform = ZeroTransform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ToLastDayOfMonthImpl
|
||||||
|
{
|
||||||
|
static constexpr auto name = "toLastDayOfMonth";
|
||||||
|
|
||||||
|
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
|
||||||
|
{
|
||||||
|
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
|
||||||
|
}
|
||||||
|
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
|
||||||
|
{
|
||||||
|
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
|
||||||
|
}
|
||||||
|
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
|
||||||
|
{
|
||||||
|
return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d));
|
||||||
|
}
|
||||||
|
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
|
||||||
|
{
|
||||||
|
return time_zone.toLastDayNumOfMonth(DayNum(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
using FactorTransform = ZeroTransform;
|
||||||
|
};
|
||||||
|
|
||||||
struct ToStartOfQuarterImpl
|
struct ToStartOfQuarterImpl
|
||||||
{
|
{
|
||||||
static constexpr auto name = "toStartOfQuarter";
|
static constexpr auto name = "toStartOfQuarter";
|
||||||
|
@ -20,6 +20,7 @@ void registerFunctionToISOYear(FunctionFactory &);
|
|||||||
void registerFunctionToCustomWeek(FunctionFactory &);
|
void registerFunctionToCustomWeek(FunctionFactory &);
|
||||||
void registerFunctionToModifiedJulianDay(FunctionFactory &);
|
void registerFunctionToModifiedJulianDay(FunctionFactory &);
|
||||||
void registerFunctionToStartOfMonth(FunctionFactory &);
|
void registerFunctionToStartOfMonth(FunctionFactory &);
|
||||||
|
void registerFunctionToLastDayOfMonth(FunctionFactory &);
|
||||||
void registerFunctionToStartOfQuarter(FunctionFactory &);
|
void registerFunctionToStartOfQuarter(FunctionFactory &);
|
||||||
void registerFunctionToStartOfYear(FunctionFactory &);
|
void registerFunctionToStartOfYear(FunctionFactory &);
|
||||||
void registerFunctionToStartOfMinute(FunctionFactory &);
|
void registerFunctionToStartOfMinute(FunctionFactory &);
|
||||||
@ -91,6 +92,7 @@ void registerFunctionsDateTime(FunctionFactory & factory)
|
|||||||
registerFunctionToCustomWeek(factory);
|
registerFunctionToCustomWeek(factory);
|
||||||
registerFunctionToModifiedJulianDay(factory);
|
registerFunctionToModifiedJulianDay(factory);
|
||||||
registerFunctionToStartOfMonth(factory);
|
registerFunctionToStartOfMonth(factory);
|
||||||
|
registerFunctionToLastDayOfMonth(factory);
|
||||||
registerFunctionToStartOfQuarter(factory);
|
registerFunctionToStartOfQuarter(factory);
|
||||||
registerFunctionToStartOfYear(factory);
|
registerFunctionToStartOfYear(factory);
|
||||||
registerFunctionToStartOfSecond(factory);
|
registerFunctionToStartOfSecond(factory);
|
||||||
|
21
src/Functions/toLastDayOfMonth.cpp
Normal file
21
src/Functions/toLastDayOfMonth.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <Functions/FunctionFactory.h>
|
||||||
|
#include <Functions/DateTimeTransforms.h>
|
||||||
|
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
using FunctionToLastDayOfMonth = FunctionDateOrDateTimeToSomething<DataTypeDate, ToLastDayOfMonthImpl>;
|
||||||
|
|
||||||
|
void registerFunctionToLastDayOfMonth(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionToLastDayOfMonth>();
|
||||||
|
|
||||||
|
/// MysQL compatibility alias.
|
||||||
|
factory.registerFunction<FunctionToLastDayOfMonth>("LAST_DAY", FunctionFactory::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +229,7 @@ std::map<std::string, FuncRet> func_to_return_type = {
|
|||||||
{"torelativeweeknum", FuncRet(Type::i, "")}, {"torelativedaynum", FuncRet(Type::i, "")}, {"torelativehournum", FuncRet(Type::i, "")},
|
{"torelativeweeknum", FuncRet(Type::i, "")}, {"torelativedaynum", FuncRet(Type::i, "")}, {"torelativehournum", FuncRet(Type::i, "")},
|
||||||
{"torelativeminutenum", FuncRet(Type::i, "")}, {"torelativesecondsnum", FuncRet(Type::i, "")}, {"datediff", FuncRet(Type::d | Type::dt, "")},
|
{"torelativeminutenum", FuncRet(Type::i, "")}, {"torelativesecondsnum", FuncRet(Type::i, "")}, {"datediff", FuncRet(Type::d | Type::dt, "")},
|
||||||
{"formatdatetime", FuncRet(Type::s, "")}, {"now", FuncRet(Type::dt | Type::d, "now()")}, {"today", FuncRet(Type::d | Type::dt, "today()")},
|
{"formatdatetime", FuncRet(Type::s, "")}, {"now", FuncRet(Type::dt | Type::d, "now()")}, {"today", FuncRet(Type::d | Type::dt, "today()")},
|
||||||
{"yesterday", FuncRet(Type::d | Type::dt, "yesterday()")}
|
{"yesterday", FuncRet(Type::d | Type::dt, "yesterday()")}, {"tolastdayofmonth", FuncRet(Type::dt | Type::d, "")}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set<std::string> func_args_same_types = {
|
std::set<std::string> func_args_same_types = {
|
||||||
@ -253,7 +253,7 @@ std::map<std::string, ColumnType> func_to_param_type = {
|
|||||||
{"tostartofinterval", Type::d | Type::dt}, {"totime", Type::d | Type::dt}, {"torelativehonthnum", Type::d | Type::dt},
|
{"tostartofinterval", Type::d | Type::dt}, {"totime", Type::d | Type::dt}, {"torelativehonthnum", Type::d | Type::dt},
|
||||||
{"torelativeweeknum", Type::d | Type::dt}, {"torelativedaynum", Type::d | Type::dt}, {"torelativehournum", Type::d | Type::dt},
|
{"torelativeweeknum", Type::d | Type::dt}, {"torelativedaynum", Type::d | Type::dt}, {"torelativehournum", Type::d | Type::dt},
|
||||||
{"torelativeminutenum", Type::d | Type::dt}, {"torelativesecondnum", Type::d | Type::dt}, {"datediff", Type::d | Type::dt},
|
{"torelativeminutenum", Type::d | Type::dt}, {"torelativesecondnum", Type::d | Type::dt}, {"datediff", Type::d | Type::dt},
|
||||||
{"formatdatetime", Type::dt}
|
{"formatdatetime", Type::dt}, {"tolastdayofmonth", Type::d | Type::dt}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user