Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flash 411] use compatible new datetime/ date #224

Merged
merged 11 commits into from
Sep 16, 2019
468 changes: 468 additions & 0 deletions dbms/src/Common/MyTime.cpp

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions dbms/src/Common/MyTime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once

#include <Core/Field.h>

namespace DB
{

struct MyTimeBase
{

enum MyTimeType : UInt8
{
TypeDate = 0,
TypeDateTime,
TypeTimeStamp,
TypeDuration
};

UInt16 year; // year <= 9999
UInt8 month; // month <= 12
UInt8 day; // day <= 31
// When it's type is Time, HH:MM:SS may be 839:59:59 to -839:59:59, so use int16 to avoid overflow
Int16 hour;
UInt8 minute;
UInt8 second;
UInt32 micro_second; // ms second <= 999999

UInt8 fsp;

MyTimeBase() = default;
MyTimeBase(UInt64 packed, UInt8 fsp_ = 0);
MyTimeBase(UInt16 year_, UInt8 month_, UInt8 day_, UInt16 hour_, UInt8 minute_, UInt8 second_, UInt32 micro_second_, UInt8 fsp_);

UInt64 toPackedUInt() const;

// DateFormat returns a textual representation of the time value formatted
// according to layout
// See http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
String dateFormat(const String & layout) const;

protected:
void convertDateFormat(char c, String & result) const;
};

struct MyDateTime : public MyTimeBase
{
MyDateTime(UInt64 packed, UInt8 fsp) : MyTimeBase(packed, fsp) {}

MyDateTime(UInt16 year_, UInt8 month_, UInt8 day_, UInt16 hour_, UInt8 minute_, UInt8 second_, UInt32 micro_second_, UInt8 fsp_)
: MyTimeBase(year_, month_, day_, hour_, minute_, second_, micro_second_, fsp_)
{}

String toString() const;
};

struct MyDate : public MyTimeBase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MyDate inherits from MyTimeBase may introduce too much overhead. Can we use a lightweight class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TiDB use uint64 to store date type, we can optimize it in the future.

{
MyDate(UInt64 packed) : MyTimeBase(packed) {}

MyDate(UInt16 year_, UInt8 month_, UInt8 day_) : MyTimeBase(year_, month_, day_, 0, 0, 0, 0, 0) {}

String toString() const { return dateFormat("%Y-%m-%d"); }
};

Field parseMyDateTime(const String & str);

} // namespace DB
4 changes: 4 additions & 0 deletions dbms/src/Core/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ enum class TypeIndex
Function,
AggregateFunction,
LowCardinality,
MyDate,
MyDateTime,
MyTimeStamp,
MyTime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MyTime is mapping TypeDuration in MyTimeType enum? Better to use the same suffix, MyTime => MyDuration or TypeDuration => TypeTime

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep consistent with MySQL Grammar

};

template <typename T> struct TypeId;
Expand Down
10 changes: 5 additions & 5 deletions dbms/src/DataTypes/DataTypeDate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ namespace DB

void DataTypeDate::serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
writeDateText(DayNum_t(static_cast<const ColumnUInt32 &>(column).getData()[row_num]), ostr);
writeDateText(DayNum_t(static_cast<const ColumnUInt16 &>(column).getData()[row_num]), ostr);
}

static void deserializeText(IColumn & column, ReadBuffer & istr)
{
DayNum_t x;
readDateText(x, istr);
static_cast<ColumnUInt32 &>(column).getData().push_back(x);
static_cast<ColumnUInt16 &>(column).getData().push_back(x);
}

void DataTypeDate::serializeTextEscaped(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
Expand All @@ -44,7 +44,7 @@ void DataTypeDate::deserializeTextQuoted(IColumn & column, ReadBuffer & istr) co
assertChar('\'', istr);
readDateText(x, istr);
assertChar('\'', istr);
static_cast<ColumnUInt32 &>(column).getData().push_back(x); /// It's important to do this at the end - for exception safety.
static_cast<ColumnUInt16 &>(column).getData().push_back(x); /// It's important to do this at the end - for exception safety.
}

void DataTypeDate::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettingsJSON &) const
Expand All @@ -60,7 +60,7 @@ void DataTypeDate::deserializeTextJSON(IColumn & column, ReadBuffer & istr) cons
assertChar('"', istr);
readDateText(x, istr);
assertChar('"', istr);
static_cast<ColumnUInt32 &>(column).getData().push_back(x);
static_cast<ColumnUInt16 &>(column).getData().push_back(x);
}

void DataTypeDate::serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
Expand All @@ -74,7 +74,7 @@ void DataTypeDate::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const
{
LocalDate value;
readCSV(value, istr);
static_cast<ColumnUInt32 &>(column).getData().push_back(value.getDayNum());
static_cast<ColumnUInt16 &>(column).getData().push_back(value.getDayNum());
}

bool DataTypeDate::equals(const IDataType & rhs) const
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/DataTypes/DataTypeDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace DB
{

class DataTypeDate final : public DataTypeNumberBase<UInt32>
class DataTypeDate final : public DataTypeNumberBase<UInt16>
{
public:
const char * getFamilyName() const override { return "Date"; }
Expand Down
10 changes: 5 additions & 5 deletions dbms/src/DataTypes/DataTypeDateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ std::string DataTypeDateTime::getName() const

void DataTypeDateTime::serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
writeDateTimeText(static_cast<const ColumnInt64 &>(column).getData()[row_num], ostr, time_zone);
writeDateTimeText(static_cast<const ColumnUInt32 &>(column).getData()[row_num], ostr, time_zone);
}

void DataTypeDateTime::serializeTextEscaped(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
Expand All @@ -46,7 +46,7 @@ void DataTypeDateTime::deserializeTextEscaped(IColumn & column, ReadBuffer & ist
{
time_t x;
readDateTimeText(x, istr, time_zone);
static_cast<ColumnInt64 &>(column).getData().push_back(x);
static_cast<ColumnUInt32 &>(column).getData().push_back(x);
}

void DataTypeDateTime::serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
Expand All @@ -68,7 +68,7 @@ void DataTypeDateTime::deserializeTextQuoted(IColumn & column, ReadBuffer & istr
{
readIntText(x, istr);
}
static_cast<ColumnInt64 &>(column).getData().push_back(x); /// It's important to do this at the end - for exception safety.
static_cast<ColumnUInt32 &>(column).getData().push_back(x); /// It's important to do this at the end - for exception safety.
}

void DataTypeDateTime::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettingsJSON &) const
Expand All @@ -90,7 +90,7 @@ void DataTypeDateTime::deserializeTextJSON(IColumn & column, ReadBuffer & istr)
{
readIntText(x, istr);
}
static_cast<ColumnInt64 &>(column).getData().push_back(x);
static_cast<ColumnUInt32 &>(column).getData().push_back(x);
}

void DataTypeDateTime::serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
Expand All @@ -104,7 +104,7 @@ void DataTypeDateTime::deserializeTextCSV(IColumn & column, ReadBuffer & istr, c
{
time_t x;
readDateTimeCSV(x, istr, time_zone);
static_cast<ColumnInt64 &>(column).getData().push_back(x);
static_cast<ColumnUInt32 &>(column).getData().push_back(x);
}

bool DataTypeDateTime::equals(const IDataType & rhs) const
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/DataTypes/DataTypeDateTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace DB
* Server time zone is the time zone specified in 'timezone' parameter in configuration file,
* or system time zone at the moment of server startup.
*/
class DataTypeDateTime final : public DataTypeNumberBase<Int64>
class DataTypeDateTime final : public DataTypeNumberBase<UInt32>
{
public:
DataTypeDateTime(const std::string & time_zone_name = "");
Expand Down
4 changes: 4 additions & 0 deletions dbms/src/DataTypes/DataTypeFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ void DataTypeFactory::registerSimpleDataType(const String & name, SimpleCreator
void registerDataTypeNumbers(DataTypeFactory & factory);
void registerDataTypeDate(DataTypeFactory & factory);
void registerDataTypeDateTime(DataTypeFactory & factory);
void registerDataTypeMyDateTime(DataTypeFactory & factory);
void registerDataTypeMyDate(DataTypeFactory & factory);
JaySon-Huang marked this conversation as resolved.
Show resolved Hide resolved
void registerDataTypeString(DataTypeFactory & factory);
void registerDataTypeFixedString(DataTypeFactory & factory);
void registerDataTypeDecimal(DataTypeFactory & factory);
Expand All @@ -126,6 +128,7 @@ DataTypeFactory::DataTypeFactory()
registerDataTypeNumbers(*this);
registerDataTypeDate(*this);
registerDataTypeDateTime(*this);
registerDataTypeMyDateTime(*this);
registerDataTypeString(*this);
registerDataTypeFixedString(*this);
registerDataTypeDecimal(*this);
Expand All @@ -138,6 +141,7 @@ DataTypeFactory::DataTypeFactory()
registerDataTypeAggregateFunction(*this);
registerDataTypeNested(*this);
registerDataTypeInterval(*this);
registerDataTypeMyDate(*this);
}

}
87 changes: 87 additions & 0 deletions dbms/src/DataTypes/DataTypeMyDate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

#include <IO/ReadHelpers.h>
#include <IO/WriteHelpers.h>

#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/DataTypeMyDate.h>


namespace DB
{

void DataTypeMyDate::serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
writeMyDateText(static_cast<const ColumnUInt64 &>(column).getData()[row_num], ostr);
}

static void deserializeText(IColumn & column, ReadBuffer & istr)
{
UInt64 x = 0;
readMyDateText(x, istr);
static_cast<ColumnUInt64 &>(column).getData().push_back(x);
}

void DataTypeMyDate::serializeTextEscaped(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
serializeText(column, row_num, ostr);
}

void DataTypeMyDate::deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const { deserializeText(column, istr); }

void DataTypeMyDate::serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
writeChar('\'', ostr);
serializeText(column, row_num, ostr);
writeChar('\'', ostr);
}

void DataTypeMyDate::deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const
{
UInt64 x = 0;
assertChar('\'', istr);
readMyDateText(x, istr);
assertChar('\'', istr);
static_cast<ColumnUInt64 &>(column).getData().push_back(x); /// It's important to do this at the end - for exception safety.
}

void DataTypeMyDate::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettingsJSON &) const
{
writeChar('"', ostr);
serializeText(column, row_num, ostr);
writeChar('"', ostr);
}

void DataTypeMyDate::deserializeTextJSON(IColumn & column, ReadBuffer & istr) const
{
UInt64 x = 0;
assertChar('"', istr);
readMyDateText(x, istr);
assertChar('"', istr);
static_cast<ColumnUInt64 &>(column).getData().push_back(x);
}

void DataTypeMyDate::serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
{
writeChar('"', ostr);
serializeText(column, row_num, ostr);
writeChar('"', ostr);
}

void DataTypeMyDate::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const char /*delimiter*/) const
{
UInt64 value = 0;
readCSV(value, istr);
static_cast<ColumnUInt64 &>(column).getData().push_back(value);
}

bool DataTypeMyDate::equals(const IDataType & rhs) const { return typeid(rhs) == typeid(*this); }


void registerDataTypeMyDate(DataTypeFactory & factory)
{
factory.registerSimpleDataType(
"MyDate", [] { return DataTypePtr(std::make_shared<DataTypeMyDate>()); }, DataTypeFactory::CaseInsensitive);
}

} // namespace DB
33 changes: 33 additions & 0 deletions dbms/src/DataTypes/DataTypeMyDate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <DataTypes/DataTypeMyTimeBase.h>


namespace DB
{

class DataTypeMyDate final : public DataTypeMyTimeBase
{
public:
const char * getFamilyName() const override { return "MyDate"; }

TypeIndex getTypeId() const override { return TypeIndex::MyDate; }

void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextEscaped(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override;
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettingsJSON &) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const char delimiter) const override;

bool canBeUsedAsVersion() const override { return true; }
bool isDateOrDateTime() const override { return true; }
bool canBeInsideNullable() const override { return true; }

bool equals(const IDataType & rhs) const override;
};

} // namespace DB
Loading