diff options
author | unknown <tulin@dl145b.mysql.com> | 2005-07-20 07:53:10 +0200 |
---|---|---|
committer | unknown <tulin@dl145b.mysql.com> | 2005-07-20 07:53:10 +0200 |
commit | 49e1bba3465a7af49b73225bf2d17e2ba5333e91 (patch) | |
tree | 7f7a1503ba15f11a67dc0148085dd7ceb97e727d | |
parent | ee7e3e710fb08ccb7c3ce701605fdb8e3cfba59d (diff) | |
parent | f03607ea9e72f726ce11b60826bbf30ebabc2806 (diff) | |
download | mariadb-git-49e1bba3465a7af49b73225bf2d17e2ba5333e91.tar.gz |
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
extra/perror.c:
Auto merged
include/my_global.h:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/ps_7ndb.result:
Auto merged
BitKeeper/deleted/.del-var~62c955ccf2da1a21:
Auto merged
mysql-test/t/disabled.def:
Auto merged
sql/field.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/item.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_show.cc:
Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.cpp:
Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.hpp:
Auto merged
storage/ndb/src/mgmsrv/main.cpp:
Auto merged
45 files changed, 585 insertions, 471 deletions
diff --git a/.bzrignore b/.bzrignore index ca4cade7f09..746f141bd42 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1119,3 +1119,4 @@ vio/viotest-ssl ndb/src/dummy.cpp innobase/mkinstalldirs mkinstalldirs +mysql-test/var diff --git a/extra/perror.c b/extra/perror.c index 283c3b0c107..551dc3096d4 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -41,7 +41,7 @@ static struct my_option my_long_options[] = {"info", 'I', "Synonym for --help.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_NDBCLUSTER_DB - {"ndb", 0, "Ndbcluster storage engine specific error codes.", (gptr*) &ndb_code, + {"ndb", 257, "Ndbcluster storage engine specific error codes.", (gptr*) &ndb_code, (gptr*) &ndb_code, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif #ifdef HAVE_SYS_ERRLIST diff --git a/include/my_global.h b/include/my_global.h index 5a93e47a608..f81216e3add 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1093,7 +1093,8 @@ do { doubleget_union _tmp; \ #define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0) #define float8get(V,M) doubleget((V),(M)) #define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) -#define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) +#define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V),sizeof(float)) +#define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float)) #define float8store(V,M) doublestore((V),(M)) #endif /* __i386__ */ @@ -1264,7 +1265,8 @@ do { doubleget_union _tmp; \ *(((char*)T)+1)=(((A) >> 16));\ *(((char*)T)+0)=(((A) >> 24)); } while(0) -#define floatstore(T,V) memcpy_fixed((byte*)(T), (byte*)(&V), sizeof(float)) +#define floatget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float)) +#define floatstore(T,V) memcpy_fixed((byte*) (T),(byte*)(&V),sizeof(float)) #define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double)) #define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double)) #define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong)) @@ -1279,7 +1281,8 @@ do { doubleget_union _tmp; \ #define shortstore(T,V) int2store(T,V) #define longstore(T,V) int4store(T,V) #ifndef floatstore -#define floatstore(T,V) memcpy_fixed((byte*)(T), (byte*)(&V), sizeof(float)) +#define floatstore(T,V) memcpy_fixed((byte*) (T),(byte*) (&V),sizeof(float)) +#define floatget(V,M) memcpy_fixed((byte*) &V, (byte*) (M), sizeof(float)) #endif #ifndef doubleget #define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double)) diff --git a/include/my_time.h b/include/my_time.h index 8058df8fe4e..aa68a6f0bbd 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -53,7 +53,7 @@ enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut); longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, - my_bool fuzzy_date, int *was_cut); + uint flags, int *was_cut); ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *time); ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *time); ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *time); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index f9ddf7fa665..024d19ff24b 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3585,7 +3585,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME *tm= (MYSQL_TIME *)buffer; - (void) str_to_datetime(value, length, tm, 0, &err); + (void) str_to_datetime(value, length, tm, TIME_FUZZY_DATE, &err); *param->error= test(err) && (param->buffer_type == MYSQL_TYPE_DATE && tm->time_type != MYSQL_TIMESTAMP_DATE); break; @@ -3703,7 +3703,8 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, case MYSQL_TYPE_DATETIME: { int error; - value= number_to_datetime(value, (MYSQL_TIME *) buffer, 1, &error); + value= number_to_datetime(value, (MYSQL_TIME *) buffer, TIME_FUZZY_DATE, + &error); *param->error= test(error); break; } diff --git a/mysql-test/lib/init_db.sql b/mysql-test/lib/init_db.sql index 77f9b18cb08..fa02b350425 100644 --- a/mysql-test/lib/init_db.sql +++ b/mysql-test/lib/init_db.sql @@ -553,7 +553,7 @@ CREATE TABLE proc ( 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE' - ) DEFAULT 0 NOT NULL, + ) DEFAULT '' NOT NULL, comment char(64) binary DEFAULT '' NOT NULL, PRIMARY KEY (db,name,type) ) comment='Stored Procedures'; diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 8217a0e7ba6..74ab1e35534 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -434,7 +434,7 @@ explain extended select makedate(1997,1), addtime("31.12.97 11.59.59.999999 PM", 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 Warnings: -Note 1003 select makedate(1997,1) AS `makedate(1997,1)`,addtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'31.12.97 11.59.59.999999 PM') AS `addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,subtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'31.12.97 11.59.59.999999 PM') AS `subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,timediff(_latin1'01.01.97 11:59:59.000001 PM',_latin1'31.12.95 11:59:59.000002 PM') AS `timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM")`,cast(str_to_date(_latin1'15-01-2001 12:59:59',_latin1'%d-%m-%Y %H:%i:%S') as time) AS `cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME)`,maketime(23,11,12) AS `maketime(23,11,12)`,microsecond(_latin1'1997-12-31 23:59:59.000001') AS `microsecond("1997-12-31 23:59:59.000001")` +Note 1003 select makedate(1997,1) AS `makedate(1997,1)`,addtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'1 1.1.1.000002') AS `addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,subtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'1 1.1.1.000002') AS `subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,timediff(_latin1'01.01.97 11:59:59.000001 PM',_latin1'31.12.95 11:59:59.000002 PM') AS `timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM")`,cast(str_to_date(_latin1'15-01-2001 12:59:59',_latin1'%d-%m-%Y %H:%i:%S') as time) AS `cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME)`,maketime(23,11,12) AS `maketime(23,11,12)`,microsecond(_latin1'1997-12-31 23:59:59.000001') AS `microsecond("1997-12-31 23:59:59.000001")` create table t1 (d date); insert into t1 values ('2004-07-14'),('2005-07-14'); select date_format(d,"%d") from t1 order by 1; diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 64dc09f864c..5d0e1d703a6 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -2976,25 +2976,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 792d74231f2..da0421d2caa 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -2959,25 +2959,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 7dcb8546a83..ff52847a0dc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -2960,25 +2960,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 77b1a242452..9af8f6ed6ce 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -2896,25 +2896,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 @@ -5908,25 +5908,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 0489c7ef078..b7d63b97c09 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -2959,25 +2959,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index b0049b3e943..c54c09cf6aa 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -2959,25 +2959,25 @@ Warnings: Warning 1265 Data truncated for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 Warnings: Warning 1264 Out of range value adjusted for column 'c13' at row 1 -Warning 1265 Data truncated for column 'c14' at row 1 +Warning 1264 Out of range value adjusted for column 'c14' at row 1 Warning 1265 Data truncated for column 'c15' at row 1 Warning 1264 Out of range value adjusted for column 'c16' at row 1 Warning 1264 Out of range value adjusted for column 'c17' at row 1 diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 2a38c5fc86f..14c45270b04 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2579,6 +2579,25 @@ K2C4 K4N4 F2I4 WART 0100 1 WART 0200 1 WART 0300 3 +select found_rows(); +found_rows() +3 +select count(*) from t1; +count(*) +15 +select found_rows(); +found_rows() +1 +select count(*) from t1 limit 2,3; +count(*) +select found_rows(); +found_rows() +0 +select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3; +count(*) +select found_rows(); +found_rows() +1 DROP TABLE t1; CREATE TABLE t1 ( a BLOB, INDEX (a(20)) ); CREATE TABLE t2 ( a BLOB, INDEX (a(20)) ); diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index adc22cd1ac2..49f118b1d96 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1245,3 +1245,16 @@ t1 CREATE TABLE `t1` ( `b` date NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +set @@sql_mode='traditional'; +create table t1 (d date); +insert into t1 values ('2000-10-00'); +ERROR 22007: Incorrect date value: '2000-10-00' for column 'd' at row 1 +insert into t1 values (1000); +ERROR 22007: Incorrect date value: '1000' for column 'd' at row 1 +insert into t1 values ('2000-10-01'); +update t1 set d = 1100; +ERROR 22007: Incorrect date value: '1100' for column 'd' at row 1 +select * from t1; +d +2000-10-01 +drop table t1; diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index a90bdf9ad5b..df51a6aac9b 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -40,6 +40,12 @@ insert into t1 (i, ts) values Warnings: Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2 insert into t1 (i, ts) values +(unix_timestamp(20030330015959),20030330015959), +(unix_timestamp(20030330023000),20030330023000), +(unix_timestamp(20030330030000),20030330030000); +Warnings: +Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2 +insert into t1 (i, ts) values (unix_timestamp('2003-05-01 00:00:00'),'2003-05-01 00:00:00'); insert into t1 (i, ts) values (unix_timestamp('2003-10-26 01:00:00'),'2003-10-26 01:00:00'), @@ -54,6 +60,9 @@ i ts 1048985999 2003-03-30 00:59:59 1048986000 2003-03-30 01:00:00 1048986000 2003-03-30 01:00:00 +1048985999 2003-03-30 00:59:59 +1048986000 2003-03-30 01:00:00 +1048986000 2003-03-30 01:00:00 1051740000 2003-04-30 22:00:00 1067122800 2003-10-25 23:00:00 1067126400 2003-10-26 00:00:00 diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 98f7829ca1c..33c7e837997 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -100,12 +100,12 @@ create table t1 (t datetime); insert into t1 values (20030102030460),(20030102036301),(20030102240401), (20030132030401),(20031302030401),(100001202030401); Warnings: -Warning 1265 Data truncated for column 't' at row 1 -Warning 1265 Data truncated for column 't' at row 2 -Warning 1265 Data truncated for column 't' at row 3 -Warning 1265 Data truncated for column 't' at row 4 -Warning 1265 Data truncated for column 't' at row 5 -Warning 1265 Data truncated for column 't' at row 6 +Warning 1264 Out of range value adjusted for column 't' at row 1 +Warning 1264 Out of range value adjusted for column 't' at row 2 +Warning 1264 Out of range value adjusted for column 't' at row 3 +Warning 1264 Out of range value adjusted for column 't' at row 4 +Warning 1264 Out of range value adjusted for column 't' at row 5 +Warning 1264 Out of range value adjusted for column 't' at row 6 select * from t1; t 0000-00-00 00:00:00 diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 624fae4d728..c8078a0604e 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2016,3 +2016,11 @@ CALL p1(); DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1; +create table t1(f1 datetime); +insert into t1 values('2005.01.01 12:0:0'); +create view v1 as select f1, subtime(f1, '1:1:1') as sb from t1; +select * from v1; +f1 sb +2005-01-01 12:00:00 2005-01-01 10:58:59 +drop view v1; +drop table t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index c5f96ec4201..7d397ff2112 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,3 +11,4 @@ ############################################################################## sp-goto:GOTO is currently is disabled - will be fixed in the future +ndb_condition_pushdown:Bug #12021 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 90f42f3896e..ef26712af06 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2152,10 +2152,17 @@ INSERT INTO t1 VALUES SELECT K2C4, K4N4, F2I4 FROM t1 WHERE K2C4 = 'WART' AND (F2I4 = 2 AND K2C4 = 'WART' OR (F2I4 = 2 OR K4N4 = '0200')); - SELECT K2C4, K4N4, F2I4 FROM t1 WHERE K2C4 = 'WART' AND (K2C4 = 'WART' OR K4N4 = '0200'); +select found_rows(); +select count(*) from t1; +select found_rows(); +select count(*) from t1 limit 2,3; +select found_rows(); +select SQL_CALC_FOUND_ROWS count(*) from t1 limit 2,3; +select found_rows(); + DROP TABLE t1; # diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 6ac88e4d629..71b57424e75 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1103,3 +1103,18 @@ create table t1(a int, b date not null); alter table t1 modify a bigint unsigned not null; show create table t1; drop table t1; + +# +# Bug #5906: handle invalid date due to conversion +# +set @@sql_mode='traditional'; +create table t1 (d date); +--error 1292 +insert into t1 values ('2000-10-00'); +--error 1292 +insert into t1 values (1000); +insert into t1 values ('2000-10-01'); +--error 1292 +update t1 set d = 1100; +select * from t1; +drop table t1; diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test index 0b5aaed5d30..40fcd153877 100644 --- a/mysql-test/t/timezone2.test +++ b/mysql-test/t/timezone2.test @@ -48,6 +48,11 @@ insert into t1 (i, ts) values (unix_timestamp('2003-03-30 01:59:59'),'2003-03-30 01:59:59'), (unix_timestamp('2003-03-30 02:30:00'),'2003-03-30 02:30:00'), (unix_timestamp('2003-03-30 03:00:00'),'2003-03-30 03:00:00'); +# Values around and in spring time-gap +insert into t1 (i, ts) values + (unix_timestamp(20030330015959),20030330015959), + (unix_timestamp(20030330023000),20030330023000), + (unix_timestamp(20030330030000),20030330030000); # Normal value with DST insert into t1 (i, ts) values (unix_timestamp('2003-05-01 00:00:00'),'2003-05-01 00:00:00'); diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 449bca63f0d..16a94820596 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1853,3 +1853,13 @@ CALL p1(); DROP PROCEDURE p1; DROP VIEW v1; DROP TABLE t1; + +# +# Bug #11760 Typo in Item_func_add_time::print() results in NULLs returned +# subtime() in view +create table t1(f1 datetime); +insert into t1 values('2005.01.01 12:0:0'); +create view v1 as select f1, subtime(f1, '1:1:1') as sb from t1; +select * from v1; +drop view v1; +drop table t1; diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 3a06c4d1fb5..873aff251db 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -106,29 +106,47 @@ parse_arguments() { } +# +# First, try to find BASEDIR and ledir (where mysqld is) +# + MY_PWD=`pwd` -# Check if we are starting this relative (for the binary release) -if test -f ./share/mysql/english/errmsg.sys -a \ - -x ./bin/mysqld +# Check for the directories we would expect from a binary release install +if test -f ./share/mysql/english/errmsg.sys -a -x ./bin/mysqld then MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is +# Check for the directories we would expect from a source install +elif test -f ./share/mysql/english/errmsg.sys -a \ + -x ./libexec/mysqld +then + MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are + ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is +# Since we didn't find anything, used the compiled-in defaults +else + MY_BASEDIR_VERSION=@prefix@ + ledir=@libexecdir@ +fi + +# +# Second, try to find the data directory +# + +# Try where the binary installs put it +if test -d $MY_BASEDIR_VERSION/data/mysql +then DATADIR=$MY_BASEDIR_VERSION/data if test -z "$defaults" -a -r "$DATADIR/my.cnf" then defaults="--defaults-extra-file=$DATADIR/my.cnf" fi -# Check if this is a 'moved install directory' -elif test -f ./share/mysql/english/errmsg.sys -a \ - -x ./libexec/mysqld +# Next try where the source installs put it +elif test -d $MY_BASEDIR_VERSION/var/mysql then - MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are - ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is DATADIR=$MY_BASEDIR_VERSION/var +# Or just give up and use our compiled-in default else - MY_BASEDIR_VERSION=@prefix@ DATADIR=@localstatedir@ - ledir=@libexecdir@ fi if test -z "$MYSQL_HOME" diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 1078259f15d..c00c0e7be83 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -56,11 +56,14 @@ uint calc_days_in_year(uint year) } /* - check date. + Check datetime value for validity according to flags. - SYNOPOSIS - bool check_date() - time Date to check. + SYNOPSIS + check_date() + ltime - Date to check. + not_zero_date - ltime is not the zero date + flags - flags to check + was_cut - set to whether the value was truncated NOTES Here we assume that year and month is ok ! @@ -69,18 +72,35 @@ uint calc_days_in_year(uint year) RETURN 0 ok - 1 errro + 1 error */ -bool check_date(MYSQL_TIME *ltime) +bool check_date(const MYSQL_TIME *ltime, bool not_zero_date, ulong flags, + int *was_cut) { - if (ltime->month && ltime->day > days_in_month[ltime->month-1]) + + if (not_zero_date) { - if (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 || - ltime->day != 29) - return 1; + if ((((flags & TIME_NO_ZERO_IN_DATE) || !(flags & TIME_FUZZY_DATE)) && + (ltime->month == 0 || ltime->day == 0)) || + (!(flags & TIME_INVALID_DATES) && + ltime->month && ltime->day > days_in_month[ltime->month-1] && + (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 || + ltime->day != 29))) + { + *was_cut= 2; + return TRUE; + } } - return 0; + else if (flags & TIME_NO_ZERO_DATE) + { + /* + We don't set *was_cut here to signal that the problem was a zero date + and not an invalid date + */ + return TRUE; + } + return FALSE; } @@ -100,7 +120,7 @@ bool check_date(MYSQL_TIME *ltime) TIME_INVALID_DATES Allow 2000-02-31 was_cut 0 Value ok 1 If value was cut during conversion - 2 Date part was withing ranges but date was wrong + 2 Date part was within ranges but date was wrong DESCRIPTION At least the following formats are recogniced (based on number of digits) @@ -168,8 +188,6 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, *was_cut= 1; DBUG_RETURN(MYSQL_TIMESTAMP_NONE); } - if (flags & TIME_NO_ZERO_IN_DATE) - flags&= ~TIME_FUZZY_DATE; is_internal_format= 0; /* This has to be changed if want to activate different timestamp formats */ @@ -385,22 +403,10 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, if (year_length == 2 && not_zero_date) l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); - if (!not_zero_date && (flags & TIME_NO_ZERO_DATE)) - { - /* - We don't set *was_cut here to signal that the problem was a zero date - and not an invalid date - */ - goto err; - } - if (number_of_fields < 3 || l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || - l_time->minute > 59 || l_time->second > 59 || - (!(flags & TIME_FUZZY_DATE) && (l_time->month == 0 || - l_time->day == 0) && - not_zero_date)) + l_time->minute > 59 || l_time->second > 59) { /* Only give warning for a zero date if there is some garbage after */ if (!not_zero_date) /* If zero date */ @@ -418,15 +424,12 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, goto err; } + if (check_date(l_time, not_zero_date, flags, was_cut)) + goto err; + l_time->time_type= (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME); - if (not_zero_date && !(flags & TIME_INVALID_DATES) && check_date(l_time)) - { - *was_cut= 2; /* Not correct date */ - goto err; - } - for (; str != end ; str++) { if (!my_isspace(&my_charset_latin1,*str)) @@ -881,9 +884,10 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to) number_to_datetime() nr - datetime value as number time_res - pointer for structure for broken-down representation - fuzzy_date - indicates whenever we allow fuzzy dates - was_cut - set ot 1 if there was some kind of error during - conversion or to 0 if everything was OK. + flags - flags to use in validating date, as in str_to_datetime() + was_cut 0 Value ok + 1 If value was cut during conversion + 2 Date part was within ranges but date was wrong DESCRIPTION Convert a datetime value of formats YYMMDD, YYYYMMDD, YYMMDDHHMSS, @@ -893,12 +897,13 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to) This function also checks if datetime value fits in DATETIME range. RETURN VALUE + -1 Timestamp with wrong values + anything else DATETIME as integer in YYYYMMDDHHMMSS format Datetime value in YYYYMMDDHHMMSS format. - If input value is not valid datetime value then 0 is returned. */ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, - my_bool fuzzy_date, int *was_cut) + uint flags, int *was_cut) { long part1,part2; @@ -952,13 +957,17 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, if (time_res->year <= 9999 && time_res->month <= 12 && time_res->day <= 31 && time_res->hour <= 23 && time_res->minute <= 59 && time_res->second <= 59 && - (fuzzy_date || (time_res->month != 0 && time_res->day != 0) || nr==0)) + !check_date(time_res, (nr != 0), flags, was_cut)) return nr; + /* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */ + if (!nr && flags & TIME_NO_ZERO_DATE) + return LL(-1); + err: *was_cut= 1; - return LL(0); + return LL(-1); } diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc index 34bcbd4fc4b..77cb0c8de0f 100644 --- a/sql/des_key_file.cc +++ b/sql/des_key_file.cc @@ -21,18 +21,6 @@ struct st_des_keyschedule des_keyschedule[10]; uint des_default_key; -pthread_mutex_t LOCK_des_key_file; -static int initialized= 0; - -void -init_des_key_file() -{ - if (!initialized) - { - initialized=1; - pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); - } -} /* Function which loads DES keys from plaintext file into memory on MySQL @@ -55,8 +43,6 @@ load_des_key_file(const char *file_name) DBUG_ENTER("load_des_key_file"); DBUG_PRINT("enter",("name: %s",file_name)); - init_des_key_file(); - VOID(pthread_mutex_lock(&LOCK_des_key_file)); if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 || init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME))) @@ -113,15 +99,4 @@ error: VOID(pthread_mutex_unlock(&LOCK_des_key_file)); DBUG_RETURN(result); } - - -void free_des_key_file() -{ - if (initialized) - { - initialized= 01; - pthread_mutex_destroy(&LOCK_des_key_file); - } -} - #endif /* HAVE_OPENSSL */ diff --git a/sql/field.cc b/sql/field.cc index 0a8f0a39262..7661041eca2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4472,13 +4472,13 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) bool in_dst_time_gap; THD *thd= table->in_use; + /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ have_smth_to_conv= (str_to_datetime(from, len, &l_time, - ((table->in_use->variables.sql_mode & - MODE_NO_ZERO_DATE) | - MODE_NO_ZERO_IN_DATE), - &error) > + (table->in_use->variables.sql_mode & + MODE_NO_ZERO_DATE) | + MODE_NO_ZERO_IN_DATE, &error) > MYSQL_TIMESTAMP_ERROR); - + if (error || !have_smth_to_conv) { error= 1; @@ -4491,16 +4491,15 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { if (!(tmp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_DATETIME, !error); - error= 1; } else if (in_dst_time_gap) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_INVALID_TIMESTAMP, + ER_WARN_INVALID_TIMESTAMP, from, len, MYSQL_TIMESTAMP_DATETIME, !error); error= 1; } @@ -4525,8 +4524,8 @@ int Field_timestamp::store(double nr) int error= 0; if (nr < 0 || nr > 99991231235959.0) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATETIME); nr= 0; // Avoid overflow on buff error= 1; @@ -4544,35 +4543,35 @@ int Field_timestamp::store(longlong nr) bool in_dst_time_gap; THD *thd= table->in_use; - if (number_to_datetime(nr, &l_time, 0, &error)) + /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ + long tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode & + MODE_NO_ZERO_DATE) | + MODE_NO_ZERO_IN_DATE, &error); + if (tmp < 0) + { + error= 2; + } + + if (!error && tmp) { if (!(timestamp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - nr, MYSQL_TIMESTAMP_DATETIME, 1); + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, + nr, MYSQL_TIMESTAMP_DATETIME, 1); error= 1; } - if (in_dst_time_gap) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_INVALID_TIMESTAMP, - nr, MYSQL_TIMESTAMP_DATETIME, !error); + ER_WARN_INVALID_TIMESTAMP, + nr, MYSQL_TIMESTAMP_DATETIME, 1); error= 1; } - } - else if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + } else if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATETIME, 1); - if (!error && timestamp == 0 && - (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE)) - { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, - nr, MYSQL_TIMESTAMP_DATETIME, 1); - } #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4582,7 +4581,7 @@ int Field_timestamp::store(longlong nr) else #endif longstore(ptr,(uint32) timestamp); - + return error; } @@ -5155,14 +5154,14 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) TIME l_time; uint32 tmp; int error; - + if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE | (table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)), &error) <= MYSQL_TIMESTAMP_ERROR) { - tmp=0; + tmp= 0; error= 2; } else @@ -5193,56 +5192,50 @@ int Field_date::store(double nr) if (nr < 0.0 || nr > 99991231.0) { tmp=0L; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATE); error= 1; } else tmp=(long) rint(nr); - /* - We don't need to check for zero dates here as this date type is only - used in .frm tables from very old MySQL versions - */ - -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - { - int4store(ptr,tmp); - } - else -#endif - longstore(ptr,tmp); - return error; + return Field_date::store(tmp); } int Field_date::store(longlong nr) { - long tmp; - int error= 0; - if (nr >= LL(19000000000000) && nr < LL(99991231235959)) - nr=nr/LL(1000000); // Timestamp to date - if (nr < 0 || nr > LL(99991231)) + TIME not_used; + int error; + longlong initial_nr= nr; + + nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | + MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), &error); + + if (nr < 0) { - tmp=0L; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - nr, MYSQL_TIMESTAMP_DATE, 0); - error= 1; + nr= 0; + error= 2; } - else - tmp=(long) nr; + + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED, initial_nr, + MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { - int4store(ptr,tmp); + int4store(ptr, nr); } else #endif - longstore(ptr,tmp); + longstore(ptr, nr); return error; } @@ -5366,7 +5359,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) MODE_INVALID_DATES))), &error) <= MYSQL_TIMESTAMP_ERROR) { - tmp=0L; + tmp= 0L; error= 2; } else @@ -5375,7 +5368,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_DATE, 1); - + int3store(ptr,tmp); return error; } @@ -5386,7 +5379,7 @@ int Field_newdate::store(double nr) if (nr < 0.0 || nr > 99991231235959.0) { int3store(ptr,(int32) 0); - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); return 1; } @@ -5396,52 +5389,28 @@ int Field_newdate::store(double nr) int Field_newdate::store(longlong nr) { - int32 tmp; - int error= 0; - if (nr >= LL(100000000) && nr <= LL(99991231235959)) - nr=nr/LL(1000000); // Timestamp to date - if (nr < 0L || nr > 99991231L) - { - tmp=0; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, - MYSQL_TIMESTAMP_DATE, 1); - error= 1; + TIME l_time; + long tmp; + int error; + if ((tmp= number_to_datetime(nr, &l_time, + (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), + &error) < 0)) + { + tmp= 0L; + error= 2; } else - { - uint month, day; + tmp= l_time.day + l_time.month*32 + l_time.year*16*32; - tmp=(int32) nr; - if (tmp) - { - if (tmp < YY_PART_YEAR*10000L) // Fix short dates - tmp+= (uint32) 20000000L; - else if (tmp < 999999L) - tmp+= (uint32) 19000000L; - - month= (uint) ((tmp/100) % 100); - day= (uint) (tmp%100); - if (month > 12 || day > 31) - { - tmp=0L; // Don't allow date to change - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, - MYSQL_TIMESTAMP_DATE, 1); - error= 1; - } - else - tmp= day + month*32 + (tmp/10000)*16*32; - } - else if (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) - { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - 0, MYSQL_TIMESTAMP_DATE); - error= 1; - } - } - int3store(ptr, tmp); + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED,nr,MYSQL_TIMESTAMP_DATE, 1); + + int3store(ptr,tmp); return error; } @@ -5568,7 +5537,7 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) int error; ulonglong tmp= 0; enum enum_mysql_timestamp_type func_res; - + func_res= str_to_datetime(from, len, &time_tmp, (TIME_FUZZY_DATE | (table->in_use->variables.sql_mode & @@ -5581,7 +5550,7 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; // Fix if invalid zero date if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_DATETIME, 1); @@ -5618,21 +5587,25 @@ int Field_datetime::store(longlong nr) TIME not_used; int error; longlong initial_nr= nr; - - nr= number_to_datetime(nr, ¬_used, 1, &error); - if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, initial_nr, - MYSQL_TIMESTAMP_DATETIME, 1); - else if (nr == 0 && table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) + nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | + MODE_NO_ZERO_DATE | + MODE_INVALID_DATES))), &error); + + if (nr < 0) { - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, - initial_nr, MYSQL_TIMESTAMP_DATE, 1); - error= 1; + nr= 0; + error= 2; } + if (error) + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : + WARN_DATA_TRUNCATED, initial_nr, + MYSQL_TIMESTAMP_DATETIME, 1); + #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 0dc82666f52..fc7347ef9af 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -322,7 +322,34 @@ static void do_field_real(Copy_field *copy) } +/* + string copy for single byte characters set when to string is shorter than + from string +*/ + static void do_cut_string(Copy_field *copy) +{ + CHARSET_INFO *cs= copy->from_field->charset(); + memcpy(copy->to_ptr,copy->from_ptr,copy->to_length); + + /* Check if we loosed any important characters */ + if (cs->cset->scan(cs, + copy->from_ptr + copy->to_length, + copy->from_ptr + copy->from_length, + MY_SEQ_SPACES) < copy->from_length - copy->to_length) + { + copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1); + } +} + + +/* + string copy for multi byte characters set when to string is shorter than + from string +*/ + +static void do_cut_string_complex(Copy_field *copy) { // Shorter string field int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); @@ -349,6 +376,8 @@ static void do_cut_string(Copy_field *copy) } + + static void do_expand_string(Copy_field *copy) { CHARSET_INFO *cs= copy->from_field->charset(); @@ -550,7 +579,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) do_varstring1 : do_varstring2); } else if (to_length < from_length) - return do_cut_string; + return (from->charset()->mbmaxlen == 1 ? + do_cut_string : do_cut_string_complex); else if (to_length > from_length) return do_expand_string; } diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 856a053db9e..ae6952d4e5b 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -26,7 +26,7 @@ /* Blackhole storage engine handlerton */ -static handlerton myisam_hton= { +static handlerton blackhole_hton= { "BLACKHOLE", 0, /* slot */ 0, /* savepoint size. */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c3882436149..59d05368779 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -709,8 +709,8 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, blob_ptr= (char*)""; } - DBUG_PRINT("value", ("set blob ptr=%x len=%u", - (unsigned)blob_ptr, blob_len)); + DBUG_PRINT("value", ("set blob ptr=%p len=%u", + blob_ptr, blob_len)); DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26)); if (set_blob_value) diff --git a/sql/hostname.cc b/sql/hostname.cc index 39223556024..12b69a97859 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -130,15 +130,23 @@ void reset_host_errors(struct in_addr *in) VOID(pthread_mutex_unlock(&hostname_cache->lock)); } +/* Deal with systems that don't defined INADDR_LOOPBACK */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001UL +#endif my_string ip_to_hostname(struct in_addr *in, uint *errors) { uint i; host_entry *entry; DBUG_ENTER("ip_to_hostname"); + *errors=0; + + /* We always treat the loopback address as "localhost". */ + if (in->s_addr == INADDR_LOOPBACK) + return (char *)my_localhost; /* Check first if we have name in cache */ - *errors=0; if (!(specialflag & SPECIAL_NO_HOST_CACHE)) { VOID(pthread_mutex_lock(&hostname_cache->lock)); diff --git a/sql/item.cc b/sql/item.cc index 593708688f1..604f2f6dd2c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3328,7 +3328,12 @@ void Item::make_field(Send_field *tmp_field) void Item_empty_string::make_field(Send_field *tmp_field) { - init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); + enum_field_types type= FIELD_TYPE_VAR_STRING; + if (max_length >= 16777216) + type= FIELD_TYPE_LONG_BLOB; + else if (max_length >= 65536) + type= FIELD_TYPE_MEDIUM_BLOB; + init_make_field(tmp_field, type); } diff --git a/sql/item_func.cc b/sql/item_func.cc index c3bdb11418f..53895cc7331 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4231,14 +4231,15 @@ Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, bool Item_func_get_system_var::fix_fields(THD *thd, Item **ref) { - Item *item= var->item(thd, var_type, &component); + Item *item; DBUG_ENTER("Item_func_get_system_var::fix_fields"); + /* Evaluate the system variable and substitute the result (a basic constant) instead of this item. If the variable can not be evaluated, the error is reported in sys_var::item(). */ - if (item == 0) + if (!(item= var->item(thd, var_type, &component))) DBUG_RETURN(1); // Impossible item->set_name(name, 0, system_charset_info); // don't allocate a new name thd->change_item_tree(ref, item); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6d519c73b13..eb37609c28e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -335,19 +335,20 @@ null: void Item_func_concat::fix_length_and_dec() { - max_length=0; + ulonglong max_result_length= 0; if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) return; for (uint i=0 ; i < arg_count ; i++) - max_length+=args[i]->max_length; + max_result_length+= args[i]->max_length; - if (max_length > MAX_BLOB_WIDTH) + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } /* @@ -378,9 +379,6 @@ String *Item_func_des_encrypt::val_str(String *str) if (arg_count == 1) { - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - /* Protect against someone doing FLUSH DES_KEY_FILE */ VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number=des_default_key]; @@ -391,10 +389,6 @@ String *Item_func_des_encrypt::val_str(String *str) key_number= (uint) args[1]->val_int(); if (key_number > 9) goto error; - - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number]; VOID(pthread_mutex_unlock(&LOCK_des_key_file)); @@ -482,9 +476,6 @@ String *Item_func_des_decrypt::val_str(String *str) if (!(current_thd->master_access & SUPER_ACL) || key_number > 9) goto error; - /* Make sure LOCK_des_key_file was initialized. */ - init_des_key_file(); - VOID(pthread_mutex_lock(&LOCK_des_key_file)); keyschedule= des_keyschedule[key_number]; VOID(pthread_mutex_unlock(&LOCK_des_key_file)); @@ -658,7 +649,7 @@ null: void Item_func_concat_ws::fix_length_and_dec() { - max_length=0; + ulonglong max_result_length; if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) return; @@ -668,15 +659,16 @@ void Item_func_concat_ws::fix_length_and_dec() it is done on parser level in sql_yacc.yy so, (arg_count - 2) is safe here. */ - max_length= args[0]->max_length * (arg_count - 2); + max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2); for (uint i=1 ; i < arg_count ; i++) - max_length+=args[i]->max_length; + max_result_length+=args[i]->max_length; - if (max_length > MAX_BLOB_WIDTH) + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } @@ -855,18 +847,19 @@ null: void Item_func_replace::fix_length_and_dec() { - max_length=args[0]->max_length; + ulonglong max_result_length= args[0]->max_length; int diff=(int) (args[2]->max_length - args[1]->max_length); if (diff > 0 && args[1]->max_length) { // Calculate of maxreplaces - uint max_substrs= max_length/args[1]->max_length; - max_length+= max_substrs * (uint) diff; + ulonglong max_substrs= max_result_length/args[1]->max_length; + max_result_length+= max_substrs * (uint) diff; } - if (max_length > MAX_BLOB_WIDTH) + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV)) return; @@ -914,18 +907,22 @@ null: void Item_func_insert::fix_length_and_dec() { Item *cargs[2]; + ulonglong max_result_length; + cargs[0]= args[0]; cargs[1]= args[3]; if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) return; args[0]= cargs[0]; args[3]= cargs[1]; - max_length=args[0]->max_length+args[3]->max_length; - if (max_length > MAX_BLOB_WIDTH) + max_result_length= ((ulonglong) args[0]->max_length+ + (ulonglong) args[3]->max_length); + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } @@ -2001,17 +1998,19 @@ void Item_func_repeat::fix_length_and_dec() collation.set(args[0]->collation); if (args[1]->const_item()) { - max_length=(long) (args[0]->max_length * args[1]->val_int()); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong max_result_length= ((ulonglong) args[0]->max_length * + args[1]->val_int()); + if (max_result_length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_result_length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) max_result_length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } @@ -2066,6 +2065,7 @@ err: void Item_func_rpad::fix_length_and_dec() { Item *cargs[2]; + cargs[0]= args[0]; cargs[1]= args[2]; if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) @@ -2074,18 +2074,20 @@ void Item_func_rpad::fix_length_and_dec() args[2]= cargs[1]; if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; - max_length=max(args[0]->max_length,length); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong length= ((ulonglong) args[1]->val_int() * + collation.collation->mbmaxlen); + length= max((ulonglong) args[0]->max_length, length); + if (length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } @@ -2160,18 +2162,20 @@ void Item_func_lpad::fix_length_and_dec() if (args[1]->const_item()) { - uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen; - max_length=max(args[0]->max_length,length); - if (max_length >= MAX_BLOB_WIDTH) + ulonglong length= ((ulonglong) args[1]->val_int() * + collation.collation->mbmaxlen); + length= max((ulonglong) args[0]->max_length, length); + if (length >= MAX_BLOB_WIDTH) { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + length= MAX_BLOB_WIDTH; + maybe_null= 1; } + max_length= (ulong) length; } else { - max_length=MAX_BLOB_WIDTH; - maybe_null=1; + max_length= MAX_BLOB_WIDTH; + maybe_null= 1; } } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cac9613f1ad..aa377d0bdd8 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1555,7 +1555,7 @@ void Item_func_date_format::fix_length_and_dec() { fixed_length=0; /* The result is a binary string (no reason to use collation->mbmaxlen */ - max_length=args[1]->max_length*10; + max_length=min(args[1]->max_length,MAX_BLOB_WIDTH) * 10; set_if_smaller(max_length,MAX_BLOB_WIDTH); } maybe_null=1; // If wrong date @@ -2524,7 +2524,7 @@ void Item_func_add_time::print(String *str) } args[0]->print(str); str->append(','); - args[0]->print(str); + args[1]->print(str); str->append(')'); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 9b30989278e..29f1160466e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000-2004 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 */ @@ -2775,6 +2775,16 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, */ handle_dup= DUP_ERROR; } + /* + We need to set thd->lex->sql_command and thd->lex->duplicates + since InnoDB tests these variables to decide if this is a LOAD + DATA ... REPLACE INTO ... statement even though mysql_parse() + is not called. This is not needed in 5.0 since there the LOAD + DATA ... statement is replicated using mysql_parse(), which + sets the thd->lex fields correctly. + */ + thd->lex->sql_command= SQLCOM_LOAD; + thd->lex->duplicates= handle_dup; sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG); String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 933b2f8efad..1cc1aa836a8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -806,9 +806,7 @@ extern char *des_key_file; extern struct st_des_keyschedule des_keyschedule[10]; extern uint des_default_key; extern pthread_mutex_t LOCK_des_key_file; -void init_des_key_file(); bool load_des_key_file(const char *file_name); -void free_des_key_file(); #endif /* HAVE_OPENSSL */ /* sql_do.cc */ @@ -1173,8 +1171,11 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, - LOCK_global_system_variables, LOCK_user_conn, + LOCK_global_system_variables, LOCK_user_conn, LOCK_bytes_sent, LOCK_bytes_received; +#ifdef HAVE_OPENSSL +extern pthread_mutex_t LOCK_des_key_file; +#endif extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 412d6175e10..e4a44b41317 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -448,6 +448,9 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; +#ifdef HAVE_OPENSSL +pthread_mutex_t LOCK_des_key_file; +#endif rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; pthread_cond_t COND_refresh,COND_thread_count; pthread_t signal_thread; @@ -676,7 +679,11 @@ static void close_connections(void) end_thr_alarm(0); // Abort old alarms. end_slave(); - /* First signal all threads that it's time to die */ + /* + First signal all threads that it's time to die + This will give the threads some time to gracefully abort their + statements and inform their clients that the server is about to die. + */ THD *tmp; (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list @@ -686,13 +693,7 @@ static void close_connections(void) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", tmp->thread_id)); - /* - Re: bug 7403 - close_connection will be called mulitple times - a wholesale clean up of our network code is a very large project. - This will wake up the socket on Windows and prevent the printing of - the error message that we are force closing a connection. - */ - close_connection(tmp, 0, 0); + tmp->killed= THD::KILL_CONNECTION; if (tmp->mysys_var) { tmp->mysys_var->abort=1; @@ -709,9 +710,13 @@ static void close_connections(void) (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list if (thread_count) - sleep(1); // Give threads time to die + sleep(2); // Give threads time to die - /* Force remaining threads to die by closing the connection to the client */ + /* + Force remaining threads to die by closing the connection to the client + This will ensure that threads that are waiting for a command from the + client on a blocking read call are aborted. + */ for (;;) { @@ -726,8 +731,9 @@ static void close_connections(void) #ifndef __bsdi__ // Bug in BSDI kernel if (tmp->vio_ok()) { - sql_print_error(ER(ER_FORCING_CLOSE),my_progname, - tmp->thread_id,tmp->user ? tmp->user : ""); + if (global_system_variables.log_warnings) + sql_print_warning(ER(ER_FORCING_CLOSE),my_progname, + tmp->thread_id,tmp->user ? tmp->user : ""); close_connection(tmp,0,0); } #endif @@ -1040,7 +1046,6 @@ void clean_up(bool print_message) #ifdef HAVE_OPENSSL if (ssl_acceptor_fd) my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); - free_des_key_file(); #endif /* HAVE_OPENSSL */ #ifdef USE_REGEX regex_end(); @@ -1112,6 +1117,9 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_received); (void) pthread_mutex_destroy(&LOCK_user_conn); +#ifdef HAVE_OPENSSL + (void) pthread_mutex_destroy(&LOCK_des_key_file); +#endif #ifdef HAVE_REPLICATION (void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status); @@ -2615,6 +2623,9 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); +#ifdef HAVE_OPENSSL + (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); +#endif (void) my_rwlock_init(&LOCK_sys_init_connect, NULL); (void) my_rwlock_init(&LOCK_sys_init_slave, NULL); (void) my_rwlock_init(&LOCK_grant, NULL); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 58af959888e..3a7defebddd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -779,29 +779,19 @@ static int check_connection(THD *thd) return (ER_OUT_OF_RESOURCES); thd->host_or_ip= thd->ip; vio_in_addr(net->vio,&thd->remote.sin_addr); -#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread) - /* Fast local hostname resolve for Win32 */ - if (!strcmp(thd->ip,"127.0.0.1")) + if (!(specialflag & SPECIAL_NO_RESOLVE)) { - thd->host= (char*) my_localhost; - thd->host_or_ip= my_localhost; - } - else -#endif - { - if (!(specialflag & SPECIAL_NO_RESOLVE)) + vio_in_addr(net->vio,&thd->remote.sin_addr); + thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); + /* Cut very long hostnames to avoid possible overflows */ + if (thd->host) { - vio_in_addr(net->vio,&thd->remote.sin_addr); - thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); - /* Cut very long hostnames to avoid possible overflows */ - if (thd->host) - { - thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0; - thd->host_or_ip= thd->host; - } - if (connect_errors > max_connect_errors) - return(ER_HOST_IS_BLOCKED); + if (thd->host != my_localhost) + thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0; + thd->host_or_ip= thd->host; } + if (connect_errors > max_connect_errors) + return(ER_HOST_IS_BLOCKED); } DBUG_PRINT("info",("Host: %s ip: %s", thd->host ? thd->host : "unknown host", diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9ec2cff71a1..87366fe157d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -319,7 +319,7 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len) return; float4get(data,*pos); #else - data= *(float*) *pos; + floatget(data, *pos); #endif param->set_double((double) data); *pos+= 4; @@ -333,7 +333,7 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len) return; float8get(data,*pos); #else - data= *(double*) *pos; + doubleget(data, *pos); #endif param->set_double((double) data); *pos+= 8; @@ -601,10 +601,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, Item_param **begin= stmt->param_array; Item_param **end= begin + stmt->param_count; uint32 length= 0; - String str; const String *res; - DBUG_ENTER("insert_params_withlog"); if (query->copy(stmt->query, stmt->query_length, default_charset_info)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 45460d0da01..e994b5ff26b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1203,14 +1203,18 @@ JOIN::exec() else { error= (int) result->send_eof(); - send_records=1; + send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : + thd->sent_row_count); } } else + { error=(int) result->send_eof(); + send_records= 0; + } } - /* Single select (without union and limit) always returns 1 row */ - thd->limit_found_rows= 1; + /* Single select (without union) always returns 0 or 1 row */ + thd->limit_found_rows= send_records; thd->examined_row_count= 0; DBUG_VOID_RETURN; } @@ -5212,6 +5216,7 @@ static void add_not_null_conds(JOIN *join) if (tab->ref.null_rejecting & (1 << keypart)) { Item *item= tab->ref.items[keypart]; + Item *notnull; DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *not_null_item= (Item_field*)item; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; @@ -5222,7 +5227,6 @@ static void add_not_null_conds(JOIN *join) */ if (!referred_tab || referred_tab->join != join) continue; - Item *notnull; if (!(notnull= new Item_func_isnotnull(not_null_item))) DBUG_VOID_RETURN; /* diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp index b1fe0735612..34a2d8c1302 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp @@ -62,8 +62,6 @@ ConfigInfo::m_sectionNames[]={ DB_TOKEN, MGM_TOKEN, API_TOKEN, - "REP", - "EXTERNAL REP", "TCP", "SCI", @@ -100,6 +98,7 @@ static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char * static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data); static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data); static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data); +static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data); const ConfigInfo::SectionRule ConfigInfo::m_SectionRules[] = { @@ -110,8 +109,6 @@ ConfigInfo::m_SectionRules[] = { { DB_TOKEN, transformNode, 0 }, { API_TOKEN, transformNode, 0 }, { MGM_TOKEN, transformNode, 0 }, - { "REP", transformNode, 0 }, - { "EXTERNAL REP", transformExtNode, 0 }, { MGM_TOKEN, fixShmUniqueId, 0 }, @@ -128,8 +125,6 @@ ConfigInfo::m_SectionRules[] = { { DB_TOKEN, fixNodeHostname, 0 }, { API_TOKEN, fixNodeHostname, 0 }, { MGM_TOKEN, fixNodeHostname, 0 }, - { "REP", fixNodeHostname, 0 }, - //{ "EXTERNAL REP", fixNodeHostname, 0 }, { "TCP", fixNodeId, "NodeId1" }, { "TCP", fixNodeId, "NodeId2" }, @@ -168,6 +163,10 @@ ConfigInfo::m_SectionRules[] = { { "*", fixDepricated, 0 }, { "*", applyDefaultValues, "system" }, + { DB_TOKEN, checkLocalhostHostnameMix, 0 }, + { API_TOKEN, checkLocalhostHostnameMix, 0 }, + { MGM_TOKEN, checkLocalhostHostnameMix, 0 }, + { DB_TOKEN, fixFileSystemPath, 0 }, { DB_TOKEN, fixBackupDataDir, 0 }, @@ -193,7 +192,6 @@ ConfigInfo::m_SectionRules[] = { { DB_TOKEN, saveInConfigValues, 0 }, { API_TOKEN, saveInConfigValues, 0 }, { MGM_TOKEN, saveInConfigValues, 0 }, - { "REP", saveInConfigValues, 0 }, { "TCP", saveInConfigValues, 0 }, { "SHM", saveInConfigValues, 0 }, @@ -345,17 +343,6 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0 }, { - CFG_SYS_REPLICATION_ROLE, - "ReplicationRole", - "SYSTEM", - "Role in Global Replication (None, Primary, or Standby)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { CFG_SYS_PRIMARY_MGM_NODE, "PrimaryMGMNode", "SYSTEM", @@ -402,7 +389,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INTERNAL, false, ConfigInfo::CI_STRING, - UNDEFINED, + "localhost", 0, 0 }, { @@ -1219,78 +1206,6 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { STR_VALUE(MAX_INT_RNIL) }, /*************************************************************************** - * REP - ***************************************************************************/ - { - CFG_SECTION_NODE, - "REP", - "REP", - "Node section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)NODE_TYPE_REP, - 0, 0 - }, - - { - CFG_NODE_HOST, - "HostName", - "REP", - "Name of computer for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_NODE_SYSTEM, - "System", - "REP", - "Name of system for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_NODE_ID, - "Id", - "REP", - "Number identifying replication node (REP)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_NODES) }, - - { - KEY_INTERNAL, - "ExecuteOnComputer", - "REP", - "String referencing an earlier defined COMPUTER", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_REP_HEARTBEAT_INTERVAL, - "HeartbeatIntervalRepRep", - "REP", - "Time between REP-REP heartbeats. Connection closed after 3 missed HBs", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "3000", - "100", - STR_VALUE(MAX_INT_RNIL) }, - - /*************************************************************************** * API ***************************************************************************/ { @@ -1313,7 +1228,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INTERNAL, false, ConfigInfo::CI_STRING, - UNDEFINED, + "", 0, 0 }, { @@ -1433,7 +1348,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INTERNAL, false, ConfigInfo::CI_STRING, - UNDEFINED, + "", 0, 0 }, { @@ -2464,7 +2379,15 @@ ConfigInfo::isSection(const char * section) const { } const char* -ConfigInfo::getAlias(const char * section) const { +ConfigInfo::nameToAlias(const char * name) { + for (int i = 0; m_sectionNameAliases[i].name != 0; i++) + if(!strcasecmp(name, m_sectionNameAliases[i].name)) + return m_sectionNameAliases[i].alias; + return 0; +} + +const char* +ConfigInfo::getAlias(const char * section) { for (int i = 0; m_sectionNameAliases[i].name != 0; i++) if(!strcasecmp(section, m_sectionNameAliases[i].alias)) return m_sectionNameAliases[i].name; @@ -2623,7 +2546,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ return true; } -static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx) +static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data) { DBUG_ENTER("checkLocalhostHostnameMix"); const char * hostname= 0; @@ -2643,7 +2566,7 @@ static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx) } if (localhost_used) { - ctx.reportError("Mixing of localhost with other hostname(%s) is illegal", + ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal", hostname); DBUG_RETURN(false); } @@ -2652,21 +2575,17 @@ static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx) } bool -fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ - +fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data) +{ const char * hostname; + DBUG_ENTER("fixNodeHostname"); + if (ctx.m_currentSection->get("HostName", &hostname)) - return checkLocalhostHostnameMix(ctx); + DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); const char * compId; - if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)){ - const char * type; - if(ctx.m_currentSection->get("Type", &type) && strcmp(type,DB_TOKEN) == 0) - require(ctx.m_currentSection->put("HostName", "localhost")); - else - require(ctx.m_currentSection->put("HostName", "")); - return checkLocalhostHostnameMix(ctx); - } + if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)) + DBUG_RETURN(true); const Properties * computer; char tmp[255]; @@ -2675,18 +2594,18 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ ctx.reportError("Computer \"%s\" not declared" "- [%s] starting at line: %d", compId, ctx.fname, ctx.m_sectionLineno); - return false; + DBUG_RETURN(false); } if(!computer->get("HostName", &hostname)){ ctx.reportError("HostName missing in [COMPUTER] (Id: %d) " " - [%s] starting at line: %d", compId, ctx.fname, ctx.m_sectionLineno); - return false; + DBUG_RETURN(false); } require(ctx.m_currentSection->put("HostName", hostname)); - return checkLocalhostHostnameMix(ctx); + DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); } bool @@ -2870,7 +2789,7 @@ transformComputer(InitConfigFileParser::Context & ctx, const char * data){ return true; } - return checkLocalhostHostnameMix(ctx); + return checkLocalhostHostnameMix(ctx,0); } /** @@ -2878,7 +2797,9 @@ transformComputer(InitConfigFileParser::Context & ctx, const char * data){ */ void applyDefaultValues(InitConfigFileParser::Context & ctx, - const Properties * defaults){ + const Properties * defaults) +{ + DBUG_ENTER("applyDefaultValues"); if(defaults != NULL){ Properties::Iterator it(defaults); @@ -2891,26 +2812,58 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, Uint32 val = 0; ::require(defaults->get(name, &val)); ctx.m_currentSection->put(name, val); + DBUG_PRINT("info",("%s=%d #default",name,val)); break; } case ConfigInfo::CI_INT64:{ Uint64 val = 0; ::require(defaults->get(name, &val)); ctx.m_currentSection->put64(name, val); + DBUG_PRINT("info",("%s=%lld #default",name,val)); break; } case ConfigInfo::CI_STRING:{ const char * val; ::require(defaults->get(name, &val)); ctx.m_currentSection->put(name, val); + DBUG_PRINT("info",("%s=%s #default",name,val)); break; } case ConfigInfo::CI_SECTION: break; } } +#ifndef DBUG_OFF + else + { + switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ + case ConfigInfo::CI_INT: + case ConfigInfo::CI_BOOL:{ + Uint32 val = 0; + ::require(ctx.m_currentSection->get(name, &val)); + DBUG_PRINT("info",("%s=%d",name,val)); + break; + } + case ConfigInfo::CI_INT64:{ + Uint64 val = 0; + ::require(ctx.m_currentSection->get(name, &val)); + DBUG_PRINT("info",("%s=%lld",name,val)); + break; + } + case ConfigInfo::CI_STRING:{ + const char * val; + ::require(ctx.m_currentSection->get(name, &val)); + DBUG_PRINT("info",("%s=%s",name,val)); + break; + } + case ConfigInfo::CI_SECTION: + break; + } + } +#endif } } + DBUG_VOID_RETURN; } bool @@ -3482,6 +3435,8 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ return true; } +extern int g_print_full_config; + static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ const Properties * sec; @@ -3503,6 +3458,12 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ break; } + if (g_print_full_config) + { + const char *alias= ConfigInfo::nameToAlias(ctx.fname); + printf("[%s]\n", alias ? alias : ctx.fname); + } + Uint32 no = 0; ctx.m_userProperties.get("$Section", id, &no); ctx.m_userProperties.put("$Section", id, no+1, true); @@ -3530,18 +3491,24 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ Uint32 val; require(ctx.m_currentSection->get(n, &val)); ok = ctx.m_configValues.put(id, val); + if (g_print_full_config) + printf("%s=%u\n", n, val); break; } case PropertiesType_Uint64:{ Uint64 val; require(ctx.m_currentSection->get(n, &val)); ok = ctx.m_configValues.put64(id, val); + if (g_print_full_config) + printf("%s=%llu\n", n, val); break; } case PropertiesType_char:{ const char * val; require(ctx.m_currentSection->get(n, &val)); ok = ctx.m_configValues.put(id, val); + if (g_print_full_config) + printf("%s=%s\n", n, val); break; } default: diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.hpp b/storage/ndb/src/mgmsrv/ConfigInfo.hpp index dff8b34bf4a..871ee62040e 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.hpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.hpp @@ -105,7 +105,8 @@ public: * @note Result is not defined if section/name are wrong! */ bool verify(const Properties* secti, const char* fname, Uint64 value) const; - const char* getAlias(const char*) const; + static const char* nameToAlias(const char*); + static const char* getAlias(const char*); bool isSection(const char*) const; const char* getDescription(const Properties * sec, const char* fname) const; diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp index 07b369d4ebc..ec20101493e 100644 --- a/storage/ndb/src/mgmsrv/main.cpp +++ b/storage/ndb/src/mgmsrv/main.cpp @@ -121,6 +121,7 @@ struct MgmGlobals { }; int g_no_nodeid_checks= 0; +int g_print_full_config; static MgmGlobals *glob= 0; /****************************************************************************** @@ -147,6 +148,9 @@ static struct my_option my_long_options[] = { "config-file", 'f', "Specify cluster configuration file", (gptr*) &opt_config_filename, (gptr*) &opt_config_filename, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "print-full-config", 'P', "Print full config and exit", + (gptr*) &g_print_full_config, (gptr*) &g_print_full_config, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)", (gptr*) &opt_daemon, (gptr*) &opt_daemon, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, @@ -208,7 +212,8 @@ int main(int argc, char** argv) exit(ho_error); if (opt_interactive || - opt_non_interactive) { + opt_non_interactive || + g_print_full_config) { opt_daemon= 0; } @@ -220,6 +225,9 @@ int main(int argc, char** argv) opt_config_filename, opt_connect_str); + if (g_print_full_config) + goto the_end; + if (glob->mgmObject->init()) goto error_end; @@ -358,6 +366,7 @@ int main(int argc, char** argv) glob->mgmObject->get_config_retriever()->disconnect(); glob->socketServer->stopSessions(true); g_eventLogger.info("Shutdown complete"); + the_end: delete glob; ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); return 0; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ffd99915168..76d0ab2e4cc 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -690,13 +690,20 @@ static void verify_col_data(const char *table, const char *col, /* Utility function to verify the field members */ -static void verify_prepare_field(MYSQL_RES *result, - unsigned int no, const char *name, - const char *org_name, - enum enum_field_types type, - const char *table, - const char *org_table, const char *db, - unsigned long length, const char *def) +#define verify_prepare_field(result,no,name,org_name,type,table,\ + org_table,db,length,def) \ + do_verify_prepare_field((result),(no),(name),(org_name),(type), \ + (table),(org_table),(db),(length),(def), \ + __FILE__, __LINE__) + +static void do_verify_prepare_field(MYSQL_RES *result, + unsigned int no, const char *name, + const char *org_name, + enum enum_field_types type, + const char *table, + const char *org_table, const char *db, + unsigned long length, const char *def, + const char *file, int line) { MYSQL_FIELD *field; CHARSET_INFO *cs; @@ -743,8 +750,9 @@ static void verify_prepare_field(MYSQL_RES *result, { if (field->type != type) { - fprintf(stderr, "Expected field type: %d, got type: %d\n", - (int) type, (int) field->type); + fprintf(stderr, + "Expected field type: %d, got type: %d in file %s, line %d\n", + (int) type, (int) field->type, file, line); DIE_UNLESS(field->type == type); } } @@ -7426,8 +7434,8 @@ static void test_explain_bug() MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, 0, 0, "", 64, 0); - verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", - MYSQL_TYPE_BLOB, 0, 0, "", 0, 0); + verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB, + 0, 0, "", 0, 0); verify_prepare_field(result, 2, "Null", "IS_NULLABLE", mysql_get_server_version(mysql) <= 50000 ? |