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

兼容性提升 #238

Merged
merged 17 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/common/datetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern time_t str_to_timestamp(const char* str_time);

// encode DATETIME to string format
// ref: https://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html
extern std::string datetime_to_str(uint64_t datetime);
extern std::string datetime_to_str(uint64_t datetime, int precision_len = 0);
extern uint64_t str_to_datetime(const char* str_time, bool* is_full_datetime = nullptr);

extern time_t datetime_to_timestamp(uint64_t datetime);
Expand Down
44 changes: 36 additions & 8 deletions include/common/expr_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace baikaldb {

struct ExprValue {
pb::PrimitiveType type;
int32_t float_precision_len;
int32_t float_precision_len = -1; // -1代表未定义精度,保留原值的最大精度。0代表不保留小数点部分
union {
bool bool_val;
int8_t int8_val;
Expand All @@ -50,7 +50,7 @@ struct ExprValue {

explicit ExprValue(pb::PrimitiveType type_ = pb::NULL_TYPE) : type(type_) {
_u.int64_val = 0;
float_precision_len = 0;
float_precision_len = -1;
if (type_ == pb::BITMAP) {
_u.bitmap = new(std::nothrow) Roaring();
} else if (type_ == pb::TDIGEST) {
Expand Down Expand Up @@ -124,7 +124,7 @@ struct ExprValue {
}
explicit ExprValue(const pb::ExprValue& value) {
type = value.type();
float_precision_len = 0;
float_precision_len = -1;
switch (type) {
case pb::BOOL:
_u.bool_val = value.bool_val();
Expand Down Expand Up @@ -187,7 +187,7 @@ struct ExprValue {

explicit ExprValue(pb::PrimitiveType primitive_type, const std::string& value_str) {
type = pb::STRING;
float_precision_len = 0;
float_precision_len = -1;
str_val = value_str;
if (primitive_type == pb::STRING
|| primitive_type == pb::HEX
Expand Down Expand Up @@ -624,7 +624,7 @@ struct ExprValue {
case pb::TDIGEST:
return str_val;
case pb::DATETIME:
return datetime_to_str(_u.uint64_val);
return datetime_to_str(_u.uint64_val, float_precision_len);
case pb::TIME:
return time_to_str(_u.int32_val);
case pb::TIMESTAMP:
Expand Down Expand Up @@ -860,14 +860,18 @@ struct ExprValue {
return ret;
}
// 默认不带us
static ExprValue Now(int precision = 0) {
static ExprValue Now(int32_t precision = 0) {
ExprValue tmp(pb::TIMESTAMP);
tmp._u.uint32_val = time(NULL);
tmp.cast_to(pb::DATETIME);
if (precision == 6) {

if (precision > 0 and precision <= 6) {
timeval tv;
gettimeofday(&tv, NULL);
tmp._u.uint64_val |= tv.tv_usec;
tmp.set_precision_len(precision);
} else {
tmp.set_precision_len(0);
}
return tmp;
}
Expand All @@ -883,7 +887,7 @@ struct ExprValue {
ExprValue ret(pb::UINT64);
return ret;
}
static ExprValue UTC_TIMESTAMP() {
static ExprValue UTC_TIMESTAMP(int32_t precision = 0) {
// static int UTC_OFFSET = 8 * 60 * 60;
time_t current_time;
struct tm timeinfo;
Expand All @@ -896,6 +900,11 @@ struct ExprValue {
timeval tv;
gettimeofday(&tv, NULL);
tmp._u.uint64_val |= tv.tv_usec;
if (precision >=0 && precision <= 6) {
tmp.set_precision_len(precision);
} else {
tmp.set_precision_len(0);
}
return tmp;
}
// For string, end-self
Expand Down Expand Up @@ -924,6 +933,25 @@ struct ExprValue {
return ev._u.uint64_val;
}
};

void dt_cast_len() {
if (float_precision_len >= 0 and float_precision_len <= 6) {
uint64_t carry = std::pow(10, (6 - float_precision_len));
uint64_t oldmic = _u.uint64_val & 0xffffff;
uint64_t newmic = ::round(oldmic / carry) * carry;
_u.uint64_val = (_u.uint64_val & ~0xffffff) | newmic;
}
}

void set_precision_len(int32_t precision) {
if (float_precision_len == precision) {
return;
}
float_precision_len = precision;
if (type == pb::DATETIME) {
dt_cast_len();
}
}
};

using ExprValueFlatSet = butil::FlatSet<ExprValue, ExprValue::HashFunction>;
Expand Down
12 changes: 11 additions & 1 deletion include/common/type_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ inline std::string to_mysql_type_string(pb::PrimitiveType type) {
}
}

inline std::string to_mysql_type_full_string(pb::PrimitiveType type) {
inline std::string to_mysql_type_full_string(pb::PrimitiveType type,
int32_t float_total_len = -1, int32_t float_precision_len = -1) {
switch (type) {
case pb::BOOL:
return "tinyint(3)";
Expand All @@ -413,12 +414,21 @@ inline std::string to_mysql_type_full_string(pb::PrimitiveType type) {
case pb::UINT64:
return "bigint(21) unsigned";
case pb::FLOAT:
if (float_total_len != -1 && float_precision_len != -1) {
return "float(" + std::to_string(float_total_len) + "," + std::to_string(float_precision_len) + ")";
}
return "float";
case pb::DOUBLE:
if (float_total_len != -1 && float_precision_len != -1) {
return "double(" + std::to_string(float_total_len) + "," + std::to_string(float_precision_len) + ")";
}
return "double";
case pb::STRING:
return "varchar(1024)";
case pb::DATETIME:
if (float_precision_len > 0 && float_precision_len <= 6) {
return "datetime(" + std::to_string(float_precision_len) + ")";
}
return "datetime";
case pb::DATE:
return "date";
Expand Down
9 changes: 8 additions & 1 deletion include/meta_server/table_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,15 @@ class TableManager {
return false;
}

bool check_field_is_compatible_type(pb::PrimitiveType src_type, pb::PrimitiveType target_type) {
bool check_field_is_compatible_type(const pb::FieldInfo& src_field, const pb::FieldInfo& target_field) {
auto src_type = src_field.mysql_type();
auto target_type = target_field.mysql_type();
if (src_type == target_type) {
if (src_type == pb::DATETIME || src_type == pb::FLOAT || src_type == pb::DOUBLE) {
if (src_field.float_precision_len() > target_field.float_precision_len()) {
wy1433 marked this conversation as resolved.
Show resolved Hide resolved
return false;
}
}
return true;
}
switch (src_type) {
Expand Down
11 changes: 11 additions & 0 deletions include/sqlparser/sql_parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,12 @@ FunctionCallNonKeyword:
fun->fn_name = $1;
$$ = fun;
}
| UTC_TIMESTAMP '(' INTEGER_LIT ')' {
FuncExpr* fun = new_node(FuncExpr);
fun->fn_name = $1;
fun->children.push_back($3, parser->arena);
$$ = fun;
}
| TIMESTAMP '(' ExprList ')' {
FuncExpr* fun = new_node(FuncExpr);
fun->fn_name = $1;
Expand Down Expand Up @@ -4067,6 +4073,11 @@ DateAndTimeType:
// TODO: fractional seconds precision
FieldType* field_type = new_node(FieldType);
field_type->type = MYSQL_TYPE_DATETIME;
if ($2 >= 1 && $2 <= 6) {
field_type->float_len = $2;
} else {
field_type->float_len = 0;
}
$$ = field_type;
}
| TIMESTAMP OptFieldLen
Expand Down
14 changes: 8 additions & 6 deletions src/common/datetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ std::string timestamp_to_str(time_t timestamp, bool is_utc) {
}
// encode DATETIME to string format
// ref: https://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html
std::string datetime_to_str(uint64_t datetime) {
std::string datetime_to_str(uint64_t datetime, int precision_len) {
int year_month = ((datetime >> 46) & 0x1FFFF);
int year = year_month / 13;
int month = year_month % 13;
Expand All @@ -51,12 +51,14 @@ std::string datetime_to_str(uint64_t datetime) {
int macrosec = (datetime & 0xFFFFFF);

char buf[30] = {0};
if (macrosec > 0) {
snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%06d",
year, month, day, hour, minute, second, macrosec);
snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%06d",
year, month, day, hour, minute, second, macrosec);
if (precision_len > 0 and precision_len <=6) {
buf[20 + precision_len] = 0;
wy1433 marked this conversation as resolved.
Show resolved Hide resolved
} else if (precision_len == 0) {
buf[19] = 0;
} else {
snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",
year, month, day, hour, minute, second);
buf[26] = 0;
}
return std::string(buf);
}
Expand Down
3 changes: 2 additions & 1 deletion src/common/information_schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,8 @@ void InformationSchema::init_columns() {
}
record->set_string(record->get_field_by_name("CHARACTER_SET_NAME"), "utf8");
record->set_string(record->get_field_by_name("COLLATION_NAME"), "utf8_general_ci");
record->set_string(record->get_field_by_name("COLUMN_TYPE"), to_mysql_type_full_string(field.type));
record->set_string(record->get_field_by_name("COLUMN_TYPE"),
to_mysql_type_full_string(field.type, field.float_total_len, field.float_precision_len));
std::vector<std::string> extra_vec;
if (field_index.count(field.id) == 0) {
record->set_string(record->get_field_by_name("COLUMN_KEY"), " ");
Expand Down
2 changes: 1 addition & 1 deletion src/common/schema_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3137,7 +3137,7 @@ int SchemaFactory::fill_default_value(SmartRecord record, FieldInfo& field) {
}
ExprValue default_value = field.default_expr_value;
if (field.default_value == "(current_timestamp())") {
default_value = ExprValue::Now();
default_value = ExprValue::Now(field.float_precision_len);
default_value.cast_to(field.type);
}
// mysql非strict mode,不填not null字段会补充空串/0等
Expand Down
5 changes: 3 additions & 2 deletions src/exec/dml_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,10 +716,11 @@ int DMLNode::update_row(RuntimeState* state, SmartRecord record, MemRow* row) {
for (size_t i = 0; i < _update_exprs.size(); i++) {
auto& slot = _update_slots[i];
auto expr = _update_exprs[i];

auto field = _update_fields[slot.field_id()];
if (field->type == pb::FLOAT || field->type == pb::DOUBLE) {
if (field->type == pb::FLOAT || field->type == pb::DOUBLE || field->type == pb::DATETIME) {
auto& expr_value = expr->get_value(row).cast_to(slot.slot_type());
expr_value.float_precision_len = field->float_precision_len;
expr_value.set_precision_len(field->float_precision_len);
record->set_value(record->get_field_by_tag(slot.field_id()), expr_value);
} else {
record->set_value(record->get_field_by_tag(slot.field_id()),
Expand Down
6 changes: 3 additions & 3 deletions src/exec/insert_manager_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ int InsertManagerNode::subquery_open(RuntimeState* state) {
}
// 20190101101112 这种转换现在只支持string类型
pb::PrimitiveType field_type = table_field_map[_selected_field_ids[i]]->type;
result.float_precision_len = table_field_map[_selected_field_ids[i]]->float_precision_len;
result.set_precision_len(table_field_map[_selected_field_ids[i]]->float_precision_len);
if (is_datetime_specic(field_type) && result.is_numberic()) {
result.cast_to(pb::STRING).cast_to(field_type);
} else {
Expand Down Expand Up @@ -655,9 +655,9 @@ void InsertManagerNode::update_record(const SmartRecord& record, const SmartReco
auto& slot = _update_slots[i];
auto expr = _update_exprs[i];
auto field = _update_fields[slot.field_id()];
if (field->type == pb::FLOAT || field->type == pb::DOUBLE) {
if (field->type == pb::FLOAT || field->type == pb::DOUBLE || field->type == pb::DATETIME) {
auto& expr_value = expr->get_value(row).cast_to(slot.slot_type());
expr_value.float_precision_len = field->float_precision_len;
expr_value.set_precision_len(field->float_precision_len);
record->set_value(record->get_field_by_tag(slot.field_id()), expr_value);
} else {
record->set_value(record->get_field_by_tag(slot.field_id()),
Expand Down
2 changes: 1 addition & 1 deletion src/exec/load_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ int LoadNode::fill_field_value(SmartRecord record, FieldInfo& field, ExprValue&
}
ExprValue default_value = field.default_expr_value;
if (field.default_value == "(current_timestamp())") {
default_value = ExprValue::Now();
default_value = ExprValue::Now(field.float_precision_len);
default_value.cast_to(field.type);
}
if (0 != record->set_value(record->get_field_by_tag(field.id), default_value)) {
Expand Down
4 changes: 2 additions & 2 deletions src/exec/update_manager_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ void UpdateManagerNode::update_record(RuntimeState* state, SmartRecord record) {
auto& slot = _update_slots[i];
auto expr = _update_exprs[i];
auto field = _update_fields[slot.field_id()];
if (field->type == pb::FLOAT || field->type == pb::DOUBLE) {
if (field->type == pb::FLOAT || field->type == pb::DOUBLE || field->type == pb::DATETIME) {
auto& expr_value = expr->get_value(row).cast_to(slot.slot_type());
expr_value.float_precision_len = field->float_precision_len;
expr_value.set_precision_len(field->float_precision_len);
record->set_value(record->get_field_by_tag(slot.field_id()), expr_value);
} else {
record->set_value(record->get_field_by_tag(slot.field_id()),
Expand Down
4 changes: 2 additions & 2 deletions src/expr/fn_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void FunctionManager::register_operators() {
register_object_ret("current_date", current_date, pb::DATE);
register_object_ret("curtime", curtime, pb::TIME);
register_object_ret("current_time", current_time, pb::TIME);
register_object_ret("current_timestamp", current_timestamp, pb::TIMESTAMP);
register_object_ret("current_timestamp", current_timestamp, pb::DATETIME);
register_object_ret("timestamp", timestamp, pb::TIMESTAMP);
register_object_ret("date", date, pb::DATE);
register_object_ret("hour", hour, pb::UINT32);
Expand All @@ -192,7 +192,7 @@ void FunctionManager::register_operators() {
register_object_ret("time_to_sec", time_to_sec, pb::UINT32);
register_object_ret("sec_to_time", sec_to_time, pb::TIME);
register_object_ret("weekday", weekday, pb::UINT32);
register_object_ret("datediff", datediff, pb::UINT32);
register_object_ret("datediff", datediff, pb::INT32);
register_object_ret("date_add", date_add, pb::DATETIME);
register_object_ret("date_sub", date_sub, pb::DATETIME);
register_object_ret("extract", extract, pb::UINT32);
Expand Down
18 changes: 14 additions & 4 deletions src/expr/internal_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,11 +912,17 @@ ExprValue now(const std::vector<ExprValue>& input) {
}

ExprValue current_timestamp(const std::vector<ExprValue>& input) {
if (input.size() > 0) {
return ExprValue::Now(input[0].get_numberic<int>());
}
return ExprValue::Now(0);
}

ExprValue utc_timestamp(const std::vector<ExprValue>& input) {
return ExprValue::UTC_TIMESTAMP();
if (input.size() > 0) {
return ExprValue::UTC_TIMESTAMP(input[0].get_numberic<int>());
}
return ExprValue::UTC_TIMESTAMP(0);
}

ExprValue timestamp(const std::vector<ExprValue>& input) {
Expand Down Expand Up @@ -1494,8 +1500,10 @@ ExprValue datediff(const std::vector<ExprValue>& input) {
if (right.type == pb::INT64) {
right.cast_to(pb::STRING);
}
time_t t1 = left.cast_to(pb::TIMESTAMP)._u.uint32_val;
time_t t2 = right.cast_to(pb::TIMESTAMP)._u.uint32_val;
left.cast_to(pb::DATE);
right.cast_to(pb::DATE);
int64_t t1 = left.cast_to(pb::TIMESTAMP)._u.uint32_val;
int64_t t2 = right.cast_to(pb::TIMESTAMP)._u.uint32_val;
ExprValue tmp(pb::INT32);
tmp._u.int32_val = (t1 - t2) / (3600 * 24);
return tmp;
Expand Down Expand Up @@ -2243,7 +2251,9 @@ ExprValue cast_to_datetime(const std::vector<ExprValue>& input) {
return ExprValue::Null();
}
ExprValue tmp = input[0];
return tmp.cast_to(pb::DATETIME);
tmp.cast_to(pb::DATETIME);
tmp.set_precision_len(0);
return tmp;
}

ExprValue cast_to_time(const std::vector<ExprValue>& input) {
Expand Down
4 changes: 2 additions & 2 deletions src/logical_plan/ddl_planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ int DDLPlanner::add_column_def(pb::SchemaInfo& table, parser::ColumnDef* column,
DB_WARNING("data_type is unsupported: %s", column->name->name.value);
return -1;
}
if (data_type == pb::FLOAT || data_type == pb::DOUBLE) {
if (data_type == pb::FLOAT || data_type == pb::DOUBLE || pb::DATETIME) {
if (column->type->total_len != -1) {
field->set_float_total_len((int8_t)column->type->total_len);
}
Expand Down Expand Up @@ -269,7 +269,7 @@ int DDLPlanner::add_column_def(pb::SchemaInfo& table, parser::ColumnDef* column,
} else if (col_option->type == parser::COLUMN_OPT_DEFAULT_VAL && col_option->expr != nullptr) {
if (col_option->expr->to_string() == "(current_timestamp())") {
if (is_current_timestamp_specic(data_type)) {
field->set_default_literal(ExprValue::Now().get_string());
field->set_default_literal(ExprValue::Now(field->float_precision_len()).get_string());
field->set_default_value("(current_timestamp())");
continue;
} else {
Expand Down
Loading