mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 17:54:16 +01:00
Updated CONNECT engine to support date and timestamp for the full range.
MDEV-32188 make TIMESTAMP use whole 32-bit unsigned range This was done by changing DTVAL to use longlong to internally store the date/timestamp instead of an int. I had to preserve the old binary representation used for dates in TABLE_TYPE=BIN. One consequence is that TABLE_TYPE=BIN cannot support the full date bit range.
This commit is contained in:
parent
b879b8a5c8
commit
c862416338
4 changed files with 105 additions and 19 deletions
24
storage/connect/mysql-test/connect/r/func_time_64.result
Normal file
24
storage/connect/mysql-test/connect/r/func_time_64.result
Normal file
|
@ -0,0 +1,24 @@
|
|||
set @@time_zone="+00:00";
|
||||
create table t1 (c timestamp) ENGINE=Connect TABLE_TYPE=DOS FILE_NAME='func_time_64.dos';
|
||||
insert into t1 values (from_unixtime(power(2,31)-1));
|
||||
insert into t1 values (from_unixtime(power(2,32)-1));
|
||||
select c, unix_timestamp(c) from t1;
|
||||
c unix_timestamp(c)
|
||||
2038-01-19 03:14:07 2147483647
|
||||
2106-02-07 06:28:15 4294967295
|
||||
drop table t1;
|
||||
create table t1 (d datetime, c timestamp) ENGINE=Connect TABLE_TYPE=BIN FILE_NAME='func_time_64.dos';
|
||||
insert into t1 (d,c) values (from_unixtime(power(2,31)-1), from_unixtime(power(2,31)-1));
|
||||
insert into t1 (d,c) values (from_unixtime(power(2,32)-1), from_unixtime(power(2,32)-1));
|
||||
insert ignore into t1 values ("1962-03-03","1962-03-03");
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c' at row 1
|
||||
select d, c, unix_timestamp(c) from t1;
|
||||
d c unix_timestamp(c)
|
||||
2038-01-19 03:14:07 2038-01-19 03:14:07 2147483647
|
||||
1969-12-31 23:59:59 0000-00-00 00:00:00 0
|
||||
1962-03-03 00:00:00 NULL NULL
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c' at row 2
|
||||
Warning 1105 Out of range value -1 for column 'c' at row 2
|
||||
drop table t1;
|
24
storage/connect/mysql-test/connect/t/func_time_64.test
Normal file
24
storage/connect/mysql-test/connect/t/func_time_64.test
Normal file
|
@ -0,0 +1,24 @@
|
|||
--source include/have_64bit_timestamp.inc
|
||||
|
||||
let $MARIADB_DATADIR= `select @@datadir`;
|
||||
|
||||
set @@time_zone="+00:00";
|
||||
create table t1 (c timestamp) ENGINE=Connect TABLE_TYPE=DOS FILE_NAME='func_time_64.dos';
|
||||
insert into t1 values (from_unixtime(power(2,31)-1));
|
||||
insert into t1 values (from_unixtime(power(2,32)-1));
|
||||
|
||||
select c, unix_timestamp(c) from t1;
|
||||
|
||||
drop table t1;
|
||||
--remove_file $MARIADB_DATADIR/test/func_time_64.dos
|
||||
|
||||
create table t1 (d datetime, c timestamp) ENGINE=Connect TABLE_TYPE=BIN FILE_NAME='func_time_64.dos';
|
||||
insert into t1 (d,c) values (from_unixtime(power(2,31)-1), from_unixtime(power(2,31)-1));
|
||||
insert into t1 (d,c) values (from_unixtime(power(2,32)-1), from_unixtime(power(2,32)-1));
|
||||
insert ignore into t1 values ("1962-03-03","1962-03-03");
|
||||
|
||||
select d, c, unix_timestamp(c) from t1;
|
||||
|
||||
drop table t1;
|
||||
--remove_file $MARIADB_DATADIR/test/func_time_64.dos
|
||||
|
|
@ -277,6 +277,7 @@ const char *GetFmt(int type, bool un)
|
|||
case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break;
|
||||
case TYPE_DOUBLE: fmt = "%.*lf"; break;
|
||||
case TYPE_BIN: fmt = "%*x"; break;
|
||||
case TYPE_DATE: fmt = "%llu"; break;
|
||||
default: fmt = (un) ? "%u" : "%d"; break;
|
||||
} // endswitch Type
|
||||
|
||||
|
@ -533,6 +534,7 @@ const char *VALUE::GetXfmt(void)
|
|||
case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break;
|
||||
case TYPE_DOUBLE: fmt = "%*.*lf"; break;
|
||||
case TYPE_BIN: fmt = "%*x"; break;
|
||||
case TYPE_DATE: fmt = "%*lld"; break;
|
||||
default: fmt = (Unsigned) ? "%*u" : "%*d"; break;
|
||||
} // endswitch Type
|
||||
|
||||
|
@ -2353,7 +2355,7 @@ bool BINVAL::SetConstFormat(PGLOBAL, FORMAT& fmt)
|
|||
/* DTVAL public constructor for new void values. */
|
||||
/***********************************************************************/
|
||||
DTVAL::DTVAL(PGLOBAL g, int n, int prec, PCSZ fmt)
|
||||
: TYPVAL<int>((int)0, TYPE_DATE)
|
||||
: TYPVAL<dtval_timestamp_t>(0, TYPE_DATE)
|
||||
{
|
||||
if (!fmt) {
|
||||
Pdtp = NULL;
|
||||
|
@ -2369,7 +2371,7 @@ DTVAL::DTVAL(PGLOBAL g, int n, int prec, PCSZ fmt)
|
|||
/***********************************************************************/
|
||||
/* DTVAL public constructor from int. */
|
||||
/***********************************************************************/
|
||||
DTVAL::DTVAL(int n) : TYPVAL<int>(n, TYPE_DATE)
|
||||
DTVAL::DTVAL(int n) : TYPVAL<dtval_timestamp_t>(n, TYPE_DATE)
|
||||
{
|
||||
Pdtp = NULL;
|
||||
Len = 19;
|
||||
|
@ -2462,15 +2464,14 @@ struct tm *DTVAL::GetGmTime(struct tm *tm_buffer)
|
|||
time_t t = (time_t)Tval;
|
||||
|
||||
if (Tval < 0) {
|
||||
int n;
|
||||
|
||||
longlong n;
|
||||
for (n = 0; t < 0; n += 4)
|
||||
t += FOURYEARS;
|
||||
|
||||
datm = gmtime_mysql(&t, tm_buffer);
|
||||
|
||||
if (datm)
|
||||
datm->tm_year -= n;
|
||||
datm->tm_year -= (int) n;
|
||||
|
||||
} else
|
||||
datm = gmtime_mysql(&t, tm_buffer);
|
||||
|
@ -2521,10 +2522,10 @@ bool DTVAL::MakeTime(struct tm *ptm)
|
|||
|
||||
} // endif t
|
||||
|
||||
Tval= (int) t;
|
||||
Tval= (dtval_timestamp_t) t;
|
||||
|
||||
if (trace(2))
|
||||
htrc("MakeTime Ival=%d\n", Tval);
|
||||
htrc("MakeTime Ival=%lld\n", (longlong) Tval);
|
||||
|
||||
return false;
|
||||
} // end of MakeTime
|
||||
|
@ -2646,7 +2647,7 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
|
|||
// Assuming that this timestamp is in milliseconds
|
||||
SetValue((int)(valp->GetBigintValue() / 1000));
|
||||
} else
|
||||
SetValue(valp->GetIntValue());
|
||||
SetValue(valp->GetBigintValue());
|
||||
|
||||
} else
|
||||
Reset();
|
||||
|
@ -2688,7 +2689,7 @@ bool DTVAL::SetValue_char(const char *p, int n)
|
|||
|
||||
Null = (Nullable && ndv == 0);
|
||||
} else {
|
||||
rc = TYPVAL<int>::SetValue_char(p, n);
|
||||
rc = TYPVAL<dtval_timestamp_t>::SetValue_char(p, n);
|
||||
Null = (Nullable && Tval == 0);
|
||||
} // endif Pdtp
|
||||
|
||||
|
@ -2711,11 +2712,11 @@ void DTVAL::SetValue_psz(PCSZ p)
|
|||
MakeDate(NULL, dval, ndv);
|
||||
|
||||
if (trace(2))
|
||||
htrc(" setting date: '%s' -> %d\n", Sdate, Tval);
|
||||
htrc(" setting date: '%s' -> %lld\n", Sdate, (longlong) Tval);
|
||||
|
||||
Null = (Nullable && ndv == 0);
|
||||
} else {
|
||||
TYPVAL<int>::SetValue_psz(p);
|
||||
TYPVAL<dtval_timestamp_t>::SetValue_psz(p);
|
||||
Null = (Nullable && Tval == 0);
|
||||
} // endif Pdtp
|
||||
|
||||
|
@ -2740,7 +2741,7 @@ void DTVAL::SetValue_pvblk(PVBLK blk, int n)
|
|||
/***********************************************************************/
|
||||
/* DTVAL SetValue: get date as an integer. */
|
||||
/***********************************************************************/
|
||||
void DTVAL::SetValue(int n)
|
||||
void DTVAL::SetValue(dtval_timestamp_t n)
|
||||
{
|
||||
Tval = n;
|
||||
|
||||
|
@ -2774,7 +2775,7 @@ char *DTVAL::GetCharString(char *p)
|
|||
|
||||
return Sdate;
|
||||
} else
|
||||
sprintf(p, "%d", Tval);
|
||||
sprintf(p, "%lld", (longlong) Tval);
|
||||
|
||||
//Null = false; ??????????????
|
||||
return p;
|
||||
|
@ -2806,7 +2807,7 @@ int DTVAL::ShowValue(char *buf, int len)
|
|||
*buf = '\0'; // DEFAULT VALUE ???
|
||||
|
||||
} else
|
||||
rv = TYPVAL<int>::ShowValue(buf, len);
|
||||
rv = TYPVAL<dtval_timestamp_t>::ShowValue(buf, len);
|
||||
|
||||
return rv;
|
||||
} // end of ShowValue
|
||||
|
@ -2888,4 +2889,35 @@ bool DTVAL::FormatValue(PVAL vp, PCSZ fmt)
|
|||
|
||||
} // end of FormatValue
|
||||
|
||||
|
||||
void DTVAL::SetBinValue(void* p)
|
||||
{
|
||||
#if defined(UNALIGNED_OK)
|
||||
// x86 can cast non-aligned memory directly
|
||||
Tval = *(int *)p;
|
||||
#else
|
||||
int tmp;
|
||||
memcpy(&tmp, p, sizeof(tmp));
|
||||
Tval= tmp;
|
||||
#endif
|
||||
Null = false;
|
||||
} // end of SetBinValue
|
||||
|
||||
|
||||
bool DTVAL::GetBinValue(void *buf, int buflen, bool go)
|
||||
{
|
||||
if (go)
|
||||
#if defined(UNALIGNED_OK)
|
||||
// x86 can cast non-aligned memory directly
|
||||
*(int *)buf = (int) Tval;
|
||||
#else
|
||||
{
|
||||
int tmp= (int) Tval;
|
||||
memcpy(buf, &tmp, sizeof(tmp));
|
||||
}
|
||||
#endif
|
||||
Null = false;
|
||||
return false;
|
||||
} // end of GetBinValue
|
||||
|
||||
/* -------------------------- End of Value --------------------------- */
|
||||
|
|
|
@ -60,6 +60,9 @@ DllExport ulonglong CharToNumber(PCSZ, int, ulonglong, bool,
|
|||
bool *minus = NULL, bool *rc = NULL);
|
||||
DllExport BYTE OpBmp(PGLOBAL g, OPVAL opc);
|
||||
|
||||
/* Type for date and timestamps */
|
||||
typedef longlong dtval_timestamp_t;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Class VALUE represents a constant or variable of any valid type. */
|
||||
/***********************************************************************/
|
||||
|
@ -407,21 +410,24 @@ public:
|
|||
/***********************************************************************/
|
||||
/* Class DTVAL: represents a time stamp value. */
|
||||
/***********************************************************************/
|
||||
class DllExport DTVAL : public TYPVAL<int> {
|
||||
|
||||
class DllExport DTVAL : public TYPVAL<dtval_timestamp_t> {
|
||||
public:
|
||||
// Constructors
|
||||
DTVAL(PGLOBAL g, int n, int p, PCSZ fmt);
|
||||
DTVAL(int n);
|
||||
using TYPVAL<int>::SetValue;
|
||||
using TYPVAL<dtval_timestamp_t>::SetValue;
|
||||
|
||||
// Implementation
|
||||
virtual bool SetValue_pval(PVAL valp, bool chktype);
|
||||
virtual bool SetValue_char(const char *p, int n);
|
||||
virtual void SetValue_psz(PCSZ s);
|
||||
virtual void SetValue_pvblk(PVBLK blk, int n);
|
||||
virtual void SetValue(int n);
|
||||
virtual void SetValue(dtval_timestamp_t n);
|
||||
virtual void SetBinValue(void* p);
|
||||
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
||||
virtual PSZ GetCharValue(void) { return Sdate; }
|
||||
virtual char *GetCharString(char *p);
|
||||
virtual char *GetCharString(char *p);
|
||||
virtual int ShowValue(char *buf, int len);
|
||||
virtual bool FormatValue(PVAL vp, PCSZ fmt);
|
||||
bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
|
||||
|
@ -438,7 +444,7 @@ class DllExport DTVAL : public TYPVAL<int> {
|
|||
|
||||
protected:
|
||||
// Default constructor not to be used
|
||||
DTVAL(void) : TYPVAL<int>() {}
|
||||
DTVAL(void) : TYPVAL<dtval_timestamp_t>() {}
|
||||
|
||||
// Members
|
||||
static int Shift; // Time zone shift in seconds
|
||||
|
|
Loading…
Add table
Reference in a new issue