summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2004-06-24 19:08:36 +0400
committerunknown <konstantin@mysql.com>2004-06-24 19:08:36 +0400
commit9dde418895f2d236234b975c4ada88ad624e8ba4 (patch)
tree51efbaacdacd9dad5c2745e3ccb58a3614f4f608
parent85e9258b05b2490e35aa60adecf48a3f65245eb0 (diff)
downloadmariadb-git-9dde418895f2d236234b975c4ada88ad624e8ba4.tar.gz
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)"
-rw-r--r--VC++Files/libmysql/libmysql.dsp4
-rw-r--r--VC++Files/libmysqld/libmysqld.dsp4
-rw-r--r--VC++Files/sql/mysqld.dsp4
-rw-r--r--include/Makefile.am2
-rw-r--r--include/my_time.h46
-rw-r--r--include/mysql.h18
-rw-r--r--include/mysql_time.h37
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--libmysql/libmysql.c88
-rw-r--r--libmysqld/Makefile.am5
-rw-r--r--sql-common/Makefile.am2
-rw-r--r--sql/Makefile.am5
-rw-r--r--sql/field.cc85
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_timefunc.cc66
-rw-r--r--sql/mysql_priv.h8
-rw-r--r--sql/mysqld.cc27
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/set_var.h2
-rw-r--r--sql/sql_prepare.cc45
-rw-r--r--sql/sql_yacc.yy6
-rw-r--r--sql/structs.h25
-rw-r--r--sql/time.cc585
-rw-r--r--sql/tztime.cc6
-rw-r--r--tests/client_test.c76
25 files changed, 387 insertions, 771 deletions
diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp
index c315775443b..f382f36cb85 100644
--- a/VC++Files/libmysql/libmysql.dsp
+++ b/VC++Files/libmysql/libmysql.dsp
@@ -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
diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp
index 8d4dac20b6c..5a98b70c4c9 100644
--- a/VC++Files/libmysqld/libmysqld.dsp
+++ b/VC++Files/libmysqld/libmysqld.dsp
@@ -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
diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp
index 3f6b591cbdb..62f7c0597cb 100644
--- a/VC++Files/sql/mysqld.dsp
+++ b/VC++Files/sql/mysqld.dsp
@@ -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"
diff --git a/include/Makefile.am b/include/Makefile.am
index 10e1b12a770..bf5fd0aca0c 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -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\
diff --git a/include/my_time.h b/include/my_time.h
new file mode 100644
index 00000000000..e42f7e9e402
--- /dev/null
+++ b/include/my_time.h
@@ -0,0 +1,46 @@
+/* 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_ */
diff --git a/include/mysql.h b/include/mysql.h
index 931995fb1ac..12220c259b7 100644
--- a/include/mysql.h
+++ b/include/mysql.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
diff --git a/include/mysql_time.h b/include/mysql_time.h
new file mode 100644
index 00000000000..943d018fc14
--- /dev/null
+++ b/include/mysql_time.h
@@ -0,0 +1,37 @@
+/* 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_ */
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 883ea2b5932..b073155f02b 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -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
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index d29a7deb69e..c24b0de68aa 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -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;
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 58e11e4f297..226846c65d4 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -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=
diff --git a/sql-common/Makefile.am b/sql-common/Makefile.am
index 1f397c0ea87..6bd42d70e4f 100644
--- a/sql-common/Makefile.am
+++ b/sql-common/Makefile.am
@@ -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.%
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 9fecf6a0d8f..9777e1b8533 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -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) $<
diff --git a/sql/field.cc b/sql/field.cc
index f113b98cccd..8368b18e78a 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -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);
diff --git a/sql/item.cc b/sql/item.cc
index 35e1312b540..0e9a73aacb2 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -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;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a5ea72374c1..786bcf434ed 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -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;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index db8d534064d..b4431089fa1 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -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>
@@ -1001,12 +1002,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);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3c23ecd3c3d..71c6bac4500 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -309,15 +309,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];
@@ -4928,18 +4919,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}
};
@@ -6045,11 +6036,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);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index aa45afc3c30..840a7ae075a 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -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 */
diff --git a/sql/set_var.h b/sql/set_var.h
index c2b4ca34b2d..a51e44285d6 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -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,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 09b442f8dfc..3e88a2ecd4f 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -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*/
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 49ef2f29dfc..5fbb84d202e 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -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 */
diff --git a/sql/structs.h b/sql/structs.h
index ee231186e1a..c30d85f59cb 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -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 {
diff --git a/sql/time.cc b/sql/time.cc
index b5550b98e8c..132612e53c5 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -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;
@@ -748,190 +403,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;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 0b0ae2839df..a62720f2eeb 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -584,7 +584,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;
}
@@ -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_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
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;
}
diff --git a/tests/client_test.c b/tests/client_test.c
index c035691fe47..de9f9cfd577 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -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.