mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
dbms: development [#CONV-2944].
This commit is contained in:
parent
ec8c0b21fd
commit
0652f9da96
@ -13,17 +13,18 @@ namespace DB
|
||||
/** Функции работы с датой и временем.
|
||||
*
|
||||
* toYear, toMonth, toDayOfMonth, toDayOfWeek, toHour, toMinute, toSecond,
|
||||
* toMonday, toStartOfMonth,
|
||||
* toMonday, toStartOfMonth, toStartOfYear, toStartOfMinute, toStartOfHour
|
||||
* toTime,
|
||||
* TODO: makeDate, makeDateTime, now, toStartOfMinute, toStartOfHour, toStartOfYear
|
||||
* now
|
||||
* TODO: makeDate, makeDateTime
|
||||
*
|
||||
* (toDate - расположена в файле FunctionsConversion.h)
|
||||
*
|
||||
* Возвращаемые типы:
|
||||
* toYear -> UInt16
|
||||
* toMonth, toDayOfMonth, toDayOfWeek, toHour, toMinute, toSecond -> UInt8
|
||||
* toMonday, toStartOfMonth -> Date
|
||||
* toTime -> DateTime
|
||||
* toMonday, toStartOfMonth, toStartOfYear -> Date
|
||||
* toStartOfMinute, toStartOfHour, toTime, now -> DateTime
|
||||
*/
|
||||
|
||||
struct ToYearImpl
|
||||
@ -61,7 +62,7 @@ struct ToHourImpl
|
||||
|
||||
struct ToMinuteImpl
|
||||
{
|
||||
static inline UInt8 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toMinute(t); }
|
||||
static inline UInt8 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toMinuteInaccurate(t); }
|
||||
static inline UInt8 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut)
|
||||
{
|
||||
throw Exception("Illegal type Date of argument for function toMinute", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
@ -70,7 +71,7 @@ struct ToMinuteImpl
|
||||
|
||||
struct ToSecondImpl
|
||||
{
|
||||
static inline UInt8 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toSecond(t); }
|
||||
static inline UInt8 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toSecondInaccurate(t); }
|
||||
static inline UInt8 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut)
|
||||
{
|
||||
throw Exception("Illegal type Date of argument for function toSecond", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
@ -79,16 +80,23 @@ struct ToSecondImpl
|
||||
|
||||
struct ToMondayImpl
|
||||
{
|
||||
static inline UInt32 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toWeek(t); }
|
||||
static inline UInt32 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut) { return date_lut.toWeek(Yandex::DayNum_t(d)); }
|
||||
static inline UInt16 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfWeek(date_lut.toDayNum(t)); }
|
||||
static inline UInt16 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfWeek(Yandex::DayNum_t(d)); }
|
||||
};
|
||||
|
||||
struct ToStartOfMonthImpl
|
||||
{
|
||||
static inline UInt32 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayOfMonth(t); }
|
||||
static inline UInt32 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayOfMonth(Yandex::DayNum_t(d)); }
|
||||
static inline UInt16 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfMonth(date_lut.toDayNum(t)); }
|
||||
static inline UInt16 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfMonth(Yandex::DayNum_t(d)); }
|
||||
};
|
||||
|
||||
struct ToStartOfYearImpl
|
||||
{
|
||||
static inline UInt16 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfYear(date_lut.toDayNum(t)); }
|
||||
static inline UInt16 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut) { return date_lut.toFirstDayNumOfYear(Yandex::DayNum_t(d)); }
|
||||
};
|
||||
|
||||
|
||||
struct ToTimeImpl
|
||||
{
|
||||
/// При переводе во время, дату будем приравнивать к 1970-01-02.
|
||||
@ -99,6 +107,24 @@ struct ToTimeImpl
|
||||
}
|
||||
};
|
||||
|
||||
struct ToStartOfMinuteImpl
|
||||
{
|
||||
static inline UInt32 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toStartOfMinute(t); }
|
||||
static inline UInt32 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut)
|
||||
{
|
||||
throw Exception("Illegal type Date of argument for function toStartOfMinute", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
};
|
||||
|
||||
struct ToStartOfHourImpl
|
||||
{
|
||||
static inline UInt32 execute(UInt32 t, Yandex::DateLUTSingleton & date_lut) { return date_lut.toStartOfHour(t); }
|
||||
static inline UInt32 execute(UInt16 d, Yandex::DateLUTSingleton & date_lut)
|
||||
{
|
||||
throw Exception("Illegal type Date of argument for function toStartOfHour", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename FromType, typename ToType, typename Transform, typename Name>
|
||||
struct DateTimeTransformImpl
|
||||
@ -169,6 +195,37 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/// Получить текущее время. (Оно - константа, вычисляется один раз за весь запрос.)
|
||||
class FunctionNow : public IFunction
|
||||
{
|
||||
public:
|
||||
/// Получить имя функции.
|
||||
String getName() const
|
||||
{
|
||||
return "now";
|
||||
}
|
||||
|
||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
||||
{
|
||||
if (arguments.size() != 0)
|
||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||
+ Poco::NumberFormatter::format(arguments.size()) + ", should be 0.",
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
||||
return new DataTypeDateTime;
|
||||
}
|
||||
|
||||
/// Выполнить функцию над блоком.
|
||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||
{
|
||||
block.getByPosition(result).column = new ColumnConstUInt32(
|
||||
block.getByPosition(0).column->size(),
|
||||
time(0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct NameToYear { static const char * get() { return "toYear"; } };
|
||||
struct NameToMonth { static const char * get() { return "toMonth"; } };
|
||||
struct NameToDayOfMonth { static const char * get() { return "toDayOfMonth"; } };
|
||||
@ -178,6 +235,9 @@ struct NameToMinute { static const char * get() { return "toMinute"; } };
|
||||
struct NameToSecond { static const char * get() { return "toSecond"; } };
|
||||
struct NameToMonday { static const char * get() { return "toMonday"; } };
|
||||
struct NameToStartOfMonth { static const char * get() { return "toStartOfMonth"; } };
|
||||
struct NameToStartOfYear { static const char * get() { return "toStartOfYear"; } };
|
||||
struct NameToStartOfMinute { static const char * get() { return "toStartOfMinute"; } };
|
||||
struct NameToStartOfHour { static const char * get() { return "toStartOfHour"; } };
|
||||
struct NameToTime { static const char * get() { return "toTime"; } };
|
||||
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeUInt16, ToYearImpl, NameToYear> FunctionToYear;
|
||||
@ -187,8 +247,11 @@ typedef FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToDayOfWeekImpl, NameT
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToHourImpl, NameToHour> FunctionToHour;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToMinuteImpl, NameToMinute> FunctionToMinute;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToSecondImpl, NameToSecond> FunctionToSecond;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToMondayImpl, NameToMonday> FunctionToMonday;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfMonthImpl, NameToStartOfMonth> FunctionToStartOfMonth;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDate, ToMondayImpl, NameToMonday> FunctionToMonday;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDate, ToStartOfMonthImpl, NameToStartOfMonth> FunctionToStartOfMonth;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDate, ToStartOfYearImpl, NameToStartOfYear> FunctionToStartOfYear;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfMinuteImpl, NameToStartOfMinute> FunctionToStartOfMinute;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfHourImpl, NameToStartOfHour> FunctionToStartOfHour;
|
||||
typedef FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToTimeImpl, NameToTime> FunctionToTime;
|
||||
|
||||
}
|
||||
|
@ -309,8 +309,8 @@ inline void writeDateTimeText(time_t datetime, WriteBuffer & buf)
|
||||
s[9] += values.day_of_month % 10;
|
||||
|
||||
UInt8 hour = date_lut.toHourInaccurate(datetime);
|
||||
UInt8 minute = date_lut.toMinute(datetime);
|
||||
UInt8 second = date_lut.toSecond(datetime);
|
||||
UInt8 minute = date_lut.toMinuteInaccurate(datetime);
|
||||
UInt8 second = date_lut.toSecondInaccurate(datetime);
|
||||
|
||||
s[11] += hour / 10;
|
||||
s[12] += hour % 10;
|
||||
|
@ -83,7 +83,11 @@ namespace FunctionsLibrary
|
||||
("toSecond", new FunctionToSecond)
|
||||
("toMonday", new FunctionToMonday)
|
||||
("toStartOfMonth", new FunctionToStartOfMonth)
|
||||
("toStartOfYear", new FunctionToStartOfYear)
|
||||
("toStartOfMinute", new FunctionToStartOfMinute)
|
||||
("toStartOfHour", new FunctionToStartOfHour)
|
||||
("toTime", new FunctionToTime)
|
||||
("now", new FunctionNow)
|
||||
|
||||
("position", new FunctionPosition)
|
||||
("positionUTF8", new FunctionPositionUTF8)
|
||||
|
@ -80,8 +80,8 @@ public:
|
||||
typedef std::map<UInt16, BlockWithDateInterval> BlocksByMonth;
|
||||
BlocksByMonth blocks_by_month;
|
||||
|
||||
UInt16 min_month = date_lut.toFirstDayOfMonth(Yandex::DayNum_t(min_date));
|
||||
UInt16 max_month = date_lut.toFirstDayOfMonth(Yandex::DayNum_t(max_date));
|
||||
UInt16 min_month = date_lut.toFirstDayNumOfMonth(Yandex::DayNum_t(min_date));
|
||||
UInt16 max_month = date_lut.toFirstDayNumOfMonth(Yandex::DayNum_t(max_date));
|
||||
|
||||
/// Типичный случай - когда месяц один (ничего разделять не нужно).
|
||||
if (min_month == max_month)
|
||||
@ -90,7 +90,7 @@ public:
|
||||
{
|
||||
for (size_t i = 0; i < rows; ++i)
|
||||
{
|
||||
UInt16 month = date_lut.toFirstDayOfMonth(Yandex::DayNum_t(dates[i]));
|
||||
UInt16 month = date_lut.toFirstDayNumOfMonth(Yandex::DayNum_t(dates[i]));
|
||||
|
||||
BlockWithDateInterval & block_for_month = blocks_by_month[month];
|
||||
if (!block_for_month.block)
|
||||
@ -210,8 +210,8 @@ private:
|
||||
new_data_part->name = part_name;
|
||||
new_data_part->size = rows / storage.index_granularity;
|
||||
new_data_part->modification_time = time(0);
|
||||
new_data_part->left_month = date_lut.toFirstDayOfMonth(new_data_part->left_date);
|
||||
new_data_part->right_month = date_lut.toFirstDayOfMonth(new_data_part->right_date);
|
||||
new_data_part->left_month = date_lut.toFirstDayNumOfMonth(new_data_part->left_date);
|
||||
new_data_part->right_month = date_lut.toFirstDayNumOfMonth(new_data_part->right_date);
|
||||
|
||||
storage.data_parts.insert(new_data_part);
|
||||
storage.all_data_parts.insert(new_data_part);
|
||||
@ -1094,8 +1094,8 @@ void StorageMergeTree::loadDataParts()
|
||||
|
||||
part->modification_time = it->getLastModified().epochTime();
|
||||
|
||||
part->left_month = date_lut.toFirstDayOfMonth(part->left_date);
|
||||
part->right_month = date_lut.toFirstDayOfMonth(part->right_date);
|
||||
part->left_month = date_lut.toFirstDayNumOfMonth(part->left_date);
|
||||
part->right_month = date_lut.toFirstDayNumOfMonth(part->right_date);
|
||||
|
||||
data_parts.insert(part);
|
||||
}
|
||||
@ -1367,8 +1367,8 @@ void StorageMergeTree::mergeParts(DataPartPtr left, DataPartPtr right)
|
||||
new_data_part->name = getPartName(
|
||||
new_data_part->left_date, new_data_part->right_date, new_data_part->left, new_data_part->right, new_data_part->level);
|
||||
new_data_part->size = left->size + right->size;
|
||||
new_data_part->left_month = date_lut.toFirstDayOfMonth(new_data_part->left_date);
|
||||
new_data_part->right_month = date_lut.toFirstDayOfMonth(new_data_part->right_date);
|
||||
new_data_part->left_month = date_lut.toFirstDayNumOfMonth(new_data_part->left_date);
|
||||
new_data_part->right_month = date_lut.toFirstDayNumOfMonth(new_data_part->right_date);
|
||||
|
||||
/** Читаем из левого и правого куска, сливаем и пишем в новый.
|
||||
* Попутно вычисляем выражение для сортировки.
|
||||
|
@ -50,8 +50,8 @@ private:
|
||||
m_month = values.month;
|
||||
m_day = values.day_of_month;
|
||||
m_hour = date_lut.toHourInaccurate(time);
|
||||
m_minute = date_lut.toMinute(time);
|
||||
m_second = date_lut.toSecond(time);
|
||||
m_minute = date_lut.toMinuteInaccurate(time);
|
||||
m_second = date_lut.toSecondInaccurate(time);
|
||||
}
|
||||
|
||||
void init(const char * s, size_t length)
|
||||
|
Loading…
Reference in New Issue
Block a user