Commit a30fcdc6 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Fix for Bug#4030 "Client side conversion string -> date type doesn't

work (prepared statements)" and after-review fixes:
- str_to_TIME renamed to str_to_datetime to pair with str_to_time
- functions str_to_time and str_to_TIME moved to sql-common
- send_data_str now supports MYSQL_TYPE_TIME, MYSQL_TIME_DATE,
  MYSQL_TIME_DATETIME types of user input buffers.
- few more comments in the client library
- a test case added.
parent 3bcbdcb4
...@@ -427,6 +427,10 @@ SOURCE=.\pack.c ...@@ -427,6 +427,10 @@ SOURCE=.\pack.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\my_time.c
# End Source File
# Begin Source File
SOURCE=.\password.c SOURCE=.\password.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -368,6 +368,10 @@ SOURCE="..\sql-common\pack.c" ...@@ -368,6 +368,10 @@ SOURCE="..\sql-common\pack.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql-common\my_time.c
# End Source File
# Begin Source File
SOURCE=..\libmysql\password.c SOURCE=..\libmysql\password.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -1053,6 +1053,10 @@ SOURCE=.\pack.c ...@@ -1053,6 +1053,10 @@ SOURCE=.\pack.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\my_time.c
# End Source File
# Begin Source File
SOURCE=.\password.c SOURCE=.\password.c
!IF "$(CFG)" == "mysqld - Win32 Release" !IF "$(CFG)" == "mysqld - Win32 Release"
......
...@@ -22,7 +22,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ ...@@ -22,7 +22,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \
errmsg.h my_global.h my_net.h my_alloc.h \ errmsg.h my_global.h my_net.h my_alloc.h \
my_getopt.h sslopt-longopts.h my_dir.h typelib.h \ my_getopt.h sslopt-longopts.h my_dir.h typelib.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
sql_state.h $(BUILT_SOURCES) sql_state.h mysql_time.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h config-os2.h config-netware.h \ noinst_HEADERS = config-win.h config-os2.h config-netware.h \
nisam.h heap.h merge.h my_bitmap.h\ nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\ myisam.h myisampack.h myisammrg.h ft_global.h\
......
/* Copyright (C) 2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This is a private header of sql-common library, containing
declarations for my_time.c
*/
#ifndef _my_time_h_
#define _my_time_h_
#include "my_global.h"
#include "mysql_time.h"
C_MODE_START
extern ulonglong log_10_int[20];
#define YY_PART_YEAR 70
/* Flags to str_to_datetime */
#define TIME_FUZZY_DATE 1
#define TIME_DATETIME_ONLY 2
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
uint flags, int *was_cut);
bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time,
int *was_cut);
C_MODE_END
#endif /* _my_time_h_ */
...@@ -55,6 +55,7 @@ typedef int my_socket; ...@@ -55,6 +55,7 @@ typedef int my_socket;
#endif /* _global_h */ #endif /* _global_h */
#include "mysql_com.h" #include "mysql_com.h"
#include "mysql_time.h"
#include "mysql_version.h" #include "mysql_version.h"
#include "typelib.h" #include "typelib.h"
...@@ -533,23 +534,6 @@ enum enum_mysql_stmt_state ...@@ -533,23 +534,6 @@ enum enum_mysql_stmt_state
MYSQL_STMT_FETCH_DONE MYSQL_STMT_FETCH_DONE
}; };
/*
client TIME structure to handle TIME, DATE and TIMESTAMP directly in
binary protocol
*/
enum mysql_st_timestamp_type { MYSQL_TIMESTAMP_NONE, MYSQL_TIMESTAMP_DATE,
MYSQL_TIMESTAMP_FULL, MYSQL_TIMESTAMP_TIME };
typedef struct mysql_st_time
{
unsigned int year,month,day,hour,minute,second;
unsigned long second_part;
my_bool neg;
enum mysql_st_timestamp_type time_type;
} MYSQL_TIME;
/* bind structure */ /* bind structure */
typedef struct st_mysql_bind typedef struct st_mysql_bind
......
/* Copyright (C) 2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _mysql_time_h_
#define _mysql_time_h_
/* Time declarations shared between server and client library */
enum enum_mysql_timestamp_type
{
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
};
typedef struct st_mysql_time
{
unsigned int year, month, day, hour, minute, second;
unsigned long second_part;
my_bool neg;
enum enum_mysql_timestamp_type time_type;
} MYSQL_TIME;
#endif /* _mysql_time_h_ */
...@@ -65,7 +65,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ ...@@ -65,7 +65,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_pread.lo mf_cache.lo md5.lo sha1.lo\ my_pread.lo mf_cache.lo md5.lo sha1.lo\
my_getopt.lo my_gethostbyname.lo my_port.lo my_getopt.lo my_gethostbyname.lo my_port.lo
sqlobjects = net.lo sqlobjects = net.lo
sql_cmn_objects = pack.lo client.lo sql_cmn_objects = pack.lo client.lo my_time.lo
# Not needed in the minimum library # Not needed in the minimum library
mysysobjects2 = my_lib.lo mysysobjects2 = my_lib.lo
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <my_global.h> #include <my_global.h>
#include <my_sys.h> #include <my_sys.h>
#include <my_time.h>
#include <mysys_err.h> #include <mysys_err.h>
#include <m_string.h> #include <m_string.h>
#include <m_ctype.h> #include <m_ctype.h>
...@@ -3008,33 +3009,33 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number, ...@@ -3008,33 +3009,33 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
/******************************************************************** /********************************************************************
Fetch-bind related implementations Fetch and conversion of result set rows (binary protocol).
*********************************************************************/ *********************************************************************/
/****************************************************************************
Functions to fetch data to application buffers
All functions have the following characteristics:
SYNOPSIS
fetch_result_xxx()
param MySQL bind param
row Row value
RETURN VALUES
0 ok
1 Error (Can't alloc net->buffer)
****************************************************************************/
static void set_zero_time(MYSQL_TIME *tm) static void set_zero_time(MYSQL_TIME *tm)
{ {
tm->year= tm->month= tm->day= 0; bzero((void *)tm, sizeof(*tm));
tm->hour= tm->minute= tm->second= 0;
tm->second_part= 0;
tm->neg= (bool)0;
} }
/* Read TIME from binary packet and return it to MYSQL_TIME */
/*
Read date, (time, datetime) value from network buffer and store it
in MYSQL_TIME structure.
SYNOPSIS
read_binary_{date,time,datetime}()
tm MYSQL_TIME structure to fill
pos pointer to current position in network buffer.
These functions increase pos to point to the beginning of this
field (this is just due to implementation of net_field_length
which is used to get length of binary representation of
time value).
Auxiliary functions to read time (date, datetime) values from network
buffer and store in MYSQL_TIME structure. Jointly used by conversion
and no-conversion fetching.
*/
static uint read_binary_time(MYSQL_TIME *tm, uchar **pos) static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
{ {
uchar *to; uchar *to;
...@@ -3060,7 +3061,6 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos) ...@@ -3060,7 +3061,6 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
return length; return length;
} }
/* Read DATETIME from binary packet and return it to MYSQL_TIME */
static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos) static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
{ {
uchar *to; uchar *to;
...@@ -3091,7 +3091,6 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos) ...@@ -3091,7 +3091,6 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
return length; return length;
} }
/* Read DATE from binary packet and return it to MYSQL_TIME */
static uint read_binary_date(MYSQL_TIME *tm, uchar **pos) static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
{ {
uchar *to; uchar *to;
...@@ -3115,7 +3114,8 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos) ...@@ -3115,7 +3114,8 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
} }
/* Convert Numeric to buffer types */ /* Convert integer value to client buffer type. */
static void send_data_long(MYSQL_BIND *param, MYSQL_FIELD *field, static void send_data_long(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong value) longlong value)
{ {
...@@ -3273,6 +3273,21 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length) ...@@ -3273,6 +3273,21 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
doublestore(buffer, data); doublestore(buffer, data);
break; break;
} }
case MYSQL_TYPE_TIME:
{
int dummy;
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
str_to_time(value, length, tm, &dummy);
break;
}
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
{
int dummy;
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
str_to_datetime(value, length, tm, 0, &dummy);
break;
}
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
...@@ -3332,7 +3347,7 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime, ...@@ -3332,7 +3347,7 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
length= my_sprintf(buff,(buff, "%04d-%02d-%02d", ltime.year, length= my_sprintf(buff,(buff, "%04d-%02d-%02d", ltime.year,
ltime.month,ltime.day)); ltime.month,ltime.day));
break; break;
case MYSQL_TIMESTAMP_FULL: case MYSQL_TIMESTAMP_DATETIME:
length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d", length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
ltime.year,ltime.month,ltime.day, ltime.year,ltime.month,ltime.day,
ltime.hour,ltime.minute,ltime.second)); ltime.hour,ltime.minute,ltime.second));
...@@ -3351,7 +3366,7 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime, ...@@ -3351,7 +3366,7 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
} }
/* Fetch data to buffers */ /* Fetch data to client buffers with conversion. */
static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row) static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
{ {
...@@ -3437,7 +3452,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row) ...@@ -3437,7 +3452,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
MYSQL_TIME tm; MYSQL_TIME tm;
length= read_binary_datetime(&tm, row); length= read_binary_datetime(&tm, row);
tm.time_type= MYSQL_TIMESTAMP_FULL; tm.time_type= MYSQL_TIMESTAMP_DATETIME;
send_data_time(param, tm, length); send_data_time(param, tm, length);
break; break;
} }
...@@ -3450,6 +3465,25 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row) ...@@ -3450,6 +3465,25 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
} }
/*
Functions to fetch data to application buffers without conversion.
All functions have the following characteristics:
SYNOPSIS
fetch_result_xxx()
param MySQL bind param
pos Row value
DESCRIPTION
These are no-conversion functions, used in binary protocol to store
rows in application buffers. A function used only if type of binary data
is compatible with type of application buffer.
RETURN
none
*/
static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row) static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
{ {
*param->buffer= **row; *param->buffer= **row;
......
...@@ -33,7 +33,8 @@ noinst_LIBRARIES = libmysqld_int.a ...@@ -33,7 +33,8 @@ noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
my_time.c
noinst_HEADERS = embedded_priv.h emb_qcache.h noinst_HEADERS = embedded_priv.h emb_qcache.h
...@@ -56,7 +57,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ...@@ -56,7 +57,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc spatial.cc gstream.cc sql_help.cc tztime.cc my_time.c
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
libmysqld_a_SOURCES= libmysqld_a_SOURCES=
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in ## Process this file with automake to create Makefile.in
EXTRA_DIST = client.c pack.c EXTRA_DIST = client.c pack.c my_time.c
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
...@@ -89,7 +89,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ ...@@ -89,7 +89,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
client.c sql_client.cc mini_client_errors.c pack.c\ client.c sql_client.cc mini_client_errors.c pack.c\
stacktrace.c repl_failsafe.h repl_failsafe.cc \ stacktrace.c repl_failsafe.h repl_failsafe.cc \
gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \ gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \
tztime.cc examples/ha_example.cc examples/ha_archive.cc tztime.cc my_time.c \
examples/ha_example.cc examples/ha_archive.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
...@@ -114,6 +115,8 @@ link_sources: ...@@ -114,6 +115,8 @@ link_sources:
@LN_CP_F@ ../sql-common/pack.c pack.c @LN_CP_F@ ../sql-common/pack.c pack.c
rm -f client.c rm -f client.c
@LN_CP_F@ ../sql-common/client.c client.c @LN_CP_F@ ../sql-common/client.c client.c
rm -f my_time.c
@LN_CP_F@ ../sql-common/my_time.c my_time.c
gen_lex_hash.o: gen_lex_hash.cc lex.h gen_lex_hash.o: gen_lex_hash.cc lex.h
$(CXXCOMPILE) -c $(INCLUDES) $< $(CXXCOMPILE) -c $(INCLUDES) $<
......
...@@ -398,8 +398,8 @@ bool Field::get_date(TIME *ltime,uint fuzzydate) ...@@ -398,8 +398,8 @@ bool Field::get_date(TIME *ltime,uint fuzzydate)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res; String tmp(buff,sizeof(buff),&my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_TIME_with_warn(res->ptr(), res->length(), ltime, fuzzydate) <= str_to_datetime_with_warn(res->ptr(), res->length(),
TIMESTAMP_DATETIME_ERROR) ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
return 1; return 1;
return 0; return 0;
} }
...@@ -2918,12 +2918,12 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -2918,12 +2918,12 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
bool in_dst_time_gap; bool in_dst_time_gap;
THD *thd= table->in_use; THD *thd= table->in_use;
have_smth_to_conv= (str_to_TIME(from, len, &l_time, 0, &error) > have_smth_to_conv= (str_to_datetime(from, len, &l_time, 0, &error) >
TIMESTAMP_DATETIME_ERROR); MYSQL_TIMESTAMP_ERROR);
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_DATETIME, 1); from, len, MYSQL_TIMESTAMP_DATETIME, 1);
if (have_smth_to_conv) if (have_smth_to_conv)
{ {
...@@ -2931,7 +2931,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -2931,7 +2931,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_DATETIME, !error); from, len, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1; error= 1;
} }
...@@ -2939,7 +2939,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -2939,7 +2939,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_INVALID_TIMESTAMP, ER_WARN_INVALID_TIMESTAMP,
from, len, TIMESTAMP_DATETIME, !error); from, len, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1; error= 1;
} }
} }
...@@ -2962,7 +2962,7 @@ int Field_timestamp::store(double nr) ...@@ -2962,7 +2962,7 @@ int Field_timestamp::store(double nr)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME); nr, MYSQL_TIMESTAMP_DATETIME);
nr= 0; // Avoid overflow on buff nr= 0; // Avoid overflow on buff
error= 1; error= 1;
} }
...@@ -2985,7 +2985,7 @@ int Field_timestamp::store(longlong nr) ...@@ -2985,7 +2985,7 @@ int Field_timestamp::store(longlong nr)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME, 1); nr, MYSQL_TIMESTAMP_DATETIME, 1);
error= 1; error= 1;
} }
...@@ -2993,14 +2993,14 @@ int Field_timestamp::store(longlong nr) ...@@ -2993,14 +2993,14 @@ int Field_timestamp::store(longlong nr)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_INVALID_TIMESTAMP, ER_WARN_INVALID_TIMESTAMP,
nr, TIMESTAMP_DATETIME, !error); nr, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1; error= 1;
} }
} }
else if (error) else if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, ER_WARN_DATA_TRUNCATED,
nr, TIMESTAMP_DATETIME, 1); nr, MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
...@@ -3232,14 +3232,14 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3232,14 +3232,14 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
tmp=0L; tmp=0L;
error= 1; error= 1;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_TIME, 1); from, len, MYSQL_TIMESTAMP_TIME, 1);
} }
else else
{ {
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_TIME, 1); from, len, MYSQL_TIMESTAMP_TIME, 1);
if (ltime.month) if (ltime.month)
ltime.day=0; ltime.day=0;
...@@ -3249,7 +3249,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3249,7 +3249,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
tmp=8385959; tmp=8385959;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_TIME, !error); from, len, MYSQL_TIMESTAMP_TIME, !error);
error= 1; error= 1;
} }
} }
...@@ -3269,14 +3269,14 @@ int Field_time::store(double nr) ...@@ -3269,14 +3269,14 @@ int Field_time::store(double nr)
{ {
tmp=8385959L; tmp=8385959L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
error= 1; error= 1;
} }
else if (nr < -8385959.0) else if (nr < -8385959.0)
{ {
tmp= -8385959L; tmp= -8385959L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
error= 1; error= 1;
} }
else else
...@@ -3288,7 +3288,8 @@ int Field_time::store(double nr) ...@@ -3288,7 +3288,8 @@ int Field_time::store(double nr)
{ {
tmp=0; tmp=0;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME);
error= 1; error= 1;
} }
} }
...@@ -3305,14 +3306,16 @@ int Field_time::store(longlong nr) ...@@ -3305,14 +3306,16 @@ int Field_time::store(longlong nr)
{ {
tmp=8385959L; tmp=8385959L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME, 1);
error= 1; error= 1;
} }
else if (nr < (longlong) -8385959L) else if (nr < (longlong) -8385959L)
{ {
tmp= -8385959L; tmp= -8385959L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME, 1);
error= 1; error= 1;
} }
else else
...@@ -3322,7 +3325,8 @@ int Field_time::store(longlong nr) ...@@ -3322,7 +3325,8 @@ int Field_time::store(longlong nr)
{ {
tmp=0; tmp=0;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME, 1);
error= 1; error= 1;
} }
} }
...@@ -3417,7 +3421,7 @@ bool Field_time::get_time(TIME *ltime) ...@@ -3417,7 +3421,7 @@ bool Field_time::get_time(TIME *ltime)
ltime->minute= (int) tmp/100; ltime->minute= (int) tmp/100;
ltime->second= (int) tmp % 100; ltime->second= (int) tmp % 100;
ltime->second_part=0; ltime->second_part=0;
ltime->time_type= TIMESTAMP_TIME; ltime->time_type= MYSQL_TIMESTAMP_TIME;
return 0; return 0;
} }
...@@ -3566,8 +3570,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) ...@@ -3566,8 +3570,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
uint32 tmp; uint32 tmp;
int error; int error;
if (str_to_TIME(from, len, &l_time, 1, &error) <= if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
TIMESTAMP_DATETIME_ERROR)
{ {
tmp=0; tmp=0;
error= 1; error= 1;
...@@ -3577,7 +3580,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) ...@@ -3577,7 +3580,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_DATE, 1); from, len, MYSQL_TIMESTAMP_DATE, 1);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
...@@ -3602,7 +3605,7 @@ int Field_date::store(double nr) ...@@ -3602,7 +3605,7 @@ int Field_date::store(double nr)
tmp=0L; tmp=0L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATE); nr, MYSQL_TIMESTAMP_DATE);
error= 1; error= 1;
} }
else else
...@@ -3630,7 +3633,7 @@ int Field_date::store(longlong nr) ...@@ -3630,7 +3633,7 @@ int Field_date::store(longlong nr)
tmp=0L; tmp=0L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATE, 0); nr, MYSQL_TIMESTAMP_DATE, 0);
error= 1; error= 1;
} }
else else
...@@ -3758,8 +3761,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3758,8 +3761,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
TIME l_time; TIME l_time;
long tmp; long tmp;
int error; int error;
if (str_to_TIME(from, len, &l_time, 1, &error) <= if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
TIMESTAMP_DATETIME_ERROR)
{ {
tmp=0L; tmp=0L;
error= 1; error= 1;
...@@ -3769,7 +3771,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3769,7 +3771,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_DATE, 1); from, len, MYSQL_TIMESTAMP_DATE, 1);
int3store(ptr,tmp); int3store(ptr,tmp);
return error; return error;
...@@ -3781,7 +3783,7 @@ int Field_newdate::store(double nr) ...@@ -3781,7 +3783,7 @@ int Field_newdate::store(double nr)
{ {
(void) Field_newdate::store((longlong) -1); (void) Field_newdate::store((longlong) -1);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, nr, TIMESTAMP_DATE); ER_WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE);
return 1; return 1;
} }
else else
...@@ -3799,7 +3801,8 @@ int Field_newdate::store(longlong nr) ...@@ -3799,7 +3801,8 @@ int Field_newdate::store(longlong nr)
{ {
tmp=0; tmp=0;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_DATE, 1); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_DATE, 1);
error= 1; error= 1;
} }
else else
...@@ -3818,7 +3821,8 @@ int Field_newdate::store(longlong nr) ...@@ -3818,7 +3821,8 @@ int Field_newdate::store(longlong nr)
{ {
tmp=0L; // Don't allow date to change tmp=0L; // Don't allow date to change
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_DATE, 1); ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_DATE, 1);
error= 1; error= 1;
} }
else else
...@@ -3831,7 +3835,7 @@ int Field_newdate::store(longlong nr) ...@@ -3831,7 +3835,7 @@ int Field_newdate::store(longlong nr)
void Field_newdate::store_time(TIME *ltime,timestamp_type type) void Field_newdate::store_time(TIME *ltime,timestamp_type type)
{ {
long tmp; long tmp;
if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME)
tmp=ltime->year*16*32+ltime->month*32+ltime->day; tmp=ltime->year*16*32+ltime->month*32+ltime->day;
else else
{ {
...@@ -3895,7 +3899,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) ...@@ -3895,7 +3899,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
ltime->day= tmp & 31; ltime->day= tmp & 31;
ltime->month= (tmp >> 5) & 15; ltime->month= (tmp >> 5) & 15;
ltime->year= (tmp >> 9); ltime->year= (tmp >> 9);
ltime->time_type=TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0; ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0; return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
} }
...@@ -3939,14 +3943,13 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3939,14 +3943,13 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
int error; int error;
ulonglong tmp= 0; ulonglong tmp= 0;
if (str_to_TIME(from, len, &time_tmp, 1, &error) > if (str_to_datetime(from, len, &time_tmp, 1, &error) > MYSQL_TIMESTAMP_ERROR)
TIMESTAMP_DATETIME_ERROR)
tmp= TIME_to_ulonglong_datetime(&time_tmp); tmp= TIME_to_ulonglong_datetime(&time_tmp);
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_DATETIME, 1); from, len, MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
...@@ -3967,7 +3970,7 @@ int Field_datetime::store(double nr) ...@@ -3967,7 +3970,7 @@ int Field_datetime::store(double nr)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME); nr, MYSQL_TIMESTAMP_DATETIME);
nr=0.0; nr=0.0;
error= 1; error= 1;
} }
...@@ -3987,7 +3990,7 @@ int Field_datetime::store(longlong nr) ...@@ -3987,7 +3990,7 @@ int Field_datetime::store(longlong nr)
if (error) if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, initial_nr, ER_WARN_DATA_TRUNCATED, initial_nr,
TIMESTAMP_DATETIME, 1); MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
...@@ -4004,7 +4007,7 @@ int Field_datetime::store(longlong nr) ...@@ -4004,7 +4007,7 @@ int Field_datetime::store(longlong nr)
void Field_datetime::store_time(TIME *ltime,timestamp_type type) void Field_datetime::store_time(TIME *ltime,timestamp_type type)
{ {
longlong tmp; longlong tmp;
if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME)
tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+ tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+
(ltime->hour*10000L+ltime->minute*100+ltime->second)); (ltime->hour*10000L+ltime->minute*100+ltime->second));
else else
...@@ -4103,7 +4106,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) ...@@ -4103,7 +4106,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate)
part1=(uint32) (tmp/LL(1000000)); part1=(uint32) (tmp/LL(1000000));
part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); part2=(uint32) (tmp - (ulonglong) part1*LL(1000000));
ltime->time_type= TIMESTAMP_DATETIME; ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
ltime->neg= 0; ltime->neg= 0;
ltime->second_part= 0; ltime->second_part= 0;
ltime->second= (int) (part2%100); ltime->second= (int) (part2%100);
......
...@@ -228,8 +228,8 @@ bool Item::get_date(TIME *ltime,uint fuzzydate) ...@@ -228,8 +228,8 @@ bool Item::get_date(TIME *ltime,uint fuzzydate)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff), &my_charset_bin),*res; String tmp(buff,sizeof(buff), &my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_TIME_with_warn(res->ptr(),res->length(),ltime,fuzzydate) <= str_to_datetime_with_warn(res->ptr(), res->length(),
TIMESTAMP_DATETIME_ERROR) ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
{ {
bzero((char*) ltime,sizeof(*ltime)); bzero((char*) ltime,sizeof(*ltime));
return 1; return 1;
......
...@@ -425,21 +425,21 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -425,21 +425,21 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->append(month_names[l_time->month-1],3); str->append(month_names[l_time->month-1],3);
break; break;
case 'W': case 'W':
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month, weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0); l_time->day),0);
str->append(day_names[weekday]); str->append(day_names[weekday]);
break; break;
case 'a': case 'a':
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0); l_time->day),0);
str->append(day_names[weekday],3); str->append(day_names[weekday],3);
break; break;
case 'D': case 'D':
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
length= int10_to_str(l_time->day, intbuff, 10) - intbuff; length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
str->append_with_prefill(intbuff, length, 1, '0'); str->append_with_prefill(intbuff, length, 1, '0');
...@@ -507,7 +507,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -507,7 +507,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->append_with_prefill(intbuff, length, 2, '0'); str->append_with_prefill(intbuff, length, 2, '0');
break; break;
case 'j': case 'j':
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
length= int10_to_str(calc_daynr(l_time->year,l_time->month, length= int10_to_str(calc_daynr(l_time->year,l_time->month,
l_time->day) - l_time->day) -
...@@ -555,7 +555,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -555,7 +555,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'u': case 'u':
{ {
uint year; uint year;
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
length= int10_to_str(calc_week(l_time, length= int10_to_str(calc_week(l_time,
(*ptr) == 'U' ? (*ptr) == 'U' ?
...@@ -569,7 +569,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -569,7 +569,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'V': case 'V':
{ {
uint year; uint year;
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
length= int10_to_str(calc_week(l_time, length= int10_to_str(calc_week(l_time,
((*ptr) == 'V' ? ((*ptr) == 'V' ?
...@@ -584,7 +584,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -584,7 +584,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'X': case 'X':
{ {
uint year; uint year;
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
(void) calc_week(l_time, (void) calc_week(l_time,
((*ptr) == 'X' ? ((*ptr) == 'X' ?
...@@ -596,7 +596,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -596,7 +596,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
} }
break; break;
case 'w': case 'w':
if (type == TIMESTAMP_TIME) if (type == MYSQL_TIMESTAMP_TIME)
return 1; return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),1); l_time->day),1);
...@@ -1107,7 +1107,7 @@ int Item_date::save_in_field(Field *field, bool no_conversions) ...@@ -1107,7 +1107,7 @@ int Item_date::save_in_field(Field *field, bool no_conversions)
if (get_date(&ltime, TIME_FUZZY_DATE)) if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null(field); return set_field_to_null(field);
field->set_notnull(); field->set_notnull();
field->store_time(&ltime, TIMESTAMP_DATE); field->store_time(&ltime, MYSQL_TIMESTAMP_DATE);
return 0; return 0;
} }
...@@ -1129,7 +1129,7 @@ bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date) ...@@ -1129,7 +1129,7 @@ bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
return 1; return 1;
bzero(ltime, sizeof(TIME)); bzero(ltime, sizeof(TIME));
get_date_from_daynr((long) value, &ltime->year, &ltime->month, &ltime->day); get_date_from_daynr((long) value, &ltime->year, &ltime->month, &ltime->day);
ltime->time_type= TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0; return 0;
} }
...@@ -1144,7 +1144,7 @@ void Item_func_curdate::fix_length_and_dec() ...@@ -1144,7 +1144,7 @@ void Item_func_curdate::fix_length_and_dec()
/* We don't need to set second_part and neg because they already 0 */ /* We don't need to set second_part and neg because they already 0 */
ltime.hour= ltime.minute= ltime.second= 0; ltime.hour= ltime.minute= ltime.second= 0;
ltime.time_type=TIMESTAMP_DATE; ltime.time_type= MYSQL_TIMESTAMP_DATE;
value= (longlong) TIME_to_ulonglong_date(&ltime); value= (longlong) TIME_to_ulonglong_date(&ltime);
} }
...@@ -1308,7 +1308,7 @@ bool Item_func_now::get_date(TIME *res, ...@@ -1308,7 +1308,7 @@ bool Item_func_now::get_date(TIME *res,
int Item_func_now::save_in_field(Field *to, bool no_conversions) int Item_func_now::save_in_field(Field *to, bool no_conversions)
{ {
to->set_notnull(); to->set_notnull();
to->store_time(&ltime,TIMESTAMP_DATETIME); to->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
return 0; return 0;
} }
...@@ -1494,7 +1494,9 @@ String *Item_func_date_format::val_str(String *str) ...@@ -1494,7 +1494,9 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */ /* Create the result string */
if (!make_date_time(&date_time_format, &l_time, if (!make_date_time(&date_time_format, &l_time,
is_time_format ? TIMESTAMP_TIME : TIMESTAMP_DATE, str)) is_time_format ? MYSQL_TIMESTAMP_TIME :
MYSQL_TIMESTAMP_DATE,
str))
return str; return str;
null_date: null_date:
...@@ -1713,7 +1715,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) ...@@ -1713,7 +1715,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
case INTERVAL_DAY_HOUR: case INTERVAL_DAY_HOUR:
{ {
longlong sec, days, daynr, microseconds, extra_sec; longlong sec, days, daynr, microseconds, extra_sec;
ltime->time_type=TIMESTAMP_DATETIME; // Return full date ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
microseconds= ltime->second_part + sign*interval.second_part; microseconds= ltime->second_part + sign*interval.second_part;
extra_sec= microseconds/1000000L; extra_sec= microseconds/1000000L;
microseconds= microseconds%1000000L; microseconds= microseconds%1000000L;
...@@ -1798,7 +1800,7 @@ String *Item_date_add_interval::val_str(String *str) ...@@ -1798,7 +1800,7 @@ String *Item_date_add_interval::val_str(String *str)
if (Item_date_add_interval::get_date(&ltime,0)) if (Item_date_add_interval::get_date(&ltime,0))
return 0; return 0;
if (ltime.time_type == TIMESTAMP_DATE) if (ltime.time_type == MYSQL_TIMESTAMP_DATE)
format= DATE_ONLY; format= DATE_ONLY;
else if (ltime.second_part) else if (ltime.second_part)
format= DATE_TIME_MICROSECOND; format= DATE_TIME_MICROSECOND;
...@@ -1821,7 +1823,7 @@ longlong Item_date_add_interval::val_int() ...@@ -1821,7 +1823,7 @@ longlong Item_date_add_interval::val_int()
if (Item_date_add_interval::get_date(&ltime,0)) if (Item_date_add_interval::get_date(&ltime,0))
return (longlong) 0; return (longlong) 0;
date = (ltime.year*100L + ltime.month)*100L + ltime.day; date = (ltime.year*100L + ltime.month)*100L + ltime.day;
return ltime.time_type == TIMESTAMP_DATE ? date : return ltime.time_type == MYSQL_TIMESTAMP_DATE ? date :
((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second; ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
} }
...@@ -2069,7 +2071,7 @@ String *Item_datetime_typecast::val_str(String *str) ...@@ -2069,7 +2071,7 @@ String *Item_datetime_typecast::val_str(String *str)
bool Item_time_typecast::get_time(TIME *ltime) bool Item_time_typecast::get_time(TIME *ltime)
{ {
bool res= get_arg0_time(ltime); bool res= get_arg0_time(ltime);
ltime->time_type= TIMESTAMP_TIME; ltime->time_type= MYSQL_TIMESTAMP_TIME;
return res; return res;
} }
...@@ -2092,7 +2094,7 @@ String *Item_time_typecast::val_str(String *str) ...@@ -2092,7 +2094,7 @@ String *Item_time_typecast::val_str(String *str)
bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date) bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date)
{ {
bool res= get_arg0_date(ltime,1); bool res= get_arg0_date(ltime,1);
ltime->time_type= TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
return res; return res;
} }
...@@ -2198,17 +2200,17 @@ String *Item_func_add_time::val_str(String *str) ...@@ -2198,17 +2200,17 @@ String *Item_func_add_time::val_str(String *str)
{ {
if (get_arg0_date(&l_time1,1) || if (get_arg0_date(&l_time1,1) ||
args[1]->get_time(&l_time2) || args[1]->get_time(&l_time2) ||
l_time1.time_type == TIMESTAMP_TIME || l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
l_time2.time_type != TIMESTAMP_TIME) l_time2.time_type != MYSQL_TIMESTAMP_TIME)
goto null_date; goto null_date;
} }
else // ADDTIME function else // ADDTIME function
{ {
if (args[0]->get_time(&l_time1) || if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) || args[1]->get_time(&l_time2) ||
l_time2.time_type == TIMESTAMP_DATETIME) l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
goto null_date; goto null_date;
is_time= (l_time1.time_type == TIMESTAMP_TIME); is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg)) if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg))
l_time3.neg= 1; l_time3.neg= 1;
} }
...@@ -2324,7 +2326,7 @@ String *Item_func_timediff::val_str(String *str) ...@@ -2324,7 +2326,7 @@ String *Item_func_timediff::val_str(String *str)
if (l_time1.neg != l_time2.neg) if (l_time1.neg != l_time2.neg)
l_sign= -l_sign; l_sign= -l_sign;
if (l_time1.time_type == TIMESTAMP_TIME) // Time value if (l_time1.time_type == MYSQL_TIMESTAMP_TIME) // Time value
days= l_time1.day - l_sign*l_time2.day; days= l_time1.day - l_sign*l_time2.day;
else // DateTime value else // DateTime value
days= (calc_daynr((uint) l_time1.year, days= (calc_daynr((uint) l_time1.year,
...@@ -2466,13 +2468,13 @@ void Item_func_get_format::print(String *str) ...@@ -2466,13 +2468,13 @@ void Item_func_get_format::print(String *str)
str->append('('); str->append('(');
switch (type) { switch (type) {
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
str->append("DATE, "); str->append("DATE, ");
break; break;
case TIMESTAMP_DATETIME: case MYSQL_TIMESTAMP_DATETIME:
str->append("DATETIME, "); str->append("DATETIME, ");
break; break;
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
str->append("TIME, "); str->append("TIME, ");
break; break;
default: default:
...@@ -2555,25 +2557,25 @@ void Item_func_str_to_date::fix_length_and_dec() ...@@ -2555,25 +2557,25 @@ void Item_func_str_to_date::fix_length_and_dec()
decimals=0; decimals=0;
cached_field_type= MYSQL_TYPE_STRING; cached_field_type= MYSQL_TYPE_STRING;
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
cached_timestamp_type= TIMESTAMP_NONE; cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
if ((const_item= args[1]->const_item())) if ((const_item= args[1]->const_item()))
{ {
format= args[1]->val_str(&format_str); format= args[1]->val_str(&format_str);
cached_format_type= check_result_type(format->ptr(), format->length()); cached_format_type= check_result_type(format->ptr(), format->length());
switch (cached_format_type) { switch (cached_format_type) {
case DATE_ONLY: case DATE_ONLY:
cached_timestamp_type= TIMESTAMP_DATE; cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
cached_field_type= MYSQL_TYPE_DATE; cached_field_type= MYSQL_TYPE_DATE;
max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break; break;
case TIME_ONLY: case TIME_ONLY:
case TIME_MICROSECOND: case TIME_MICROSECOND:
cached_timestamp_type= TIMESTAMP_TIME; cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
cached_field_type= MYSQL_TYPE_TIME; cached_field_type= MYSQL_TYPE_TIME;
max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break; break;
default: default:
cached_timestamp_type= TIMESTAMP_DATETIME; cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
cached_field_type= MYSQL_TYPE_DATETIME; cached_field_type= MYSQL_TYPE_DATETIME;
break; break;
} }
...@@ -2599,7 +2601,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) ...@@ -2599,7 +2601,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
if (extract_date_time(&date_time_format, val->ptr(), val->length(), if (extract_date_time(&date_time_format, val->ptr(), val->length(),
ltime, cached_timestamp_type)) ltime, cached_timestamp_type))
goto null_date; goto null_date;
if (cached_timestamp_type == TIMESTAMP_TIME && ltime->day) if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day)
{ {
/* /*
Day part for time type can be nonzero value and so Day part for time type can be nonzero value and so
...@@ -2640,6 +2642,6 @@ bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date) ...@@ -2640,6 +2642,6 @@ bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
ltime->day= days_in_month[month_idx]; ltime->day= days_in_month[month_idx];
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366) if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
ltime->day= 29; ltime->day= 29;
ltime->time_type= TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0; return 0;
} }
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <mysql_version.h> #include <mysql_version.h>
#include <mysql_embed.h> #include <mysql_embed.h>
#include <my_sys.h> #include <my_sys.h>
#include <my_time.h>
#include <m_string.h> #include <m_string.h>
#include <hash.h> #include <hash.h>
#include <signal.h> #include <signal.h>
...@@ -1001,12 +1002,9 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, ...@@ -1001,12 +1002,9 @@ void get_date_from_daynr(long daynr,uint *year, uint *month,
void init_time(void); void init_time(void);
my_time_t my_system_gmt_sec(const TIME *, long *current_timezone, bool *not_exist); my_time_t my_system_gmt_sec(const TIME *, long *current_timezone, bool *not_exist);
my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist); my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist);
bool str_to_time(const char *str,uint length,TIME *l_time, int *was_cut);
bool str_to_time_with_warn(const char *str,uint length,TIME *l_time); bool str_to_time_with_warn(const char *str,uint length,TIME *l_time);
timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time, timestamp_type str_to_datetime_with_warn(const char *str, uint length,
uint flags, int *was_cut); TIME *l_time, uint flags);
timestamp_type str_to_TIME_with_warn(const char *str, uint length,
TIME *l_time, uint flags);
longlong number_to_TIME(longlong nr, TIME *time_res, bool fuzzy_date, longlong number_to_TIME(longlong nr, TIME *time_res, bool fuzzy_date,
int *was_cut); int *was_cut);
void localtime_to_TIME(TIME *to, struct tm *from); void localtime_to_TIME(TIME *to, struct tm *from);
......
...@@ -309,15 +309,6 @@ ulong my_bind_addr; /* the address we bind to */ ...@@ -309,15 +309,6 @@ ulong my_bind_addr; /* the address we bind to */
volatile ulong cached_thread_count= 0; volatile ulong cached_thread_count= 0;
double log_10[32]; /* 10 potences */ double log_10[32]; /* 10 potences */
ulonglong log_10_int[20]=
{
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000),
ULL(1000000000000), ULL(10000000000000), ULL(100000000000000),
ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000),
ULL(1000000000000000000), ULL(10000000000000000000)
};
time_t start_time; time_t start_time;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
...@@ -4928,18 +4919,18 @@ The minimum value for this variable is 4096.", ...@@ -4928,18 +4919,18 @@ The minimum value for this variable is 4096.",
0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0}, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
{ "date-format", OPT_DATE_FORMAT, { "date-format", OPT_DATE_FORMAT,
"The DATE format (For future).", "The DATE format (For future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_DATE], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
(gptr*) &opt_date_time_formats[TIMESTAMP_DATE], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "datetime-format", OPT_DATETIME_FORMAT, { "datetime-format", OPT_DATETIME_FORMAT,
"The DATETIME/TIMESTAMP format (for future).", "The DATETIME/TIMESTAMP format (for future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
(gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "time-format", OPT_TIME_FORMAT, { "time-format", OPT_TIME_FORMAT,
"The TIME format (for future).", "The TIME format (for future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_TIME], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
(gptr*) &opt_date_time_formats[TIMESTAMP_TIME], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
}; };
...@@ -6045,11 +6036,11 @@ static void get_options(int argc,char **argv) ...@@ -6045,11 +6036,11 @@ static void get_options(int argc,char **argv)
if (opt_log_queries_not_using_indexes) if (opt_log_queries_not_using_indexes)
opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES; opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES;
if (init_global_datetime_format(TIMESTAMP_DATE, if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
&global_system_variables.date_format) || &global_system_variables.date_format) ||
init_global_datetime_format(TIMESTAMP_TIME, init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
&global_system_variables.time_format) || &global_system_variables.time_format) ||
init_global_datetime_format(TIMESTAMP_DATETIME, init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
&global_system_variables.datetime_format)) &global_system_variables.datetime_format))
exit(1); exit(1);
} }
......
...@@ -351,13 +351,13 @@ sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_p ...@@ -351,13 +351,13 @@ sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_p
sys_var_thd_date_time_format sys_time_format("time_format", sys_var_thd_date_time_format sys_time_format("time_format",
&SV::time_format, &SV::time_format,
TIMESTAMP_TIME); MYSQL_TIMESTAMP_TIME);
sys_var_thd_date_time_format sys_date_format("date_format", sys_var_thd_date_time_format sys_date_format("date_format",
&SV::date_format, &SV::date_format,
TIMESTAMP_DATE); MYSQL_TIMESTAMP_DATE);
sys_var_thd_date_time_format sys_datetime_format("datetime_format", sys_var_thd_date_time_format sys_datetime_format("datetime_format",
&SV::datetime_format, &SV::datetime_format,
TIMESTAMP_DATETIME); MYSQL_TIMESTAMP_DATETIME);
/* Variables that are bits in THD */ /* Variables that are bits in THD */
......
...@@ -669,7 +669,7 @@ public: ...@@ -669,7 +669,7 @@ public:
class sys_var_thd_date_time_format :public sys_var_thd class sys_var_thd_date_time_format :public sys_var_thd
{ {
DATE_TIME_FORMAT *SV::*offset; DATE_TIME_FORMAT *SV::*offset;
enum timestamp_type date_time_type; timestamp_type date_time_type;
public: public:
sys_var_thd_date_time_format(const char *name_arg, sys_var_thd_date_time_format(const char *name_arg,
DATE_TIME_FORMAT *SV::*offset_arg, DATE_TIME_FORMAT *SV::*offset_arg,
......
...@@ -361,7 +361,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) ...@@ -361,7 +361,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
} }
tm.day= tm.year= tm.month= 0; tm.day= tm.year= tm.month= 0;
param->set_time(&tm, TIMESTAMP_TIME, param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
*pos+= length; *pos+= length;
...@@ -396,7 +396,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) ...@@ -396,7 +396,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
param->set_time(&tm, TIMESTAMP_DATETIME, param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
*pos+= length; *pos+= length;
...@@ -423,7 +423,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) ...@@ -423,7 +423,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
tm.second_part= 0; tm.second_part= 0;
tm.neg= 0; tm.neg= 0;
param->set_time(&tm, TIMESTAMP_DATE, param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
*pos+= length; *pos+= length;
...@@ -432,58 +432,25 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) ...@@ -432,58 +432,25 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
#else/*!EMBEDDED_LIBRARY*/ #else/*!EMBEDDED_LIBRARY*/
void set_param_time(Item_param *param, uchar **pos, ulong len) void set_param_time(Item_param *param, uchar **pos, ulong len)
{ {
TIME tm;
MYSQL_TIME *to= (MYSQL_TIME*)*pos; MYSQL_TIME *to= (MYSQL_TIME*)*pos;
param->set_time(to, MYSQL_TIMESTAMP_TIME,
tm.second_part= to->second_part;
tm.day= to->day;
tm.hour= to->hour;
tm.minute= to->minute;
tm.second= to->second;
tm.year= tm.month= 0;
tm.neg= to->neg;
param->set_time(&tm, TIMESTAMP_TIME,
MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
void set_param_datetime(Item_param *param, uchar **pos, ulong len) void set_param_datetime(Item_param *param, uchar **pos, ulong len)
{ {
TIME tm;
MYSQL_TIME *to= (MYSQL_TIME*)*pos; MYSQL_TIME *to= (MYSQL_TIME*)*pos;
tm.second_part= to->second_part; param->set_time(to, MYSQL_TIMESTAMP_DATETIME,
tm.day= to->day;
tm.hour= to->hour;
tm.minute= to->minute;
tm.second= to->second;
tm.year= to->year;
tm.month= to->month;
tm.neg= 0;
param->set_time(&tm, TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
void set_param_date(Item_param *param, uchar **pos, ulong len) void set_param_date(Item_param *param, uchar **pos, ulong len)
{ {
TIME tm;
MYSQL_TIME *to= (MYSQL_TIME*)*pos; MYSQL_TIME *to= (MYSQL_TIME*)*pos;
tm.second_part= to->second_part;
tm.day= to->day;
tm.year= to->year;
tm.month= to->month;
tm.neg= 0;
tm.hour= tm.minute= tm.second= 0;
tm.second_part= 0;
tm.neg= 0;
param->set_time(&tm, TIMESTAMP_DATE, param->set_time(to, MYSQL_TIMESTAMP_DATE,
MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
......
...@@ -3530,9 +3530,9 @@ interval: ...@@ -3530,9 +3530,9 @@ interval:
| YEAR_SYM { $$=INTERVAL_YEAR; }; | YEAR_SYM { $$=INTERVAL_YEAR; };
date_time_type: date_time_type:
DATE_SYM {$$=TIMESTAMP_DATE;} DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;}
| TIME_SYM {$$=TIMESTAMP_TIME;} | TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;}
| DATETIME {$$=TIMESTAMP_DATETIME;}; | DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;};
table_alias: table_alias:
/* empty */ /* empty */
......
...@@ -130,23 +130,14 @@ typedef struct st_read_record { /* Parameter to read_record */ ...@@ -130,23 +130,14 @@ typedef struct st_read_record { /* Parameter to read_record */
} READ_RECORD; } READ_RECORD;
enum timestamp_type /*
{ Originally MySQL used TIME structure inside server only, but since
TIMESTAMP_NONE= -2, TIMESTAMP_DATETIME_ERROR= -1, 4.1 it's exported to user in the new client API. Define aliases for
TIMESTAMP_DATE= 0, TIMESTAMP_DATETIME= 1, TIMESTAMP_TIME= 2 new names to keep existing code simple.
}; */
/* Parameters to str_to_TIME */ typedef struct st_mysql_time TIME;
#define TIME_FUZZY_DATE 1 typedef enum enum_mysql_timestamp_type timestamp_type;
#define TIME_DATETIME_ONLY 2
typedef struct st_time {
uint year,month,day,hour,minute,second;
ulong second_part;
bool neg;
timestamp_type time_type;
} TIME;
typedef struct { typedef struct {
......
...@@ -345,364 +345,19 @@ ulong convert_month_to_period(ulong month) ...@@ -345,364 +345,19 @@ ulong convert_month_to_period(ulong month)
} }
/* Position for YYYY-DD-MM HH-MM-DD.FFFFFF AM in default format */
static uchar internal_format_positions[]=
{0, 1, 2, 3, 4, 5, 6, (uchar) 255};
static char time_separator=':';
/*
Convert a timestamp string to a TIME value.
SYNOPSIS
str_to_TIME()
str String to parse
length Length of string
l_time Date is stored here
flags Bitmap of following items
TIME_FUZZY_DATE Set if we should allow partial dates
TIME_DATETIME_ONLY Set if we only allow full datetimes.
was_cut Set to 1 if value was cut during conversion or to 0
otherwise.
DESCRIPTION
At least the following formats are recogniced (based on number of digits)
YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS
YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS
YYYYMMDDTHHMMSS where T is a the character T (ISO8601)
Also dates where all parts are zero are allowed
The second part may have an optional .###### fraction part.
NOTES
This function should work with a format position vector as long as the
following things holds:
- All date are kept together and all time parts are kept together
- Date and time parts must be separated by blank
- Second fractions must come after second part and be separated
by a '.'. (The second fractions are optional)
- AM/PM must come after second fractions (or after seconds if no fractions)
- Year must always been specified.
- If time is before date, then we will use datetime format only if
the argument consist of two parts, separated by space.
Otherwise we will assume the argument is a date.
- The hour part must be specified in hour-minute-second order.
RETURN VALUES
TIMESTAMP_NONE String wasn't a timestamp, like
[DD [HH:[MM:[SS]]]].fraction.
l_time is not changed.
TIMESTAMP_DATE DATE string (YY MM and DD parts ok)
TIMESTAMP_DATETIME Full timestamp
TIMESTAMP_DATETIME_ERROR Timestamp with wrong values.
All elements in l_time is set to 0
*/
#define MAX_DATE_PARTS 8
timestamp_type
str_to_TIME(const char *str, uint length, TIME *l_time, uint flags,
int *was_cut)
{
uint field_length, year_length, digits, i, number_of_fields;
uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
uint add_hours= 0, start_loop;
ulong not_zero_date, allow_space;
bool is_internal_format;
const char *pos, *last_field_pos;
const char *end=str+length;
const uchar *format_position;
bool found_delimitier= 0, found_space= 0;
uint frac_pos, frac_len;
DBUG_ENTER("str_to_TIME");
DBUG_PRINT("ENTER",("str: %.*s",length,str));
LINT_INIT(field_length);
LINT_INIT(year_length);
LINT_INIT(last_field_pos);
*was_cut= 0;
// Skip space at start
for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
;
if (str == end || ! my_isdigit(&my_charset_latin1, *str))
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE);
}
is_internal_format= 0;
/* This has to be changed if want to activate different timestamp formats */
format_position= internal_format_positions;
/*
Calculate number of digits in first part.
If length= 8 or >= 14 then year is of format YYYY.
(YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS)
*/
for (pos=str; pos != end && my_isdigit(&my_charset_latin1,*pos) ; pos++)
;
digits= (uint) (pos-str);
start_loop= 0; // Start of scan loop
date_len[format_position[0]]= 0; // Length of year field
if (pos == end)
{
/* Found date in internal format (only numbers like YYYYMMDD) */
year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
field_length=year_length-1;
is_internal_format= 1;
format_position= internal_format_positions;
}
else
{
if (format_position[0] >= 3) // If year is after HHMMDD
{
/*
If year is not in first part then we have to determinate if we got
a date field or a datetime field.
We do this by checking if there is two numbers separated by
space in the input.
*/
while (pos < end && !my_isspace(&my_charset_latin1, *pos))
pos++;
while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
pos++;
if (pos == end)
{
if (flags & TIME_DATETIME_ONLY)
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE); // Can't be a full datetime
}
/* Date field. Set hour, minutes and seconds to 0 */
date[0]= date[1]= date[2]= date[3]= date[4]= 0;
start_loop= 5; // Start with first date part
}
}
}
/*
Only allow space in the first "part" of the datetime field and:
- after days, part seconds
- before and after AM/PM (handled by code later)
2003-03-03 20:00:20 AM
20:00:20.000000 AM 03-03-2000
*/
i= max((uint) format_position[0], (uint) format_position[1]);
set_if_bigger(i, (uint) format_position[2]);
allow_space= ((1 << i) | (1 << format_position[6]));
allow_space&= (1 | 2 | 4 | 8);
not_zero_date= 0;
for (i = start_loop;
i < MAX_DATE_PARTS-1 && str != end &&
my_isdigit(&my_charset_latin1,*str);
i++)
{
const char *start= str;
ulong tmp_value= (uint) (uchar) (*str++ - '0');
while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
(!is_internal_format || field_length--))
{
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
str++;
}
date_len[i]= (uint) (str - start);
if (tmp_value > 999999) // Impossible date part
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE);
}
date[i]=tmp_value;
not_zero_date|= tmp_value;
/* Length-1 of next field */
field_length= format_position[i+1] == 0 ? 3 : 1;
if ((last_field_pos= str) == end)
{
i++; // Register last found part
break;
}
/* Allow a 'T' after day to allow CCYYMMDDT type of fields */
if (i == format_position[2] && *str == 'T')
{
str++; // ISO8601: CCYYMMDDThhmmss
continue;
}
if (i == format_position[5]) // Seconds
{
if (*str == '.') // Followed by part seconds
{
str++;
field_length= 5; // 5 digits after first (=6)
}
continue;
/* No part seconds */
date[++i]= 0;
}
while (str != end &&
(my_ispunct(&my_charset_latin1,*str) ||
my_isspace(&my_charset_latin1,*str)))
{
if (my_isspace(&my_charset_latin1,*str))
{
if (!(allow_space & (1 << i)))
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE);
}
found_space= 1;
}
str++;
found_delimitier= 1; // Should be a 'normal' date
}
/* Check if next position is AM/PM */
if (i == format_position[6]) // Seconds, time for AM/PM
{
i++; // Skip AM/PM part
if (format_position[7] != 255) // If using AM/PM
{
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
{
if (str[0] == 'p' || str[0] == 'P')
add_hours= 12;
else if (str[0] != 'a' || str[0] != 'A')
continue; // Not AM/PM
str+= 2; // Skip AM/PM
/* Skip space after AM/PM */
while (str != end && my_isspace(&my_charset_latin1,*str))
str++;
}
}
}
last_field_pos= str;
}
if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY))
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE); // Can't be a datetime
}
str= last_field_pos;
number_of_fields= i - start_loop;
while (i < MAX_DATE_PARTS)
{
date_len[i]= 0;
date[i++]= 0;
}
if (!is_internal_format)
{
year_length= date_len[(uint) format_position[0]];
if (!year_length) // Year must be specified
{
*was_cut= 1;
DBUG_RETURN(TIMESTAMP_NONE);
}
l_time->year= date[(uint) format_position[0]];
l_time->month= date[(uint) format_position[1]];
l_time->day= date[(uint) format_position[2]];
l_time->hour= date[(uint) format_position[3]];
l_time->minute= date[(uint) format_position[4]];
l_time->second= date[(uint) format_position[5]];
frac_pos= (uint) format_position[6];
frac_len= date_len[frac_pos];
if (frac_len < 6)
date[frac_pos]*= (uint) log_10_int[6 - frac_len];
l_time->second_part= date[frac_pos];
if (format_position[7] != (uchar) 255)
{
if (l_time->hour > 12)
{
*was_cut= 1;
goto err;
}
l_time->hour= l_time->hour%12 + add_hours;
}
}
else
{
l_time->year= date[0];
l_time->month= date[1];
l_time->day= date[2];
l_time->hour= date[3];
l_time->minute= date[4];
l_time->second= date[5];
if (date_len[6] < 6)
date[6]*= (uint) log_10_int[6 - date_len[6]];
l_time->second_part=date[6];
}
l_time->neg= 0;
if (year_length == 2 && i >= format_position[1] && i >=format_position[2] &&
(l_time->month || l_time->day))
l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
if (number_of_fields < 3 || l_time->month > 12 ||
l_time->day > 31 || l_time->hour > 23 ||
l_time->minute > 59 || l_time->second > 59 ||
(!(flags & TIME_FUZZY_DATE) && (l_time->month == 0 || l_time->day == 0)))
{
/* Only give warning for a zero date if there is some garbage after */
if (!not_zero_date) // If zero date
{
for (; str != end ; str++)
{
if (!my_isspace(&my_charset_latin1, *str))
{
not_zero_date= 1; // Give warning
break;
}
}
}
if (not_zero_date)
*was_cut= 1;
goto err;
}
l_time->time_type= (number_of_fields <= 3 ?
TIMESTAMP_DATE : TIMESTAMP_DATETIME);
for (; str != end ; str++)
{
if (!my_isspace(&my_charset_latin1,*str))
{
*was_cut= 1;
break;
}
}
DBUG_RETURN(l_time->time_type=
(number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_DATETIME));
err:
bzero((char*) l_time, sizeof(*l_time));
DBUG_RETURN(TIMESTAMP_DATETIME_ERROR);
}
/* /*
Convert a timestamp string to a TIME value and produce a warning Convert a timestamp string to a TIME value and produce a warning
if string was truncated during conversion. if string was truncated during conversion.
NOTE NOTE
See description of str_to_TIME() for more information. See description of str_to_datetime() for more information.
*/ */
timestamp_type timestamp_type
str_to_TIME_with_warn(const char *str, uint length, TIME *l_time, uint flags) str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
uint flags)
{ {
int was_cut; int was_cut;
timestamp_type ts_type= str_to_TIME(str, length, l_time, flags, &was_cut); timestamp_type ts_type= str_to_datetime(str, length, l_time, flags, &was_cut);
if (was_cut) if (was_cut)
make_truncated_value_warning(current_thd, str, length, ts_type); make_truncated_value_warning(current_thd, str, length, ts_type);
return ts_type; return ts_type;
...@@ -747,190 +402,6 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *in_dst_time_gap) ...@@ -747,190 +402,6 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *in_dst_time_gap)
} }
/*
Convert a time string to a TIME struct.
SYNOPSIS
str_to_time()
str A string in full TIMESTAMP format or
[-] DAYS [H]H:MM:SS, [H]H:MM:SS, [M]M:SS, [H]HMMSS,
[M]MSS or [S]S
There may be an optional [.second_part] after seconds
length Length of str
l_time Store result here
was_cut Set to 1 if value was cut during conversion or to 0
otherwise.
NOTES
Because of the extra days argument, this function can only
work with times where the time arguments are in the above order.
RETURN
0 ok
1 error
*/
bool str_to_time(const char *str, uint length, TIME *l_time, int *was_cut)
{
long date[5],value;
const char *end=str+length, *end_of_days;
bool found_days,found_hours;
uint state;
l_time->neg=0;
*was_cut= 0;
for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
length--;
if (str != end && *str == '-')
{
l_time->neg=1;
str++;
length--;
}
if (str == end)
return 1;
/* Check first if this is a full TIMESTAMP */
if (length >= 12)
{ // Probably full timestamp
enum timestamp_type res= str_to_TIME(str,length,l_time,
(TIME_FUZZY_DATE |
TIME_DATETIME_ONLY),
was_cut);
if ((int) res >= (int) TIMESTAMP_DATETIME_ERROR)
return res == TIMESTAMP_DATETIME_ERROR;
/* We need to restore was_cut flag since str_to_TIME can modify it */
*was_cut= 0;
}
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
value=value*10L + (long) (*str - '0');
/* Skip all space after 'days' */
end_of_days= str;
for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
;
LINT_INIT(state);
found_days=found_hours=0;
if ((uint) (end-str) > 1 && str != end_of_days &&
my_isdigit(&my_charset_latin1, *str))
{ // Found days part
date[0]= value;
state= 1; // Assume next is hours
found_days= 1;
}
else if ((end-str) > 1 && *str == time_separator &&
my_isdigit(&my_charset_latin1, str[1]))
{
date[0]=0; // Assume we found hours
date[1]=value;
state=2;
found_hours=1;
str++; // skip ':'
}
else
{
/* String given as one number; assume HHMMSS format */
date[0]= 0;
date[1]= value/10000;
date[2]= value/100 % 100;
date[3]= value % 100;
state=4;
goto fractional;
}
/* Read hours, minutes and seconds */
for (;;)
{
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
value=value*10L + (long) (*str - '0');
date[state++]=value;
if (state == 4 || (end-str) < 2 || *str != time_separator ||
!my_isdigit(&my_charset_latin1,str[1]))
break;
str++; // Skip time_separator (':')
}
if (state != 4)
{ // Not HH:MM:SS
/* Fix the date to assume that seconds was given */
if (!found_hours && !found_days)
{
bmove_upp((char*) (date+4), (char*) (date+state),
sizeof(long)*(state-1));
bzero((char*) date, sizeof(long)*(4-state));
}
else
bzero((char*) (date+state), sizeof(long)*(4-state));
}
fractional:
/* Get fractional second part */
if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
{
uint field_length=5;
str++; value=(uint) (uchar) (*str - '0');
while (++str != end &&
my_isdigit(&my_charset_latin1,str[0]) &&
field_length--)
value=value*10 + (uint) (uchar) (*str - '0');
if (field_length)
value*= (long) log_10_int[field_length];
date[4]=value;
}
else
date[4]=0;
if (internal_format_positions[7] != 255)
{
/* Read a possible AM/PM */
while (str != end && my_isspace(&my_charset_latin1, *str))
str++;
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
{
if (str[0] == 'p' || str[0] == 'P')
{
str+= 2;
date[1]= date[1]%12 + 12;
}
else if (str[0] == 'a' || str[0] == 'A')
str+=2;
}
}
/* Some simple checks */
if (date[2] >= 60 || date[3] >= 60)
{
*was_cut= 1;
return 1;
}
l_time->year= 0; // For protocol::store_time
l_time->month= 0;
l_time->day= date[0];
l_time->hour= date[1];
l_time->minute= date[2];
l_time->second= date[3];
l_time->second_part= date[4];
l_time->time_type= TIMESTAMP_TIME;
/* Check if there is garbage at end of the TIME specification */
if (str != end)
{
do
{
if (!my_isspace(&my_charset_latin1,*str))
{
*was_cut= 1;
break;
}
} while (++str != end);
}
return 0;
}
/* /*
Convert a time string to a TIME struct and produce a warning Convert a time string to a TIME struct and produce a warning
if string was cut during conversion. if string was cut during conversion.
...@@ -944,7 +415,7 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time) ...@@ -944,7 +415,7 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time)
int was_cut; int was_cut;
bool ret_val= str_to_time(str, length, l_time, &was_cut); bool ret_val= str_to_time(str, length, l_time, &was_cut);
if (was_cut) if (was_cut)
make_truncated_value_warning(current_thd, str, length, TIMESTAMP_TIME); make_truncated_value_warning(current_thd, str, length, MYSQL_TIMESTAMP_TIME);
return ret_val; return ret_val;
} }
...@@ -1210,10 +681,10 @@ bool parse_date_time_format(timestamp_type format_type, ...@@ -1210,10 +681,10 @@ bool parse_date_time_format(timestamp_type format_type,
The last test is to ensure that %p is used if and only if The last test is to ensure that %p is used if and only if
it's needed. it's needed.
*/ */
if ((format_type == TIMESTAMP_DATETIME && if ((format_type == MYSQL_TIMESTAMP_DATETIME &&
!test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) || !test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) ||
(format_type == TIMESTAMP_DATE && part_map != (1 | 2 | 4)) || (format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
(format_type == TIMESTAMP_TIME && (format_type == MYSQL_TIMESTAMP_TIME &&
!test_all_bits(part_map, 8 | 16 | 32)) || !test_all_bits(part_map, 8 | 16 | 32)) ||
!allow_separator || // %option should be last !allow_separator || // %option should be last
(need_p && dt_pos[6] +1 != dt_pos[7]) || (need_p && dt_pos[6] +1 != dt_pos[7]) ||
...@@ -1256,10 +727,10 @@ bool parse_date_time_format(timestamp_type format_type, ...@@ -1256,10 +727,10 @@ bool parse_date_time_format(timestamp_type format_type,
format_str= 0; format_str= 0;
switch (format_type) { switch (format_type) {
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
format_str= known_date_time_formats[INTERNAL_FORMAT].date_format; format_str= known_date_time_formats[INTERNAL_FORMAT].date_format;
/* fall through */ /* fall through */
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
if (!format_str) if (!format_str)
format_str=known_date_time_formats[INTERNAL_FORMAT].time_format; format_str=known_date_time_formats[INTERNAL_FORMAT].time_format;
...@@ -1274,7 +745,7 @@ bool parse_date_time_format(timestamp_type format_type, ...@@ -1274,7 +745,7 @@ bool parse_date_time_format(timestamp_type format_type,
return 0; return 0;
if (separator_map == (1 | 2)) if (separator_map == (1 | 2))
{ {
if (format_type == TIMESTAMP_TIME) if (format_type == MYSQL_TIMESTAMP_TIME)
{ {
if (*(format+2) != *(format+5)) if (*(format+2) != *(format+5))
break; // Error break; // Error
...@@ -1284,7 +755,7 @@ bool parse_date_time_format(timestamp_type format_type, ...@@ -1284,7 +755,7 @@ bool parse_date_time_format(timestamp_type format_type,
return 0; return 0;
} }
break; break;
case TIMESTAMP_DATETIME: case MYSQL_TIMESTAMP_DATETIME:
/* /*
If there is no separators, allow the internal format as we can read If there is no separators, allow the internal format as we can read
this. If separators are used, they must be between each part. this. If separators are used, they must be between each part.
...@@ -1403,11 +874,11 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format, ...@@ -1403,11 +874,11 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
timestamp_type type) timestamp_type type)
{ {
switch (type) { switch (type) {
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
return format->date_format; return format->date_format;
case TIMESTAMP_DATETIME: case MYSQL_TIMESTAMP_DATETIME:
return format->datetime_format; return format->datetime_format;
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
return format->time_format; return format->time_format;
default: default:
DBUG_ASSERT(0); // Impossible DBUG_ASSERT(0); // Impossible
...@@ -1489,13 +960,13 @@ void make_truncated_value_warning(THD *thd, const char *str_val, ...@@ -1489,13 +960,13 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
str.append('\0'); str.append('\0');
switch (time_type) { switch (time_type) {
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
type_str= "date"; type_str= "date";
break; break;
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
type_str= "time"; type_str= "time";
break; break;
case TIMESTAMP_DATETIME: // FALLTHROUGH case MYSQL_TIMESTAMP_DATETIME: // FALLTHROUGH
default: default:
type_str= "datetime"; type_str= "datetime";
break; break;
...@@ -1565,14 +1036,14 @@ ulonglong TIME_to_ulonglong_time(const TIME *time) ...@@ -1565,14 +1036,14 @@ ulonglong TIME_to_ulonglong_time(const TIME *time)
ulonglong TIME_to_ulonglong(const TIME *time) ulonglong TIME_to_ulonglong(const TIME *time)
{ {
switch (time->time_type) { switch (time->time_type) {
case TIMESTAMP_DATETIME: case MYSQL_TIMESTAMP_DATETIME:
return TIME_to_ulonglong_datetime(time); return TIME_to_ulonglong_datetime(time);
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
return TIME_to_ulonglong_date(time); return TIME_to_ulonglong_date(time);
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
return TIME_to_ulonglong_time(time); return TIME_to_ulonglong_time(time);
case TIMESTAMP_NONE: case MYSQL_TIMESTAMP_NONE:
case TIMESTAMP_DATETIME_ERROR: case MYSQL_TIMESTAMP_ERROR:
return ULL(0); return ULL(0);
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
...@@ -1595,17 +1066,17 @@ ulonglong TIME_to_ulonglong(const TIME *time) ...@@ -1595,17 +1066,17 @@ ulonglong TIME_to_ulonglong(const TIME *time)
void TIME_to_string(const TIME *time, String *str) void TIME_to_string(const TIME *time, String *str)
{ {
switch (time->time_type) { switch (time->time_type) {
case TIMESTAMP_DATETIME: case MYSQL_TIMESTAMP_DATETIME:
make_datetime((DATE_TIME_FORMAT*) 0, time, str); make_datetime((DATE_TIME_FORMAT*) 0, time, str);
break; break;
case TIMESTAMP_DATE: case MYSQL_TIMESTAMP_DATE:
make_date((DATE_TIME_FORMAT*) 0, time, str); make_date((DATE_TIME_FORMAT*) 0, time, str);
break; break;
case TIMESTAMP_TIME: case MYSQL_TIMESTAMP_TIME:
make_time((DATE_TIME_FORMAT*) 0, time, str); make_time((DATE_TIME_FORMAT*) 0, time, str);
break; break;
case TIMESTAMP_NONE: case MYSQL_TIMESTAMP_NONE:
case TIMESTAMP_DATETIME_ERROR: case MYSQL_TIMESTAMP_ERROR:
str->length(0); str->length(0);
str->set_charset(&my_charset_bin); str->set_charset(&my_charset_bin);
break; break;
......
...@@ -584,7 +584,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset) ...@@ -584,7 +584,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset)
/* filling MySQL specific TIME members */ /* filling MySQL specific TIME members */
tmp->neg= 0; tmp->second_part= 0; tmp->neg= 0; tmp->second_part= 0;
tmp->time_type= TIMESTAMP_DATETIME; tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
} }
...@@ -1011,7 +1011,7 @@ Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const ...@@ -1011,7 +1011,7 @@ Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
localtime_r(&tmp_t, &tmp_tm); localtime_r(&tmp_t, &tmp_tm);
localtime_to_TIME(tmp, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm);
tmp->time_type= TIMESTAMP_DATETIME; tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
} }
...@@ -1094,7 +1094,7 @@ Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const ...@@ -1094,7 +1094,7 @@ Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
time_t tmp_t= (time_t)t; time_t tmp_t= (time_t)t;
gmtime_r(&tmp_t, &tmp_tm); gmtime_r(&tmp_t, &tmp_tm);
localtime_to_TIME(tmp, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm);
tmp->time_type= TIMESTAMP_DATETIME; tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
} }
......
...@@ -9964,6 +9964,80 @@ static void test_bug4236() ...@@ -9964,6 +9964,80 @@ static void test_bug4236()
} }
static void test_bug4030()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[3];
MYSQL_TIME time_canonical, time_out;
MYSQL_TIME date_canonical, date_out;
MYSQL_TIME datetime_canonical, datetime_out;
const char *stmt_text;
int rc;
myheader("test_bug4030");
/* Check that microseconds are inserted and selected successfully */
/* Execute a query with time values in prepared mode */
stmt= mysql_stmt_init(mysql);
stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
"'2003-12-31 23:59:59.123456'";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_execute(stmt, rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
/* Bind output buffers */
bzero(bind, sizeof(bind));
bzero(&time_canonical, sizeof(time_canonical));
bzero(&time_out, sizeof(time_out));
bzero(&date_canonical, sizeof(date_canonical));
bzero(&date_out, sizeof(date_out));
bzero(&datetime_canonical, sizeof(datetime_canonical));
bzero(&datetime_out, sizeof(datetime_out));
bind[0].buffer_type= MYSQL_TYPE_TIME;
bind[0].buffer= (char*) &time_out;
bind[1].buffer_type= MYSQL_TYPE_DATE;
bind[1].buffer= (char*) &date_out;
bind[2].buffer_type= MYSQL_TYPE_DATETIME;
bind[2].buffer= (char*) &datetime_out;
time_canonical.hour= 23;
time_canonical.minute= 59;
time_canonical.second= 59;
time_canonical.second_part= 123456;
time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
date_canonical.year= 2003;
date_canonical.month= 12;
date_canonical.day= 31;
date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
datetime_canonical= time_canonical;
datetime_canonical.year= 2003;
datetime_canonical.month= 12;
datetime_canonical.day= 31;
datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
mysql_stmt_bind_result(stmt, bind);
rc= mysql_stmt_fetch(stmt);
assert(rc == 0);
printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
time_out.second_part);
printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
datetime_out.day, datetime_out.hour,
datetime_out.minute, datetime_out.second,
datetime_out.second_part);
assert(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
assert(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
assert(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
mysql_stmt_close(stmt);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -10259,6 +10333,8 @@ int main(int argc, char **argv) ...@@ -10259,6 +10333,8 @@ int main(int argc, char **argv)
test_bug4026(); /* test microseconds precision of time types */ test_bug4026(); /* test microseconds precision of time types */
test_bug4079(); /* erroneous subquery in prepared statement */ test_bug4079(); /* erroneous subquery in prepared statement */
test_bug4236(); /* init -> execute */ test_bug4236(); /* init -> execute */
test_bug4030(); /* test conversion string -> time types in
libmysql */
/* /*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment