diff options
85 files changed, 2852 insertions, 1845 deletions
diff --git a/.bzrignore b/.bzrignore index 920522c7592..e9de6662cb2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -420,6 +420,7 @@ libmysqld/sql_unions.cc libmysqld/sql_update.cc libmysqld/sql_yacc.cc libmysqld/stacktrace.c +libmysqld/strfunc.cc libmysqld/table.cc libmysqld/thr_malloc.cc libmysqld/time.cc diff --git a/BUILD/compile-pentium-valgrind-max b/BUILD/compile-pentium-valgrind-max index f47061b95dd..d0e25fa2f40 100755 --- a/BUILD/compile-pentium-valgrind-max +++ b/BUILD/compile-pentium-valgrind-max @@ -14,6 +14,7 @@ extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam -- if test -z "$just_print" then + set +v echo "\ ****************************************************************************** Note that by default BUILD/compile-pentium-valgrind-max calls 'configure' with diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp index 593c53a57ba..953761be297 100644 --- a/VC++Files/libmysqld/libmysqld.dsp +++ b/VC++Files/libmysqld/libmysqld.dsp @@ -446,6 +446,10 @@ SOURCE=..\strings\strcont.c # End Source File # Begin Source File +SOURCE=..\sql\strfunc.cpp +# End Source File +# Begin Source File + SOURCE=..\strings\strinstr.c # End Source File # Begin Source File diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp index f8724fb0b06..b8413a9a7ae 100644 --- a/VC++Files/sql/mysqld.dsp +++ b/VC++Files/sql/mysqld.dsp @@ -1253,6 +1253,26 @@ SOURCE=.\sql_yacc.cpp # End Source File # Begin Source File +SOURCE=.\strfunc.cpp + +!IF "$(CFG)" == "mysqld - Win32 Release" + +!ELSEIF "$(CFG)" == "mysqld - Win32 Debug" + +# ADD CPP /G5 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "mysqld - Win32 nt" + +!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt" + +!ELSEIF "$(CFG)" == "mysqld - Win32 Max" + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=.\table.cpp # End Source File # Begin Source File diff --git a/VC++Files/sql/mysqldmax.dsp b/VC++Files/sql/mysqldmax.dsp index 24ea83159d9..a7ed1b918c7 100644 --- a/VC++Files/sql/mysqldmax.dsp +++ b/VC++Files/sql/mysqldmax.dsp @@ -945,6 +945,22 @@ SOURCE=.\sql_yacc.cpp # End Source File # Begin Source File +SOURCE=.\strfunc.cpp + +!IF "$(CFG)" == "mysqldmax - Win32 Release" + +!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug" + +# ADD CPP /G5 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt" + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=.\table.cpp # End Source File # Begin Source File diff --git a/VC++Files/strings/strings.dsp b/VC++Files/strings/strings.dsp index 038f460771d..4e43cc875c8 100644 --- a/VC++Files/strings/strings.dsp +++ b/VC++Files/strings/strings.dsp @@ -188,6 +188,10 @@ SOURCE=.\longlong2str.c # End Source File # Begin Source File +SOURCE=.\my_strtoll10.c +# End Source File +# Begin Source File + SOURCE=.\my_vsnprintf.c # End Source File # Begin Source File diff --git a/include/m_ctype.h b/include/m_ctype.h index a896afe750a..e2b2f7f1668 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -86,7 +86,7 @@ enum my_lex_states { MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT, MY_LEX_IDENT_SEP, MY_LEX_IDENT_START, - MY_LEX_FOUND_IDENT, MY_LEX_REAL, MY_LEX_HEX_NUMBER, + MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END, MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL, MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE, diff --git a/include/m_string.h b/include/m_string.h index 062d0b4cf65..d72342fb3c1 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -232,6 +232,7 @@ extern char *int2str(long val,char *dst,int radix); extern char *int10_to_str(long val,char *dst,int radix); extern char *str2int(const char *src,int radix,long lower,long upper, long *val); +longlong my_strtoll10(const char *nptr, char **endptr, int *error); #if SIZEOF_LONG == SIZEOF_LONG_LONG #define longlong2str(A,B,C) int2str((A),(B),(C)) #define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C)) diff --git a/include/my_pthread.h b/include/my_pthread.h index 424452a9298..82a2bb1accc 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -669,8 +669,6 @@ extern pthread_t shutdown_th, main_th, signal_th; #define thread_safe_increment(V,L) atomic_add(1,(atomic_t*) &V); #define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V); #define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V); -#define statistic_increment(V,L) thread_safe_increment((V),(L)) -#define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) #else #define thread_safe_increment(V,L) \ pthread_mutex_lock((L)); (V)++; pthread_mutex_unlock((L)); @@ -678,6 +676,7 @@ extern pthread_t shutdown_th, main_th, signal_th; pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L)); #define thread_safe_sub(V,C,L) \ pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L)); +#endif /* HAVE_ATOMIC_ADD */ #ifdef SAFE_STATISTICS #define statistic_increment(V,L) thread_safe_increment((V),(L)) #define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) @@ -685,7 +684,6 @@ extern pthread_t shutdown_th, main_th, signal_th; #define statistic_increment(V,L) (V)++ #define statistic_add(V,C,L) (V)+=(C) #endif /* SAFE_STATISTICS */ -#endif /* HAVE_ATOMIC_ADD */ #endif /* thread_safe_increment */ #ifdef __cplusplus diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 60204349de2..91b10ab578a 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -295,7 +295,12 @@ #define ER_BAD_SLAVE_UNTIL_COND 1276 #define ER_MISSING_SKIP_SLAVE 1277 #define ER_UNTIL_COND_IGNORED 1278 -#define ER_WRONG_INDEX_NAME 1279 -#define ER_WARN_QC_RESIZE 1280 -#define ER_BAD_FT_COLUMN 1281 -#define ER_ERROR_MESSAGES 282 +#define ER_WRONG_NAME 1279 +#define ER_TABLE 1280 +#define ER_DATABASE 1281 +#define ER_COLUMN 1282 +#define ER_INDEX 1283 +#define ER_CATALOG 1284 +#define ER_WARN_QC_RESIZE 1285 +#define ER_BAD_FT_COLUMN 1286 +#define ER_ERROR_MESSAGES 287 diff --git a/include/sql_state.h b/include/sql_state.h index 222636d3bec..d55fb137e27 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -159,4 +159,4 @@ ER_WARN_TOO_MANY_RECORDS, "01000", "", ER_WARN_NULL_TO_NOTNULL, "01000", "", ER_WARN_DATA_OUT_OF_RANGE, "01000", "", ER_WARN_DATA_TRUNCATED, "01000", "", -ER_WRONG_INDEX_NAME, "42000", "", +ER_WRONG_NAME, "42000", "", diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 09b03bce79a..7e04f53e9ff 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -38,7 +38,7 @@ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c noinst_HEADERS = embedded_priv.h -sqlsources = derror.cc field.cc field_conv.cc filesort.cc \ +sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \ hostname.cc init.cc password.c \ diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 94affe6b2f7..eda2f3b2a34 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -394,7 +394,7 @@ SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/slave.log" SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/slave.err" CURRENT_TEST="$MYSQL_TEST_DIR/var/log/current_test" -SMALL_SERVER="-O key_buffer_size=1M -O sort_buffer=256K -O max_heap_table_size=1M" +SMALL_SERVER="--key_buffer_size=1M --sort_buffer=256K --max_heap_table_size=1M" export MASTER_MYPORT export SLAVE_MYPORT @@ -795,13 +795,13 @@ manager_launch() ident=$1 shift if [ $USE_MANAGER = 0 ] ; then - $@ >> $CUR_MYERR 2>&1 & + $@ >> $CUR_MYERR 2>&1 & sleep 2 #hack return fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF -def_exec $ident $@ +def_exec $ident "$@" set_exec_stdout $ident $CUR_MYERR set_exec_stderr $ident $CUR_MYERR set_exec_con $ident root localhost $CUR_MYSOCK diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 3db2f3d5519..07ea97258d9 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -219,6 +219,13 @@ a test drop table t1; create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `word` varchar(255) collate latin1_german2_ci NOT NULL default '', + `word2` varchar(255) collate latin1_german2_ci NOT NULL default '', + KEY `word` (`word`) +) TYPE=MyISAM CHARSET=latin1 COLLATE=latin1_german2_ci insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); update t1 set word2=word; select word, word=binary 0xdf as t from t1 having t > 0; @@ -273,6 +280,11 @@ drop table t1; CREATE TABLE t1 ( s1 CHAR(5) CHARACTER SET latin1 COLLATE latin1_german2_ci ); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `s1` char(5) collate latin1_german2_ci default NULL +) TYPE=MyISAM CHARSET=latin1 COLLATE=latin1_german2_ci INSERT INTO t1 VALUES ('Ü'); INSERT INTO t1 VALUES ('ue'); SELECT DISTINCT s1 FROM t1; diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 5a53c1db2e1..1fe07692290 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -1,5 +1,5 @@ SET CHARACTER SET koi8r; -DROP TABLE IF EXISTS ÔÁÂÌÉÃÁ; +DROP TABLE IF EXISTS ÔÁÂÌÉÃÁ, t1; SET CHARACTER SET koi8r; CREATE TABLE t1 (a CHAR(10) CHARACTER SET cp1251) SELECT _koi8r'ÐÒÏÂÁ' AS a; SHOW CREATE TABLE t1; @@ -14,7 +14,7 @@ SELECT HEX(a) FROM t1; HEX(a) EFF0EEE1E0 DROP TABLE t1; -CREATE TABLE ÔÁÂÌÉÃÁ +CREATE TABLE `ÔÁÂÌÉÃÁ` ( ÐÏÌÅ CHAR(32) CHARACTER SET koi8r NOT NULL COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÐÏÌÑ" ) COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ"; diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index e21e05b4dfe..346d086f34c 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -1,151 +1,315 @@ +drop table if exists t1; +Warnings: +Note 1051 Unknown table 't1' SHOW GLOBAL VARIABLES LIKE "%_format%"; Variable_name Value date_format %d.%m.%Y -datetime_format %Y/%d/%m-%H:%i:%s +datetime_format %Y-%m-%d %H:%i:%s default_week_format 0 time_format %H.%i.%s SHOW SESSION VARIABLES LIKE "%_format%"; Variable_name Value date_format %d.%m.%Y -datetime_format %Y/%d/%m-%H:%i:%s +datetime_format %Y-%m-%d %H:%i:%s default_week_format 0 time_format %H.%i.%s -SET date_format="%d.%m.%Y"; -select CAST("01.01.2001" as DATE) as a; -a -01.01.2001 -SET datetime_format="%d.%m.%Y %H.%i.%s"; -select CAST("01.01.2001 05.12.06" as DATETIME) as a; -a -01.01.2001 05.12.06 -SET time_format="%H.%i.%s"; -select CAST("05.12.06" as TIME) as a; -a -05.12.06 -SET datetime_format="%d.%m.%Y %h:%i:%s %p"; -select CAST("01.01.2001 05:12:06AM" as DATETIME) as a; -a -01.01.2001 05:12:06 AM -select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a; -a -01.01.2001 05:12:06 PM -SET time_format="%h:%i:%s %p"; -select CAST("05:12:06 AM" as TIME) as a; -a -05:12:06 AM -select CAST("05:12:06.1234PM" as TIME) as a; -a -05:12:06.001234 PM -SET time_format="%h.%i.%s %p"; -SET date_format='%d.%m.%y'; -SET datetime_format="%d.%m.%y %h.%i.%s %p"; -select CAST("12-12-06" as DATE) as a; -a -12.12.06 -select adddate("01.01.97 11.59.59.000001 PM", 10); -adddate("01.01.97 11.59.59.000001 PM", 10) -11.01.97 11.59.59.000001 PM -select datediff("31.12.97 11.59:59.000001 PM","01.01.98"); -datediff("31.12.97 11.59:59.000001 PM","01.01.98") --1 -select weekofyear("31.11.97 11:59:59.000001 PM"); -weekofyear("31.11.97 11:59:59.000001 PM") -49 -select makedate(1997,1); -makedate(1997,1) -01.01.97 -select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"); -addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002") -02.01.98 01.01.01.000001 AM -select maketime(23,11,12); -maketime(23,11,12) -11.11.12 PM -select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"); -timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM") -8795.59.59.999999 PM -SET time_format="%H%i%s"; -SET time_format="%h%i%s"; -ERROR HY000: Unknown error +SET time_format='%H%i%s'; +SET time_format='%H:%i:%s.%f'; +SET time_format='%h-%i-%s.%f%p'; +SET time_format='%h:%i:%s.%f %p'; +SET time_format='%h:%i:%s%p'; +SET date_format='%Y%m%d'; +SET date_format='%Y.%m.%d'; +SET date_format='%d.%m.%Y'; +SET date_format='%m-%d-%Y'; +set datetime_format= '%Y%m%d%H%i%s'; +set datetime_format= '%Y-%m-%d %H:%i:%s'; +set datetime_format= '%m-%d-%y %H:%i:%s.%f'; +set datetime_format= '%d-%m-%Y %h:%i:%s%p'; +set datetime_format= '%H:%i:%s %Y-%m-%d'; +set datetime_format= '%H:%i:%s.%f %m-%d-%Y'; +set datetime_format= '%h:%i:%s %p %Y-%m-%d'; +set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d'; +SHOW SESSION VARIABLES LIKE "%format"; +Variable_name Value +date_format %m-%d-%Y +datetime_format %h:%i:%s.%f %p %Y-%m-%d +default_week_format 0 +time_format %h:%i:%s%p +SET time_format='%h:%i:%s'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%h:%i:%s' +SET time_format='%H %i:%s'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H %i:%s' +SET time_format='%H::%i:%s'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H::%i:%s' +SET time_format='%H:%i:%s%f'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H:%i:%s%f' +SET time_format='%H:%i.%f:%s'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H:%i.%f:%s' +SET time_format='%H:%i:%s%p'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H:%i:%s%p' +SET time_format='%h:%i:%s.%f %p %Y-%m-%d'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%h:%i:%s.%f %p %Y-%m-%d' +SET time_format='%H%i%s.%f'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H%i%s.%f' +SET time_format='%H:%i-%s.%f'; +ERROR 42000: Variable 'time_format' can't be set to the value of '%H:%i-%s.%f' SET date_format='%d.%m.%d'; -ERROR HY000: Unknown error -SET datetime_format="%d.%m.%y %h.%i.%s"; -ERROR HY000: Unknown error +ERROR 42000: Variable 'date_format' can't be set to the value of '%d.%m.%d' +SET datetime_format='%h.%m.%y %d.%i.%s'; +ERROR 42000: Variable 'datetime_format' can't be set to the value of '%h.%m.%y %d.%i.%s' +set datetime_format= '%H:%i:%s.%f %p %Y-%m-%d'; +ERROR 42000: Variable 'datetime_format' can't be set to the value of '%H:%i:%s.%f %p %Y-%m-%d' +set GLOBAL datetime_format= '%H:%i:%s %Y-%m-%d'; +SET SESSION datetime_format=default; +select @@global.datetime_format, @@session.datetime_format; +@@global.datetime_format @@session.datetime_format +%H:%i:%s %Y-%m-%d %H:%i:%s %Y-%m-%d +SET GLOBAL datetime_format=default; +SET SESSION datetime_format=default; +select @@global.datetime_format, @@session.datetime_format; +@@global.datetime_format @@session.datetime_format +%Y-%m-%d %H:%i:%s %Y-%m-%d %H:%i:%s SET GLOBAL date_format=default; -SHOW GLOBAL VARIABLES LIKE "date_format%"; -Variable_name Value -date_format %d.%m.%Y SET GLOBAL time_format=default; -SHOW GLOBAL VARIABLES LIKE "time_format%"; -Variable_name Value -time_format %H.%i.%s SET GLOBAL datetime_format=default; -SHOW GLOBAL VARIABLES LIKE "datetime_format%"; -Variable_name Value -datetime_format %Y/%d/%m-%H:%i:%s -SET date_format=default; -SHOW SESSION VARIABLES LIKE "date_format%"; -Variable_name Value -date_format %d.%m.%Y SET time_format=default; -SHOW SESSION VARIABLES LIKE "time_format%"; -Variable_name Value -time_format %H.%i.%s +SET date_format=default; SET datetime_format=default; -SHOW SESSION VARIABLES LIKE "datetime_format%"; -Variable_name Value -datetime_format %Y/%d/%m-%H:%i:%s -SET time_format='%i:%s:%H'; -select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME); -cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME) -59:59:12 -SET GLOBAL date_format='%Y-%m-%d'; -SET GLOBAL time_format='%H:%i:%s'; -SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s'; -SET date_format='%Y-%m-%d'; -SET time_format='%H:%i:%s'; -SET datetime_format='%Y-%m-%d %H:%i:%s'; -select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S"); -str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") -2001-01-15 12:59:59 -select str_to_date("15 September 2001", "%d %M %Y"); -str_to_date("15 September 2001", "%d %M %Y") -2001-09-15 00:00:00 -select str_to_date("15 Septembeb 2001", "%d %M %Y"); -str_to_date("15 Septembeb 2001", "%d %M %Y") -NULL -select str_to_date("15 MAY 2001", "%d %b %Y"); -str_to_date("15 MAY 2001", "%d %b %Y") -2001-05-15 00:00:00 -select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y"); -str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y") -2001-05-15 00:00:00 -select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y"); -str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y") -NULL -select str_to_date("Sundai 15 MA", "%W %d %b %Y"); -str_to_date("Sundai 15 MA", "%W %d %b %Y") -NULL -select str_to_date("Tuesday 52 2001", "%W %V %X"); -str_to_date("Tuesday 52 2001", "%W %V %X") -NULL -select str_to_date("Sunday 01 2001", "%W %V %X"); -str_to_date("Sunday 01 2001", "%W %V %X") -NULL -select str_to_date("Tuesday 00 2002", "%W %U %Y"); -str_to_date("Tuesday 00 2002", "%W %U %Y") -2002-01-01 00:00:00 -select str_to_date("Thursday 53 1998", "%W %u %Y"); -str_to_date("Thursday 53 1998", "%W %u %Y") -1998-12-31 00:00:00 -select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S"); -str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S") -2001-01-15 00:00:00 -select str_to_date("15-01-20", "%d-%m-%Y"); -str_to_date("15-01-20", "%d-%m-%Y") -NULL -select str_to_date("15-2001-1", "%d-%Y-%c"); -str_to_date("15-2001-1", "%d-%Y-%c") -2001-01-15 00:00:00 +select str_to_date(concat('15-01-2001',' 2:59:58.999'), +concat('%d-%m-%Y',' ','%H:%i:%s.%f')); +str_to_date(concat('15-01-2001',' 2:59:58.999'), +concat('%d-%m-%Y',' ','%H:%i:%s.%f')) +2001-01-15 02:59:58.000999 +create table t1 (date char(30), format char(30) not null); +insert into t1 values +('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'), +('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'), +('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'), +('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'), +('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'), +('2003-01-02 12:11:12.12345 am', '%Y-%m-%d %h:%i:%S.%f%p'), +('2003-01-02 11:11:12Pm', '%Y-%m-%d %h:%i:%S%p'), +('10:20:10', '%H:%i:%s'), +('10:20:10', '%h:%i:%s.%f'), +('10:20:10AM', '%h:%i:%s%p'), +('10:20:10.44AM', '%h:%i:%s.%f%p'), +('15-01-2001 12:59:58', '%d-%m-%Y %H:%i:%S'), +('15 September 2001', '%d %M %Y'), +('15 SEPTEMB 2001', '%d %M %Y'), +('15 MAY 2001', '%d %b %Y'), +('Sunday 15 MAY 2001', '%W %d %b %Y'), +('Sund 15 MAY 2001', '%W %d %b %Y'), +('Tuesday 00 2002', '%W %U %Y'), +('Thursday 53 1998', '%W %u %Y'), +('15-01-2001', '%d-%m-%Y %H:%i:%S'), +('15-01-20', '%d-%m-%y'), +('15-2001-1', '%d-%Y-%c'); +select date,format,str_to_date(date, format) as str_to_date from t1; +date format str_to_date +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 +10:20:10 %H:%i:%s 0000-00-00 10:20:10 +10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 +15 September 2001 %d %M %Y 2001-09-15 00:00:00 +15 SEPTEMB 2001 %d %M %Y 2001-01-15 00:00:00 +15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 +Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 +15-01-20 %d-%m-%y 2020-01-15 00:00:00 +15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 +select date,format,concat('',str_to_date(date, format)) as con from t1; +date format con +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 +10:20:10 %H:%i:%s 0000-00-00 10:20:10 +10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 +15 September 2001 %d %M %Y 2001-09-15 00:00:00 +15 SEPTEMB 2001 %d %M %Y 2001-01-15 00:00:00 +15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 +Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 +15-01-20 %d-%m-%y 2020-01-15 00:00:00 +15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 +select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1; +date format datetime +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 +10:20:10 %H:%i:%s 0000-00-00 10:20:10 +10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 +15 September 2001 %d %M %Y 2001-09-15 00:00:00 +15 SEPTEMB 2001 %d %M %Y 2001-01-15 00:00:00 +15 MAY 2001 %d %b %Y 2001-05-15 00:00:00 +Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 00:00:00 +Tuesday 00 2002 %W %U %Y 2002-01-01 00:00:00 +Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00 +15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 +15-01-20 %d-%m-%y 2020-01-15 00:00:00 +15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 +select date,format,DATE(str_to_date(date, format)) as date2 from t1; +date format date2 +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 +10:20:10 %H:%i:%s 0000-00-00 +10:20:10 %h:%i:%s.%f 0000-00-00 +10:20:10AM %h:%i:%s%p 0000-00-00 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 +15 September 2001 %d %M %Y 2001-09-15 +15 SEPTEMB 2001 %d %M %Y 2001-01-15 +15 MAY 2001 %d %b %Y 2001-05-15 +Sunday 15 MAY 2001 %W %d %b %Y 2001-05-15 +Sund 15 MAY 2001 %W %d %b %Y 2001-05-15 +Tuesday 00 2002 %W %U %Y 2002-01-01 +Thursday 53 1998 %W %u %Y 1998-12-31 +15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 +15-01-20 %d-%m-%y 2020-01-15 +15-2001-1 %d-%Y-%c 2001-01-15 +select date,format,TIME(str_to_date(date, format)) as time from t1; +date format time +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 +10:20:10 %H:%i:%s 10:20:10 +10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 +15 September 2001 %d %M %Y 00:00:00 +15 SEPTEMB 2001 %d %M %Y 00:00:00 +15 MAY 2001 %d %b %Y 00:00:00 +Sunday 15 MAY 2001 %W %d %b %Y 00:00:00 +Sund 15 MAY 2001 %W %d %b %Y 00:00:00 +Tuesday 00 2002 %W %U %Y 00:00:00 +Thursday 53 1998 %W %u %Y 00:00:00 +15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 +15-01-20 %d-%m-%y 00:00:00 +15-2001-1 %d-%Y-%c 00:00:00 +select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; +date format time2 +2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12 +03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02 +2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12 +2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345 +2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345 +2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345 +2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 +10:20:10 %H:%i:%s 10:20:10 +10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044 +15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 +15 September 2001 %d %M %Y 00:00:00 +15 SEPTEMB 2001 %d %M %Y 00:00:00 +15 MAY 2001 %d %b %Y 00:00:00 +Sunday 15 MAY 2001 %W %d %b %Y 00:00:00 +Sund 15 MAY 2001 %W %d %b %Y 00:00:00 +Tuesday 00 2002 %W %U %Y 00:00:00 +Thursday 53 1998 %W %u %Y 00:00:00 +15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 +15-01-20 %d-%m-%y 00:00:00 +15-2001-1 %d-%Y-%c 00:00:00 +truncate table t1; +insert into t1 values +('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'), +('2003-01-02 10:11:12.123456', '%Y-%m-%d %h:%i:%S %p'), +('2003-01-02 10:11:12AM', '%Y-%m-%d %h:%i:%S.%f %p'), +('2003-01-02 10:11:12AN', '%Y-%m-%d %h:%i:%S%p'), +('2003-01-02 10:11:12 PM', '%y-%m-%d %H:%i:%S %p'), +('10:20:10AM', '%H:%i:%s%p'), +('15 Septembei 2001', '%d %M %Y'), +('15 Ju 2001', '%d %M %Y'), +('Sund 15 MA', '%W %d %b %Y'), +('Sunday 01 2001', '%W %V %X'), +('Thursdai 12 1998', '%W %u %Y'), +(NULL, get_format(DATE,'USA')), +('Tuesday 52 2001', '%W %V %X'); +select date,format,str_to_date(date, format) as str_to_date from t1; +date format str_to_date +2003-01-02 10:11:12 PM %Y-%m-%d %H:%i:%S %p NULL +2003-01-02 10:11:12.123456 %Y-%m-%d %h:%i:%S %p NULL +2003-01-02 10:11:12AM %Y-%m-%d %h:%i:%S.%f %p NULL +2003-01-02 10:11:12AN %Y-%m-%d %h:%i:%S%p NULL +2003-01-02 10:11:12 PM %y-%m-%d %H:%i:%S %p NULL +10:20:10AM %H:%i:%s%p NULL +15 Septembei 2001 %d %M %Y NULL +15 Ju 2001 %d %M %Y NULL +Sund 15 MA %W %d %b %Y NULL +Sunday 01 2001 %W %V %X NULL +Thursdai 12 1998 %W %u %Y NULL +NULL %m.%d.%Y NULL +Tuesday 52 2001 %W %V %X NULL +select date,format,concat(str_to_date(date, format),'') as con from t1; +date format con +2003-01-02 10:11:12 PM %Y-%m-%d %H:%i:%S %p NULL +2003-01-02 10:11:12.123456 %Y-%m-%d %h:%i:%S %p NULL +2003-01-02 10:11:12AM %Y-%m-%d %h:%i:%S.%f %p NULL +2003-01-02 10:11:12AN %Y-%m-%d %h:%i:%S%p NULL +2003-01-02 10:11:12 PM %y-%m-%d %H:%i:%S %p NULL +10:20:10AM %H:%i:%s%p NULL +15 Septembei 2001 %d %M %Y NULL +15 Ju 2001 %d %M %Y NULL +Sund 15 MA %W %d %b %Y NULL +Sunday 01 2001 %W %V %X NULL +Thursdai 12 1998 %W %u %Y NULL +NULL %m.%d.%Y NULL +Tuesday 52 2001 %W %V %X NULL +truncate table t1; +insert into t1 values +('10:20:10AM', '%h:%i:%s'), +('2003-01-02 10:11:12', '%Y-%m-%d %h:%i:%S'), +('03-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'); +select date,format,str_to_date(date, format) as str_to_date from t1; +date format str_to_date +10:20:10AM %h:%i:%s 0000-00-00 10:20:10 +2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12 +03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12 +select date,format,concat(str_to_date(date, format),'') as con from t1; +date format con +10:20:10AM %h:%i:%s 0000-00-00 10:20:10 +2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12 +03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12 +drop table t1; select get_format(DATE, 'USA') as a; a %m.%d.%Y @@ -154,7 +318,13 @@ a %H%i%s select get_format(DATETIME, 'eur') as a; a -%Y-%m-%d-%H.%i.%s +%Y-%m-%d %H.%i.%s +select get_format(DATE, 'TEST') as a; +a +NULL +select str_to_date('15-01-2001 12:59:59', GET_FORMAT(DATE,'USA')); +str_to_date('15-01-2001 12:59:59', GET_FORMAT(DATE,'USA')) +NULL explain extended select makedate(1997,1), addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"),cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME), maketime(23,11,12),microsecond("1997-12-31 23:59:59.000001"); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 0e46f7dd16d..461fc1018c1 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -65,6 +65,6 @@ NULL 50000 NULL Warnings: -Error 1258 Z_DATA_ERROR: Input data was corrupted for zlib +Error 1258 ZLIB: Input data was corrupted for zlib Error 1255 Too big size of uncompressed data. The maximum size is 1048576. (probably, length of uncompressed data was corrupted) drop table t1; diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index cf2b8814047..e7b64066c37 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -74,3 +74,4 @@ f 5 7 drop table t1,t2; +create temporary table t3 (f int); diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 059808161a3..cec7dd17e6d 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -40,9 +40,9 @@ create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null -- error 1044,1 create table not_existing_database.test (a int); ---error 1103 +--error 1279 create table `a/a` (a int); ---error 1103 +--error 1279 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int); --error 1059 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int); @@ -66,11 +66,11 @@ create table test_$1.test2$ (a int); drop table test_$1.test2$; drop database test_$1; ---error 1103 +--error 1279 create table `` (a int); ---error 1103 +--error 1279 drop table if exists ``; ---error 1166 +--error 1279 create table t1 (`` int); --error 1279 create table t1 (i int, index `` (i)); @@ -254,12 +254,16 @@ create table t2 like t3; show create table t2; select * from t2; create table t3 like t1; -!$1050 create table t3 like test_$1.t3; +--error 1050 +create table t3 like test_$1.t3; --error 1044,1 create table non_existing_database.t1 like t1; -!$1051 create table t3 like non_existing_table; -!$1050 create temporary table t3 like t1; -!$1103 create table t3 like `a/a`; +--error 1051 +create table t3 like non_existing_table; +--error 1050 +create temporary table t3 like t1; +--error 1279 +create table t3 like `a/a`; drop table t1, t2, t3; drop table t3; drop database test_$1; diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 52ee227b011..a5d0c29baf6 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -64,6 +64,7 @@ drop table t1; # The below checks both binary and character comparisons. # create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +show create table t1; insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); update t1 set word2=word; select word, word=binary 0xdf as t from t1 having t > 0; @@ -85,6 +86,7 @@ drop table t1; CREATE TABLE t1 ( s1 CHAR(5) CHARACTER SET latin1 COLLATE latin1_german2_ci ); +show create table t1; INSERT INTO t1 VALUES ('Ü'); INSERT INTO t1 VALUES ('ue'); SELECT DISTINCT s1 FROM t1; diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 325a8f075ed..2f08e021df2 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -1,7 +1,7 @@ SET CHARACTER SET koi8r; --disable_warnings -DROP TABLE IF EXISTS ÔÁÂÌÉÃÁ; +DROP TABLE IF EXISTS ÔÁÂÌÉÃÁ, t1; --enable_warnings SET CHARACTER SET koi8r; @@ -11,7 +11,7 @@ SELECT a FROM t1; SELECT HEX(a) FROM t1; DROP TABLE t1; -CREATE TABLE ÔÁÂÌÉÃÁ +CREATE TABLE `ÔÁÂÌÉÃÁ` ( ÐÏÌÅ CHAR(32) CHARACTER SET koi8r NOT NULL COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÐÏÌÑ" ) COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ"; diff --git a/mysql-test/t/date_formats-master.opt b/mysql-test/t/date_formats-master.opt index 7977a601dd7..ab243fe729c 100644 --- a/mysql-test/t/date_formats-master.opt +++ b/mysql-test/t/date_formats-master.opt @@ -1 +1 @@ ---date_format=%d.%m.%Y --time_format=%H.%i.%s --datetime_format=%Y/%d/%m-%H:%i:%s +--date-format=%d.%m.%Y --time-format=%H.%i.%s diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index e2d0e5d2c6d..d9219d3ac2e 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -1,83 +1,202 @@ +# +# Test of date format functions +# + +--disable-warnings +drop table if exists t1; +--enable-warnings + SHOW GLOBAL VARIABLES LIKE "%_format%"; SHOW SESSION VARIABLES LIKE "%_format%"; -SET date_format="%d.%m.%Y"; -select CAST("01.01.2001" as DATE) as a; -SET datetime_format="%d.%m.%Y %H.%i.%s"; -select CAST("01.01.2001 05.12.06" as DATETIME) as a; -SET time_format="%H.%i.%s"; -select CAST("05.12.06" as TIME) as a; - -SET datetime_format="%d.%m.%Y %h:%i:%s %p"; -select CAST("01.01.2001 05:12:06AM" as DATETIME) as a; -select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a; - -SET time_format="%h:%i:%s %p"; -select CAST("05:12:06 AM" as TIME) as a; -select CAST("05:12:06.1234PM" as TIME) as a; - -SET time_format="%h.%i.%s %p"; -SET date_format='%d.%m.%y'; -SET datetime_format="%d.%m.%y %h.%i.%s %p"; -select CAST("12-12-06" as DATE) as a; - -select adddate("01.01.97 11.59.59.000001 PM", 10); -select datediff("31.12.97 11.59:59.000001 PM","01.01.98"); -select weekofyear("31.11.97 11:59:59.000001 PM"); -select makedate(1997,1); -select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"); -select maketime(23,11,12); -select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"); - -SET time_format="%H%i%s"; ---error 1105 -SET time_format="%h%i%s"; ---error 1105 +# +# Test setting a lot of different formats to see which formats are accepted and +# which aren't +# + +SET time_format='%H%i%s'; +SET time_format='%H:%i:%s.%f'; +SET time_format='%h-%i-%s.%f%p'; +SET time_format='%h:%i:%s.%f %p'; +SET time_format='%h:%i:%s%p'; + +SET date_format='%Y%m%d'; +SET date_format='%Y.%m.%d'; +SET date_format='%d.%m.%Y'; +SET date_format='%m-%d-%Y'; + +set datetime_format= '%Y%m%d%H%i%s'; +set datetime_format= '%Y-%m-%d %H:%i:%s'; +set datetime_format= '%m-%d-%y %H:%i:%s.%f'; +set datetime_format= '%d-%m-%Y %h:%i:%s%p'; +set datetime_format= '%H:%i:%s %Y-%m-%d'; +set datetime_format= '%H:%i:%s.%f %m-%d-%Y'; +set datetime_format= '%h:%i:%s %p %Y-%m-%d'; +set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d'; + +SHOW SESSION VARIABLES LIKE "%format"; + +--error 1231 +SET time_format='%h:%i:%s'; +--error 1231 +SET time_format='%H %i:%s'; +--error 1231 +SET time_format='%H::%i:%s'; +--error 1231 +SET time_format='%H:%i:%s%f'; +--error 1231 +SET time_format='%H:%i.%f:%s'; +--error 1231 +SET time_format='%H:%i:%s%p'; +--error 1231 +SET time_format='%h:%i:%s.%f %p %Y-%m-%d'; +--error 1231 +SET time_format='%H%i%s.%f'; +--error 1231 +SET time_format='%H:%i-%s.%f'; +--error 1231 SET date_format='%d.%m.%d'; ---error 1105 -SET datetime_format="%d.%m.%y %h.%i.%s"; +--error 1231 +SET datetime_format='%h.%m.%y %d.%i.%s'; +--error 1231 +set datetime_format= '%H:%i:%s.%f %p %Y-%m-%d'; + +# +# Test GLOBAL values + +set GLOBAL datetime_format= '%H:%i:%s %Y-%m-%d'; +SET SESSION datetime_format=default; +select @@global.datetime_format, @@session.datetime_format; +SET GLOBAL datetime_format=default; +SET SESSION datetime_format=default; +select @@global.datetime_format, @@session.datetime_format; SET GLOBAL date_format=default; -SHOW GLOBAL VARIABLES LIKE "date_format%"; SET GLOBAL time_format=default; -SHOW GLOBAL VARIABLES LIKE "time_format%"; SET GLOBAL datetime_format=default; -SHOW GLOBAL VARIABLES LIKE "datetime_format%"; - -SET date_format=default; -SHOW SESSION VARIABLES LIKE "date_format%"; SET time_format=default; -SHOW SESSION VARIABLES LIKE "time_format%"; +SET date_format=default; SET datetime_format=default; -SHOW SESSION VARIABLES LIKE "datetime_format%"; - -SET time_format='%i:%s:%H'; -select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME); - -SET GLOBAL date_format='%Y-%m-%d'; -SET GLOBAL time_format='%H:%i:%s'; -SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s'; -SET date_format='%Y-%m-%d'; -SET time_format='%H:%i:%s'; -SET datetime_format='%Y-%m-%d %H:%i:%s'; - -select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S"); -select str_to_date("15 September 2001", "%d %M %Y"); -select str_to_date("15 Septembeb 2001", "%d %M %Y"); -select str_to_date("15 MAY 2001", "%d %b %Y"); -select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y"); -select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y"); -select str_to_date("Sundai 15 MA", "%W %d %b %Y"); -select str_to_date("Tuesday 52 2001", "%W %V %X"); -select str_to_date("Sunday 01 2001", "%W %V %X"); -select str_to_date("Tuesday 00 2002", "%W %U %Y"); -select str_to_date("Thursday 53 1998", "%W %u %Y"); -select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S"); -select str_to_date("15-01-20", "%d-%m-%Y"); -select str_to_date("15-2001-1", "%d-%Y-%c"); + +# +# The following tests will work only when we at some point will enable +# dynamic changing of formats +# + +# SET date_format='%d.%m.%Y'; +# select CAST('01.01.2001' as DATE) as a; +# SET datetime_format='%d.%m.%Y %H.%i.%s'; +# select CAST('01.01.2001 05.12.06' as DATETIME) as a; +# SET time_format='%H.%i.%s'; +# select CAST('05.12.06' as TIME) as a; +# +# SET datetime_format='%d.%m.%Y %h:%i:%s %p'; +# select CAST('01.01.2001 05:12:06AM' as DATETIME) as a; +# select CAST('01.01.2001 05:12:06 PM' as DATETIME) as a; +# +# SET time_format='%h:%i:%s %p'; +# select CAST('05:12:06 AM' as TIME) as a; +# select CAST('05:12:06.1234PM' as TIME) as a; +# +# SET time_format='%h.%i.%s %p'; +# SET date_format='%d.%m.%y'; +# SET datetime_format='%d.%m.%y %h.%i.%s %p'; +# select CAST('12-12-06' as DATE) as a; +# +# select adddate('01.01.97 11.59.59.000001 PM', 10); +# select datediff('31.12.97 11.59:59.000001 PM','01.01.98'); +# select weekofyear('31.11.97 11:59:59.000001 PM'); +# select makedate(1997,1); +# select addtime('31.12.97 11.59.59.999999 PM', '1 1.1.1.000002'); +# select maketime(23,11,12); +# select timediff('01.01.97 11:59:59.000001 PM','31.12.95 11:59:59.000002 PM'); +# +# SET time_format='%i:%s:%H'; +# select cast(str_to_date('15-01-2001 12:59:59', '%d-%m-%Y %H:%i:%S') as TIME); + +# +# Test of str_to_date +# + +select str_to_date(concat('15-01-2001',' 2:59:58.999'), + concat('%d-%m-%Y',' ','%H:%i:%s.%f')); + +create table t1 (date char(30), format char(30) not null); +insert into t1 values +('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'), +('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'), +('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'), +('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'), +('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'), +('2003-01-02 12:11:12.12345 am', '%Y-%m-%d %h:%i:%S.%f%p'), +('2003-01-02 11:11:12Pm', '%Y-%m-%d %h:%i:%S%p'), +('10:20:10', '%H:%i:%s'), +('10:20:10', '%h:%i:%s.%f'), +('10:20:10AM', '%h:%i:%s%p'), +('10:20:10.44AM', '%h:%i:%s.%f%p'), +('15-01-2001 12:59:58', '%d-%m-%Y %H:%i:%S'), +('15 September 2001', '%d %M %Y'), +('15 SEPTEMB 2001', '%d %M %Y'), +('15 MAY 2001', '%d %b %Y'), +('Sunday 15 MAY 2001', '%W %d %b %Y'), +('Sund 15 MAY 2001', '%W %d %b %Y'), +('Tuesday 00 2002', '%W %U %Y'), +('Thursday 53 1998', '%W %u %Y'), +('15-01-2001', '%d-%m-%Y %H:%i:%S'), +('15-01-20', '%d-%m-%y'), +('15-2001-1', '%d-%Y-%c'); + +# Use through protocol functions +select date,format,str_to_date(date, format) as str_to_date from t1; +# Use as a string +select date,format,concat('',str_to_date(date, format)) as con from t1; +# Use as datetime +select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1; +select date,format,DATE(str_to_date(date, format)) as date2 from t1; +select date,format,TIME(str_to_date(date, format)) as time from t1; +select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; + +# Test wrong dates + +truncate table t1; +insert into t1 values +('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'), +('2003-01-02 10:11:12.123456', '%Y-%m-%d %h:%i:%S %p'), +('2003-01-02 10:11:12AM', '%Y-%m-%d %h:%i:%S.%f %p'), +('2003-01-02 10:11:12AN', '%Y-%m-%d %h:%i:%S%p'), +('2003-01-02 10:11:12 PM', '%y-%m-%d %H:%i:%S %p'), +('10:20:10AM', '%H:%i:%s%p'), +('15 Septembei 2001', '%d %M %Y'), +('15 Ju 2001', '%d %M %Y'), +('Sund 15 MA', '%W %d %b %Y'), +('Sunday 01 2001', '%W %V %X'), +('Thursdai 12 1998', '%W %u %Y'), +(NULL, get_format(DATE,'USA')), +('Tuesday 52 2001', '%W %V %X'); +select date,format,str_to_date(date, format) as str_to_date from t1; +select date,format,concat(str_to_date(date, format),'') as con from t1; + +# Test 'maybe' date formats and 'strange but correct' results + +truncate table t1; +insert into t1 values +('10:20:10AM', '%h:%i:%s'), +('2003-01-02 10:11:12', '%Y-%m-%d %h:%i:%S'), +('03-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'); + +select date,format,str_to_date(date, format) as str_to_date from t1; +select date,format,concat(str_to_date(date, format),'') as con from t1; + +drop table t1; + +# +# Test of get_format +# select get_format(DATE, 'USA') as a; select get_format(TIME, 'internal') as a; select get_format(DATETIME, 'eur') as a; +select get_format(DATE, 'TEST') as a; +select str_to_date('15-01-2001 12:59:59', GET_FORMAT(DATE,'USA')); explain extended select makedate(1997,1), addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"),cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME), maketime(23,11,12),microsecond("1997-12-31 23:59:59.000001"); diff --git a/mysql-test/t/overflow.test b/mysql-test/t/overflow.test index 6619a87cabb..7a9616fd24e 100644 --- a/mysql-test/t/overflow.test +++ b/mysql-test/t/overflow.test @@ -1,4 +1,4 @@ connect (con1,localhost,boo,,); connection con1; --- error 1064,1102 +-- error 1064,1102,1279 drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; diff --git a/mysql-test/t/rpl_temporary-master.opt b/mysql-test/t/rpl_temporary-master.opt new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/mysql-test/t/rpl_temporary-master.opt diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index f1373d7ef23..0df8ceb6377 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -108,3 +108,11 @@ drop temporary table t3; select * from t2; drop table t1,t2; + +# Create last a temporary table that is not dropped at end to ensure that we +# don't get any memory leaks for this + +create temporary table t3 (f int); +sync_with_master; + +# The server will now close done diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index f618c342936..4be0cd0c6a2 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -65,7 +65,7 @@ drop table t1; # disable_query_log; ---error 1103,1103 +--error 1279,1279 create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="tmp"; # Check that we cannot link over a table from another database. @@ -75,7 +75,7 @@ create database mysqltest; --error 1,1 create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="/this-dir-does-not-exist"; ---error 1103,1103 +--error 1279,1279 create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="not-hard-path"; --error 1,1 diff --git a/mysys/default.c b/mysys/default.c index 15eb358df22..b1d9e40a1c2 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000-2003 MySQL 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 @@ -214,6 +214,7 @@ int load_defaults(const char *conf_file, const char **groups, res= (char**) (ptr+sizeof(alloc)); /* copy name + found arguments + command line arguments to new array */ + res[0]= argv[0][0]; /* Name MUST be set, even by embedded library */ memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*)); /* Skipp --defaults-file and --defaults-extra-file */ (*argc)-= args_used; diff --git a/sql/Makefile.am b/sql/Makefile.am index 69b9c58dd6d..0167124a892 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -63,7 +63,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ thr_malloc.cc item_create.cc item_subselect.cc \ item_row.cc item_geofunc.cc \ - field.cc key.cc sql_class.cc sql_list.cc \ + field.cc strfunc.cc key.cc sql_class.cc sql_list.cc \ net_serv.cc protocol.cc sql_state.c \ lock.cc my_lock.c \ sql_string.cc sql_manager.cc sql_map.cc \ diff --git a/sql/derror.cc b/sql/derror.cc index f5fe92da238..8d4f8e664e2 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -117,7 +117,7 @@ Check that the above file is the right version for this program!", point[i]= *point +uint2korr(head+10+i+i); } VOID(my_close(file,MYF(0))); - DBUG_RETURN(FALSE); + DBUG_RETURN(0); err: switch (funktpos) { @@ -136,7 +136,7 @@ err1: if (file != FERR) VOID(my_close(file,MYF(MY_WME))); unireg_abort(1); - return 1; + DEBUG_RETURN(1); // Impossible } /* read_texts */ diff --git a/sql/field.cc b/sql/field.cc index c30c06c6395..04e9c45327b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -274,13 +274,14 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) return copy->length+(int) copy->strip; } -bool Field::get_date(TIME *ltime,bool fuzzydate) + +bool Field::get_date(TIME *ltime,uint fuzzydate) { char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || - str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate,current_thd)<= - WRONG_TIMESTAMP_FULL) + str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) <= + TIMESTAMP_DATETIME_ERROR) return 1; return 0; } @@ -290,39 +291,44 @@ bool Field::get_time(TIME *ltime) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || - str_to_time(res->ptr(),res->length(),ltime,current_thd)) + str_to_time(res->ptr(),res->length(),ltime)) return 1; return 0; } +/* + This is called when storing a date in a string + + NOTES + Needs to be changed if/when we want to support different time formats +*/ -/* This is called when storing a date in a string */ void Field::store_time(TIME *ltime,timestamp_type type) { char buff[25]; - String tmp((char*) buff,sizeof(buff),&my_charset_bin); - DATETIME_FORMAT *tmp_format= 0; - bool is_time_only= 0; - switch (type) { case TIMESTAMP_NONE: - case WRONG_TIMESTAMP_FULL: + case TIMESTAMP_DATETIME_ERROR: store("",0,&my_charset_bin); // Probably an error - return; + break; case TIMESTAMP_DATE: - tmp_format= &t_datetime_frm(current_thd, DATE_FORMAT_TYPE).datetime_format; + sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); + store(buff,10,&my_charset_bin); break; - case TIMESTAMP_FULL: - tmp_format=&t_datetime_frm(current_thd,DATETIME_FORMAT_TYPE).datetime_format; + case TIMESTAMP_DATETIME: + sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", + ltime->year,ltime->month,ltime->day, + ltime->hour,ltime->minute,ltime->second); + store(buff,19,&my_charset_bin); break; case TIMESTAMP_TIME: - tmp_format= &t_datetime_frm(current_thd, TIME_FORMAT_TYPE).datetime_format; - is_time_only= 1; + { + ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d", + ltime->hour,ltime->minute,ltime->second)); + store(buff,(uint) length, &my_charset_bin); break; } - make_datetime(&tmp, ltime, is_time_only, 0, - tmp_format->format, tmp_format->format_length, 1); - store(tmp.ptr(),tmp.length(),&my_charset_bin); + } } @@ -2693,7 +2699,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { - long tmp=(long) str_to_timestamp(from,len,current_thd); + long tmp=(long) str_to_timestamp(from,len); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -2908,7 +2914,7 @@ String *Field_timestamp::val_str(String *val_buffer, } -bool Field_timestamp::get_date(TIME *ltime, bool fuzzydate) +bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate) { long temp; #ifdef WORDS_BIGENDIAN @@ -2937,7 +2943,7 @@ bool Field_timestamp::get_date(TIME *ltime, bool fuzzydate) ltime->second= start->tm_sec; ltime->second_part= 0; ltime->neg= 0; - ltime->time_type=TIMESTAMP_FULL; + ltime->time_type=TIMESTAMP_DATETIME; } return 0; } @@ -2951,7 +2957,7 @@ bool Field_timestamp::get_time(TIME *ltime) bool Field_timestamp::send_binary(Protocol *protocol) { TIME tm; - Field_timestamp::get_date(&tm, 1); + Field_timestamp::get_date(&tm, TIME_FUZZY_DATE); return protocol->store(&tm); } @@ -3027,7 +3033,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) TIME ltime; long tmp; int error= 0; - if (str_to_time(from,len,<ime,current_thd)) + if (str_to_time(from,len,<ime)) { tmp=0L; error= 1; @@ -3137,27 +3143,23 @@ String *Field_time::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { TIME ltime; - val_buffer->alloc(16); + val_buffer->alloc(19); long tmp=(long) sint3korr(ptr); - const char *sign=""; ltime.neg= 0; if (tmp < 0) { tmp= -tmp; ltime.neg= 1; } - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (current_thd, TIME_FORMAT_TYPE).datetime_format); ltime.day= (uint) 0; ltime.hour= (uint) (tmp/10000); ltime.minute= (uint) (tmp/100 % 100); ltime.second= (uint) (tmp % 100); - make_datetime(val_buffer, <ime, 0, 0, - tmp_format->format, - tmp_format->format_length, 1); + make_time((DATE_TIME_FORMAT*) 0, <ime, val_buffer); return val_buffer; } + bool Field_time::get_time(TIME *ltime) { long tmp=(long) sint3korr(ptr); @@ -3320,7 +3322,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) TIME l_time; uint32 tmp; int error= 0; - if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL) + if (str_to_TIME(from,len,&l_time,1) <= TIMESTAMP_DATETIME_ERROR) { tmp=0; error= 1; @@ -3432,7 +3434,6 @@ String *Field_date::val_str(String *val_buffer, { TIME ltime; val_buffer->alloc(field_length); - val_buffer->length(field_length); int32 tmp; #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -3440,18 +3441,15 @@ String *Field_date::val_str(String *val_buffer, else #endif longget(tmp,ptr); - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (current_thd, DATE_FORMAT_TYPE).datetime_format); ltime.neg= 0; ltime.year= (int) ((uint32) tmp/10000L % 10000); ltime.month= (int) ((uint32) tmp/100 % 100); ltime.day= (int) ((uint32) tmp % 100); - make_datetime(val_buffer, <ime, 0, 0, - tmp_format->format, - tmp_format->format_length, 1); + make_date((DATE_TIME_FORMAT *) 0, <ime, val_buffer); return val_buffer; } + int Field_date::cmp(const char *a_ptr, const char *b_ptr) { int32 a,b; @@ -3507,7 +3505,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) TIME l_time; long tmp; int error= 0; - if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL) + if (str_to_TIME(from,len,&l_time,1) <= TIMESTAMP_DATETIME_ERROR) { tmp=0L; error= 1; @@ -3572,7 +3570,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_FULL) + if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) tmp=ltime->year*16*32+ltime->month*32+ltime->day; else { @@ -3628,7 +3626,7 @@ String *Field_newdate::val_str(String *val_buffer, return val_buffer; } -bool Field_newdate::get_date(TIME *ltime,bool fuzzydate) +bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) { if (is_null()) return 1; @@ -3676,7 +3674,7 @@ void Field_newdate::sql_type(String &res) const int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { - longlong tmp=str_to_datetime(from,len,1,current_thd); + longlong tmp=str_to_datetime(from,len,1); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -3730,7 +3728,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_FULL) + if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+ (ltime->hour*10000L+ltime->minute*100+ltime->second)); else @@ -3751,7 +3749,7 @@ void Field_datetime::store_time(TIME *ltime,timestamp_type type) bool Field_datetime::send_binary(Protocol *protocol) { TIME tm; - Field_datetime::get_date(&tm, 1); + Field_datetime::get_date(&tm, TIME_FUZZY_DATE); return protocol->store(&tm); } @@ -3822,14 +3820,14 @@ String *Field_datetime::val_str(String *val_buffer, return val_buffer; } -bool Field_datetime::get_date(TIME *ltime,bool fuzzydate) +bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) { longlong tmp=Field_datetime::val_int(); uint32 part1,part2; part1=(uint32) (tmp/LL(1000000)); part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); - ltime->time_type= TIMESTAMP_FULL; + ltime->time_type= TIMESTAMP_DATETIME; ltime->neg= 0; ltime->second_part= 0; ltime->second= (int) (part2%100); @@ -4921,26 +4919,6 @@ void Field_enum::store_type(ulonglong value) } -uint find_enum(TYPELIB *lib,const char *x, uint length) -{ - const char *end=x+length; - while (end > x && my_isspace(system_charset_info,end[-1])) - end--; - - const char *i; - const char *j; - for (uint pos=0 ; (j=lib->type_names[pos]) ; pos++) - { - for (i=x ; i != end && - my_toupper(system_charset_info,*i) == - my_toupper(system_charset_info,*j) ; i++, j++) ; - if (i == end && ! *j) - return(pos+1); - } - return(0); -} - - /* ** Note. Storing a empty string in a enum field gives a warning ** (if there isn't a empty value in the enum) @@ -4958,7 +4936,11 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) from= tmpstr.ptr(); length= tmpstr.length(); } - uint tmp=find_enum(typelib,from,length); + + /* Remove end space */ + while (length > 0 && my_isspace(system_charset_info,from[length-1])) + length--; + uint tmp=find_type(typelib, from, length, 0); if (!tmp) { if (length < 6) // Can't be more than 99999 enums @@ -5111,49 +5093,8 @@ void Field_enum::sql_type(String &res) const For example "One,two,five" If one uses this string in a number context one gets the bits as a longlong number. - - If there was a value in string that wasn't in set, the 'err_pos' points to - the last invalid value found. 'err_len' will be set to length of the - error string. */ -ulonglong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, - uint *err_len, bool *set_warning) -{ - const char *end= x + length; - *err_pos= 0; // No error yet - while (end > x && my_isspace(system_charset_info, end[-1])) - end--; - - *err_len= 0; - ulonglong found= 0; - if (x != end) - { - const char *start= x; - for (;;) - { - const char *pos= start; - uint var_len; - - for (; pos != end && *pos != field_separator; pos++) ; - var_len= (uint) (pos - start); - uint find= find_enum(lib, start, var_len); - if (!find) - { - *err_pos= (char*) start; - *err_len= var_len; - *set_warning= 1; - } - else - found|= ((longlong) 1 << (find - 1)); - if (pos == end) - break; - start= pos + 1; - } - } - return found; -} - int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { @@ -5512,7 +5453,7 @@ create_field::create_field(Field *old_field,Field *orig_field) case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break; default: sql_type= FIELD_TYPE_LONG_BLOB; break; } - length /= charset->mbmaxlen; + length /= charset->mbmaxlen; // QQ: Probably not needed break; case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: diff --git a/sql/field.h b/sql/field.h index e7d4bb2416a..692e64d1146 100644 --- a/sql/field.h +++ b/sql/field.h @@ -224,7 +224,7 @@ public: uint offset(); // Should be inline ... void copy_from_tmp(int offset); uint fill_cache_field(struct st_cache_field *copy); - virtual bool get_date(TIME *ltime,bool fuzzydate); + virtual bool get_date(TIME *ltime,uint fuzzydate); virtual bool get_time(TIME *ltime); virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; } virtual bool has_charset(void) const { return FALSE; } @@ -647,7 +647,7 @@ public: longget(tmp,ptr); return tmp; } - bool get_date(TIME *ltime,bool fuzzydate); + bool get_date(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); }; @@ -735,7 +735,7 @@ public: void sql_type(String &str) const; bool store_for_compare() { return 1; } bool zero_pack() const { return 1; } - bool get_date(TIME *ltime,bool fuzzydate); + bool get_date(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); }; @@ -805,7 +805,7 @@ public: void sql_type(String &str) const; bool store_for_compare() { return 1; } bool zero_pack() const { return 1; } - bool get_date(TIME *ltime,bool fuzzydate); + bool get_date(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); }; @@ -1160,9 +1160,6 @@ uint pack_length_to_packflag(uint type); uint32 calc_pack_length(enum_field_types type,uint32 length); bool set_field_to_null(Field *field); bool set_field_to_null_with_conversions(Field *field, bool no_conversions); -uint find_enum(TYPELIB *typelib,const char *x, uint length); -ulonglong find_set(TYPELIB *typelib,const char *x, uint length, - char **err_pos, uint *err_len, bool *set_warning); bool test_if_int(const char *str, int length, const char *int_end, CHARSET_INFO *cs); diff --git a/sql/init.cc b/sql/init.cc index 8b15fef4ee3..033dfd72843 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -42,8 +42,6 @@ void unireg_init(ulong options) #endif VOID(strmov(reg_ext,".frm")); - for (i=0 ; i < 6 ; i++) // YYMMDDHHMMSS - dayord.pos[i]=i; specialflag=SPECIAL_SAME_DB_NAME; /* Make a tab of powers of 10 */ for (i=0,nr=1.0; i < array_elements(log_10) ; i++) diff --git a/sql/item.cc b/sql/item.cc index 421574ed636..24710654d4a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,8 +46,10 @@ Item::Item(): collation.set(default_charset(), DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; - thd= current_thd; - next= thd->free_list; // Put in free list + + /* Put item in free list so that we can free all items at end */ + THD *thd= current_thd; + next= thd->free_list; thd->free_list= this; /* Item constructor can be called during execution other then SQL_COM @@ -69,7 +71,7 @@ Item::Item(): Used for duplicating lists in processing queries with temporary tables */ -Item::Item(THD *c_thd, Item &item): +Item::Item(THD *thd, Item &item): str_value(item.str_value), name(item.name), max_length(item.max_length), @@ -82,8 +84,7 @@ Item::Item(THD *c_thd, Item &item): fixed(item.fixed), collation(item.collation) { - next=c_thd->free_list; // Put in free list - thd= c_thd; + next= thd->free_list; // Put in free list thd->free_list= this; } @@ -183,13 +184,13 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const As a extra convenience the time structure is reset on error! */ -bool Item::get_date(TIME *ltime,bool fuzzydate) +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(res->ptr(),res->length(),ltime,fuzzydate, thd) <= - WRONG_TIMESTAMP_FULL) + str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) <= + TIMESTAMP_DATETIME_ERROR) { bzero((char*) ltime,sizeof(*ltime)); return 1; @@ -207,7 +208,7 @@ bool Item::get_time(TIME *ltime) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_time(res->ptr(),res->length(),ltime, thd)) + str_to_time(res->ptr(),res->length(),ltime)) { bzero((char*) ltime,sizeof(*ltime)); return 1; @@ -360,7 +361,7 @@ String *Item_field::str_result(String *str) return result_field->val_str(str,&str_value); } -bool Item_field::get_date(TIME *ltime,bool fuzzydate) +bool Item_field::get_date(TIME *ltime,uint fuzzydate) { if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate)) { @@ -370,7 +371,7 @@ bool Item_field::get_date(TIME *ltime,bool fuzzydate) return 0; } -bool Item_field::get_date_result(TIME *ltime,bool fuzzydate) +bool Item_field::get_date_result(TIME *ltime,uint fuzzydate) { if ((null_value=result_field->is_null()) || result_field->get_date(ltime,fuzzydate)) @@ -692,28 +693,25 @@ String *Item_param::query_val_str(String* str) } else { - DATETIME_FORMAT *tmp_format= 0; - bool is_time_only= 0; + char buff[40]; + String tmp(buff,sizeof(buff), &my_charset_bin); switch (ltime.time_type) { - case TIMESTAMP_NONE: - case WRONG_TIMESTAMP_FULL: - break; - case TIMESTAMP_DATE: - tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; - break; - case TIMESTAMP_FULL: - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; - break; - case TIMESTAMP_TIME: - { - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; - is_time_only= 1; - break; - } + case TIMESTAMP_NONE: + case TIMESTAMP_DATETIME_ERROR: + tmp.length(0); // Should never happen + break; + case TIMESTAMP_DATE: + make_date((DATE_TIME_FORMAT*) 0, <ime, &tmp); + break; + case TIMESTAMP_DATETIME: + make_datetime((DATE_TIME_FORMAT*) 0, <ime, &tmp); + break; + case TIMESTAMP_TIME: + make_time((DATE_TIME_FORMAT*) 0, <ime, &tmp); + break; } - make_datetime(str, <ime, is_time_only, 0, - tmp_format->format, tmp_format->format_length, 0); + str->append(tmp); } str->append('\''); } @@ -769,7 +767,7 @@ String* Item_ref_null_helper::val_str(String* s) owner->was_null|= null_value= (*ref)->null_value; return tmp; } -bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate) +bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate) { return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate)); } @@ -990,6 +988,7 @@ enum_field_types Item::field_type() const FIELD_TYPE_DOUBLE); } + Field *Item::tmp_table_field_from_field_type(TABLE *table) { switch (field_type()) @@ -1366,7 +1365,7 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_TIMESTAMP: { TIME tm; - get_date(&tm, 1); + get_date(&tm, TIME_FUZZY_DATE); if (!null_value) { if (type == MYSQL_TYPE_DATE) diff --git a/sql/item.h b/sql/item.h index dcefde05605..f473ca33676 100644 --- a/sql/item.h +++ b/sql/item.h @@ -114,14 +114,6 @@ public: my_bool fixed; /* If item fixed with fix_fields */ DTCollation collation; - - /* - thd is current_thd value. Like some other Item's fields it - will be a problem for using one Item in different threads - (as stored procedures may want to do in the future) - */ - THD *thd; - // alloc & destruct is done as start of select using sql_alloc Item(); /* @@ -132,7 +124,7 @@ public: top AND/OR ctructure of WHERE clause to protect it of optimisation changes in prepared statements */ - Item(THD *c_thd, Item &item); + Item(THD *thd, Item &item); virtual ~Item() { name=0; } /*lint -e1509 */ void set_name(const char *str,uint length, CHARSET_INFO *cs); void init_make_field(Send_field *tmp_field,enum enum_field_types type); @@ -185,9 +177,9 @@ public: void print_item_w_name(String *); virtual void update_used_tables() {} virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields) {} - virtual bool get_date(TIME *ltime,bool fuzzydate); + virtual bool get_date(TIME *ltime,uint fuzzydate); virtual bool get_time(TIME *ltime); - virtual bool get_date_result(TIME *ltime,bool fuzzydate) + virtual bool get_date_result(TIME *ltime,uint fuzzydate) { return get_date(ltime,fuzzydate); } virtual bool is_null() { return 0; } virtual void top_level_item() {} @@ -286,8 +278,8 @@ public: } Field *get_tmp_table_field() { return result_field; } Field *tmp_table_field(TABLE *t_arg) { return result_field; } - bool get_date(TIME *ltime,bool fuzzydate); - bool get_date_result(TIME *ltime,bool fuzzydate); + bool get_date(TIME *ltime,uint fuzzydate); + bool get_date_result(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } Item *get_tmp_table_item(THD *thd); @@ -469,6 +461,13 @@ public: { collation.set(cs, dv); str_value.set(str,length,cs); + /* + We have to have a different max_length than 'length' here to + ensure that we get the right length if we do use the item + to create a new table. In this case max_length must be the maximum + number of chars for a string of this type because we in create_field:: + divide the max_length with mbmaxlen). + */ max_length= str_value.numchars()*cs->mbmaxlen; set_name(str, length, cs); decimals=NOT_FIXED_DEC; @@ -623,7 +622,7 @@ public: (void) (*ref)->val_int_result(); return (*ref)->null_value; } - bool get_date(TIME *ltime,bool fuzzydate) + bool get_date(TIME *ltime,uint fuzzydate) { return (null_value=(*ref)->get_date_result(ltime,fuzzydate)); } @@ -658,7 +657,7 @@ public: double val(); longlong val_int(); String* val_str(String* s); - bool get_date(TIME *ltime, bool fuzzydate); + bool get_date(TIME *ltime, uint fuzzydate); void print(String *str); }; diff --git a/sql/item_create.cc b/sql/item_create.cc index a25ccfe984b..5c44d8b00ff 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -450,7 +450,8 @@ Item *create_load_file(Item* a) } -Item *create_func_cast(Item *a, Cast_target cast_type, int len, CHARSET_INFO *cs) +Item *create_func_cast(Item *a, Cast_target cast_type, int len, + CHARSET_INFO *cs) { Item *res; LINT_INIT(res); diff --git a/sql/item_func.cc b/sql/item_func.cc index bcb4ec9aa7f..e6120f2e93c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1323,8 +1323,8 @@ void Item_func_find_in_set::fix_length_and_dec() String *find=args[0]->val_str(&value); if (find) { - enum_value=find_enum(((Field_enum*) field)->typelib,find->ptr(), - find->length()); + enum_value= find_type(((Field_enum*) field)->typelib,find->ptr(), + find->length(), 0); enum_bit=0; if (enum_value) enum_bit=LL(1) << (enum_value-1); @@ -2146,8 +2146,8 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, } /* - When a user variable is updated (in a SET command or a query like SELECT @a:= - ). + When a user variable is updated (in a SET command or a query like + SELECT @a:= ). */ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, @@ -2506,14 +2506,15 @@ void Item_func_get_user_var::fix_length_and_dec() sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION' in dispatch_command()). Instead of building a one-element list to pass to sql_set_variables(), we could instead manually call check() and update(); - this would save memory and time; but calling sql_set_variables() makes one - unique place to maintain (sql_set_variables()). + this would save memory and time; but calling sql_set_variables() makes + one unique place to maintain (sql_set_variables()). */ List<set_var_base> tmp_var_list; tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, new Item_null()))); - if (sql_set_variables(thd, &tmp_var_list)) /* this will create the variable */ + /* Create the variable */ + if (sql_set_variables(thd, &tmp_var_list)) goto err; if (!(var_entry= get_variable(&thd->user_vars, name, 0))) goto err; diff --git a/sql/item_func.h b/sql/item_func.h index b9498ed0b5d..6b43ebaccbe 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -127,9 +127,9 @@ public: void print_op(String *str); void print_args(String *str, uint from); void fix_num_length_and_dec(); - inline bool get_arg0_date(TIME *ltime,bool fuzzy_date) + inline bool get_arg0_date(TIME *ltime, uint fuzzy_date) { - return (null_value=args[0]->get_date(ltime,fuzzy_date)); + return (null_value=args[0]->get_date(ltime, fuzzy_date)); } inline bool get_arg0_time(TIME *ltime) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 00b1ebb0732..a7949511f02 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -361,7 +361,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; + max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; } const char *func_name() const { return "database"; } }; @@ -373,7 +373,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen; + max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen; } const char *func_name() const { return "user"; } }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 46d39b4ced6..cf71f2b3bef 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL 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 @@ -25,310 +25,290 @@ #include <m_ctype.h> #include <time.h> -/* -** Todo: Move month and days to language files -*/ +/* TODO: Move month and days to language files */ #define MAX_DAY_NUMBER 3652424L -static String month_names[] = -{ - String("January", &my_charset_latin1), - String("February", &my_charset_latin1), - String("March", &my_charset_latin1), - String("April", &my_charset_latin1), - String("May", &my_charset_latin1), - String("June", &my_charset_latin1), - String("July", &my_charset_latin1), - String("August", &my_charset_latin1), - String("September", &my_charset_latin1), - String("October", &my_charset_latin1), - String("November", &my_charset_latin1), - String("December", &my_charset_latin1) +static const char *month_names[]= +{ + "January", "February", "March", "April", "May", "June", "July", "August", + "September", "October", "November", "December", NullS }; -static String day_names[] = + +TYPELIB month_names_typelib= +{ array_elements(month_names)-1,"", month_names }; + +static const char *day_names[]= +{ + "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" ,"Sunday", NullS +}; + +TYPELIB day_names_typelib= +{ array_elements(day_names)-1,"", day_names}; + + +enum date_time_format_types { - String("Monday", &my_charset_latin1), - String("Tuesday", &my_charset_latin1), - String("Wednesday", &my_charset_latin1), - String("Thursday", &my_charset_latin1), - String("Friday", &my_charset_latin1), - String("Saturday", &my_charset_latin1), - String("Sunday", &my_charset_latin1) + TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND }; -uint check_names(String *arr,int item_count,const char *val_ptr, - const char *val_end, uint *val, bool check_part) +/* + OPTIMIZATION TODO: + - Replace the switch with a function that should be called for each + date type. + - Remove sprintf and opencode the conversion, like we do in + Field_datetime. + + The reason for this functions existence is that as we don't have a + way to know if a datetime/time value has microseconds in them + we are now only adding microseconds to the output if the + value has microseconds. + + We can't use a standard make_date_time() for this as we don't know + if someone will use %f in the format specifier in which case we would get + the microseconds twice. +*/ + +static bool make_datetime(date_time_format_types format, TIME *ltime, + String *str) { - for (int i= 0; i < item_count; i++) - { - String *tmp=&arr[i]; - if (!my_strnncoll(&my_charset_latin1, - (const uchar *) val_ptr, 3, - (const uchar *) tmp->ptr(), 3)) - { - if (check_part) - { - *val= i+1; - return 3; - } + char *buff; + CHARSET_INFO *cs= &my_charset_bin; + uint length= 30; - int part_len= tmp->length() - 3; - int val_len= val_end - val_ptr - 3; - if (val_len < part_len) - return 0; - val_ptr+=3; - if (!my_strnncoll(&my_charset_latin1, - (const uchar *) val_ptr, part_len, - (const uchar *) tmp->ptr() + 3, part_len)) - { - *val= i+1; - return tmp->length(); - } - return 0; - } - } - return 0; -} + if (str->alloc(length)) + return 1; + buff= (char*) str->ptr(); -uint check_val_is_digit(const char *ptr, uint val_len, uint digit_count) -{ - uint i; - uint verify_count= (val_len < digit_count ? val_len : digit_count); - uint digit_found= 0; - for (i= 0; i < verify_count; i++) - { - if (!my_isdigit(&my_charset_latin1, *(ptr+i))) - break; - digit_found++; + switch (format) { + case TIME_ONLY: + length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d", + ltime->neg ? "-" : "", + ltime->hour, ltime->minute, ltime->second); + break; + case TIME_MICROSECOND: + length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06d", + ltime->neg ? "-" : "", + ltime->hour, ltime->minute, ltime->second, + ltime->second_part); + break; + case DATE_ONLY: + length= cs->cset->snprintf(cs, buff, length, "%04d-%02d-%02d", + ltime->year, ltime->month, ltime->day); + break; + case DATE_TIME: + length= cs->cset->snprintf(cs, buff, length, + "%04d-%02d-%02d %02d:%02d:%02d", + ltime->year, ltime->month, ltime->day, + ltime->hour, ltime->minute, ltime->second); + break; + case DATE_TIME_MICROSECOND: + length= cs->cset->snprintf(cs, buff, length, + "%04d-%02d-%02d %02d:%02d:%02d.%06d", + ltime->year, ltime->month, ltime->day, + ltime->hour, ltime->minute, ltime->second, + ltime->second_part); + break; } - return digit_found; + + str->length(length); + str->set_charset(cs); + return 0; } /* Extract datetime value to TIME struct from string value according to format string. + + SYNOPSIS + extract_date_time() + format date/time format specification + val String to decode + length Length of string + l_time Store result here + + RETURN + 0 ok + 1 error */ -bool extract_datetime(const char *str_val, uint str_val_len, - const char *str_format, uint str_format_len, - TIME *l_time) + +static bool extract_date_time(DATE_TIME_FORMAT *format, + const char *val, uint length, TIME *l_time) { - char intbuff[15]; int weekday= 0, yearday= 0, daypart= 0, len; - int val_len= 0; int week_number= -1; - ulong length; CHARSET_INFO *cs= &my_charset_bin; - int err= 0; + int error= 0; bool usa_time= 0; bool sunday_first= 0; - const char *rT_format= "%H:%i:%s"; uint part_len= 0; - const char *val_ptr=str_val; - const char *val_end= str_val + str_val_len; - const char *ptr=str_format; - const char *end=ptr+ str_format_len; + const char *val_ptr= val; + const char *val_end= val + length; + const char *ptr= format->format.str; + const char *end= ptr+ format->format.length; + DBUG_ENTER("extract_date_time"); - DBUG_ENTER("extract_datetime"); - for (; ptr != end && val_ptr != val_end; ptr++) + bzero((char*) l_time, sizeof(*l_time)); + + for (; ptr != end && val != val_end; ptr++) { + if (*ptr == '%' && ptr+1 != end) { - val_len= val_end - val_ptr; - char *val_end1= (char *) val_end; + int val_len; + char *tmp; + + /* Skip pre-space between each argument */ + while (my_isspace(cs, *val) && val != val_end) + val++; + + val_len= (uint) (val_end - val); switch (*++ptr) { - case 'h': - case 'I': - case 'H': - l_time->hour= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - usa_time= (*ptr == 'I' || *ptr == 'h'); - val_ptr+=2; - break; - case 'k': - case 'l': - l_time->hour= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err) - return 1; - usa_time= (*ptr == 'l'); - val_ptr= val_end1; - break; - case 'e': - l_time->day= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err) - return 1; - val_ptr= val_end1; - break; - case 'c': - l_time->month= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err) - return 1; - val_ptr= val_end1; - break; + /* Year */ case 'Y': - l_time->year= my_strntoll(cs, val_ptr, - 4, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 4)) - return 1; - val_ptr+=4; + tmp= (char*) val + min(4, val_len); + l_time->year= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; case 'y': - l_time->year= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; + tmp= (char*) val + min(2, val_len); + l_time->year= (int) my_strtoll10(val, &tmp, &error); + val= tmp; l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); - val_ptr+=2; break; + + /* Month */ case 'm': - l_time->month= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - val_ptr+=2; + case 'c': + tmp= (char*) val + min(2, val_len); + l_time->month= (int) my_strtoll10(val, &tmp, &error); + val= tmp; + break; + case 'M': + case 'b': + if ((l_time->month= check_word(&month_names_typelib, + val, val_end, &val)) <= 0) + goto err; break; + /* Day */ case 'd': - l_time->day= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - val_ptr+=2; + case 'e': + tmp= (char*) val + min(2, val_len); + l_time->day= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; case 'D': - l_time->day= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_len < val_end1 - val_ptr + 2)) - return 1; - val_ptr= val_end1 + 2; + tmp= (char*) val + min(2, val_len); + l_time->day= (int) my_strtoll10(val, &tmp, &error); + /* Skip 'st, 'nd, 'th .. */ + val= tmp + min((int) (end-tmp), 2); + break; + + /* Hour */ + case 'h': + case 'I': + case 'l': + usa_time= 1; + /* fall through */ + case 'k': + case 'H': + tmp= (char*) val + min(2, val_len); + l_time->hour= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; + + /* Minute */ case 'i': - l_time->minute=my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - val_ptr+=2; + tmp= (char*) val + min(2, val_len); + l_time->minute= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; + + /* Second */ case 's': case 'S': - l_time->second= my_strntoll(cs, val_ptr, - 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - val_ptr+=2; + tmp= (char*) val + min(2, val_len); + l_time->second= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; - case 'M': - if (val_len < 3 || - !(part_len= check_names(month_names, 12 , val_ptr, - val_end, &l_time->month, 0))) - return 1; - val_ptr+= part_len; + + /* Second part */ + case 'f': + tmp= (char*) val_end; + l_time->second_part= my_strtoll10(val, &tmp, &error); + val= tmp; break; - case 'b': - if (val_len < 3 || - !(part_len= check_names(month_names, 12 , val_ptr, - val_end,(uint *) &l_time->month, 1))) - return 1; - val_ptr+= part_len; + + /* AM / PM */ + case 'p': + if (val_len < 2 || ! usa_time) + goto err; + if (!my_strnncoll(&my_charset_latin1, + (const uchar *) val, 2, + (const uchar *) "PM", 2)) + daypart= 12; + else if (my_strnncoll(&my_charset_latin1, + (const uchar *) val, 2, + (const uchar *) "AM", 2)) + goto err; break; + + /* Exotic things */ case 'W': - if (val_len < 3 || - !(part_len= check_names(day_names, 7 , val_ptr, - val_end,(uint *) &weekday, 0))) - return 1; - val_ptr+= part_len; - break; case 'a': - if (val_len < 3 || - !(part_len= check_names(day_names, 7 , val_ptr, - val_end,(uint *) &weekday, 1))) - return 1; - val_ptr+= part_len; + if ((weekday= check_word(&day_names_typelib, val, val_end, &val)) <= 0) + goto err; break; case 'w': - weekday= my_strntoll(cs, val_ptr, 1, 10, &val_end1, &err); - if (err) - return 1; - val_ptr++; + tmp= (char*) val + 1; + if ((weekday= (int) my_strtoll10(val, &tmp, &error)) <= 0 || + weekday >= 7) + goto err; + val= tmp; break; case 'j': - yearday= my_strntoll(cs, val_ptr, 3, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 3)) - return 1; - val_ptr+=3; - break; - case 'f': - l_time->second_part= my_strntoll(cs, val_ptr, 3, 10, &val_end1, &err); - if (err) - return 1; - val_ptr= val_end1; - break; - case 'p': - if (val_len < 2) - return 1; - if (!my_strnncoll(&my_charset_latin1, - (const uchar *) val_ptr, 2, - (const uchar *) "PM", 2)) - { - daypart= 12; - val_ptr+= 2; - } + tmp= (char*) val + min(val_len, 3); + yearday= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; + case 'U': - week_number= my_strntoll(cs, val_ptr, 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; sunday_first= 1; - val_ptr+=2; - break; + /* Fall through */ case 'u': - week_number= my_strntoll(cs, val_ptr, 2, 10, &val_end1, &err); - if (err || (val_end1 - val_ptr != 2)) - return 1; - sunday_first=0; - val_ptr+=2; - break; - case 'r': - case 'T': - usa_time= (*ptr == 'r'); - if (extract_datetime(val_ptr, val_end-val_ptr, - rT_format, strlen(rT_format), - l_time)) - return 1; - val_ptr+=8; + tmp= (char*) val + min(val_len, 2); + week_number= (int) my_strtoll10(val, &tmp, &error); + val= tmp; break; + default: - if (*val_ptr != *ptr) - return 1; - val_ptr++; + goto err; } + if (error) // Error from my_strtoll10 + goto err; } - else + else if (!my_isspace(cs, *ptr)) { - if (*val_ptr != *ptr) - return 1; - val_ptr++; + if (*val != *ptr) + goto err; + val++; } } if (usa_time) { if (l_time->hour > 12 || l_time->hour < 1) - return 1; + goto err; l_time->hour= l_time->hour%12+daypart; } if (yearday > 0) { uint days= calc_daynr(l_time->year,1,1) + yearday - 1; - if (days > 0 || days < MAX_DAY_NUMBER) - { - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); - } + if (days <= 0 || days >= MAX_DAY_NUMBER) + goto err; + get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (week_number >= 0 && weekday) @@ -337,7 +317,7 @@ bool extract_datetime(const char *str_val, uint str_val_len, uint weekday_b; if (weekday > 7 || weekday < 0) - return 1; + goto err; if (sunday_first) weekday = weekday%7; @@ -361,43 +341,43 @@ bool extract_datetime(const char *str_val, uint str_val_len, weekday =weekday - weekday_b - !sunday_first; days+= weekday; } - if (days > 0 || days < MAX_DAY_NUMBER) - { - get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); - } + if (days <= 0 || days >= MAX_DAY_NUMBER) + goto err; + get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); } if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || l_time->minute > 59 || l_time->second > 59) - return 1; + goto err; DBUG_RETURN(0); -} +err: + DBUG_RETURN(1); +} /* - Print datetime string from TIME struct - according to format string. + Create a formated date/time value in a string */ - -String *make_datetime(String *str, TIME *l_time, - const bool is_time_only, - const bool add_second_frac, - const char *ptr, uint format_length, - bool set_len_to_zero) +bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, + timestamp_type type, String *str) { char intbuff[15]; uint days_i; uint hours_i; uint weekday; ulong length; - if (set_len_to_zero) - str->length(0); + const char *ptr, *end; + + str->length(0); + str->set_charset(&my_charset_bin); + if (l_time->neg) str->append("-", 1); - const char *end=ptr+format_length; + + end= (ptr= format->format.str) + format->format.length; for (; ptr != end ; ptr++) { if (*ptr != '%' || ptr+1 == end) @@ -407,29 +387,31 @@ String *make_datetime(String *str, TIME *l_time, switch (*++ptr) { case 'M': if (!l_time->month) - return 0; + return 1; str->append(month_names[l_time->month-1]); break; case 'b': if (!l_time->month) - return 0; - str->append(month_names[l_time->month-1].ptr(),3); + return 1; + str->append(month_names[l_time->month-1],3); break; case 'W': - if (is_time_only) - return 0; - weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),0); + if (type == 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 (is_time_only) - return 0; - weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),0); - str->append(day_names[weekday].ptr(),3); + if (type == 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 (is_time_only) - return 0; + if (type == TIMESTAMP_TIME) + return 1; length= int10_to_str(l_time->day, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 1, '0'); if (l_time->day >= 10 && l_time->day <= 19) @@ -496,9 +478,10 @@ String *make_datetime(String *str, TIME *l_time, str->append_with_prefill(intbuff, length, 2, '0'); break; case 'j': - if (is_time_only) - return 0; - length= int10_to_str(calc_daynr(l_time->year,l_time->month,l_time->day) - + if (type == TIMESTAMP_TIME) + return 1; + length= int10_to_str(calc_daynr(l_time->year,l_time->month, + l_time->day) - calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 3, '0'); break; @@ -529,12 +512,6 @@ String *make_datetime(String *str, TIME *l_time, case 's': length= int10_to_str(l_time->second, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 2, '0'); - if (add_second_frac) - { - str->append('.'); - length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 6, '0'); - } break; case 'T': length= my_sprintf(intbuff, @@ -549,8 +526,8 @@ String *make_datetime(String *str, TIME *l_time, case 'u': { uint year; - if (is_time_only) - return 0; + if (type == TIMESTAMP_TIME) + return 1; length= int10_to_str(calc_week(l_time, 0, (*ptr) == 'U', &year), intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 2, '0'); @@ -560,8 +537,8 @@ String *make_datetime(String *str, TIME *l_time, case 'V': { uint year; - if (is_time_only) - return 0; + if (type == TIMESTAMP_TIME) + return 1; length= int10_to_str(calc_week(l_time, 1, (*ptr) == 'V', &year), intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 2, '0'); @@ -571,27 +548,29 @@ String *make_datetime(String *str, TIME *l_time, case 'X': { uint year; - if (is_time_only) - return 0; + if (type == TIMESTAMP_TIME) + return 1; (void) calc_week(l_time, 1, (*ptr) == 'X', &year); length= int10_to_str(year, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 4, '0'); } break; case 'w': - if (is_time_only) - return 0; - weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),1); + if (type == TIMESTAMP_TIME) + return 1; + weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, + l_time->day),1); length= int10_to_str(weekday, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 1, '0'); break; + default: str->append(*ptr); break; } } } - return str; + return 0; } @@ -691,21 +670,24 @@ longlong Item_func_month::val_int() return (longlong) ltime.month; } + String* Item_func_monthname::val_str(String* str) { + const char *name; uint month=(uint) Item_func_month::val_int(); + if (!month) // This is also true for NULL { null_value=1; return (String*) 0; } null_value=0; - - String *m=&month_names[month-1]; - str->copy(m->ptr(), m->length(), m->charset(), default_charset()); + name= month_names[month-1]; + str->set(name, strlen(name), system_charset_info); return str; } + // Returns the quarter of the year longlong Item_func_quarter::val_int() @@ -785,14 +767,17 @@ longlong Item_func_weekday::val_int() return (longlong) calc_weekday(tmp_value,odbc_type)+test(odbc_type); } + String* Item_func_dayname::val_str(String* str) { uint weekday=(uint) val_int(); // Always Item_func_daynr() + const char *name; + if (null_value) return (String*) 0; - String *d=&day_names[weekday]; - str->copy(d->ptr(), d->length(), d->charset(), default_charset()); + name= day_names[weekday]; + str->set(name, strlen(name), system_charset_info); return str; } @@ -808,7 +793,7 @@ longlong Item_func_year::val_int() longlong Item_func_unix_timestamp::val_int() { if (arg_count == 0) - return (longlong) thd->query_start(); + return (longlong) current_thd->query_start(); if (args[0]->type() == FIELD_ITEM) { // Optimize timestamp field Field *field=((Item_field*) args[0])->field; @@ -820,7 +805,7 @@ longlong Item_func_unix_timestamp::val_int() { return 0; /* purecov: inspected */ } - return (longlong) str_to_timestamp(str->ptr(),str->length(), thd); + return (longlong) str_to_timestamp(str->ptr(),str->length()); } @@ -840,15 +825,18 @@ longlong Item_func_time_to_sec::val_int() */ static bool get_interval_value(Item *args,interval_type int_type, - String *str_value, INTERVAL *t) + String *str_value, INTERVAL *interval) { long array[5],value; const char *str; uint32 length; - LINT_INIT(value); LINT_INIT(str); LINT_INIT(length); CHARSET_INFO *cs=str_value->charset(); - bzero((char*) t,sizeof(*t)); + LINT_INIT(value); + LINT_INIT(str); + LINT_INIT(length); + + bzero((char*) interval,sizeof(*interval)); if ((int) int_type <= INTERVAL_MICROSECOND) { value=(long) args->val_int(); @@ -856,7 +844,7 @@ static bool get_interval_value(Item *args,interval_type int_type, return 1; if (value < 0) { - t->neg=1; + interval->neg=1; value= -value; } } @@ -866,14 +854,14 @@ static bool get_interval_value(Item *args,interval_type int_type, if (!(res=args->val_str(str_value))) return (1); - /* record negative intervalls in t->neg */ + /* record negative intervalls in interval->neg */ str=res->ptr(); const char *end=str+res->length(); while (str != end && my_isspace(cs,*str)) str++; if (str != end && *str == '-') { - t->neg=1; + interval->neg=1; str++; } length=(uint32) (end-str); // Set up pointers to new str @@ -881,101 +869,101 @@ static bool get_interval_value(Item *args,interval_type int_type, switch (int_type) { case INTERVAL_YEAR: - t->year=value; + interval->year=value; break; case INTERVAL_MONTH: - t->month=value; + interval->month=value; break; case INTERVAL_DAY: - t->day=value; + interval->day=value; break; case INTERVAL_HOUR: - t->hour=value; + interval->hour=value; break; case INTERVAL_MICROSECOND: - t->second_part=value; + interval->second_part=value; break; case INTERVAL_MINUTE: - t->minute=value; + interval->minute=value; break; case INTERVAL_SECOND: - t->second=value; + interval->second=value; break; case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM if (get_interval_info(str,length,cs,2,array)) return (1); - t->year=array[0]; - t->month=array[1]; + interval->year=array[0]; + interval->month=array[1]; break; case INTERVAL_DAY_HOUR: if (get_interval_info(str,length,cs,2,array)) return (1); - t->day=array[0]; - t->hour=array[1]; + interval->day=array[0]; + interval->hour=array[1]; break; case INTERVAL_DAY_MICROSECOND: if (get_interval_info(str,length,cs,5,array)) return (1); - t->day=array[0]; - t->hour=array[1]; - t->minute=array[2]; - t->second=array[3]; - t->second_part=array[4]; + interval->day=array[0]; + interval->hour=array[1]; + interval->minute=array[2]; + interval->second=array[3]; + interval->second_part=array[4]; break; case INTERVAL_DAY_MINUTE: if (get_interval_info(str,length,cs,3,array)) return (1); - t->day=array[0]; - t->hour=array[1]; - t->minute=array[2]; + interval->day=array[0]; + interval->hour=array[1]; + interval->minute=array[2]; break; case INTERVAL_DAY_SECOND: if (get_interval_info(str,length,cs,4,array)) return (1); - t->day=array[0]; - t->hour=array[1]; - t->minute=array[2]; - t->second=array[3]; + interval->day=array[0]; + interval->hour=array[1]; + interval->minute=array[2]; + interval->second=array[3]; break; case INTERVAL_HOUR_MICROSECOND: if (get_interval_info(str,length,cs,4,array)) return (1); - t->hour=array[0]; - t->minute=array[1]; - t->second=array[2]; - t->second_part=array[3]; + interval->hour=array[0]; + interval->minute=array[1]; + interval->second=array[2]; + interval->second_part=array[3]; break; case INTERVAL_HOUR_MINUTE: if (get_interval_info(str,length,cs,2,array)) return (1); - t->hour=array[0]; - t->minute=array[1]; + interval->hour=array[0]; + interval->minute=array[1]; break; case INTERVAL_HOUR_SECOND: if (get_interval_info(str,length,cs,3,array)) return (1); - t->hour=array[0]; - t->minute=array[1]; - t->second=array[2]; + interval->hour=array[0]; + interval->minute=array[1]; + interval->second=array[2]; break; case INTERVAL_MINUTE_MICROSECOND: if (get_interval_info(str,length,cs,3,array)) return (1); - t->minute=array[0]; - t->second=array[1]; - t->second_part=array[2]; + interval->minute=array[0]; + interval->second=array[1]; + interval->second_part=array[2]; break; case INTERVAL_MINUTE_SECOND: if (get_interval_info(str,length,cs,2,array)) return (1); - t->minute=array[0]; - t->second=array[1]; + interval->minute=array[0]; + interval->second=array[1]; break; case INTERVAL_SECOND_MICROSECOND: if (get_interval_info(str,length,cs,2,array)) return (1); - t->second=array[0]; - t->second_part=array[1]; + interval->second=array[0]; + interval->second_part=array[1]; break; } return 0; @@ -984,34 +972,33 @@ static bool get_interval_value(Item *args,interval_type int_type, String *Item_date::val_str(String *str) { - DATETIME_FORMAT *tmp_format; TIME ltime; ulong value=(ulong) val_int(); if (null_value) - goto null_date; + return (String*) 0; + + if (str->alloc(11)) + { + null_value= 1; + return (String *) 0; + } ltime.year= (value/10000L) % 10000; ltime.month= (value/100)%100; ltime.day= (value%100); - ltime.neg=0; + ltime.neg= 0; ltime.time_type=TIMESTAMP_DATE; - tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; - if (make_datetime(str, <ime, 0, 0, - tmp_format->format, tmp_format->format_length, 1)) - return str; - - null_value= 1; -null_date: - return 0; + make_date((DATE_TIME_FORMAT *) 0, <ime, str); + return str; } int Item_date::save_in_field(Field *field, bool no_conversions) { TIME ltime; - timestamp_type t_type=TIMESTAMP_FULL; - if (get_date(<ime,1)) + timestamp_type t_type=TIMESTAMP_DATETIME; + if (get_date(<ime, TIME_FUZZY_DATE)) { if (null_value) return set_field_to_null(field); @@ -1039,11 +1026,11 @@ void Item_func_curdate::fix_length_and_dec() { struct tm start; - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=10*default_charset()->mbmaxlen; + max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; - store_now_in_tm(thd->query_start(),&start); + store_now_in_tm(current_thd->query_start(),&start); value=(longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+ ((uint) start.tm_mon+1)*100+ @@ -1062,7 +1049,7 @@ void Item_func_curdate::fix_length_and_dec() bool Item_func_curdate::get_date(TIME *res, - bool fuzzy_date __attribute__((unused))) + uint fuzzy_date __attribute__((unused))) { *res=ltime; return 0; @@ -1091,19 +1078,19 @@ void Item_func_curdate_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_curtime::val_str(String *str) { - str_value.set(buff,buff_length,default_charset()); + str_value.set(buff, buff_length, &my_charset_bin); return &str_value; } + void Item_func_curtime::fix_length_and_dec() { struct tm start; - DATETIME_FORMAT *tmp_format; - String tmp((char*) buff,sizeof(buff),default_charset()); + String tmp((char*) buff,sizeof(buff), &my_charset_bin); TIME ltime; decimals=0; - store_now_in_tm(thd->query_start(),&start); + store_now_in_tm(current_thd->query_start(),&start); value=(longlong) ((ulong) ((uint) start.tm_hour)*10000L+ (ulong) (((uint) start.tm_min)*100L+ (uint) start.tm_sec)); @@ -1113,12 +1100,8 @@ void Item_func_curtime::fix_length_and_dec() ltime.second= start.tm_sec; ltime.second_part= 0; ltime.neg= 0; - ltime.time_type= TIMESTAMP_TIME; - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; - make_datetime(&tmp, <ime, 0, 0, - tmp_format->format, tmp_format->format_length, 1); - buff_length= tmp.length(); - max_length= buff_length; + make_time((DATE_TIME_FORMAT *) 0, <ime, &tmp); + max_length= buff_length= tmp.length(); } @@ -1144,7 +1127,7 @@ void Item_func_curtime_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_now::val_str(String *str) { - str_value.set(buff,buff_length,default_charset()); + str_value.set(buff,buff_length, &my_charset_bin); return &str_value; } @@ -1152,11 +1135,12 @@ String *Item_func_now::val_str(String *str) void Item_func_now::fix_length_and_dec() { struct tm start; - DATETIME_FORMAT *tmp_format; String tmp((char*) buff,sizeof(buff),&my_charset_bin); - + decimals=0; - store_now_in_tm(thd->query_start(),&start); + collation.set(&my_charset_bin); + + store_now_in_tm(current_thd->query_start(),&start); value=((longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+ (((uint) start.tm_mon+1)*100+ (uint) start.tm_mday))*(longlong) 1000000L+ @@ -1173,17 +1157,15 @@ void Item_func_now::fix_length_and_dec() ltime.second= start.tm_sec; ltime.second_part= 0; ltime.neg= 0; - ltime.time_type= TIMESTAMP_FULL; + ltime.time_type= TIMESTAMP_DATETIME; - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; - make_datetime(&tmp, <ime, 0, 0, - tmp_format->format, tmp_format->format_length, 1); - buff_length= tmp.length(); - max_length= buff_length; + make_datetime((DATE_TIME_FORMAT *) 0, <ime, &tmp); + max_length= buff_length= tmp.length(); } + bool Item_func_now::get_date(TIME *res, - bool fuzzy_date __attribute__((unused))) + uint fuzzy_date __attribute__((unused))) { *res=ltime; return 0; @@ -1193,7 +1175,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(<ime,TIMESTAMP_FULL); + to->store_time(<ime,TIMESTAMP_DATETIME); return 0; } @@ -1222,12 +1204,13 @@ String *Item_func_sec_to_time::val_str(String *str) { longlong seconds=(longlong) args[0]->val_int(); uint sec; - - DATETIME_FORMAT *tmp_format; TIME ltime; - if ((null_value=args[0]->null_value)) - goto null_date; + if ((null_value=args[0]->null_value) || str->alloc(19)) + { + null_value= 1; + return (String*) 0; + } ltime.neg= 0; if (seconds < 0) @@ -1242,14 +1225,8 @@ String *Item_func_sec_to_time::val_str(String *str) ltime.minute= sec/60; ltime.second= sec % 60; - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; - if (make_datetime(str, <ime, 0, 0, - tmp_format->format, tmp_format->format_length, 1)) - return str; - - null_value= 1; -null_date: - return (String*) 0; + make_time((DATE_TIME_FORMAT *) 0, <ime, str); + return str; } @@ -1359,9 +1336,9 @@ String *Item_func_date_format::val_str(String *str) { String *format; TIME l_time; - uint size,weekday; + uint size; - if (!date_or_time) + if (!is_time_format) { if (get_arg0_date(&l_time,1)) return 0; @@ -1369,10 +1346,8 @@ String *Item_func_date_format::val_str(String *str) else { String *res; - if (!(res=args[0]->val_str(str))) - goto null_date; - - if (str_to_time(res->ptr(),res->length(),&l_time, thd)) + if (!(res=args[0]->val_str(str)) || + (str_to_time(res->ptr(),res->length(),&l_time))) goto null_date; l_time.year=l_time.month=l_time.day=0; @@ -1391,10 +1366,13 @@ String *Item_func_date_format::val_str(String *str) if (str->alloc(size)) goto null_date; + DATE_TIME_FORMAT date_time_format; + date_time_format.format.str= (char*) format->ptr(); + date_time_format.format.length= format->length(); /* Create the result string */ - if (make_datetime(str, &l_time, 0, 0, - format->ptr(), format->length(), 1)) + if (!make_date_time(&date_time_format, &l_time, + is_time_format ? TIMESTAMP_TIME : TIMESTAMP_DATE, str)) return str; null_date: @@ -1406,10 +1384,8 @@ null_date: String *Item_func_from_unixtime::val_str(String *str) { struct tm tm_tmp,*start; - DATETIME_FORMAT *tmp_format; time_t tmp=(time_t) args[0]->val_int(); - uint32 l; - CHARSET_INFO *cs=default_charset(); + CHARSET_INFO *cs= &my_charset_bin; TIME ltime; if ((null_value=args[0]->null_value)) @@ -1427,14 +1403,13 @@ String *Item_func_from_unixtime::val_str(String *str) ltime.second_part= 0; ltime.neg=0; - l=20*cs->mbmaxlen+32; - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; - if (str->alloc(l) && make_datetime(str, <ime, 1, 0, - tmp_format->format, - tmp_format->format_length, 1)) - return str; - null_value= 1; + if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN)) + goto null_date; + make_datetime((DATE_TIME_FORMAT *) 0, <ime, str); + return str; + null_date: + null_value=1; return 0; } @@ -1456,7 +1431,7 @@ longlong Item_func_from_unixtime::val_int() } bool Item_func_from_unixtime::get_date(TIME *ltime, - bool fuzzy_date __attribute__((unused))) + uint fuzzy_date __attribute__((unused))) { time_t tmp=(time_t) (ulong) args[0]->val_int(); if ((null_value=args[0]->null_value)) @@ -1479,10 +1454,11 @@ bool Item_func_from_unixtime::get_date(TIME *ltime, void Item_date_add_interval::fix_length_and_dec() { enum_field_types arg0_field_type; - collation.set(default_charset()); + + collation.set(&my_charset_bin); maybe_null=1; - max_length=26*MY_CHARSET_BIN_MB_MAXLEN; - value.alloc(32); + max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; + value.alloc(max_length); /* The field type for the result of an Item_date function is defined as @@ -1512,10 +1488,11 @@ void Item_date_add_interval::fix_length_and_dec() /* Here arg[1] is a Item_interval object */ -bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) +bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) { long period,sign; INTERVAL interval; + ltime->neg= 0; if (args[0]->get_date(ltime,0) || get_interval_value(args[1],int_type,&value,&interval)) @@ -1541,7 +1518,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) case INTERVAL_DAY_MINUTE: case INTERVAL_DAY_HOUR: long sec,days,daynr,microseconds,extra_sec; - ltime->time_type=TIMESTAMP_FULL; // Return full date + ltime->time_type=TIMESTAMP_DATETIME; // Return full date microseconds= ltime->second_part + sign*interval.second_part; extra_sec= microseconds/1000000L; microseconds= microseconds%1000000L; @@ -1616,23 +1593,26 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) String *Item_date_add_interval::val_str(String *str) { TIME ltime; - DATETIME_FORMAT *tmp_format; + enum date_time_format_types format; if (Item_date_add_interval::get_date(<ime,0)) return 0; if (ltime.time_type == TIMESTAMP_DATE) - tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; - else - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; - if (make_datetime(str, <ime, 1, ltime.second_part, - tmp_format->format, tmp_format->format_length, 1)) + format= DATE_ONLY; + else if (ltime.second_part) + format= DATE_TIME_MICROSECOND; + else + format= DATE_TIME; + + if (!make_datetime(format, <ime, str)) return str; null_value=1; return 0; } + longlong Item_date_add_interval::val_int() { TIME ltime; @@ -1715,7 +1695,7 @@ longlong Item_extract::val_int() else { String *res= args[0]->val_str(&value); - if (!res || str_to_time(res->ptr(),res->length(),<ime, thd)) + if (!res || str_to_time(res->ptr(),res->length(),<ime)) { null_value=1; return 0; @@ -1864,15 +1844,13 @@ void Item_char_typecast::fix_length_and_dec() max_length= char_length * cast_cs->mbmaxlen; } + String *Item_datetime_typecast::val_str(String *str) { TIME ltime; - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (thd, DATETIME_FORMAT_TYPE).datetime_format); - if (!get_arg0_date(<ime,1) && - make_datetime(str, <ime, 1, ltime.second_part, - tmp_format->format, tmp_format->format_length, 1)) + !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, + <ime, str)) return str; null_date: @@ -1892,12 +1870,10 @@ bool Item_time_typecast::get_time(TIME *ltime) String *Item_time_typecast::val_str(String *str) { TIME ltime; - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (thd, TIME_FORMAT_TYPE).datetime_format); if (!get_arg0_time(<ime) && - make_datetime(str, <ime, 0, ltime.second_part, - tmp_format->format, tmp_format->format_length, 1)) + !make_datetime(ltime.second_part ? TIME_MICROSECOND : TIME_ONLY, + <ime, str)) return str; null_value=1; @@ -1905,7 +1881,7 @@ String *Item_time_typecast::val_str(String *str) } -bool Item_date_typecast::get_date(TIME *ltime, bool fuzzy_date) +bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date) { bool res= get_arg0_date(ltime,1); ltime->time_type= TIMESTAMP_DATE; @@ -1916,19 +1892,18 @@ bool Item_date_typecast::get_date(TIME *ltime, bool fuzzy_date) String *Item_date_typecast::val_str(String *str) { TIME ltime; - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (thd, DATE_FORMAT_TYPE).datetime_format); - if (!get_arg0_date(<ime,1) && - make_datetime(str, <ime, 1, 0, - tmp_format->format, tmp_format->format_length, 1)) - return str; + if (!get_arg0_date(<ime,1) && !str->alloc(11)) + { + make_date((DATE_TIME_FORMAT *) 0,<ime, str); + return str; + } -null_date: null_value=1; return 0; } + /* MAKEDATE(a,b) is a date function that creates a date value from a year and day value. @@ -1943,22 +1918,21 @@ String *Item_func_makedate::val_str(String *str) if (args[0]->null_value || args[1]->null_value || yearnr < 0 || daynr <= 0) - goto null_date; + goto err; days= calc_daynr(yearnr,1,1) + daynr - 1; - if (days > 0 || days < MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31 + // Day number from year 0 to 9999-12-31 + if (days >= 0 && days < MAX_DAY_NUMBER) { null_value=0; get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day); - - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (thd, DATE_FORMAT_TYPE).datetime_format); - if (make_datetime(str, &l_time, 1, 0, - tmp_format->format, tmp_format->format_length, 1)) - return str; + if (str->alloc(11)) + goto err; + make_date((DATE_TIME_FORMAT *) 0, &l_time, str); + return str; } -null_date: +err: null_value=1; return 0; } @@ -1968,11 +1942,11 @@ void Item_func_add_time::fix_length_and_dec() { enum_field_types arg0_field_type; decimals=0; - max_length=26*MY_CHARSET_BIN_MB_MAXLEN; + max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; /* - The field type for the result of an Item_func_add_time function is defined as - follows: + The field type for the result of an Item_func_add_time function is defined + as follows: - If first arg is a MYSQL_TYPE_DATETIME or MYSQL_TYPE_TIMESTAMP result is MYSQL_TYPE_DATETIME @@ -1991,7 +1965,8 @@ void Item_func_add_time::fix_length_and_dec() } /* - ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a time/datetime value + ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a + time/datetime value t: time_or_datetime_expression a: time_expression @@ -2005,7 +1980,6 @@ String *Item_func_add_time::val_str(String *str) bool is_time= 0; long microseconds, seconds, days= 0; int l_sign= sign; - DATETIME_FORMAT *tmp_format; null_value=0; l_time3.neg= 0; @@ -2021,7 +1995,7 @@ String *Item_func_add_time::val_str(String *str) { if (args[0]->get_time(&l_time1) || args[1]->get_time(&l_time2) || - l_time2.time_type == TIMESTAMP_FULL) + l_time2.time_type == TIMESTAMP_DATETIME) goto null_date; is_time= (l_time1.time_type == TIMESTAMP_TIME); if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg)) @@ -2037,7 +2011,8 @@ String *Item_func_add_time::val_str(String *str) if (is_time) seconds+= l_time1.day*86400L; else - days+= calc_daynr((uint) l_time1.year,(uint) l_time1.month, (uint) l_time1.day); + days+= calc_daynr((uint) l_time1.year,(uint) l_time1.month, + (uint) l_time1.day); seconds= seconds + microseconds/1000000L; microseconds= microseconds%1000000L; days+= seconds/86400L; @@ -2070,21 +2045,19 @@ String *Item_func_add_time::val_str(String *str) calc_time_from_sec(&l_time3, seconds, microseconds); if (!is_time) { - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); if (l_time3.day && - make_datetime(str, &l_time3, 1, - l_time1.second_part || l_time2.second_part, - tmp_format->format, tmp_format->format_length, 1)) + !make_datetime(l_time1.second_part || l_time2.second_part ? + DATE_TIME_MICROSECOND : DATE_TIME, + &l_time3, str)) return str; goto null_date; } - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; l_time3.hour+= days*24; - if (make_datetime(str, &l_time3, 0, - l_time1.second_part || l_time2.second_part, - tmp_format->format, tmp_format->format_length, 1)) + if (!make_datetime(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2129,7 +2102,6 @@ String *Item_func_timediff::val_str(String *str) long days; int l_sign= 1; TIME l_time1 ,l_time2, l_time3; - DATETIME_FORMAT *tmp_format; null_value= 0; if (args[0]->get_time(&l_time1) || @@ -2176,10 +2148,9 @@ String *Item_func_timediff::val_str(String *str) calc_time_from_sec(&l_time3, seconds, microseconds); - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; - if (make_datetime(str, &l_time3, 0, - l_time1.second_part || l_time2.second_part, - tmp_format->format, tmp_format->format_length, 1)) + if (!make_datetime(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2196,7 +2167,6 @@ null_date: String *Item_func_maketime::val_str(String *str) { TIME ltime; - DATETIME_FORMAT *tmp_format; long hour= args[0]->val_int(); long minute= args[1]->val_int(); @@ -2206,8 +2176,9 @@ String *Item_func_maketime::val_str(String *str) args[1]->null_value || args[2]->null_value || minute > 59 || minute < 0 || - second > 59 || second < 0))) - goto null_date; + second > 59 || second < 0 || + str->alloc(19)))) + return 0; ltime.neg= 0; if (hour < 0) @@ -2218,21 +2189,19 @@ String *Item_func_maketime::val_str(String *str) ltime.hour= (ulong)hour; ltime.minute= (ulong)minute; ltime.second= (ulong)second; - tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; - if (make_datetime(str, <ime, 0, 0, - tmp_format->format, tmp_format->format_length, 1)) - return str; - -null_date: - return 0; + make_time((DATE_TIME_FORMAT *) 0, <ime, str); + return str; } + /* - MICROSECOND(a) is a function ( extraction) that extracts the microseconds from a. + MICROSECOND(a) is a function ( extraction) that extracts the microseconds + from a. a: Datetime or time value Result: int value */ + longlong Item_func_microsecond::val_int() { TIME ltime; @@ -2241,78 +2210,103 @@ longlong Item_func_microsecond::val_int() return 0; } -/* - Array of MySQL date/time/datetime formats - Firts element is date format - Second element is time format - Third element is datetime format - Fourth is format name. -*/ - -const char *datetime_formats[4][5]= -{ - {"%m.%d.%Y", "%Y-%m-%d", "%Y-%m-%d", "%d.%m.%Y", "%Y%m%d"}, - {"%h:%i:%s %p", "%H:%i:%s", "%H:%i:%s", "%H.%i.%S", "%H%i%s"}, - {"%Y-%m-%d-%H.%i.%s", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d-%H.%i.%s", "%Y%m%d%H%i%s"}, - {"USA", "JIS", "ISO", "EUR", "INTERNAL"} -}; - - -/* - Return format string according format name. - If name is unknown, result is ISO format string -*/ String *Item_func_get_format::val_str(String *str) { - String *val=args[0]->val_str(str); - const char *format_str= datetime_formats[tm_format][ISO_FORMAT]; + const char *format_name; + KNOWN_DATE_TIME_FORMAT *format; + String *val= args[0]->val_str(str); + ulong val_len; - if (!args[0]->null_value) + if ((null_value= args[0]->null_value)) + return 0; + + val_len= val->length(); + for (format= &known_date_time_formats[0]; + (format_name= format->format_name); + format++) { - const char *val_ptr= val->ptr(); - uint val_len= val->length(); - for (int i= 0; i < 5; i++) + uint format_name_len; + format_name_len= strlen(format_name); + if (val_len == format_name_len && + !my_strnncoll(&my_charset_latin1, + (const uchar *) val->ptr(), val_len, + (const uchar *) format_name, val_len)) { - const char *name_format_str= datetime_formats[3][i]; - uint format_str_len= strlen(name_format_str); - if ( val_len == format_str_len && - !my_strnncoll(&my_charset_latin1, - (const uchar *) val_ptr, val_len, - (const uchar *) name_format_str, format_str_len)) - { - format_str= datetime_formats[tm_format][i]; - break; - } + const char *format_str= get_date_time_format_str(format, type); + str->set(format_str, strlen(format_str), &my_charset_bin); + return str; } } + null_value= 1; + return 0; +} + + +void Item_func_get_format::print(String *str) +{ + str->append(func_name()); + str->append('('); + + switch (type) { + case TIMESTAMP_DATE: + str->append("DATE, "); + break; + case TIMESTAMP_DATETIME: + str->append("DATETIME, "); + break; + case TIMESTAMP_TIME: + str->append("TIME, "); + break; + default: + DBUG_ASSERT(0); + } + args[0]->print(str); + str->append(')'); +} + + +bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) +{ + DATE_TIME_FORMAT date_time_format; + char val_buff[64], format_buff[64]; + String val_str(val_buff, sizeof(val_buff), &my_charset_bin), *val; + String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format; + + val= args[0]->val_str(&val_str); + format= args[1]->val_str(&format_str); + if (args[0]->null_value || args[1]->null_value) + goto null_date; + null_value= 0; - str->length(0); - str->append(format_str); - return str; + bzero((char*) ltime, sizeof(ltime)); + date_time_format.format.str= (char*) format->ptr(); + date_time_format.format.length= format->length(); + if (extract_date_time(&date_time_format, val->ptr(), val->length(), + ltime)) + goto null_date; + return 0; + +null_date: + return (null_value=1); } String *Item_func_str_to_date::val_str(String *str) { TIME ltime; - bzero((char*) <ime, sizeof(ltime)); - DATETIME_FORMAT *tmp_format; - String *val=args[0]->val_str(str); - String *format=args[1]->val_str(str); - if (args[0]->null_value || args[1]->null_value || - extract_datetime(val->ptr(), val->length(), - format->ptr(), val->length(), - <ime)) - goto null_date; - tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; - if (make_datetime(str, <ime, 0, 0, tmp_format->format, - tmp_format->format_length, 1)) - return str; + if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE)) + return 0; -null_date: - null_value=1; + /* + The following DATE_TIME should be done dynamicly based on the + format string (wen it's a constant). For example, we should only return + microseconds if there was an %f in the format + */ + if (!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, + <ime, str)) + return str; return 0; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index af71322ff0c..ef7fa1abfa0 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -29,7 +29,7 @@ public: const char *func_name() const { return "period_add"; } void fix_length_and_dec() { - max_length=6*default_charset()->mbmaxlen; + max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } }; @@ -43,7 +43,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=6*default_charset()->mbmaxlen; + max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } }; @@ -57,7 +57,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=6*default_charset()->mbmaxlen; + max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -72,7 +72,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -86,16 +86,16 @@ public: double val() { return (double) Item_func_month::val_int(); } String *val_str(String *str) { - str->set(val_int(), default_charset()); + str->set(val_int(), &my_charset_bin); return null_value ? 0 : str; } const char *func_name() const { return "month"; } enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -110,9 +110,9 @@ public: enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=10*default_charset()->mbmaxlen; + max_length=10*my_charset_bin.mbmaxlen; maybe_null=1; } }; @@ -127,7 +127,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=3*default_charset()->mbmaxlen; + max_length=3*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -142,7 +142,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -157,7 +157,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -172,7 +172,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=1*default_charset()->mbmaxlen; + max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -187,7 +187,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -202,7 +202,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=2*default_charset()->mbmaxlen; + max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -216,7 +216,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=6*default_charset()->mbmaxlen; + max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -231,7 +231,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=4*default_charset()->mbmaxlen; + max_length=4*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -247,16 +247,16 @@ public: double val() { return (double) val_int(); } String *val_str(String *str) { - str->set(val_int(), default_charset()); + str->set(val_int(), &my_charset_bin); return null_value ? 0 : str; } const char *func_name() const { return "weekday"; } enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=1*default_charset()->mbmaxlen; + max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -270,9 +270,9 @@ class Item_func_dayname :public Item_func_weekday enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=9*default_charset()->mbmaxlen; + max_length=9*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } }; @@ -289,7 +289,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=10*default_charset()->mbmaxlen; + max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } }; @@ -303,7 +303,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=10*default_charset()->mbmaxlen; + max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } }; @@ -322,14 +322,14 @@ public: const char *func_name() const { return "date"; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=10*default_charset()->mbmaxlen; + max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } int save_in_field(Field *to, bool no_conversions); Field *tmp_table_field(TABLE *t_arg) { - return (new Field_date(maybe_null, name, t_arg, default_charset())); + return (new Field_date(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -343,7 +343,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_datetime(maybe_null, name, t_arg, default_charset())); + return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -366,7 +366,7 @@ public: void fix_length_and_dec(); Field *tmp_table_field(TABLE *t_arg) { - return (new Field_time(maybe_null, name, t_arg, default_charset())); + return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); } /* Abstract method that defines which time zone is used for conversion. @@ -408,7 +408,7 @@ public: void set_result_from_tm(struct tm *now); longlong val_int() { return (value) ; } void fix_length_and_dec(); - bool get_date(TIME *res,bool fuzzy_date); + bool get_date(TIME *res, uint fuzzy_date); virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0; }; @@ -448,7 +448,7 @@ public: int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); void fix_length_and_dec(); - bool get_date(TIME *res,bool fuzzy_date); + bool get_date(TIME *res, uint fuzzy_date); virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0; }; @@ -485,11 +485,11 @@ public: class Item_func_date_format :public Item_str_func { int fixed_length; - const bool date_or_time; + const bool is_time_format; String value; public: - Item_func_date_format(Item *a,Item *b,bool date_or_time_arg) - :Item_str_func(a,b),date_or_time(date_or_time_arg) {} + Item_func_date_format(Item *a,Item *b,bool is_time_format_arg) + :Item_str_func(a,b),is_time_format(is_time_format_arg) {} String *val_str(String *str); const char *func_name() const { return "date_format"; } void fix_length_and_dec(); @@ -507,11 +507,11 @@ class Item_func_from_unixtime :public Item_date_func const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); decimals=0; - max_length=19*default_charset()->mbmaxlen; + max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } - bool get_date(TIME *res,bool fuzzy_date); + bool get_date(TIME *res, uint fuzzy_date); }; @@ -524,15 +524,15 @@ public: String *val_str(String *); void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); maybe_null=1; - max_length=13*default_charset()->mbmaxlen; + max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } const char *func_name() const { return "sec_to_time"; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_time(maybe_null, name, t_arg, default_charset())); + return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -567,7 +567,7 @@ public: enum_field_types field_type() const { return cached_field_type; } double val() { return (double) val_int(); } longlong val_int(); - bool get_date(TIME *res,bool fuzzy_date); + bool get_date(TIME *res, uint fuzzy_date); void print(String *str); }; @@ -602,7 +602,7 @@ public: } void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); max_length=args[0]->max_length; } virtual const char* cast_type() const= 0; @@ -631,12 +631,12 @@ class Item_date_typecast :public Item_typecast public: Item_date_typecast(Item *a) :Item_typecast(a) {} String *val_str(String *str); - bool get_date(TIME *ltime, bool fuzzy_date); + bool get_date(TIME *ltime, uint fuzzy_date); const char *cast_type() const { return "date"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_date(maybe_null, name, t_arg, default_charset())); + return (new Field_date(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -651,7 +651,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_TIME; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_time(maybe_null, name, t_arg, default_charset())); + return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -665,7 +665,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_datetime(maybe_null, name, t_arg, default_charset())); + return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -679,7 +679,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=8*MY_CHARSET_BIN_MB_MAXLEN; + max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } Field *tmp_table_field(TABLE *t_arg) { @@ -728,7 +728,7 @@ public: void fix_length_and_dec() { decimals=0; - max_length=17*MY_CHARSET_BIN_MB_MAXLEN; + max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } Field *tmp_table_field(TABLE *t_arg) { @@ -747,11 +747,11 @@ public: void fix_length_and_dec() { decimals=0; - max_length=8*MY_CHARSET_BIN_MB_MAXLEN; + max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } Field *tmp_table_field(TABLE *t_arg) { - return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); + return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); } }; @@ -769,44 +769,43 @@ public: }; -enum datetime_format +enum date_time_format { USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT }; - -enum datetime_format_types -{ - DATE_FORMAT_TYPE= 0, TIME_FORMAT_TYPE, DATETIME_FORMAT_TYPE -}; - - class Item_func_get_format :public Item_str_func { - const datetime_format_types tm_format; + const timestamp_type type; public: - Item_func_get_format(datetime_format_types type_arg1, Item *a) - :Item_str_func(a), tm_format(type_arg1) {} + Item_func_get_format(timestamp_type type_arg, Item *a) + :Item_str_func(a), type(type_arg) + {} String *val_str(String *str); const char *func_name() const { return "get_format"; } void fix_length_and_dec() { + maybe_null= 1; decimals=0; max_length=17*MY_CHARSET_BIN_MB_MAXLEN; } + void print(String *str); }; -class Item_func_str_to_date :public Item_str_func +class Item_func_str_to_date :public Item_date_func { public: Item_func_str_to_date(Item *a, Item *b) - :Item_str_func(a, b) {} + :Item_date_func(a, b) + {} String *val_str(String *str); + bool get_date(TIME *ltime, uint fuzzy_date); const char *func_name() const { return "str_to_date"; } void fix_length_and_dec() { + maybe_null= 1; decimals=0; - max_length=29*MY_CHARSET_BIN_MB_MAXLEN; + max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f71fca29f56..12c772e7253 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -756,6 +756,13 @@ bool open_log(MYSQL_LOG *log, const char *hostname, /* mysqld.cc */ extern void yyerror(const char*); +/* strfunc.cc */ +ulonglong find_set(TYPELIB *typelib,const char *x, uint length, + char **err_pos, uint *err_len, bool *set_warning); +uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); +uint check_word(TYPELIB *lib, const char *val, const char *end, + const char **end_of_word); + /* External variables */ @@ -849,7 +856,6 @@ extern pthread_attr_t connection_attrib; extern I_List<THD> threads; extern I_List<NAMED_LIST> key_caches; extern MY_BITMAP temp_pool; -extern DATE_FORMAT dayord; extern String my_empty_string; extern String my_null_string; extern SHOW_VAR init_vars[],status_vars[], internal_vars[]; @@ -861,12 +867,8 @@ extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct rand_struct sql_rand; -#define g_datetime_frm(a) (global_system_variables.datetime_formats[(a)]) -#define t_datetime_frm(a, b) ((a)->variables.datetime_formats[(b)]) - -extern const char *datetime_formats[4][5]; -extern const char *opt_datetime_format_names[3]; -extern const char *opt_datetime_formats[3]; +extern const char *opt_date_time_formats[]; +extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; extern String null_string; extern HASH open_cache; @@ -938,23 +940,26 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); void init_time(void); long my_gmt_sec(TIME *, long *current_timezone); -time_t str_to_timestamp(const char *str,uint length, THD *thd); -bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd); -longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd); +time_t str_to_timestamp(const char *str,uint length); +bool str_to_time(const char *str,uint length,TIME *l_time); +longlong str_to_datetime(const char *str,uint length, uint fuzzy_date); timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time, - bool fuzzy_date, THD *thd); + uint flags); void localtime_to_TIME(TIME *to, struct tm *from); void calc_time_from_sec(TIME *to, long seconds, long microseconds); -extern DATETIME_FORMAT *make_format(DATETIME_FORMAT *datetime_format, - datetime_format_types format_type, - const char *format_str, - uint format_length, bool is_alloc); -extern String *make_datetime(String *str, TIME *l_time, - const bool is_time_only, - const bool add_second_frac, - const char *ptr, uint format_length, - bool set_len_to_zero); +extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, + const char *format_str, + uint format_length); +extern DATE_TIME_FORMAT *date_time_format_copy(THD *thd, + DATE_TIME_FORMAT *format); +const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format, + timestamp_type type); +extern bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, + timestamp_type type, String *str); +extern void make_time(DATE_TIME_FORMAT *format, TIME *l_time, String *str); +void make_date(DATE_TIME_FORMAT *format, TIME *l_time, String *str); +void make_datetime(DATE_TIME_FORMAT *format, TIME *l_time, String *str); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index eb632912575..1052eeaf11b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -318,10 +318,7 @@ char mysql_real_data_home[FN_REFLEN], language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; -const char *opt_datetime_formats[3]; -const char *opt_datetime_format_names[3]= {"date_format", - "time_format", - "datetime_format"}; +const char *opt_date_time_formats[3]; char *language_ptr, *default_collation_name, *default_character_set_name; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; @@ -357,7 +354,6 @@ struct system_variables global_system_variables; struct system_variables max_system_variables; MY_TMPDIR mysql_tmpdir_list; -DATE_FORMAT dayord; MY_BITMAP temp_pool; CHARSET_INFO *system_charset_info, *files_charset_info ; @@ -921,9 +917,12 @@ void clean_up(bool print_message) #ifdef USE_RAID end_raid(); #endif - g_datetime_frm(DATE_FORMAT_TYPE).clean(); - g_datetime_frm(TIME_FORMAT_TYPE).clean(); - g_datetime_frm(DATETIME_FORMAT_TYPE).clean(); + my_free((char*) global_system_variables.date_format, + MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*) global_system_variables.time_format, + MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*) global_system_variables.datetime_format, + MYF(MY_ALLOW_ZERO_PTR)); if (defaults_argv) free_defaults(defaults_argv); free_tmpdir(&mysql_tmpdir_list); @@ -2019,33 +2018,46 @@ bool open_log(MYSQL_LOG *log, const char *hostname, } -int init_global_datetime_format(datetime_format_types format_type, bool is_alloc) +/* + Initialize one of the global date/time format variables + + SYNOPSIS + init_global_datetime_format() + format_type What kind of format should be supported + var_ptr Pointer to variable that should be updated + + NOTES + The default value is taken from either opt_date_time_formats[] or + the ISO format (ANSI SQL) + + RETURN + 0 ok + 1 error +*/ + +bool init_global_datetime_format(timestamp_type format_type, + DATE_TIME_FORMAT **var_ptr) { - const char *format_str= opt_datetime_formats[format_type]; - uint format_length= 0; - DATETIME_FORMAT *tmp_format= &g_datetime_frm(format_type).datetime_format; + /* Get command line option */ + const char *str= opt_date_time_formats[format_type]; + DATE_TIME_FORMAT *format; - if (format_str) + if (!str) // No specified format { - format_str= opt_datetime_formats[format_type]; - format_length= strlen(format_str); - } - else - { - format_str= datetime_formats[format_type][ISO_FORMAT]; - format_length= strlen(datetime_formats[format_type][ISO_FORMAT]); - opt_datetime_formats[format_type]= format_str; + str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT], + format_type); + /* + Set the "command line" option to point to the generated string so + that we can set global formats back to default + */ + opt_date_time_formats[format_type]= str; } - if (make_format(tmp_format, format_type, format_str, - format_length, is_alloc)) + if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str)))) { - g_datetime_frm(format_type).name= opt_datetime_format_names[format_type]; - g_datetime_frm(format_type).name_length= - strlen(opt_datetime_format_names[format_type]); - g_datetime_frm(format_type).format_type= format_type; - return 0; + fprintf(stderr, "Wrong date/time format specifier: %s\n", str); + return 1; } - return 1; + return 0; } @@ -2160,17 +2172,12 @@ static int init_common_variables(const char *conf_file_name, int argc, } default_charset_info= default_collation; } - global_system_variables.collation_server= default_charset_info; - global_system_variables.collation_database= default_charset_info; - global_system_variables.collation_connection= default_charset_info; + /* Set collactions that depends on the default collation */ + global_system_variables.collation_server= default_charset_info; + global_system_variables.collation_database= default_charset_info; + global_system_variables.collation_connection= default_charset_info; global_system_variables.character_set_results= default_charset_info; - global_system_variables.character_set_client= default_charset_info; - global_system_variables.collation_connection= default_charset_info; - - if (init_global_datetime_format(DATE_FORMAT_TYPE, 1) || - init_global_datetime_format(TIME_FORMAT_TYPE, 1) || - init_global_datetime_format(DATETIME_FORMAT_TYPE, 1)) - return 1; + global_system_variables.character_set_client= default_charset_info; if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) return 1; @@ -4606,7 +4613,7 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, - "Logs will be rotated after expire-log-days days. ", + "Logs will be rotated after expire-log-days days ", (gptr*) &expire_logs_days, (gptr*) &expire_logs_days, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 99, 0, 1, 0}, @@ -4616,23 +4623,24 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.default_week_format, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0}, { "date-format", OPT_DATE_FORMAT, - "The DATE format.", - (gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE], - (gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE], + "The DATE format (For future).", + (gptr*) &opt_date_time_formats[TIMESTAMP_DATE], + (gptr*) &opt_date_time_formats[TIMESTAMP_DATE], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "datetime-format", OPT_DATETIME_FORMAT, - "The DATETIME/TIMESTAMP format.", - (gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE], - (gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE], + "The DATETIME/TIMESTAMP format (for future).", + (gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], + (gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "time-format", OPT_TIME_FORMAT, - "The TIME format.", - (gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE], - (gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE], + "The TIME format (for future).", + (gptr*) &opt_date_time_formats[TIMESTAMP_TIME], + (gptr*) &opt_date_time_formats[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} }; + struct show_var_st status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, @@ -4944,6 +4952,8 @@ static void mysql_init_variables(void) national_charset_info= &my_charset_utf8_general_ci; table_alias_charset= &my_charset_bin; + opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0; + /* Things with default values that are not zero */ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; opt_specialflag= SPECIAL_ENGLISH; @@ -5001,11 +5011,6 @@ static void mysql_init_variables(void) /* Set default values for some option variables */ - global_system_variables.collation_server= default_charset_info; - global_system_variables.collation_database= default_charset_info; - global_system_variables.collation_connection= default_charset_info; - global_system_variables.character_set_results= default_charset_info; - global_system_variables.character_set_client= default_charset_info; global_system_variables.table_type= DB_TYPE_MYISAM; global_system_variables.tx_isolation= ISO_REPEATABLE_READ; global_system_variables.select_limit= (ulonglong) HA_POS_ERROR; @@ -5014,10 +5019,6 @@ static void mysql_init_variables(void) max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; global_system_variables.old_passwords= 0; - init_global_datetime_format(DATE_FORMAT_TYPE, 0); - init_global_datetime_format(TIME_FORMAT_TYPE, 0); - init_global_datetime_format(DATETIME_FORMAT_TYPE, 0); - /* Variables that depends on compile options */ #ifndef DBUG_OFF default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", @@ -5626,7 +5627,7 @@ static void get_options(int argc,char **argv) exit(ho_error); if (argc > 0) { - fprintf(stderr, "%s: Too many arguments.\nUse --help to get a list of available options\n", my_progname); + fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv); exit(ho_error); } @@ -5681,6 +5682,15 @@ static void get_options(int argc,char **argv) opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT; if (opt_log_queries_not_using_indexes) opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES; + + if (init_global_datetime_format(TIMESTAMP_DATE, + &global_system_variables.date_format) || + init_global_datetime_format(TIMESTAMP_TIME, + &global_system_variables.time_format) || + init_global_datetime_format(TIMESTAMP_DATETIME, + &global_system_variables.datetime_format)) + exit(1); + /* Set up default values for a key cache */ KEY_CACHE_VAR *key_cache= &dflt_key_cache_var; dflt_key_cache_block_size= key_cache->block_size; diff --git a/sql/protocol.cc b/sql/protocol.cc index 0fe759cff67..d7a745d371d 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -833,12 +833,17 @@ bool Protocol_simple::store(TIME *tm) field_pos++; #endif char buff[40]; - String tmp((char*) buff,sizeof(buff),&my_charset_bin); - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (current_thd, DATETIME_FORMAT_TYPE).datetime_format); - make_datetime(&tmp, tm, 1, tm->second_part, - tmp_format->format, tmp_format->format_length, 1); - return net_store_data((char*) tmp.ptr(), tmp.length()); + uint length; + length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d", + (int) tm->year, + (int) tm->month, + (int) tm->day, + (int) tm->hour, + (int) tm->minute, + (int) tm->second)); + if (tm->second_part) + length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part)); + return net_store_data((char*) buff, length); } @@ -851,10 +856,7 @@ bool Protocol_simple::store_date(TIME *tm) #endif char buff[40]; String tmp((char*) buff,sizeof(buff),&my_charset_bin); - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (current_thd, DATE_FORMAT_TYPE).datetime_format); - make_datetime(&tmp, tm, 1, 0, - tmp_format->format, tmp_format->format_length, 1); + make_date((DATE_TIME_FORMAT *) 0, tm, &tmp); return net_store_data((char*) tmp.ptr(), tmp.length()); } @@ -873,14 +875,16 @@ bool Protocol_simple::store_time(TIME *tm) field_pos++; #endif char buff[40]; - String tmp((char*) buff,sizeof(buff),&my_charset_bin); - DATETIME_FORMAT *tmp_format= (&t_datetime_frm - (current_thd, TIME_FORMAT_TYPE).datetime_format); + uint length; uint day= (tm->year || tm->month) ? 0 : tm->day; - tm->hour= (long) day*24L+(long) tm->hour; - make_datetime(&tmp, tm, 0, tm->second_part, - tmp_format->format, tmp_format->format_length, 1); - return net_store_data((char*) tmp.ptr(), tmp.length()); + length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", + tm->neg ? "-" : "", + (long) day*24L+(long) tm->hour, + (int) tm->minute, + (int) tm->second)); + if (tm->second_part) + length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part)); + return net_store_data((char*) buff, length); } diff --git a/sql/set_var.cc b/sql/set_var.cc index 66c8ef87d5a..8d64a684476 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -299,14 +299,25 @@ sys_var_thd_ulong sys_tmp_table_size("tmp_table_size", &SV::tmp_table_size); sys_var_thd_ulong sys_net_wait_timeout("wait_timeout", &SV::net_wait_timeout); - + #ifdef HAVE_INNOBASE_DB sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct", &srv_max_buf_pool_modified_pct); #endif -/* - Variables that are bits in THD -*/ + +/* Time/date/datetime formats */ + +sys_var_thd_date_time_format sys_time_format("time_format", + &SV::time_format, + TIMESTAMP_TIME); +sys_var_thd_date_time_format sys_date_format("date_format", + &SV::date_format, + TIMESTAMP_DATE); +sys_var_thd_date_time_format sys_datetime_format("datetime_format", + &SV::datetime_format, + TIMESTAMP_DATETIME); + +/* Variables that are bits in THD */ static sys_var_thd_bit sys_autocommit("autocommit", set_option_autocommit, @@ -413,9 +424,8 @@ sys_var *sys_variables[]= &sys_collation_server, &sys_concurrent_insert, &sys_connect_timeout, - &g_datetime_frm(DATE_FORMAT_TYPE), - &g_datetime_frm(DATETIME_FORMAT_TYPE), - &g_datetime_frm(TIME_FORMAT_TYPE), + &sys_date_format, + &sys_datetime_format, &sys_default_week_format, &sys_delay_key_write, &sys_delayed_insert_limit, @@ -485,6 +495,7 @@ sys_var *sys_variables[]= &sys_rand_seed1, &sys_rand_seed2, &sys_range_alloc_block_size, + &sys_readonly, &sys_read_buff_size, &sys_read_rnd_buff_size, #ifdef HAVE_REPLICATION @@ -500,7 +511,6 @@ sys_var *sys_variables[]= &sys_slave_net_timeout, &sys_slave_skip_counter, #endif - &sys_readonly, &sys_slow_launch_time, &sys_sort_buffer, &sys_sql_big_tables, @@ -511,6 +521,7 @@ sys_var *sys_variables[]= &sys_table_cache_size, &sys_table_type, &sys_thread_cache_size, + &sys_time_format, &sys_timestamp, &sys_tmp_table_size, &sys_trans_alloc_block_size, @@ -556,9 +567,9 @@ struct show_var_st init_vars[]= { {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {"datadir", mysql_real_data_home, SHOW_CHAR}, - {"date_format", (char*) &g_datetime_frm(DATE_FORMAT_TYPE), SHOW_SYS}, - {"datetime_format", (char*) &g_datetime_frm(DATETIME_FORMAT_TYPE), SHOW_SYS}, - {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, + {sys_date_format.name, (char*) &sys_date_format, SHOW_SYS}, + {sys_datetime_format.name, (char*) &sys_datetime_format, SHOW_SYS}, + {sys_default_week_format.name, (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS}, @@ -720,7 +731,7 @@ struct show_var_st init_vars[]= { #endif {"thread_stack", (char*) &thread_stack, SHOW_LONG}, {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS}, - {"time_format", (char*) &g_datetime_frm(TIME_FORMAT_TYPE), SHOW_SYS}, + {sys_time_format.name, (char*) &sys_time_format, SHOW_SYS}, #ifdef HAVE_TZNAME {"timezone", time_zone, SHOW_CHAR}, #endif @@ -744,71 +755,6 @@ bool sys_var::check(THD *thd, set_var *var) /* Functions to check and update variables */ -char *update_datetime_format(THD *thd, enum enum_var_type type, - enum datetime_format_types format_type, - DATETIME_FORMAT *tmp_format) -{ - char *old_value; - if (type == OPT_GLOBAL) - { - pthread_mutex_lock(&LOCK_global_system_variables); - old_value= g_datetime_frm(format_type).datetime_format.format; - g_datetime_frm(format_type).datetime_format= *tmp_format; - pthread_mutex_unlock(&LOCK_global_system_variables); - } - else - { - old_value= t_datetime_frm(thd,format_type).datetime_format.format; - t_datetime_frm(thd, format_type).datetime_format= *tmp_format; - } - return old_value; -} - - -bool sys_var_datetime_format::update(THD *thd, set_var *var) -{ - DATETIME_FORMAT tmp_format; - char *old_value; - uint new_length; - - if ((new_length= var->value->str_value.length())) - { - if (!make_format(&tmp_format, format_type, - var->value->str_value.ptr(), - new_length, 1)) - return 1; - } - - old_value= update_datetime_format(thd, var->type, format_type, &tmp_format); - my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); - return 0; -} - -byte *sys_var_datetime_format::value_ptr(THD *thd, enum_var_type type, - LEX_STRING *base) -{ - if (type == OPT_GLOBAL) - return (byte*) g_datetime_frm(format_type).datetime_format.format; - return (byte*) t_datetime_frm(thd, format_type).datetime_format.format; -} - -void sys_var_datetime_format::set_default(THD *thd, enum_var_type type) -{ - DATETIME_FORMAT tmp_format; - char *old_value; - uint new_length; - - if ((new_length= strlen(opt_datetime_formats[format_type]))) - { - if (!make_format(&tmp_format, format_type, - opt_datetime_formats[format_type], - new_length, 1)) - return; - } - - old_value= update_datetime_format(thd, type, format_type, &tmp_format); - my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); -} /* The following 3 functions need to be changed in 4.1 when we allow @@ -1226,8 +1172,8 @@ bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) { if (!(res=var->value->val_str(&str)) || ((long) (var->save_result.ulong_value= - (ulong) find_type(res->c_ptr(), enum_names, 3)-1)) - < 0) + (ulong) find_type(enum_names, res->ptr(), + res->length(),1)-1)) < 0) { value= res ? res->c_ptr() : "NULL"; goto err; @@ -1341,8 +1287,12 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type, base),1); case SHOW_CHAR: { + Item_string *tmp; + pthread_mutex_lock(&LOCK_global_system_variables); char *str= (char*) value_ptr(thd, var_type, base); - return new Item_string(str, strlen(str), system_charset_info); + tmp= new Item_string(str, strlen(str), system_charset_info); + pthread_mutex_unlock(&LOCK_global_system_variables); + return tmp; } default: net_printf(thd, ER_VAR_CANT_BE_READ, name); @@ -1401,6 +1351,112 @@ byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type, } +/* Update a date_time format variable based on given value */ + +void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type, + DATE_TIME_FORMAT *new_value) +{ + DATE_TIME_FORMAT *old; + DBUG_ENTER("sys_var_date_time_format::update2"); + DBUG_DUMP("positions",(char*) new_value->positions, + sizeof(new_value->positions)); + + if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + old= (global_system_variables.*offset); + (global_system_variables.*offset)= new_value; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + { + old= (thd->variables.*offset); + (thd->variables.*offset)= new_value; + } + my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR)); + DBUG_VOID_RETURN; +} + + +bool sys_var_thd_date_time_format::update(THD *thd, set_var *var) +{ + DATE_TIME_FORMAT *new_value; + /* We must make a copy of the last value to get it into normal memory */ + new_value= date_time_format_copy((THD*) 0, + var->save_result.date_time_format); + if (!new_value) + return 1; // Out of memory + update2(thd, var->type, new_value); // Can't fail + return 0; +} + + +bool sys_var_thd_date_time_format::check(THD *thd, set_var *var) +{ + char buff[80]; + String str(buff,sizeof(buff), system_charset_info), *res; + DATE_TIME_FORMAT *format; + + if (!(res=var->value->val_str(&str))) + res= &my_empty_string; + + if (!(format= date_time_format_make(date_time_type, + res->ptr(), res->length()))) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr()); + return 1; + } + + /* + We must copy result to thread space to not get a memory leak if + update is aborted + */ + var->save_result.date_time_format= date_time_format_copy(thd, format); + my_free((char*) format, MYF(0)); + return var->save_result.date_time_format == 0; +} + + +void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type) +{ + DATE_TIME_FORMAT *res= 0; + + if (type == OPT_GLOBAL) + { + const char *format; + if ((format= opt_date_time_formats[date_time_type])) + res= date_time_format_make(date_time_type, format, strlen(format)); + } + else + { + /* Make copy with malloc */ + res= date_time_format_copy((THD *) 0, global_system_variables.*offset); + } + + if (res) // Should always be true + update2(thd, type, res); +} + + +byte *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + if (type == OPT_GLOBAL) + { + char *res; + /* + We do a copy here just to be sure things will work even if someone + is modifying the original string while the copy is accessed + (Can't happen now in SQL SHOW, but this is a good safety for the future) + */ + res= thd->strmake((global_system_variables.*offset)->format.str, + (global_system_variables.*offset)->format.length); + return (byte*) res; + } + return (byte*) (thd->variables.*offset)->format.str; +} + + typedef struct old_names_map_st { const char *old_name; @@ -1409,17 +1465,17 @@ typedef struct old_names_map_st static my_old_conv old_conv[]= { - { "cp1251_koi8" , "cp1251" }, - { "cp1250_latin2" , "cp1250" }, - { "kam_latin2" , "keybcs2" }, - { "mac_latin2" , "MacRoman" }, - { "macce_latin2" , "MacCE" }, - { "pc2_latin2" , "pclatin2" }, - { "vga_latin2" , "pclatin1" }, - { "koi8_cp1251" , "koi8r" }, - { "win1251ukr_koi8_ukr" , "win1251ukr" }, - { "koi8_ukr_win1251ukr" , "koi8u" }, - { NULL , NULL } + { "cp1251_koi8" , "cp1251" }, + { "cp1250_latin2" , "cp1250" }, + { "kam_latin2" , "keybcs2" }, + { "mac_latin2" , "MacRoman" }, + { "macce_latin2" , "MacCE" }, + { "pc2_latin2" , "pclatin2" }, + { "vga_latin2" , "pclatin1" }, + { "koi8_cp1251" , "koi8r" }, + { "win1251ukr_koi8_ukr" , "win1251ukr" }, + { "koi8_ukr_win1251ukr" , "koi8u" }, + { NULL , NULL } }; CHARSET_INFO *get_old_charset_by_name(const char *name) diff --git a/sql/set_var.h b/sql/set_var.h index 16b2c1d5d37..c799eec750a 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -54,8 +54,6 @@ public: const char *name; sys_after_update_func after_update; - sys_var() - {} sys_var(const char *name_arg) :name(name_arg),after_update(0) {} sys_var(const char *name_arg,sys_after_update_func func) @@ -195,9 +193,6 @@ public: class sys_var_thd :public sys_var { public: - sys_var_thd() - :sys_var() - {} sys_var_thd(const char *name_arg) :sys_var(name_arg) {} @@ -621,46 +616,26 @@ public: }; -class sys_var_datetime_format :public sys_var_thd +class sys_var_thd_date_time_format :public sys_var_thd { + DATE_TIME_FORMAT *SV::*offset; + enum timestamp_type date_time_type; public: - enum datetime_format_types format_type; - DATETIME_FORMAT datetime_format; - sys_var_datetime_format(): sys_var_thd() + sys_var_thd_date_time_format(const char *name_arg, + DATE_TIME_FORMAT *SV::*offset_arg, + timestamp_type date_time_type_arg) + :sys_var_thd(name_arg), offset(offset_arg), + date_time_type(date_time_type_arg) {} - - void clean() - { - my_free(datetime_format.format, MYF(MY_ALLOW_ZERO_PTR)); - datetime_format.format=0; - } - - /* - It's for copying of global_system_variables structure - in THD constructor. - */ - inline sys_var_datetime_format& operator= (sys_var_datetime_format& s) - { - if (&s != this) - { - name= s.name; name_length= s.name_length; - datetime_format= s.datetime_format; - datetime_format.format= (my_strdup_with_length - (s.datetime_format.format, - s.datetime_format. - format_length, MYF(0))); - format_type= s.format_type; - } - return *this; - } - SHOW_TYPE type() { return SHOW_CHAR; } bool check_update_type(Item_result type) { return type != STRING_RESULT; /* Only accept strings */ } bool check_default(enum_var_type type) { return 0; } + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); + void update2(THD *thd, enum_var_type type, DATE_TIME_FORMAT *new_value); byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); void set_default(THD *thd, enum_var_type type); }; @@ -718,6 +693,7 @@ public: CHARSET_INFO *charset; ulong ulong_value; ulonglong ulonglong_value; + DATE_TIME_FORMAT *date_time_format; } save_result; LEX_STRING base; /* for structs */ diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 2176fcbd441..c01df3b53cd 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -276,21 +276,26 @@ character-set=latin2 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 791060ac744..e67c430c4f7 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -270,21 +270,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 62e210f1016..5f77163eeda 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -278,21 +278,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index a0d746ce0ca..baecefb8494 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -252,36 +252,41 @@ character-set=latin1 "Reference '%-.64s' not supported (%s)", "Every derived table must have it's own alias", "Select %u was reduced during optimisation", -"Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server; consider upgrading MySQL client" -"All parts of a SPATIAL KEY must be NOT NULL" -"COLLATION '%s' is not valid for CHARACTER SET '%s'" -"Slave is already running" -"Slave has already been stopped" -"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)" -"Z_MEM_ERROR: Not enough memory available for zlib" -"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)" -"Z_DATA_ERROR: Input data was corrupted for zlib" -"%d line(s) was(were) cut by group_concat()" +"Table '%-.64s' from one of SELECT's can not be used in %-.32s", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", +"All parts of a SPATIAL KEY must be NOT NULL", +"COLLATION '%s' is not valid for CHARACTER SET '%s'", +"Slave is already running", +"Slave has already been stopped", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"ZLIB: Not enough memory available for zlib", +"ZLIB: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"ZLIB: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s'@'%s' has a password in the old format; please change the password to the new format", +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL. Otherwise you will get problems if you get an unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 0510e3fc76b..09e63ddd804 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -272,21 +272,26 @@ character-set=latin7 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 485cbe45724..0956db6681e 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -267,21 +267,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index c9760879f3c..2cc98971915 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -293,7 +293,12 @@ character-set=latin1 "Feld oder Verweis '%-.64s%s%-.64s%s%-.64s' im SELECT-Befehl Nr. %d wurde im SELECT-Befehl Nr. %d aufgelöst", "Falscher Parameter oder falsche Kombination von Parametern für START SLAVE UNTIL", "Es wird empfohlen, mit --skip-slave-start zu starten, wenn mit START SLAVE UNTIL eine Schritt-für-Schritt-Replikation ausgeführt wird. Ansonsten gibt es Probleme, wenn der Slave-Server unerwartet neu startet", -"SQL-Thread soll nicht gestartet werden. Daher werden UNTIL-Optionen ignoriert" -"Incorrect index name '%-.100s'", +"SQL-Thread soll nicht gestartet werden. Daher werden UNTIL-Optionen ignoriert", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 90ab24610ff..84e48d2f284 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -267,21 +267,26 @@ character-set=greek "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index c456e9580b3..da71f4b7da6 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -269,21 +269,26 @@ character-set=latin2 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 09b533c0fb7..f960c6c043d 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -267,21 +267,27 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", + diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 15b8640cb29..d28cc026159 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -269,21 +269,26 @@ character-set=ujis "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index d31efc94d46..c5f2b8d59ba 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -267,21 +267,27 @@ character-set=euckr "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", + diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 515a322f136..1e9028de1d7 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -269,21 +269,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index faea5402fc6..d0a5e27b5c1 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -269,21 +269,27 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", + diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2a7ea3accb8..17e6df6c443 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -271,21 +271,26 @@ character-set=latin2 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 1f3bbb5c02f..fdf428c9b6d 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -241,7 +241,7 @@ character-set=latin1 "Errado uso/colocação de '%s'", "Esta versão de MySQL não suporta ainda '%s'", "Obteve fatal erro %d: '%-.128s' do master quando lendo dados do binary log", -"Slave SQL thread ignorado a consulta devido às normas de replicação-*-tabela" +"Slave SQL thread ignorado a consulta devido às normas de replicação-*-tabela", "Definição errada da chave estrangeira para '%-.64s': %s", "Referência da chave e referência da tabela não coincidem", "Operand should contain %d column(s)", @@ -268,21 +268,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Usando engine de armazenamento %s para tabela '%s'", "Combinação ilegal de collations (%s,%s) e (%s,%s) para operação '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 78daafe04d1..8f4fdb3a702 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -252,7 +252,7 @@ character-set=latin2 "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", "Every derived table must have it's own alias", "Select %u was reduced during optimisation", @@ -271,21 +271,26 @@ character-set=latin2 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 462afdfa782..2ef6a2c553b 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -269,21 +269,26 @@ character-set=koi8r "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"óÅÒ×ÅÒ ÚÁÐÕÝÅÎ × ÒÅÖÉÍÅ --secure-auth (ÂÅÚÏÐÁÓÎÏÊ Á×ÔÏÒÉÚÁÃÉÉ), ÎÏ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%s@%s' ÐÁÒÏÌØ ÓÏÈÒÁÎ£Î × ÓÔÁÒÏÍ ÆÏÒÍÁÔÅ; ÎÅÏÂÈÏÄÉÍÏ ÏÂÎÏ×ÉÔØ ÆÏÒÍÁÔ ÐÁÒÏÌÑ" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"óÅÒ×ÅÒ ÚÁÐÕÝÅÎ × ÒÅÖÉÍÅ --secure-auth (ÂÅÚÏÐÁÓÎÏÊ Á×ÔÏÒÉÚÁÃÉÉ), ÎÏ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%s@%s' ÐÁÒÏÌØ ÓÏÈÒÁÎ£Î × ÓÔÁÒÏÍ ÆÏÒÍÁÔÅ; ÎÅÏÂÈÏÄÉÍÏ ÏÂÎÏ×ÉÔØ ÆÏÒÍÁÔ ÐÁÒÏÌÑ", "ðÏÌÅ ÉÌÉ ÓÓÙÌËÁ '%-.64s%s%-.64s%s%-.64s' ÉÚ SELECTÁ #%d ÂÙÌÁ ÎÁÊÄÅÎÁ × SELECTÅ #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "ëÅÛ ÚÁÐÒÏÓÏ× ÎÅ ÍÏÖÅÔ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÍÅÒ %lu, ÎÏ×ÙÊ ÒÁÚÍÅÒ ËÅÛÁ ÚÐÒÏÓÏ× - %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 9d12654f150..cddc1059f44 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -262,21 +262,26 @@ character-set=cp1250 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index dd222c2ef30..466e7d478b6 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -275,21 +275,26 @@ character-set=latin2 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index a21d306a3db..de8a245c7f9 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -242,7 +242,7 @@ character-set=latin1 "Equivocado uso/colocación de '%s'", "Esta versión de MySQL no soporta todavia '%s'", "Recibió fatal error %d: '%-.128s' del master cuando leyendo datos del binary log", -"Slave SQL thread ignorado el query debido a las reglas de replicación-*-tabla" +"Slave SQL thread ignorado el query debido a las reglas de replicación-*-tabla", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -269,21 +269,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 4d3e69a5b0f..d8695db30a4 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -225,7 +225,7 @@ character-set=latin1 "Fick fel vid utförande av command på mastern: %-.128s", "Fick fel vid utförande av %s: %-.128s", "Felaktig använding av %s and %s", -"SELECT-kommandona har olika antal kolumner" +"SELECT-kommandona har olika antal kolumner", "Kan inte utföra kommandot emedan du har ett READ-lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Option '%s' användes två gånger", @@ -267,21 +267,26 @@ character-set=latin1 "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Använder handler %s för tabell '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "Field or reference '%-.64s%s%-.64s%s%-.64s' of SELECT #%d was resolved in SELECT #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", -"Query cache failed to set size %lu, new query cache size is %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Felaktigt %s namn '%-.100s'", +"tabell", +"databas", +"kolumn", +"index", +"katalog", +"Storleken av "Query cache" kunde inte sättas till %lu, ny storlek är %lu", +"Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 283700b7891..3a37ee02731 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -272,21 +272,26 @@ character-set=koi8u "Record count is more than the column count at row %ld"; "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; "Data truncated, out of range for column '%s' at row %ld"; -"Data truncated for column '%s' at row %ld" +"Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users" -"Can't revoke all privileges, grant for one or more of the requested users" +"Can't drop one or more of the requested users", +"Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", -"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started." -"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" +"SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support. They can be used later when MySQL slave with SSL will be started.", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format", "óÔÏ×ÂÅÃØ ÁÂÏ ÐÏÓÉÌÁÎÎÑ '%-.64s%s%-.64s%s%-.64s' ¦Ú SELECTÕ #%d ÂÕÌÏ ÚÎÁÊÄÅÎÅ Õ SELECT¦ #%d", -"Wrong parameter or combination of parameters for START SLAVE UNTIL" -"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" -"SQL thread is not to be started so UNTIL options are ignored" -"Incorrect index name '%-.100s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL", +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", +"SQL thread is not to be started so UNTIL options are ignored", +"Incorrect %s name '%-.100s'", +"table", +"database", +"column", +"index", +"catalog", "ëÅÛ ÚÁÐÉÔ¦× ÎÅÓÐÒÏÍÏÖÅÎ ×ÓÔÁÎÏ×ÉÔÉ ÒÏÚÍ¦Ò %lu, ÎÏ×ÉÊ ÒÏÚÍ¦Ò ËÅÛÁ ÚÁÐÉÔ¦× - %lu", -"Column '%-.64s' cannot be part of FULLTEXT index" +"Column '%-.64s' cannot be part of FULLTEXT index", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index cc068451ecf..88a1d21354b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2210,7 +2210,8 @@ void get_key_map_from_key_list(key_map *map, TABLE *table, map->clear_all(); while ((name=it++)) { - if ((pos=find_type(name->c_ptr(), &table->keynames, 1+2)) <= 0) + if ((pos= find_type(&table->keynames, name->ptr(), name->length(), 1)) <= + 0) { my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), table->real_name); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ed8eaba9128..ed01e1bb038 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -210,6 +210,12 @@ void THD::init(void) { pthread_mutex_lock(&LOCK_global_system_variables); variables= global_system_variables; + variables.time_format= date_time_format_copy((THD*) 0, + variables.time_format); + variables.date_format= date_time_format_copy((THD*) 0, + variables.date_format); + variables.datetime_format= date_time_format_copy((THD*) 0, + variables.datetime_format); pthread_mutex_unlock(&LOCK_global_system_variables); server_status= SERVER_STATUS_AUTOCOMMIT; options= thd_startup_options; @@ -281,9 +287,9 @@ void THD::cleanup(void) close_thread_tables(this); } close_temporary_tables(this); - variables.datetime_formats[DATE_FORMAT_TYPE].clean(); - variables.datetime_formats[TIME_FORMAT_TYPE].clean(); - variables.datetime_formats[DATETIME_FORMAT_TYPE].clean(); + my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR)); delete_dynamic(&user_var_events); hash_free(&user_vars); if (global_read_lock) diff --git a/sql/sql_class.h b/sql/sql_class.h index a103bab1d6c..c66ebb77020 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -421,7 +421,11 @@ struct system_variables CHARSET_INFO *collation_server; CHARSET_INFO *collation_database; CHARSET_INFO *collation_connection; - sys_var_datetime_format datetime_formats[3]; + + /* DATE, DATETIME and TIME formats */ + DATE_TIME_FORMAT *date_format; + DATE_TIME_FORMAT *datetime_format; + DATE_TIME_FORMAT *time_format; }; void free_tmp_table(THD *thd, TABLE *entry); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b0f4b4ef574..b7d6c642398 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -609,7 +609,7 @@ bool mysql_change_db(THD *thd, const char *name) } if ((db_length > NAME_LEN) || check_db_name(dbname)) { - net_printf(thd,ER_WRONG_DB_NAME, dbname); + net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -675,7 +675,7 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - net_printf(thd,ER_WRONG_DB_NAME, dbname); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), dbname); DBUG_RETURN(1); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 93c4658d38c..a55b801a0fc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -40,10 +40,18 @@ LEX_STRING tmp_table_alias= {(char*) "tmp-table",8}; pthread_key(LEX*,THR_LEX); +/* Longest standard keyword name */ #define TOCK_NAME_LENGTH 24 /* - The following is based on the latin1 character set, and is only + Map to default keyword characters. This is used to test if an identifer + is 'simple', in which case we don't have to do any character set conversions + on it +*/ +uchar *bin_ident_map= my_charset_bin.ident_map; + +/* + The following data is based on the latin1 character set, and is only used when comparing keywords */ @@ -66,6 +74,7 @@ uchar to_upper_lex[] = { 208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255 }; + inline int lex_casecmp(const char *s, const char *t, uint len) { while (len-- != 0 && @@ -410,15 +419,18 @@ inline static uint int_token(const char *str,uint length) } -// yylex remember the following states from the following yylex() -// MY_LEX_EOQ ; found end of query -// MY_LEX_OPERATOR_OR_IDENT ; last state was an ident, text or number -// (which can't be followed by a signed number) +/* + yylex remember the following states from the following yylex() + + - MY_LEX_EOQ Found end of query + - MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number + (which can't be followed by a signed number) +*/ int yylex(void *arg, void *yythd) { reg1 uchar c; - int tokval; + int tokval, result_state; uint length; enum my_lex_states state,prev_state; LEX *lex= &(((THD *)yythd)->lex); @@ -503,6 +515,7 @@ int yylex(void *arg, void *yythd) #if defined(USE_MB) && defined(USE_MB_IDENT) if (use_mb(cs)) { + result_state= IDENT_QUOTED; if (my_mbcharlen(cs, yyGetLast()) > 1) { int l = my_ismbchar(cs, @@ -529,7 +542,15 @@ int yylex(void *arg, void *yythd) } else #endif - while (ident_map[c=yyGet()]) ; + { + result_state= bin_ident_map[c] ? IDENT : IDENT_QUOTED; + while (ident_map[c=yyGet()]) + { + /* If not simple character, mark that we must convert it */ + if (!bin_ident_map[c]) + result_state= IDENT_QUOTED; + } + } length= (uint) (lex->ptr - lex->tok_start)-1; if (lex->ignore_space) { @@ -560,8 +581,7 @@ int yylex(void *arg, void *yythd) (lex->charset=get_charset_by_csname(yylval->lex_str.str+1, MY_CS_PRIMARY,MYF(0)))) return(UNDERSCORE_CHARSET); - else - return(IDENT); + return(result_state); // IDENT or IDENT_QUOTED case MY_LEX_IDENT_SEP: // Found ident and now '.' yylval->lex_str.str=(char*) lex->ptr; @@ -611,21 +631,11 @@ int yylex(void *arg, void *yythd) } // fall through case MY_LEX_IDENT_START: // We come here after '.' + result_state= IDENT; #if defined(USE_MB) && defined(USE_MB_IDENT) if (use_mb(cs)) { - if (my_mbcharlen(cs, yyGetLast()) > 1) - { - int l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query); - if (l == 0) - { - state = MY_LEX_CHAR; - continue; - } - lex->ptr += l - 1; - } + result_state= IDENT_QUOTED; while (ident_map[c=yyGet()]) { if (my_mbcharlen(cs, c) > 1) @@ -641,15 +651,17 @@ int yylex(void *arg, void *yythd) } else #endif - while (ident_map[c = yyGet()]) ; - + while (ident_map[c = yyGet()]) + { + /* If not simple character, mark that we must convert it */ + if (!bin_ident_map[c]) + result_state= IDENT_QUOTED; + } if (c == '.' && ident_map[yyPeek()]) lex->next_state=MY_LEX_IDENT_SEP;// Next is '.' - // fall through - case MY_LEX_FOUND_IDENT: // Complete ident - yylval->lex_str=get_token(lex,yyLength()); - return(IDENT); + yylval->lex_str= get_token(lex,yyLength()); + return(result_state); case MY_LEX_USER_VARIABLE_DELIMITER: { @@ -699,7 +711,7 @@ int yylex(void *arg, void *yythd) if (c == delim) yySkip(); // Skip end ` lex->next_state= MY_LEX_START; - return(IDENT); + return(IDENT_QUOTED); } case MY_LEX_INT_OR_REAL: // Compleat int or incompleat real if (c != '.') @@ -924,7 +936,13 @@ int yylex(void *arg, void *yythd) We should now be able to handle: [(global | local | session) .]variable_name */ - while (ident_map[c=yyGet()]) ; + result_state= IDENT; + while (ident_map[c=yyGet()]) + { + /* If not simple character, mark that we must convert it */ + if (!bin_ident_map[c]) + result_state= IDENT_QUOTED; + } if (c == '.') lex->next_state=MY_LEX_IDENT_SEP; length= (uint) (lex->ptr - lex->tok_start)-1; @@ -934,7 +952,7 @@ int yylex(void *arg, void *yythd) return(tokval); // Was keyword } yylval->lex_str=get_token(lex,length); - return(IDENT); + return(result_state); } } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f377714461d..d6f8e2f66c7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1041,7 +1041,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1382,7 +1382,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1398,7 +1398,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) @@ -1999,7 +1999,7 @@ mysql_execute_command(THD *thd) #endif if (strlen(tables->real_name) > NAME_LEN) { - net_printf(thd,ER_WRONG_TABLE_NAME,tables->real_name); + net_printf(thd,ER_WRONG_NAME, ER(ER_TABLE), tables->real_name); break; } LOCK_ACTIVE_MI; @@ -2044,7 +2044,7 @@ mysql_execute_command(THD *thd) #endif if (strlen(tables->real_name) > NAME_LEN) { - net_printf(thd, ER_WRONG_TABLE_NAME, tables->alias); + net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), tables->alias); res=0; break; } @@ -2176,7 +2176,7 @@ mysql_execute_command(THD *thd) ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - net_printf(thd,ER_WRONG_TABLE_NAME,lex->name); + net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), lex->name); res=0; break; } @@ -2750,7 +2750,7 @@ mysql_execute_command(THD *thd) remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db); goto error; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -2915,7 +2915,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), lex->name); break; } /* @@ -2943,7 +2943,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), lex->name); break; } /* @@ -2976,7 +2976,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), lex->name); break; } if (check_access(thd,ALTER_ACL,lex->name,0,1,0)) @@ -2993,7 +2993,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), lex->name); break; } if (check_access(thd,DROP_ACL,lex->name,0,1,0)) @@ -4059,7 +4059,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { char *not_used; uint not_used2; - bool not_used3; + bool not_used3; thd->cuted_fields=0; String str,*res; @@ -4089,7 +4089,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { String str,*res; res=default_value->val_str(&str); - if (!find_enum(interval,res->ptr(),res->length())) + res->strip_sp(); + if (!find_type(interval, res->ptr(), res->length(), 0)) { net_printf(thd,ER_INVALID_DEFAULT,field_name); DBUG_RETURN(1); @@ -4242,7 +4243,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - net_printf(thd,ER_WRONG_TABLE_NAME,table->table.str); + net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), table->table.str); DBUG_RETURN(0); } @@ -4596,7 +4597,7 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 || !test_if_hard_path(*filename_ptr)) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr); + my_error(ER_WRONG_NAME, MYF(0), ER(ER_TABLE), *filename_ptr); return 1; } /* Fix is using unix filename format on dos */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index da62fc0a262..2fa08e2d649 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -332,7 +332,7 @@ SETUP_PARAM_FUNCTION(setup_param_datetime) tm.day= (uint) to[3]; tm.neg= 0; - param->set_time(&tm, TIMESTAMP_FULL); + param->set_time(&tm, TIMESTAMP_DATETIME); } *pos+= length; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1a2021abf90..d2d1926ea06 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -437,7 +437,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (check_column_name(sql_field->field_name)) { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); + my_error(ER_WRONG_NAME, MYF(0), ER(ER_COLUMN), sql_field->field_name); DBUG_RETURN(-1); } @@ -888,7 +888,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!key_info->name || check_column_name(key_info->name)) { - my_error(ER_WRONG_INDEX_NAME, MYF(0), key_info->name); + my_error(ER_WRONG_NAME, MYF(0), ER(ER_INDEX), key_info->name); DBUG_RETURN(-1); } if (!(key_info->flags & HA_NULL_PART_KEY)) @@ -1777,7 +1777,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, check_table_name(src_table,table_ident->table.length)) || table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); + my_error(ER_WRONG_NAME, MYF(0), ER(ER_TABLE), src_table); DBUG_RETURN(-1); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2036d13232f..bb37c58004f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -78,7 +78,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) CHARSET_INFO *charset; thr_lock_type lock_type; interval_type interval; - datetime_format_types datetime_format_type; + timestamp_type date_time_type; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; } @@ -246,6 +246,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token HIGH_PRIORITY %token HOSTS_SYM %token IDENT +%token IDENT_QUOTED %token IGNORE_SYM %token IMPORT %token INDEX @@ -584,8 +585,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %right BINARY COLLATE_SYM %type <lex_str> - IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME - ULONGLONG_NUM field_ident select_alias ident ident_or_text + IDENT IDENT_QUOTED TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM + LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component @@ -648,7 +649,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC UDA_CHAR_SUM UDA_FLOAT_SUM UDA_INT_SUM -%type <datetime_format_type> datetime_format_type; +%type <date_time_type> date_time_type; %type <interval> interval %type <db_type> table_types @@ -2631,7 +2632,7 @@ simple_expr: { $$= new Item_func_spatial_collection(* $3, Geometry::wkbGeometryCollection, Geometry::wkbPoint); } - | GET_FORMAT '(' datetime_format_type ',' expr ')' + | GET_FORMAT '(' date_time_type ',' expr ')' { $$= new Item_func_get_format($3, $5); } | HOUR_SYM '(' expr ')' { $$= new Item_func_hour($3); } @@ -3254,10 +3255,10 @@ interval: | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } | YEAR_SYM { $$=INTERVAL_YEAR; }; -datetime_format_type: - DATE_SYM {$$=DATE_FORMAT_TYPE;} - | TIME_SYM {$$=TIME_FORMAT_TYPE;} - | DATETIME {$$=DATETIME_FORMAT_TYPE;}; +date_time_type: + DATE_SYM {$$=TIMESTAMP_DATE;} + | TIME_SYM {$$=TIMESTAMP_TIME;} + | DATETIME {$$=TIMESTAMP_DATETIME;}; table_alias: /* empty */ @@ -4479,15 +4480,16 @@ table_ident: /* For Delphi */; IDENT_sys: - IDENT - { - THD *thd= YYTHD; - if (thd->charset_is_system_charset) - $$= $1; - else - thd->convert_string(&$$, system_charset_info, - $1.str, $1.length, thd->charset()); - } + IDENT { $$= $1; } + | IDENT_QUOTED + { + THD *thd= YYTHD; + if (thd->charset_is_system_charset) + $$= $1; + else + thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset()); + } ; TEXT_STRING_sys: diff --git a/sql/strfunc.cc b/sql/strfunc.cc new file mode 100644 index 00000000000..1db2124bcee --- /dev/null +++ b/sql/strfunc.cc @@ -0,0 +1,147 @@ +/* Copyright (C) 2003 MySQL 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 */ + +/* Some useful string utility functions used by the MySQL server */ + +#include "mysql_priv.h" + +/* + Return bitmap for strings used in a set + + SYNOPSIS + find_set() + lib Strings in set + str Strings of set-strings separated by ',' + err_pos If error, set to point to start of wrong set string + err_len If error, set to the length of wrong set string + set_warning Set to 1 if some string in set couldn't be used + + NOTE + We delete all end space from str before comparison + + RETURN + bitmap of all sets found in x. + set_warning is set to 1 if there was any sets that couldn't be set +*/ + +static const char field_separator=','; + +ulonglong find_set(TYPELIB *lib, const char *str, uint length, char **err_pos, + uint *err_len, bool *set_warning) +{ + const char *end= str + length; + *err_pos= 0; // No error yet + while (end > str && my_isspace(system_charset_info, end[-1])) + end--; + + *err_len= 0; + ulonglong found= 0; + if (str != end) + { + const char *start= str; + for (;;) + { + const char *pos= start; + uint var_len; + + for (; pos != end && *pos != field_separator; pos++) ; + var_len= (uint) (pos - start); + uint find= find_type(lib, start, var_len, 0); + if (!find) + { + *err_pos= (char*) start; + *err_len= var_len; + *set_warning= 1; + } + else + found|= ((longlong) 1 << (find - 1)); + if (pos == end) + break; + start= pos + 1; + } + } + return found; +} + + +/* + Function to find a string in a TYPELIB + (Same format as mysys/typelib.c) + + SYNOPSIS + find_type() + lib TYPELIB (struct of pointer to values + count) + find String to find + length Length of string to find + part_match Allow part matching of value + + RETURN + 0 error + > 0 position in TYPELIB->type_names +1 +*/ + +uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match) +{ + uint found_count=0, found_pos=0; + const char *end= find+length; + const char *i; + const char *j; + for (uint pos=0 ; (j=lib->type_names[pos++]) ; ) + { + for (i=find ; i != end && + my_toupper(system_charset_info,*i) == + my_toupper(system_charset_info,*j) ; i++, j++) ; + if (i == end) + { + if (! *j) + return(pos); + found_count++; + found_pos= pos; + } + } + return(found_count == 1 && part_match ? found_count : 0); +} + + +/* + Check if the first word in a string is one of the ones in TYPELIB + + SYNOPSIS + check_word() + lib TYPELIB + val String to check + end End of input + end_of_word Store value of last used byte here if we found word + + RETURN + 0 No matching value + > 1 lib->type_names[#-1] matched + end_of_word will point to separator character/end in 'val' +*/ + +uint check_word(TYPELIB *lib, const char *val, const char *end, + const char **end_of_word) +{ + int res; + const char *ptr; + + /* Fiend end of word */ + for (ptr= val ; ptr < end && my_isalpha(&my_charset_latin1, *ptr) ; ptr++) + ; + if ((res=find_type(lib, val, (uint) (ptr - val), 1)) > 0) + *end_of_word= ptr; + return res; +} diff --git a/sql/structs.h b/sql/structs.h index d9be230c049..352823cceb2 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -20,15 +20,19 @@ struct st_table; class Field; -typedef struct st_date_format { /* How to print date */ - uint pos[6]; /* Positions to YY.MM.DD HH:MM:SS */ -} DATE_FORMAT; +typedef struct lex_string { + char *str; + uint length; +} LEX_STRING; + + +typedef struct st_date_time_format { + uchar positions[8]; + char time_separator; /* Separator between hour and minute */ + uint flag; /* For future */ + LEX_STRING format; +} DATE_TIME_FORMAT; -typedef struct st_datetime_format { - byte dt_pos[8]; - char *format; - uint format_length; -} DATETIME_FORMAT; typedef struct st_keyfile_info { /* used with ha_info() */ byte ref[MAX_REFLENGTH]; /* Pointer to current row */ @@ -115,8 +119,17 @@ typedef struct st_read_record { /* Parameter to read_record */ bool print_error, ignore_not_found_rows; } READ_RECORD; -enum timestamp_type { TIMESTAMP_NONE, WRONG_TIMESTAMP_FULL, TIMESTAMP_DATE, TIMESTAMP_FULL, - TIMESTAMP_TIME}; + +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; @@ -125,12 +138,21 @@ typedef struct st_time { timestamp_type time_type; } TIME; + typedef struct { long year,month,day,hour,minute,second,second_part; bool neg; } INTERVAL; +typedef struct st_known_date_time_format { + const char *format_name; + const char *date_format; + const char *datetime_format; + const char *time_format; +} KNOWN_DATE_TIME_FORMAT; + + enum SHOW_TYPE { SHOW_UNDEF, @@ -168,11 +190,6 @@ typedef struct show_var_st { } SHOW_VAR; -typedef struct lex_string { - char *str; - uint length; -} LEX_STRING; - typedef struct st_lex_user { LEX_STRING user, host, password; } LEX_USER; diff --git a/sql/time.cc b/sql/time.cc index f2e41afa560..4f2a2a23910 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -23,14 +23,9 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037"; - /* Init some variabels needed when using my_local_time */ /* Currently only my_time_zone is inited */ -bool parse_datetime_formats(datetime_format_types format_type, - const char *format_str, uint format_length, - byte *dt_pos); - static long my_time_zone=0; void init_time(void) @@ -282,6 +277,7 @@ ulong convert_period_to_month(ulong period) return a*12+b-1; } + ulong convert_month_to_period(ulong month) { ulong year; @@ -295,6 +291,13 @@ 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. @@ -303,7 +306,9 @@ ulong convert_month_to_period(ulong month) str String to parse length Length of string l_time Date is stored here - fuzzy_date 1 if we should allow dates where one part is zero + 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. DESCRIPTION At least the following formats are recogniced (based on number of digits) @@ -312,161 +317,248 @@ ulong convert_month_to_period(ulong month) 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 TIMESTAMP_DATE DATE string (YY MM and DD parts ok) - TIMESTAMP_FULL Full timestamp + TIMESTAMP_DATETIME Full timestamp + TIMESTAMP_DATETIME_ERROR Timestamp with wrong values */ +#define MAX_DATE_PARTS 8 + timestamp_type -str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date,THD *thd) +str_to_TIME(const char *str, uint length, TIME *l_time, uint flags) { - uint field_length= 0, year_length= 0, digits, i, number_of_fields; - uint date[7], date_len[7]; - uint not_zero_date; - bool is_internal_format= 0; - const char *pos; + 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; - bool found_delimitier= 0; + const uchar *format_position; + bool found_delimitier= 0, found_space= 0; + DATE_TIME_FORMAT *format; DBUG_ENTER("str_to_TIME"); - DBUG_PRINT("enter",("str: %.*s",length,str)); + DBUG_PRINT("ENTER",("str: %.*s",length,str)); - // Skip garbage - for (; str != end && !my_isdigit(&my_charset_latin1, *str) ; str++) ; - if (str == end) + LINT_INIT(field_length); + LINT_INIT(year_length); + LINT_INIT(last_field_pos); + + // Skip space at start + for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++) + ; + if (str == end || ! my_isdigit(&my_charset_latin1, *str)) 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 first number of digits. + 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++) ; - /* Check for internal format */ - digits= (uint) (pos-str); + for (pos=str; pos != end && my_isdigit(&my_charset_latin1,*pos) ; pos++) + ; - if (pos == end || digits>=12) + digits= (uint) (pos-str); + start_loop= 0; // Start of scan loop + date_len[format_position[0]]= 0; // Length of year field + if (pos == end) { - is_internal_format= 1; + /* Found date in internal format (only numbers like YYYYMMDD) */ year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; field_length=year_length-1; - date_len[0]= year_length; + 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) + 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]= 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=0 ; i < 6 && str != end && my_isdigit(&my_charset_latin1,*str) ; i++) + for (i = start_loop; + i < MAX_DATE_PARTS-1 && str != end && + my_isdigit(&my_charset_latin1,*str); + i++) { - if (!is_internal_format) - date_len[i]= 1; - uint tmp_value=(uint) (uchar) (*str++ - '0'); - while (str != end && my_isdigit(&my_charset_latin1,str[0]) - && (is_internal_format && field_length-- || !is_internal_format) ) + 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 + (uint) (uchar) (*str - '0'); + tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0'); str++; - if (!is_internal_format) - date_len[i]+= 1; } - if (i == 2 && *str == '.') + date_len[i]+= (uint) (str - start); + if (tmp_value > 999999) // Impossible date part DBUG_RETURN(TIMESTAMP_NONE); date[i]=tmp_value; not_zero_date|= tmp_value; - if (i == 2 && str != end && *str == 'T') + + /* 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 - else if ( i != 5 ) // Skip inter-field delimiters + continue; + } + if (i == format_position[5]) // Seconds { - while (str != end && - (my_ispunct(&my_charset_latin1,*str) || - my_isspace(&my_charset_latin1,*str))) + if (*str == '.') // Followed by part seconds { - // Only allow space between days and hours - if (my_isspace(&my_charset_latin1,*str) && i != 2) - DBUG_RETURN(TIMESTAMP_NONE); str++; - found_delimitier=1; // Should be a 'normal' date + field_length= 5; // 5 digits after first (=6) } + continue; + + /* No part seconds */ + date[++i]= 0; } - if (is_internal_format) - field_length=1; // Rest fields can only be 2 - } - /* Handle second fractions */ - if (i == 6 && (uint) (end-str) >= 2 && *str == '.' && - my_isdigit(&my_charset_latin1,str[1])) - { - str++; - uint tmp_value=(uint) (uchar) (*str - '0'); - field_length=5; - while (str++ != end && my_isdigit(&my_charset_latin1,str[0]) && - field_length--) - tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); - date[6]=tmp_value; - not_zero_date|= tmp_value; + 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))) + 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[1] == 'p' || str[1] == 'P') + add_hours= 12; + else if (str[1] != 'a' || str[1] != '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; } - else - date[6]=0; - - while (str != end && (my_ispunct(&my_charset_latin1,*str) || - my_isspace(&my_charset_latin1,*str))) - str++; + if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY)) + DBUG_RETURN(TIMESTAMP_NONE); // Can't be a datetime - uint add_hours= 0; - if (!my_strnncoll(&my_charset_latin1, - (const uchar *)str, 2, - (const uchar *)"PM", 2)) - add_hours= 12; + str= last_field_pos; - number_of_fields=i; - while (i < 6) + number_of_fields= i - start_loop; + while (i < MAX_DATE_PARTS) date[i++]=0; if (!is_internal_format) { - byte *frm_pos; + year_length= date_len[(uint) format_position[0]]; + if (!year_length) // Year must be specified + DBUG_RETURN(TIMESTAMP_NONE); - if (number_of_fields <= 3) - { - frm_pos= t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format.dt_pos; - l_time->hour= 0; - l_time->minute= 0; - l_time->second= 0; - } - else + 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]]; + l_time->second_part= date[(uint) format_position[6]]; + if (format_position[7] != (uchar) 255) { - frm_pos= t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format.dt_pos; - l_time->hour= date[(int) frm_pos[3]]; - l_time->minute=date[(int) frm_pos[4]]; - l_time->second=date[(int) frm_pos[5]]; - if (frm_pos[6] == 1) - { - if (l_time->hour > 12) - DBUG_RETURN(WRONG_TIMESTAMP_FULL); - l_time->hour= l_time->hour%12 + add_hours; - } + if (l_time->hour > 12) + DBUG_RETURN(TIMESTAMP_DATETIME_ERROR); + l_time->hour= l_time->hour%12 + add_hours; } - - l_time->year= date[(int) frm_pos[0]]; - l_time->month= date[(int) frm_pos[1]]; - l_time->day= date[(int) frm_pos[2]]; - year_length= date_len[(int) frm_pos[0]]; } 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]; - } - l_time->second_part=date[6]; + 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]; + l_time->second_part=date[6]; + } l_time->neg= 0; - if (year_length == 2 && i >=2 && (l_time->month || l_time->day)) - l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); + 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 || - (!fuzzy_date && (l_time->month == 0 || l_time->day == 0))) + (!(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 @@ -481,46 +573,46 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date,THD *thd) } } if (not_zero_date) - thd->cuted_fields++; - DBUG_RETURN(WRONG_TIMESTAMP_FULL); + current_thd->cuted_fields++; + DBUG_RETURN(TIMESTAMP_DATETIME_ERROR); } - if (str != end && thd->count_cuted_fields) + if (str != end && current_thd->count_cuted_fields) { for (; str != end ; str++) { if (!my_isspace(&my_charset_latin1,*str)) { - thd->cuted_fields++; + current_thd->cuted_fields++; break; } } } DBUG_RETURN(l_time->time_type= - (number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_FULL)); + (number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_DATETIME)); } -time_t str_to_timestamp(const char *str,uint length, THD *thd) +time_t str_to_timestamp(const char *str,uint length) { TIME l_time; long not_used; - if (str_to_TIME(str,length,&l_time,0,thd) <= WRONG_TIMESTAMP_FULL) + if (str_to_TIME(str,length,&l_time,0) <= TIMESTAMP_DATETIME_ERROR) return(0); if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) { - thd->cuted_fields++; + current_thd->cuted_fields++; return(0); } return(my_gmt_sec(&l_time, ¬_used)); } -longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd) +longlong str_to_datetime(const char *str,uint length, uint fuzzy_date) { TIME l_time; - if (str_to_TIME(str,length,&l_time,fuzzy_date,thd) <= WRONG_TIMESTAMP_FULL) + if (str_to_TIME(str,length,&l_time,fuzzy_date) <= TIMESTAMP_DATETIME_ERROR) return(0); return (longlong) (l_time.year*LL(10000000000) + l_time.month*LL(100000000)+ @@ -542,22 +634,24 @@ longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd) length Length of str l_time Store result here + 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, THD *thd) +bool str_to_time(const char *str,uint length,TIME *l_time) { long date[5],value; - const char *end=str+length; + const char *end=str+length, *end_of_days; bool found_days,found_hours; uint state; - byte *frm_pos= t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format.dt_pos; l_time->neg=0; - for (; str != end && - !my_isdigit(&my_charset_latin1,*str) && *str != '-' ; str++) + for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) length--; if (str != end && *str == '-') { @@ -571,37 +665,33 @@ bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) /* Check first if this is a full TIMESTAMP */ if (length >= 12) { // Probably full timestamp - enum timestamp_type tres= str_to_TIME(str,length,l_time,1,thd); - if (tres == TIMESTAMP_FULL) - return 0; - else if (tres == WRONG_TIMESTAMP_FULL) - return 1; + enum timestamp_type res= str_to_TIME(str,length,l_time, + (TIME_FUZZY_DATE | + TIME_DATETIME_ONLY)); + if ((int) res >= (int) TIMESTAMP_DATETIME_ERROR) + return res == TIMESTAMP_DATETIME_ERROR; } /* 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'); - /* Move to last space */ - if (str != end && *str == ' ') - { - while (++str != end && str[0] == ' ') - {} - str--; - } + /* Skipp 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 == ' ' && - my_isdigit(&my_charset_latin1,str[1]))) - { // days ! - date[0]=value; - state=1; // Assume next is hours - found_days=1; - str++; // Skip space; - } - else if ((end-str) > 1 && *str == frm_pos[7] && - my_isdigit(&my_charset_latin1,str[1])) + 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; @@ -626,10 +716,10 @@ bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) 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 != frm_pos[7] || + if (state == 4 || (end-str) < 2 || *str != time_separator || !my_isdigit(&my_charset_latin1,str[1])) break; - str++; // Skip ':' + str++; // Skip time_separator (':') } if (state != 4) @@ -644,7 +734,8 @@ bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) else bzero((char*) (date+state), sizeof(long)*(4-state)); } - fractional: + +fractional: /* Get fractional second part */ if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1])) { @@ -659,18 +750,21 @@ bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) else date[4]=0; - while (str != end && !my_isalpha(&my_charset_latin1,*str)) - str++; - - if ( (end-str)>= 2 && - !my_strnncoll(&my_charset_latin1, - (const uchar *)str, 2, - (const uchar *)"PM", 2) && - frm_pos[6] == 1) + if (internal_format_positions[7] != 255) { - uint days_i= date[1]/24; - uint hours_i= date[1]%24; - date[1]= hours_i%12 + 12 + 24*days_i; + /* 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[1] == 'p' || str[1] == 'P') + { + str+= 2; + date[1]= date[1]%12 + 12; + } + else if (str[1] == 'a' || str[1] == 'A') + str+=2; + } } /* Some simple checks */ @@ -680,11 +774,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) return 1; } l_time->month=0; - l_time->day=date[0]; - l_time->hour=date[frm_pos[3] + 1]; - l_time->minute=date[frm_pos[4] + 1]; - l_time->second=date[frm_pos[5] + 1]; - l_time->second_part=date[4]; + 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 */ @@ -730,163 +824,404 @@ void calc_time_from_sec(TIME *to, long seconds, long microseconds) } -DATETIME_FORMAT *make_format(DATETIME_FORMAT *datetime_format, - datetime_format_types format_type, - const char *format_str, - uint format_length, bool is_alloc) -{ - if (format_length && - !parse_datetime_formats(format_type, format_str, - format_length, - datetime_format->dt_pos)) - { - if (is_alloc) - { - if (!(datetime_format->format= my_strdup_with_length(format_str, - format_length, - MYF(0)))) - return 0; - } - else - datetime_format->format= (char *) format_str; - datetime_format->format_length= format_length; - return datetime_format; - } - return 0; -} +/* + Parse a format string specification + SYNOPSIS + parse_date_time_format() + format_type Format of string (time, date or datetime) + format_str String to parse + format_length Length of string + date_time_format Format to fill in + + NOTES + Fills in date_time_format->positions for all date time parts. + + positions marks the position for a datetime element in the format string. + The position array elements are in the following order: + YYYY-DD-MM HH-MM-DD.FFFFFF AM + 0 1 2 3 4 5 6 7 + + If positions[0]= 5, it means that year will be the forth element to + read from the parsed date string. + + RETURN + 0 ok + 1 error +*/ -bool parse_datetime_formats(datetime_format_types format_type, - const char *format_str, uint format_length, - byte *dt_pos) +bool parse_date_time_format(timestamp_type format_type, + const char *format, uint format_length, + DATE_TIME_FORMAT *date_time_format) { - uint pos= 0; - dt_pos[0]= dt_pos[1]= dt_pos[2]= dt_pos[3]= - dt_pos[4]= dt_pos[5]= dt_pos[6]= dt_pos[7]= -1; + uint offset= 0, separators= 0; + const char *ptr= format, *format_str; + const char *end= ptr+format_length; + uchar *dt_pos= date_time_format->positions; + /* need_p is set if we are using AM/PM format */ + bool need_p= 0, allow_separator= 0; + ulong part_map= 0, separator_map= 0; + const char *parts[16]; + + date_time_format->time_separator= 0; + date_time_format->flag= 0; // For future - const char *ptr=format_str; - const char *end=ptr+format_length; - bool need_p= 0; + /* + Fill position with 'dummy' arguments to found out if a format tag is + used twice (This limit's the format to 255 characters, but this is ok) + */ + dt_pos[0]= dt_pos[1]= dt_pos[2]= dt_pos[3]= + dt_pos[4]= dt_pos[5]= dt_pos[6]= dt_pos[7]= 255; for (; ptr != end; ptr++) { if (*ptr == '%' && ptr+1 != end) { + uint position; + LINT_INIT(position); switch (*++ptr) { - case 'y': + case 'y': // Year case 'Y': - if (dt_pos[0] > -1) - return 1; - dt_pos[0]= pos; + position= 0; break; - case 'c': + case 'c': // Month case 'm': - if (dt_pos[1] > -1) - return 1; - dt_pos[1]= pos; + position= 1; break; case 'd': case 'e': - if (dt_pos[2] > -1) - return 1; - dt_pos[2]= pos; + position= 2; break; - case 'H': - case 'k': case 'h': case 'I': case 'l': - if (dt_pos[3] > -1) - return 1; - dt_pos[3]= pos; - need_p= (*ptr == 'h' || *ptr == 'l' || *ptr == 'I'); + need_p= 1; // Need AM/PM + /* Fall through */ + case 'k': + case 'H': + position= 3; break; case 'i': - if (dt_pos[4] > -1) - return 1; - dt_pos[4]= pos; + position= 4; break; case 's': case 'S': - if (dt_pos[5] > -1) - return 1; - dt_pos[5]= pos; + position= 5; + break; + case 'f': + position= 6; + if (dt_pos[5] != offset-1 || ptr[-2] != '.') + return 1; // Wrong usage of %f break; - case 'p': - if (dt_pos[6] > -1) - return 1; - /* %p should be last in format string */ - if (format_type == DATE_FORMAT_TYPE || - (pos != 6 && format_type == DATETIME_FORMAT_TYPE) || - (pos != 3 && format_type == TIME_FORMAT_TYPE)) - return 1; - dt_pos[6]= 1; + case 'p': // AM/PM + if (offset == 0) // Can't be first + return 0; + position= 7; break; default: - return 1; + return 1; // Unknown controll char } - if (dt_pos[6] == -1) - pos++; + if (dt_pos[position] != 255) // Don't allow same tag twice + return 1; + parts[position]= ptr-1; + + /* + If switching from time to date, ensure that all time parts + are used + */ + if (part_map && position <= 2 && !(part_map & (1 | 2 | 4))) + offset=5; + part_map|= (ulong) 1 << position; + dt_pos[position]= offset++; + allow_separator= 1; + } + else + { + /* + Don't allow any characters in format as this could easily confuse + the date reader + */ + if (!allow_separator) + return 1; // No separator here + allow_separator= 0; // Don't allow two separators + separators++; + /* Store in separator_map which parts are punct characters */ + if (my_ispunct(&my_charset_latin1, *ptr)) + separator_map|= (ulong) 1 << (offset-1); + else if (!my_isspace(&my_charset_latin1, *ptr)) + return 1; } } - if (pos > 5 && format_type == DATETIME_FORMAT_TYPE && - (dt_pos[0] + dt_pos[1] + dt_pos[2] + - dt_pos[3] + dt_pos[4] + dt_pos[5] != 15) || - pos > 2 && format_type == DATE_FORMAT_TYPE && - (dt_pos[0] + dt_pos[1] + dt_pos[2] != 3) || - pos > 2 && format_type == TIME_FORMAT_TYPE && - (dt_pos[3] + dt_pos[4] + dt_pos[5] != 3) || - (need_p && dt_pos[6] != 1)) - return 1; + /* If no %f, specify it after seconds. Move %p up, if necessary */ + if ((part_map & 32) && !(part_map & 64)) + { + dt_pos[6]= dt_pos[5] +1; + parts[6]= parts[5]; // For later test in (need_p) + if (dt_pos[6] == dt_pos[7]) // Move %p one step up if used + dt_pos[7]++; + } /* - Check for valid separators between date/time parst + Check that we have not used a non legal format specifier and that all + format specifiers have been used + + The last test is to ensure that %p is used if and only if + it's needed. */ - uint tmp_len= format_length; - if (dt_pos[6] == 1) + if ((format_type == 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 && + !test_all_bits(part_map, 8 | 16 | 32)) || + !allow_separator || // %option should be last + (need_p && dt_pos[6] +1 != dt_pos[7]) || + (need_p ^ (dt_pos[7] != 255))) + return 1; + + if (dt_pos[6] != 255) // If fractional seconds { - end= end - 2; - if (my_ispunct(&my_charset_latin1, *end) || my_isspace(&my_charset_latin1, *end)) - end--; - tmp_len= end - format_str; + /* remove fractional seconds from later tests */ + uint pos= dt_pos[6] -1; + /* Remove separator before %f from sep map */ + separator_map= ((separator_map & ((ulong) (1 << pos)-1)) | + ((separator_map & ~((ulong) (1 << pos)-1)) >> 1)); + if (part_map & 64) + { + separators--; // There is always a separator + need_p= 1; // force use of separators + } } + + /* + Remove possible separator before %p from sep_map + (This can either be at position 3, 4, 6 or 7) h.m.d.%f %p + */ + if (dt_pos[7] != 255) + { + if (need_p && parts[7] != parts[6]+2) + separators--; + } + /* + Calculate if %p is in first or last part of the datetime field + + At this point we have either %H-%i-%s %p 'year parts' or + 'year parts' &H-%i-%s %p" as %f was removed above + */ + offset= dt_pos[6] <= 3 ? 3 : 6; + /* Remove separator before %p from sep map */ + separator_map= ((separator_map & ((ulong) (1 << offset)-1)) | + ((separator_map & ~((ulong) (1 << offset)-1)) >> 1)); + + format_str= 0; switch (format_type) { - case DATE_FORMAT_TYPE: - case TIME_FORMAT_TYPE: - if ((tmp_len == 6 && - !my_strnncoll(&my_charset_bin, - (const uchar *) format_str, 6, - (const uchar *) datetime_formats - [format_type][INTERNAL_FORMAT], 6)) || - tmp_len == 8 && - my_ispunct(&my_charset_latin1, *(format_str+2)) && - my_ispunct(&my_charset_latin1, *(format_str+5))) + case TIMESTAMP_DATE: + format_str= known_date_time_formats[INTERNAL_FORMAT].date_format; + /* fall through */ + case TIMESTAMP_TIME: + if (!format_str) + format_str=known_date_time_formats[INTERNAL_FORMAT].time_format; + + /* + If there is no separators, allow the internal format as we can read + this. If separators are used, they must be between each part + */ + if (format_length == 6 && !need_p && + !my_strnncoll(&my_charset_bin, + (const uchar *) format, 6, + (const uchar *) format_str, 6)) + return 0; + if (separator_map == (1 | 2)) { - if (format_type == TIME_FORMAT_TYPE && tmp_len == 8) + if (format_type == TIMESTAMP_TIME) { - if (*(format_str+2) != *(format_str+5)) - return 1; - dt_pos[7]= *(format_str+2); + if (*(format+2) != *(format+5)) + break; // Error + /* Store the character used for time formats */ + date_time_format->time_separator= *(format+2); } return 0; } break; - case DATETIME_FORMAT_TYPE: - if ((tmp_len == 12 && + case 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. + Between DATE and TIME we also allow space as separator + */ + if ((format_length == 12 && !need_p && !my_strnncoll(&my_charset_bin, - (const uchar *) format_str, 12, - (const uchar *) datetime_formats - [DATETIME_FORMAT_TYPE][INTERNAL_FORMAT], 12)) || - tmp_len == 17 && - my_ispunct(&my_charset_latin1, *(format_str+2)) && - my_ispunct(&my_charset_latin1, *(format_str+5)) && - my_ispunct(&my_charset_latin1, *(format_str+11)) && - my_ispunct(&my_charset_latin1, *(format_str+14)) && - (my_ispunct(&my_charset_latin1, *(format_str+8)) || - my_isspace(&my_charset_latin1, *(format_str+8)))) + (const uchar *) format, 12, + (const uchar*) known_date_time_formats[INTERNAL_FORMAT].datetime_format, + 12)) || + (separators == 5 && separator_map == (1 | 2 | 8 | 16))) return 0; break; - } - return 1; + default: + DBUG_ASSERT(1); + break; + } + return 1; // Error +} + + +/* + Create a DATE_TIME_FORMAT object from a format string specification + + SYNOPSIS + date_time_format_make() + format_type Format to parse (time, date or datetime) + format_str String to parse + format_length Length of string + + NOTES + The returned object should be freed with my_free() + + RETURN + NULL ponter: Error + new object +*/ + +DATE_TIME_FORMAT +*date_time_format_make(timestamp_type format_type, + const char *format_str, uint format_length) +{ + DATE_TIME_FORMAT tmp; + + if (format_length && format_length < 255 && + !parse_date_time_format(format_type, format_str, + format_length, &tmp)) + { + tmp.format.str= (char*) format_str; + tmp.format.length= format_length; + return date_time_format_copy((THD *)0, &tmp); + } + return 0; +} + + +/* + Create a copy of a DATE_TIME_FORMAT object + + SYNOPSIS + date_and_time_format_copy() + thd Set if variable should be allocated in thread mem + format format to copy + + NOTES + The returned object should be freed with my_free() + + RETURN + NULL ponter: Error + new object +*/ + +DATE_TIME_FORMAT *date_time_format_copy(THD *thd, DATE_TIME_FORMAT *format) +{ + DATE_TIME_FORMAT *new_format; + ulong length= sizeof(*format) + format->format.length + 1; + + if (thd) + new_format= (DATE_TIME_FORMAT *) thd->alloc(length); + else + new_format= (DATE_TIME_FORMAT *) my_malloc(length, MYF(MY_WME)); + if (new_format) + { + /* Put format string after current pos */ + new_format->format.str= (char*) (new_format+1); + memcpy((char*) new_format->positions, (char*) format->positions, + sizeof(format->positions)); + new_format->time_separator= format->time_separator; + /* We make the string null terminated for easy printf in SHOW VARIABLES */ + memcpy((char*) new_format->format.str, format->format.str, + format->format.length); + new_format->format.str[format->format.length]= 0; + new_format->format.length= format->format.length; + } + return new_format; +} + + +KNOWN_DATE_TIME_FORMAT known_date_time_formats[6]= +{ + {"USA", "%m.%d.%Y", "%Y-%m-%d %H.%i.%s", "%h:%i:%s %p" }, + {"JIS", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" }, + {"ISO", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" }, + {"EUR", "%d.%m.%Y", "%Y-%m-%d %H.%i.%s", "%H.%i.%s" }, + {"INTERNAL", "%Y%m%d", "%Y%m%d%H%i%s", "%H%i%s" }, + { 0, 0, 0, 0 } +}; + + +/* + Return format string according format name. + If name is unknown, result is NULL +*/ + +const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format, + timestamp_type type) +{ + switch (type) { + case TIMESTAMP_DATE: + return format->date_format; + case TIMESTAMP_DATETIME: + return format->datetime_format; + case TIMESTAMP_TIME: + return format->time_format; + default: + DBUG_ASSERT(0); // Impossible + return 0; + } +} + +/**************************************************************************** + Functions to create default time/date/datetime strings + + NOTE: + For the moment the DATE_TIME_FORMAT argument is ignored becasue + MySQL doesn't support comparing of date/time/datetime strings that + are not in arbutary order as dates are compared as strings in some + context) +****************************************************************************/ + +void make_time(DATE_TIME_FORMAT *format, TIME *l_time, String *str) +{ + long length= my_sprintf((char*) str->ptr(), + ((char*) str->ptr(), + "%s%02d:%02d:%02d", + (l_time->neg ? "-" : ""), + l_time->hour, + l_time->minute, + l_time->second)); + str->length(length); + str->set_charset(&my_charset_bin); +} + + +void make_date(DATE_TIME_FORMAT *format, TIME *l_time, String *str) +{ + long length= my_sprintf((char*) str->ptr(), + ((char*) str->ptr(), + "%04d-%02d-%02d", + l_time->year, + l_time->month, + l_time->day)); + str->length(length); + str->set_charset(&my_charset_bin); +} + + +void make_datetime(DATE_TIME_FORMAT *format, TIME *l_time, String *str) +{ + long length= my_sprintf((char*) str->ptr(), + ((char*) str->ptr(), + "%04d-%02d-%02d %02d:%02d:%02d", + l_time->year, + l_time->month, + l_time->day, + l_time->hour, + l_time->minute, + l_time->second)); + str->length(length); + str->set_charset(&my_charset_bin); } diff --git a/sql/unireg.h b/sql/unireg.h index ef6a2f44ea7..66a274f3863 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -63,6 +63,10 @@ /* Max column width +1 */ #define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1) +#define MAX_DATE_WIDTH 10 /* YYYY-MM-DD */ +#define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */ +#define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */ +#define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */ #define MAX_TABLES (sizeof(table_map)*8-2) /* Max tables in join */ #define OUTER_REF_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-2)) diff --git a/strings/Makefile.am b/strings/Makefile.am index 7b2fdcccc55..61219c8abb9 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -21,20 +21,20 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 -ASRCS = strings-x86.s longlong2str-x86.s +ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c else #no assembler ASRCS = # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile -CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c +CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c endif endif @@ -47,6 +47,7 @@ EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-ucs2.c ctype-tis620.c ctype-ujis.c \ xml.c strto.c strings-x86.s \ longlong2str.c longlong2str-x86.s \ + my_strtoll10.c my_strtoll10-x86.s \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ strfill.c strcend.c is_prefix.c strstr.c strinstr.c \ strmake.c strnmov.c strmov.c strnlen.c \ diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 5a785552b45..6f28c43b2c6 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -35,12 +35,12 @@ static uchar ctype_bin[]= 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index deb9448857e..4fd288d257e 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -95,26 +95,32 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ { register int iarg; - char *to_start= to; - if ((uint) (end-to) < max(16,length)) - break; + uint res_length, to_length; + char *store_start= to, *store_end; + char buff[16]; + + if ((to_length= (uint) (end-to)) < 16 || length) + store_start= buff; iarg = va_arg(ap, int); if (*fmt == 'd') - to=int10_to_str((long) iarg,to, -10); + store_end= int10_to_str((long) iarg, store_start, -10); else - to=int10_to_str((long) (uint) iarg,to,10); + store_end= int10_to_str((long) (uint) iarg, store_start, 10); + if ((res_length= (uint) (store_end - store_start)) > to_length) + break; /* num doesn't fit in output */ /* If %#d syntax was used, we have to pre-zero/pre-space the string */ - if (length) + if (store_start == buff) { - uint res_length= (uint) (to - to_start); + length= min(length, to_length); if (res_length < length) { uint diff= (length- res_length); - bmove_upp(to+diff, to, res_length); - bfill(to-res_length, diff, pre_zero ? '0' : ' '); + bfill(to, diff, pre_zero ? '0' : ' '); to+= diff; } + bmove(to, store_start, res_length); } + to+= res_length; continue; } /* We come here on '%%', unknown code or too long parameter */ |