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

fix(tianmu): add the TIME_to_ulonglong_time_round logic, and fix up precision loss problem and value overflow problem (#1173) #1894

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 26 additions & 0 deletions mysql-test/suite/tianmu/r/issue1173.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
DROP DATABASE IF EXISTS issue1173;
CREATE DATABASE issue1173;
USE issue1173;
CREATE TABLE t1 (a TIME(1) NOT NULL);
INSERT INTO t1 VALUES ('00:00:02.9');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t1;
a a & a a | a a^0 a<<1 a<<0 a>>1 bit_count(a)
00:00:02.9 3 3 3 6 3 1 2
CREATE TABLE t2 (a DATETIME(1) NOT NULL);
INSERT INTO t2 VALUES ('2001-01-01 00:00:02.9');
INSERT INTO t2 VALUES ('2001-01-01 23:59:59.9');
INSERT INTO t2 VALUES ('9999-12-31 23:59:59.9');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t2;
a a & a a | a a^0 a<<1 a<<0 a>>1 bit_count(a)
2001-01-01 00:00:02.9 20010101000003 20010101000003 20010101000003 40020202000006 20010101000003 10005050500001 24
2001-01-01 23:59:59.9 20010102000000 20010102000000 20010102000000 40020204000000 20010102000000 10005051000000 18
9999-12-31 23:59:59.9 99991231000000 99991231000000 99991231000000 199982462000000 99991231000000 49995615500000 24
CREATE TABLE t3 (a VARCHAR(30) NOT NULL);
INSERT INTO t3 VALUES ('18446744073709551610');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t3;
a a & a a | a a^0 a<<1 a<<0 a>>1 bit_count(a)
18446744073709551610 9223372036854775807 9223372036854775807 9223372036854775807 18446744073709551614 9223372036854775807 4611686018427387903 63
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP DATABASE issue1173;
26 changes: 26 additions & 0 deletions mysql-test/suite/tianmu/t/issue1173.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--source include/have_tianmu.inc
--disable_warnings

DROP DATABASE IF EXISTS issue1173;
CREATE DATABASE issue1173;
USE issue1173;

CREATE TABLE t1 (a TIME(1) NOT NULL);
INSERT INTO t1 VALUES ('00:00:02.9');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t1;

CREATE TABLE t2 (a DATETIME(1) NOT NULL);
INSERT INTO t2 VALUES ('2001-01-01 00:00:02.9');
INSERT INTO t2 VALUES ('2001-01-01 23:59:59.9');
INSERT INTO t2 VALUES ('9999-12-31 23:59:59.9');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t2;

CREATE TABLE t3 (a VARCHAR(30) NOT NULL);
INSERT INTO t3 VALUES ('18446744073709551610');
SELECT a, a & a, a | a, a^0, a<<1, a<<0, a>>1, bit_count(a) FROM t3;

DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;

DROP DATABASE issue1173;
13 changes: 10 additions & 3 deletions storage/tianmu/core/item_tianmu_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,10 @@ bool Item_tianmudatetime_base::get_time(MYSQL_TIME *ltime) {
}

longlong Item_tianmudatetime::val_int() {
return dt.year * 10000000000LL + dt.month * 100000000 + dt.day * 1000000 + dt.hour * 10000 + dt.minute * 100 +
dt.second;
MYSQL_TIME ltime;
dt.Store(&ltime, MYSQL_TIMESTAMP_DATETIME);
longlong tmp = (longlong)TIME_to_ulonglong_datetime_round(&ltime);
return dt.Neg() ? -tmp : tmp;
}

String *Item_tianmudatetime::val_str(String *s) {
Expand Down Expand Up @@ -317,7 +319,12 @@ bool Item_tianmudate::get_time(MYSQL_TIME *ltime) {
return false;
}

longlong Item_tianmutime::val_int() { return dt.hour * 10000 + dt.minute * 100 + dt.second; }
longlong Item_tianmutime::val_int() {
MYSQL_TIME ltime;
dt.Store(&ltime, MYSQL_TIMESTAMP_TIME);
longlong tmp = (longlong)TIME_to_ulonglong_time_round(&ltime);
return dt.Neg() ? -tmp : tmp;
}
String *Item_tianmutime::val_str(String *s) {
MYSQL_TIME ltime;
get_time(&ltime);
Expand Down
22 changes: 3 additions & 19 deletions storage/tianmu/core/tianmu_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,13 +893,7 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
my_time_t secs_utc = current_txn_->Thd()->variables.time_zone->TIME_to_gmt_sec(&my_time, &myb);
common::GMTSec2GMTTime(&my_time, secs_utc);
}
types::DT dt = {};
dt.year = my_time.year;
dt.month = my_time.month;
dt.day = my_time.day;
dt.hour = my_time.hour;
dt.minute = my_time.minute;
dt.second = my_time.second;
types::DT dt(my_time);

*reinterpret_cast<int64_t *>(vc.Prepare(sizeof(int64_t))) = dt.val;
vc.ExpectedSize(sizeof(int64_t));
Expand All @@ -909,11 +903,7 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
MYSQL_TIME my_time;
std::memset(&my_time, 0, sizeof(my_time));
f->get_time(&my_time);
types::DT dt = {};
dt.time_hour = my_time.hour;
dt.minute = my_time.minute;
dt.second = my_time.second;
dt.neg = my_time.neg;
types::DT dt(my_time);

*reinterpret_cast<int64_t *>(vc.Prepare(sizeof(int64_t))) = dt.val;
vc.ExpectedSize(sizeof(int64_t));
Expand All @@ -926,13 +916,7 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
MYSQL_TIME my_time;
std::memset(&my_time, 0, sizeof(my_time));
f->get_time(&my_time);
types::DT dt = {};
dt.year = my_time.year;
dt.month = my_time.month;
dt.day = my_time.day;
dt.hour = my_time.hour;
dt.minute = my_time.minute;
dt.second = my_time.second;
types::DT dt(my_time);

*reinterpret_cast<int64_t *>(vc.Prepare(sizeof(int64_t))) = dt.val;
vc.ExpectedSize(sizeof(int64_t));
Expand Down
14 changes: 10 additions & 4 deletions strings/my_strtoll10.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,22 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error)
if (s != end && (c= (*s-'0')) <= 9)
goto overflow;

li=i*LFACTOR2+ (ulonglong) j*100 + k;

/*Check whether the number overflows*/
if (li > LLONG_MAX || li > (ulonglong) LLONG_MIN)
goto overflow;

/* Check that we didn't get an overflow with the last digit */
if (i > cutoff || (i == cutoff && (j > cutoff2 || (j == cutoff2 &&
k > cutoff3))))
goto overflow;
li=i*LFACTOR2+ (ulonglong) j*100 + k;
return (longlong) li;
return negative ? LLONG_MIN : (longlong) ULLONG_MAX;

return (negative ? -((longlong) li) : (longlong) li);

overflow: /* *endptr is set here */
*error= MY_ERRNO_ERANGE;
return negative ? LLONG_MIN : (longlong) ULLONG_MAX;
return negative ? LLONG_MIN : LLONG_MAX;

end_i:
*endptr= (char*) s;
Expand Down