Commit 29b88ff5 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/kostja/mysql/mysql-4.1-4030
parents 62aeb886 a30fcdc6
......@@ -427,6 +427,10 @@ SOURCE=.\pack.c
# End Source File
# Begin Source File
SOURCE=.\my_time.c
# End Source File
# Begin Source File
SOURCE=.\password.c
# End Source File
# Begin Source File
......
......@@ -368,6 +368,10 @@ SOURCE="..\sql-common\pack.c"
# End Source File
# Begin Source File
SOURCE=..\sql-common\my_time.c
# End Source File
# Begin Source File
SOURCE=..\libmysql\password.c
# End Source File
# Begin Source File
......
......@@ -1053,6 +1053,10 @@ SOURCE=.\pack.c
# End Source File
# Begin Source File
SOURCE=.\my_time.c
# End Source File
# Begin Source File
SOURCE=.\password.c
!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 \
errmsg.h my_global.h my_net.h my_alloc.h \
my_getopt.h sslopt-longopts.h my_dir.h typelib.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 \
nisam.h heap.h merge.h my_bitmap.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;
#endif /* _global_h */
#include "mysql_com.h"
#include "mysql_time.h"
#include "mysql_version.h"
#include "typelib.h"
......@@ -533,23 +534,6 @@ enum enum_mysql_stmt_state
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 */
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 \
my_pread.lo mf_cache.lo md5.lo sha1.lo\
my_getopt.lo my_gethostbyname.lo my_port.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
mysysobjects2 = my_lib.lo
......
......@@ -16,6 +16,7 @@
#include <my_global.h>
#include <my_sys.h>
#include <my_time.h>
#include <mysys_err.h>
#include <m_string.h>
#include <m_ctype.h>
......@@ -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)
{
tm->year= tm->month= tm->day= 0;
tm->hour= tm->minute= tm->second= 0;
tm->second_part= 0;
tm->neg= (bool)0;
bzero((void *)tm, sizeof(*tm));
}
/* 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)
{
uchar *to;
......@@ -3060,7 +3061,6 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
return length;
}
/* Read DATETIME from binary packet and return it to MYSQL_TIME */
static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
{
uchar *to;
......@@ -3091,7 +3091,6 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
return length;
}
/* Read DATE from binary packet and return it to MYSQL_TIME */
static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
{
uchar *to;
......@@ -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,
longlong value)
{
......@@ -3273,6 +3273,21 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
doublestore(buffer, data);
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_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
......@@ -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,
ltime.month,ltime.day));
break;
case MYSQL_TIMESTAMP_FULL:
case MYSQL_TIMESTAMP_DATETIME:
length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
ltime.year,ltime.month,ltime.day,
ltime.hour,ltime.minute,ltime.second));
......@@ -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)
{
......@@ -3437,7 +3452,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
MYSQL_TIME tm;
length= read_binary_datetime(&tm, row);
tm.time_type= MYSQL_TIMESTAMP_FULL;
tm.time_type= MYSQL_TIMESTAMP_DATETIME;
send_data_time(param, tm, length);
break;
}
......@@ -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)
{
*param->buffer= **row;
......
......@@ -33,7 +33,8 @@ noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
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
......@@ -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_update.cc sql_yacc.cc table.cc thr_malloc.cc time.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_a_SOURCES=
......
......@@ -15,7 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## 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
%::SCCS/s.%
......@@ -89,7 +89,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
client.c sql_client.cc mini_client_errors.c pack.c\
stacktrace.c repl_failsafe.h repl_failsafe.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_LDADD = $(LDADD) $(CXXLDFLAGS)
......@@ -114,6 +115,8 @@ link_sources:
@LN_CP_F@ ../sql-common/pack.c pack.c
rm -f 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
$(CXXCOMPILE) -c $(INCLUDES) $<
......
......@@ -398,8 +398,8 @@ bool Field::get_date(TIME *ltime,uint fuzzydate)
char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
if (!(res=val_str(&tmp)) ||
str_to_TIME_with_warn(res->ptr(), res->length(), ltime, fuzzydate) <=
TIMESTAMP_DATETIME_ERROR)
str_to_datetime_with_warn(res->ptr(), res->length(),
ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
return 1;
return 0;
}
......@@ -2918,12 +2918,12 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
bool in_dst_time_gap;
THD *thd= table->in_use;
have_smth_to_conv= (str_to_TIME(from, len, &l_time, 0, &error) >
TIMESTAMP_DATETIME_ERROR);
have_smth_to_conv= (str_to_datetime(from, len, &l_time, 0, &error) >
MYSQL_TIMESTAMP_ERROR);
if (error)
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)
{
......@@ -2931,7 +2931,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_DATETIME, !error);
from, len, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1;
}
......@@ -2939,7 +2939,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_INVALID_TIMESTAMP,
from, len, TIMESTAMP_DATETIME, !error);
from, len, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1;
}
}
......@@ -2962,7 +2962,7 @@ int Field_timestamp::store(double nr)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME);
nr, MYSQL_TIMESTAMP_DATETIME);
nr= 0; // Avoid overflow on buff
error= 1;
}
......@@ -2985,7 +2985,7 @@ int Field_timestamp::store(longlong nr)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME, 1);
nr, MYSQL_TIMESTAMP_DATETIME, 1);
error= 1;
}
......@@ -2993,14 +2993,14 @@ int Field_timestamp::store(longlong nr)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_INVALID_TIMESTAMP,
nr, TIMESTAMP_DATETIME, !error);
nr, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1;
}
}
else if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED,
nr, TIMESTAMP_DATETIME, 1);
nr, MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
......@@ -3232,14 +3232,14 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
tmp=0L;
error= 1;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_TIME, 1);
from, len, MYSQL_TIMESTAMP_TIME, 1);
}
else
{
if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED,
from, len, TIMESTAMP_TIME, 1);
from, len, MYSQL_TIMESTAMP_TIME, 1);
if (ltime.month)
ltime.day=0;
......@@ -3249,7 +3249,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
tmp=8385959;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_TIME, !error);
from, len, MYSQL_TIMESTAMP_TIME, !error);
error= 1;
}
}
......@@ -3269,14 +3269,14 @@ int Field_time::store(double nr)
{
tmp=8385959L;
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;
}
else if (nr < -8385959.0)
{
tmp= -8385959L;
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;
}
else
......@@ -3288,7 +3288,8 @@ int Field_time::store(double nr)
{
tmp=0;
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;
}
}
......@@ -3305,14 +3306,16 @@ int Field_time::store(longlong nr)
{
tmp=8385959L;
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;
}
else if (nr < (longlong) -8385959L)
{
tmp= -8385959L;
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;
}
else
......@@ -3322,7 +3325,8 @@ int Field_time::store(longlong nr)
{
tmp=0;
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;
}
}
......@@ -3417,7 +3421,7 @@ bool Field_time::get_time(TIME *ltime)
ltime->minute= (int) tmp/100;
ltime->second= (int) tmp % 100;
ltime->second_part=0;
ltime->time_type= TIMESTAMP_TIME;
ltime->time_type= MYSQL_TIMESTAMP_TIME;
return 0;
}
......@@ -3566,8 +3570,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
uint32 tmp;
int error;
if (str_to_TIME(from, len, &l_time, 1, &error) <=
TIMESTAMP_DATETIME_ERROR)
if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0;
error= 1;
......@@ -3577,7 +3580,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
if (error)
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
if (table->db_low_byte_first)
......@@ -3602,7 +3605,7 @@ int Field_date::store(double nr)
tmp=0L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATE);
nr, MYSQL_TIMESTAMP_DATE);
error= 1;
}
else
......@@ -3630,7 +3633,7 @@ int Field_date::store(longlong nr)
tmp=0L;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATE, 0);
nr, MYSQL_TIMESTAMP_DATE, 0);
error= 1;
}
else
......@@ -3758,8 +3761,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
TIME l_time;
long tmp;
int error;
if (str_to_TIME(from, len, &l_time, 1, &error) <=
TIMESTAMP_DATETIME_ERROR)
if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0L;
error= 1;
......@@ -3769,7 +3771,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
if (error)
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);
return error;
......@@ -3781,7 +3783,7 @@ int Field_newdate::store(double nr)
{
(void) Field_newdate::store((longlong) -1);
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;
}
else
......@@ -3799,7 +3801,8 @@ int Field_newdate::store(longlong nr)
{
tmp=0;
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;
}
else
......@@ -3818,7 +3821,8 @@ int Field_newdate::store(longlong nr)
{
tmp=0L; // Don't allow date to change
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;
}
else
......@@ -3831,7 +3835,7 @@ int Field_newdate::store(longlong nr)
void Field_newdate::store_time(TIME *ltime,timestamp_type type)
{
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;
else
{
......@@ -3895,7 +3899,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
ltime->day= tmp & 31;
ltime->month= (tmp >> 5) & 15;
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;
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
......@@ -3939,14 +3943,13 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
int error;
ulonglong tmp= 0;
if (str_to_TIME(from, len, &time_tmp, 1, &error) >
TIMESTAMP_DATETIME_ERROR)
if (str_to_datetime(from, len, &time_tmp, 1, &error) > MYSQL_TIMESTAMP_ERROR)
tmp= TIME_to_ulonglong_datetime(&time_tmp);
if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
from, len, TIMESTAMP_DATETIME, 1);
from, len, MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
......@@ -3967,7 +3970,7 @@ int Field_datetime::store(double nr)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, TIMESTAMP_DATETIME);
nr, MYSQL_TIMESTAMP_DATETIME);
nr=0.0;
error= 1;
}
......@@ -3987,7 +3990,7 @@ int Field_datetime::store(longlong nr)
if (error)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_TRUNCATED, initial_nr,
TIMESTAMP_DATETIME, 1);
MYSQL_TIMESTAMP_DATETIME, 1);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
......@@ -4004,7 +4007,7 @@ int Field_datetime::store(longlong nr)
void Field_datetime::store_time(TIME *ltime,timestamp_type type)
{
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)+
(ltime->hour*10000L+ltime->minute*100+ltime->second));
else
......@@ -4103,7 +4106,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate)
part1=(uint32) (tmp/LL(1000000));
part2=(uint32) (tmp - (ulonglong) part1*LL(1000000));
ltime->time_type= TIMESTAMP_DATETIME;
ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
ltime->neg= 0;
ltime->second_part= 0;
ltime->second= (int) (part2%100);
......
......@@ -228,8 +228,8 @@ bool Item::get_date(TIME *ltime,uint fuzzydate)
char buff[40];
String tmp(buff,sizeof(buff), &my_charset_bin),*res;
if (!(res=val_str(&tmp)) ||
str_to_TIME_with_warn(res->ptr(),res->length(),ltime,fuzzydate) <=
TIMESTAMP_DATETIME_ERROR)
str_to_datetime_with_warn(res->ptr(), res->length(),
ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
{
bzero((char*) ltime,sizeof(*ltime));
return 1;
......
......@@ -425,21 +425,21 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->append(month_names[l_time->month-1],3);
break;
case 'W':
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0);
str->append(day_names[weekday]);
break;
case 'a':
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),0);
str->append(day_names[weekday],3);
break;
case 'D':
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
str->append_with_prefill(intbuff, length, 1, '0');
......@@ -507,7 +507,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'j':
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
length= int10_to_str(calc_daynr(l_time->year,l_time->month,
l_time->day) -
......@@ -555,7 +555,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'u':
{
uint year;
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
length= int10_to_str(calc_week(l_time,
(*ptr) == 'U' ?
......@@ -569,7 +569,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'V':
{
uint year;
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
length= int10_to_str(calc_week(l_time,
((*ptr) == 'V' ?
......@@ -584,7 +584,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'X':
{
uint year;
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
(void) calc_week(l_time,
((*ptr) == 'X' ?
......@@ -596,7 +596,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
}
break;
case 'w':
if (type == TIMESTAMP_TIME)
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
l_time->day),1);
......@@ -1107,7 +1107,7 @@ int Item_date::save_in_field(Field *field, bool no_conversions)
if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null(field);
field->set_notnull();
field->store_time(&ltime, TIMESTAMP_DATE);
field->store_time(&ltime, MYSQL_TIMESTAMP_DATE);
return 0;
}
......@@ -1129,7 +1129,7 @@ bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
return 1;
bzero(ltime, sizeof(TIME));
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;
}
......@@ -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 */
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);
}
......@@ -1308,7 +1308,7 @@ bool Item_func_now::get_date(TIME *res,
int Item_func_now::save_in_field(Field *to, bool no_conversions)
{
to->set_notnull();
to->store_time(&ltime,TIMESTAMP_DATETIME);
to->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
return 0;
}
......@@ -1494,7 +1494,9 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */
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;
null_date:
......@@ -1713,7 +1715,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
case INTERVAL_DAY_HOUR:
{
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;
extra_sec= microseconds/1000000L;
microseconds= microseconds%1000000L;
......@@ -1798,7 +1800,7 @@ String *Item_date_add_interval::val_str(String *str)
if (Item_date_add_interval::get_date(&ltime,0))
return 0;
if (ltime.time_type == TIMESTAMP_DATE)
if (ltime.time_type == MYSQL_TIMESTAMP_DATE)
format= DATE_ONLY;
else if (ltime.second_part)
format= DATE_TIME_MICROSECOND;
......@@ -1821,7 +1823,7 @@ longlong Item_date_add_interval::val_int()
if (Item_date_add_interval::get_date(&ltime,0))
return (longlong) 0;
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;
}
......@@ -2069,7 +2071,7 @@ String *Item_datetime_typecast::val_str(String *str)
bool Item_time_typecast::get_time(TIME *ltime)
{
bool res= get_arg0_time(ltime);
ltime->time_type= TIMESTAMP_TIME;
ltime->time_type= MYSQL_TIMESTAMP_TIME;
return res;
}
......@@ -2092,7 +2094,7 @@ String *Item_time_typecast::val_str(String *str)
bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date)
{
bool res= get_arg0_date(ltime,1);
ltime->time_type= TIMESTAMP_DATE;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
return res;
}
......@@ -2198,17 +2200,17 @@ String *Item_func_add_time::val_str(String *str)
{
if (get_arg0_date(&l_time1,1) ||
args[1]->get_time(&l_time2) ||
l_time1.time_type == TIMESTAMP_TIME ||
l_time2.time_type != TIMESTAMP_TIME)
l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
l_time2.time_type != MYSQL_TIMESTAMP_TIME)
goto null_date;
}
else // ADDTIME function
{
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
l_time2.time_type == TIMESTAMP_DATETIME)
l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
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))
l_time3.neg= 1;
}
......@@ -2324,7 +2326,7 @@ String *Item_func_timediff::val_str(String *str)
if (l_time1.neg != l_time2.neg)
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;
else // DateTime value
days= (calc_daynr((uint) l_time1.year,
......@@ -2466,13 +2468,13 @@ void Item_func_get_format::print(String *str)
str->append('(');
switch (type) {
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
str->append("DATE, ");
break;
case TIMESTAMP_DATETIME:
case MYSQL_TIMESTAMP_DATETIME:
str->append("DATETIME, ");
break;
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
str->append("TIME, ");
break;
default:
......@@ -2555,25 +2557,25 @@ void Item_func_str_to_date::fix_length_and_dec()
decimals=0;
cached_field_type= MYSQL_TYPE_STRING;
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()))
{
format= args[1]->val_str(&format_str);
cached_format_type= check_result_type(format->ptr(), format->length());
switch (cached_format_type) {
case DATE_ONLY:
cached_timestamp_type= TIMESTAMP_DATE;
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
cached_field_type= MYSQL_TYPE_DATE;
max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break;
case TIME_ONLY:
case TIME_MICROSECOND:
cached_timestamp_type= TIMESTAMP_TIME;
cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
cached_field_type= MYSQL_TYPE_TIME;
max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break;
default:
cached_timestamp_type= TIMESTAMP_DATETIME;
cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
cached_field_type= MYSQL_TYPE_DATETIME;
break;
}
......@@ -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(),
ltime, cached_timestamp_type))
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
......@@ -2640,6 +2642,6 @@ bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
ltime->day= days_in_month[month_idx];
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
ltime->day= 29;
ltime->time_type= TIMESTAMP_DATE;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0;
}
......@@ -18,6 +18,7 @@
#include <mysql_version.h>
#include <mysql_embed.h>
#include <my_sys.h>
#include <my_time.h>
#include <m_string.h>
#include <hash.h>
#include <signal.h>
......@@ -1002,12 +1003,9 @@ void get_date_from_daynr(long daynr,uint *year, uint *month,
void init_time(void);
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);
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);
timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
uint flags, int *was_cut);
timestamp_type str_to_TIME_with_warn(const char *str, uint length,
TIME *l_time, uint flags);
timestamp_type str_to_datetime_with_warn(const char *str, uint length,
TIME *l_time, uint flags);
longlong number_to_TIME(longlong nr, TIME *time_res, bool fuzzy_date,
int *was_cut);
void localtime_to_TIME(TIME *to, struct tm *from);
......
......@@ -311,15 +311,6 @@ ulong my_bind_addr; /* the address we bind to */
volatile ulong cached_thread_count= 0;
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;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
......@@ -5001,18 +4992,18 @@ The minimum value for this variable is 4096.",
0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
{ "date-format", OPT_DATE_FORMAT,
"The DATE format (For future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_DATE],
(gptr*) &opt_date_time_formats[TIMESTAMP_DATE],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "datetime-format", OPT_DATETIME_FORMAT,
"The DATETIME/TIMESTAMP format (for future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME],
(gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "time-format", OPT_TIME_FORMAT,
"The TIME format (for future).",
(gptr*) &opt_date_time_formats[TIMESTAMP_TIME],
(gptr*) &opt_date_time_formats[TIMESTAMP_TIME],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
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}
};
......@@ -6118,11 +6109,11 @@ static void get_options(int argc,char **argv)
if (opt_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) ||
init_global_datetime_format(TIMESTAMP_TIME,
init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
&global_system_variables.time_format) ||
init_global_datetime_format(TIMESTAMP_DATETIME,
init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
&global_system_variables.datetime_format))
exit(1);
}
......
......@@ -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",
&SV::time_format,
TIMESTAMP_TIME);
MYSQL_TIMESTAMP_TIME);
sys_var_thd_date_time_format sys_date_format("date_format",
&SV::date_format,
TIMESTAMP_DATE);
MYSQL_TIMESTAMP_DATE);
sys_var_thd_date_time_format sys_datetime_format("datetime_format",
&SV::datetime_format,
TIMESTAMP_DATETIME);
MYSQL_TIMESTAMP_DATETIME);
/* Variables that are bits in THD */
......
......@@ -669,7 +669,7 @@ public:
class sys_var_thd_date_time_format :public sys_var_thd
{
DATE_TIME_FORMAT *SV::*offset;
enum timestamp_type date_time_type;
timestamp_type date_time_type;
public:
sys_var_thd_date_time_format(const char *name_arg,
DATE_TIME_FORMAT *SV::*offset_arg,
......
......@@ -361,7 +361,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
}
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);
}
*pos+= length;
......@@ -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;
param->set_time(&tm, TIMESTAMP_DATETIME,
param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
}
*pos+= length;
......@@ -423,7 +423,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
tm.second_part= 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);
}
*pos+= length;
......@@ -432,58 +432,25 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
#else/*!EMBEDDED_LIBRARY*/
void set_param_time(Item_param *param, uchar **pos, ulong len)
{
TIME tm;
MYSQL_TIME *to= (MYSQL_TIME*)*pos;
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,
param->set_time(to, MYSQL_TIMESTAMP_TIME,
MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
}
void set_param_datetime(Item_param *param, uchar **pos, ulong len)
{
TIME tm;
MYSQL_TIME *to= (MYSQL_TIME*)*pos;
tm.second_part= to->second_part;
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,
param->set_time(to, MYSQL_TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
}
void set_param_date(Item_param *param, uchar **pos, ulong len)
{
TIME tm;
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);
}
#endif /*!EMBEDDED_LIBRARY*/
......
......@@ -3530,9 +3530,9 @@ interval:
| YEAR_SYM { $$=INTERVAL_YEAR; };
date_time_type:
DATE_SYM {$$=TIMESTAMP_DATE;}
| TIME_SYM {$$=TIMESTAMP_TIME;}
| DATETIME {$$=TIMESTAMP_DATETIME;};
DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;}
| TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;}
| DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;};
table_alias:
/* empty */
......
......@@ -130,23 +130,14 @@ typedef struct st_read_record { /* Parameter to read_record */
} READ_RECORD;
enum timestamp_type
{
TIMESTAMP_NONE= -2, TIMESTAMP_DATETIME_ERROR= -1,
TIMESTAMP_DATE= 0, TIMESTAMP_DATETIME= 1, TIMESTAMP_TIME= 2
};
/* Parameters to str_to_TIME */
#define TIME_FUZZY_DATE 1
#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;
/*
Originally MySQL used TIME structure inside server only, but since
4.1 it's exported to user in the new client API. Define aliases for
new names to keep existing code simple.
*/
typedef struct st_mysql_time TIME;
typedef enum enum_mysql_timestamp_type timestamp_type;
typedef struct {
......
......@@ -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
if string was truncated during conversion.
NOTE
See description of str_to_TIME() for more information.
See description of str_to_datetime() for more information.
*/
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;
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)
make_truncated_value_warning(current_thd, str, length, 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)
}
/*
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
if string was cut during conversion.
......@@ -944,7 +415,7 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time)
int was_cut;
bool ret_val= str_to_time(str, length, l_time, &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;
}
......@@ -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
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))) ||
(format_type == TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
(format_type == TIMESTAMP_TIME &&
(format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
(format_type == MYSQL_TIMESTAMP_TIME &&
!test_all_bits(part_map, 8 | 16 | 32)) ||
!allow_separator || // %option should be last
(need_p && dt_pos[6] +1 != dt_pos[7]) ||
......@@ -1256,10 +727,10 @@ bool parse_date_time_format(timestamp_type format_type,
format_str= 0;
switch (format_type) {
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
format_str= known_date_time_formats[INTERNAL_FORMAT].date_format;
/* fall through */
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
if (!format_str)
format_str=known_date_time_formats[INTERNAL_FORMAT].time_format;
......@@ -1274,7 +745,7 @@ bool parse_date_time_format(timestamp_type format_type,
return 0;
if (separator_map == (1 | 2))
{
if (format_type == TIMESTAMP_TIME)
if (format_type == MYSQL_TIMESTAMP_TIME)
{
if (*(format+2) != *(format+5))
break; // Error
......@@ -1284,7 +755,7 @@ bool parse_date_time_format(timestamp_type format_type,
return 0;
}
break;
case TIMESTAMP_DATETIME:
case MYSQL_TIMESTAMP_DATETIME:
/*
If there is no separators, allow the internal format as we can read
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,
timestamp_type type)
{
switch (type) {
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
return format->date_format;
case TIMESTAMP_DATETIME:
case MYSQL_TIMESTAMP_DATETIME:
return format->datetime_format;
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
return format->time_format;
default:
DBUG_ASSERT(0); // Impossible
......@@ -1489,13 +960,13 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
str.append('\0');
switch (time_type) {
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
type_str= "date";
break;
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
type_str= "time";
break;
case TIMESTAMP_DATETIME: // FALLTHROUGH
case MYSQL_TIMESTAMP_DATETIME: // FALLTHROUGH
default:
type_str= "datetime";
break;
......@@ -1565,14 +1036,14 @@ ulonglong TIME_to_ulonglong_time(const TIME *time)
ulonglong TIME_to_ulonglong(const TIME *time)
{
switch (time->time_type) {
case TIMESTAMP_DATETIME:
case MYSQL_TIMESTAMP_DATETIME:
return TIME_to_ulonglong_datetime(time);
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
return TIME_to_ulonglong_date(time);
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
return TIME_to_ulonglong_time(time);
case TIMESTAMP_NONE:
case TIMESTAMP_DATETIME_ERROR:
case MYSQL_TIMESTAMP_NONE:
case MYSQL_TIMESTAMP_ERROR:
return ULL(0);
default:
DBUG_ASSERT(0);
......@@ -1595,17 +1066,17 @@ ulonglong TIME_to_ulonglong(const TIME *time)
void TIME_to_string(const TIME *time, String *str)
{
switch (time->time_type) {
case TIMESTAMP_DATETIME:
case MYSQL_TIMESTAMP_DATETIME:
make_datetime((DATE_TIME_FORMAT*) 0, time, str);
break;
case TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATE:
make_date((DATE_TIME_FORMAT*) 0, time, str);
break;
case TIMESTAMP_TIME:
case MYSQL_TIMESTAMP_TIME:
make_time((DATE_TIME_FORMAT*) 0, time, str);
break;
case TIMESTAMP_NONE:
case TIMESTAMP_DATETIME_ERROR:
case MYSQL_TIMESTAMP_NONE:
case MYSQL_TIMESTAMP_ERROR:
str->length(0);
str->set_charset(&my_charset_bin);
break;
......
......@@ -582,7 +582,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset)
/* filling MySQL specific TIME members */
tmp->neg= 0; tmp->second_part= 0;
tmp->time_type= TIMESTAMP_DATETIME;
tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
}
......@@ -1009,7 +1009,7 @@ Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
localtime_r(&tmp_t, &tmp_tm);
localtime_to_TIME(tmp, &tmp_tm);
tmp->time_type= TIMESTAMP_DATETIME;
tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
}
......@@ -1092,7 +1092,7 @@ Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
time_t tmp_t= (time_t)t;
gmtime_r(&tmp_t, &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()
}
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
*/
......@@ -10259,6 +10333,8 @@ int main(int argc, char **argv)
test_bug4026(); /* test microseconds precision of time types */
test_bug4079(); /* erroneous subquery in prepared statement */
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
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