diff --git a/src/lib/core/datetime.c b/src/lib/core/datetime.c index e28cb79655363bc1efdbed559a5be41e9aac929e..ab4f5ce6e55d90c8f5ff503c7dee738963ce0614 100644 --- a/src/lib/core/datetime.c +++ b/src/lib/core/datetime.c @@ -194,7 +194,7 @@ datetime_ev_now(struct datetime *now) assert(timestamp > INT32_MIN && timestamp < INT32_MAX); long sec = timestamp; now->epoch = sec; - now->nsec = (timestamp - sec) * 1000000000; + now->nsec = (timestamp - sec) * NANOS_PER_SEC; struct tm tm; localtime_r(&sec, &tm); @@ -556,8 +556,6 @@ datetime_totable(const struct datetime *date, struct interval *out) * Interval support functions: stringization and operations */ -#define NANOS_PER_SEC 1000000000LL - #define SPACE() \ do { \ if (sz > 0) { \ @@ -1047,7 +1045,7 @@ datetime_from_fields(struct datetime *dt, const struct dt_fields *fields) return -1; double nsec = fields->msec * 1000000 + fields->usec * 1000 + fields->nsec; - if (nsec < 0 || nsec > 1000000000) + if (nsec < 0 || nsec >= MAX_NANOS_PER_SEC) return -1; if (fields->tzoffset < -720 || fields->tzoffset > 840) return -1; @@ -1062,7 +1060,7 @@ datetime_from_fields(struct datetime *dt, const struct dt_fields *fields) if (frac != 0) { if (fields->count_usec > 0) return -1; - nsec = frac * 1000000000; + nsec = frac * NANOS_PER_SEC; } dt->epoch = timestamp; dt->nsec = nsec; diff --git a/src/lib/core/datetime.h b/src/lib/core/datetime.h index 91f8bce8aa5576a5ae56c4642b44621a7d672b95..fcc416305bed50745490ac4df301ec2fb3ce4af6 100644 --- a/src/lib/core/datetime.h +++ b/src/lib/core/datetime.h @@ -30,6 +30,8 @@ struct tnt_tm; #ifndef SECS_PER_DAY #define SECS_PER_DAY 86400 #define DT_EPOCH_1970_OFFSET 719163 +#define NANOS_PER_SEC 1000000000LL +#define MAX_NANOS_PER_SEC 2000000000LL #endif /** Required size of datetime_to_string string buffer */ diff --git a/src/lib/tzcode/strftime.c b/src/lib/tzcode/strftime.c index b6bfbf1ea1080fc23f1450f80b183f37a8575008..9bb437e2405dfa343019c0c1b0779234b2cc1ef9 100644 --- a/src/lib/tzcode/strftime.c +++ b/src/lib/tzcode/strftime.c @@ -35,6 +35,7 @@ #include "private.h" #include "trivia/util.h" +#include "datetime.h" #include "tzcode.h" #include "timezone.h" #include "timelocal.h" @@ -281,7 +282,7 @@ _fmt(char *buf, ssize_t size, const char *format, const struct tnt_tm *t, /* fallthru */ case 'f': { int nsec = t->tm_nsec; - assert(nsec < 1000000000); + assert(nsec < MAX_NANOS_PER_SEC); /* ** no length modifier provided - diff --git a/test/sql-luatest/datetime_test.lua b/test/sql-luatest/datetime_test.lua index 70bdd6ad4d2e029ca9b3486e315d6afc086d7593..64b4e64ffa555c897ca09aa841232444135eaedb 100644 --- a/test/sql-luatest/datetime_test.lua +++ b/test/sql-luatest/datetime_test.lua @@ -2527,9 +2527,9 @@ g.test_datetime_33_2 = function() t.assert_equals(err.message, res) -- "msec" cannot be more than 1000. - v = {msec = 1001} + v = {msec = 2000} _, err = box.execute(sql, {{['#v'] = v}}) - res = [[Type mismatch: can not convert map({"msec": 1001}) to datetime]] + res = [[Type mismatch: can not convert map({"msec": 2000}) to datetime]] t.assert_equals(err.message, res) -- "msec" cannot be less than 0. @@ -2539,9 +2539,9 @@ g.test_datetime_33_2 = function() t.assert_equals(err.message, res) -- "usec" cannot be more than 1000000. - v = {usec = 1000001} + v = {usec = 2000000} _, err = box.execute(sql, {{['#v'] = v}}) - res = [[Type mismatch: can not convert map({"usec": 1000001}) ]].. + res = [[Type mismatch: can not convert map({"usec": 2000000}) ]].. [[to datetime]] t.assert_equals(err.message, res) @@ -2552,9 +2552,9 @@ g.test_datetime_33_2 = function() t.assert_equals(err.message, res) -- "nsec" cannot be more than 1000000000. - v = {nsec = 1000000001} + v = {nsec = 2000000000} _, err = box.execute(sql, {{['#v'] = v}}) - res = [[Type mismatch: can not convert map({"nsec": 1000000001}) ]].. + res = [[Type mismatch: can not convert map({"nsec": 2000000000}) ]].. [[to datetime]] t.assert_equals(err.message, res)