Commit 9dde4188 authored by unknown's avatar unknown

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.


VC++Files/libmysql/libmysql.dsp:
  new file: my_time.c
VC++Files/libmysqld/libmysqld.dsp:
  new file: my_time.c
VC++Files/sql/mysqld.dsp:
  new file: my_time.c
include/Makefile.am:
  - mysql_time.h added to the list of installed client library headers
include/mysql.h:
  - declarations for MYSQL_TIME and enum_mysql_timestamp_type moved to 
  mysql_time.h, which is in shared use of client library and mysys.
libmysql/Makefile.shared:
  - my_time.lo added to the list of libmysql objects
libmysql/libmysql.c:
  Fix for bug#4030 "Client side conversion string -> date type doesn't work
   (prepared statements)" and cleanup.
  - added case labels for TIME/DATE/DATETIME types to send_data_str
  - comments for read_binary_{date,time,datetime}, fetch_result_*, fetch_results.
libmysqld/Makefile.am:
  - my_time.c added
sql-common/Makefile.am:
  - my_time.c added to the list of files included into source distribution.
sql/Makefile.am:
  my_time.c added to the list of mysqld sources.
sql/field.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/item.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/item_timefunc.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/mysql_priv.h:
  - added typedefs for TIME and timestamp_type
  - removed declarations for str_to_time and str_to_TIME (now this functions
    reside in mysys)
sql/mysqld.cc:
  - log_10_int moved to mysys (it's used by str_to_TIME and str_to_time)
  - enum values TIMESTAMP_{TIME,DATE,DATETIME} were renamed to
    MYSQL_TIMESTAMP_{TIME,DATE,DATETIME}
sql/set_var.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/set_var.h:
  - fixed timestamp_type usage to be compatible with typedef.
sql/sql_prepare.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME} were renamed to
    MYSQL_TIMESTAMP_{TIME,DATE,DATETIME}
  - embedded library implementation of set_param_{time,date,datetime} is
  much simplier now, as MYSQL_TIME is the same as TIME.
sql/sql_yacc.yy:
  - s/\<TIMESTAMP_/MYSQL_TIMESTAMP/gc
sql/structs.h:
  - declarations for TIME and timestamp_type replaced with typedefs
  - str_to_datetime arguments moved to mysys headers
sql/time.cc:
  - str_to_time and str_to_TIME moved to mysys
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...} as these names are now
    exported to client.
  - str_to_TIME renamed to str_to_datetime to pair with str_to_time
  - str_to_TIME_with_warn renamed accordingly
sql/tztime.cc:
  - TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to 
    MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
tests/client_test.c:
  - a test case for Bug#4030 "Client side conversion string -> date type 
  doesn't work (prepared statements)"
parent 85e9258b
...@@ -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) $<
......
This diff is collapsed.
...@@ -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,11 +1002,8 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, ...@@ -1001,11 +1002,8 @@ 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);
timestamp_type str_to_TIME_with_warn(const char *str, uint length,
TIME *l_time, uint flags); 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);
......
...@@ -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; param->set_time(to, MYSQL_TIMESTAMP_DATE,
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,
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 {
......
This diff is collapsed.
...@@ -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