diff options
-rw-r--r-- | heap/hp_hash.c | 63 | ||||
-rw-r--r-- | mysql-test/r/create.result | 22 | ||||
-rw-r--r-- | mysql-test/t/create.test | 10 | ||||
-rw-r--r-- | sql/field.h | 22 | ||||
-rw-r--r-- | sql/item.cc | 87 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | vio/vio.c | 2 | ||||
-rw-r--r-- | vio/vio_priv.h | 2 | ||||
-rw-r--r-- | vio/viosocket.c | 7 |
9 files changed, 145 insertions, 73 deletions
diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 2843407f3fe..4fdbfa16586 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -566,50 +566,87 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record) return 0; } + +/* + Update auto_increment info + + SYNOPSIS + update_auto_increment() + info MyISAM handler + record Row to update + + IMPLEMENTATION + Only replace the auto_increment value if it is higher than the previous + one. For signed columns we don't update the auto increment value if it's + less than zero. +*/ + void heap_update_auto_increment(HP_INFO *info, const byte *record) { - ulonglong value; + ulonglong value= 0; /* Store unsigned values here */ + longlong s_value= 0; /* Store signed values here */ + HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg; const uchar *key= (uchar*) record + keyseg->start; switch (info->s->auto_key_type) { case HA_KEYTYPE_INT8: + s_value= (longlong) *(char*)key; + break; case HA_KEYTYPE_BINARY: - value= (ulonglong) *(uchar*) key; + value=(ulonglong) *(uchar*) key; break; case HA_KEYTYPE_SHORT_INT: + s_value= (longlong) sint2korr(key); + break; case HA_KEYTYPE_USHORT_INT: - value= (ulonglong) uint2korr(key); + value=(ulonglong) uint2korr(key); break; case HA_KEYTYPE_LONG_INT: + s_value= (longlong) sint4korr(key); + break; case HA_KEYTYPE_ULONG_INT: - value= (ulonglong) uint4korr(key); + value=(ulonglong) uint4korr(key); break; case HA_KEYTYPE_INT24: + s_value= (longlong) sint3korr(key); + break; case HA_KEYTYPE_UINT24: - value= (ulonglong) uint3korr(key); + value=(ulonglong) uint3korr(key); break; - case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ + case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ { float f_1; - float4get(f_1, key); - value= (ulonglong) f_1; + float4get(f_1,key); + /* Ignore negative values */ + value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1; break; } - case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ + case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ { double f_1; - float8get(f_1, key); - value= (ulonglong) f_1; + float8get(f_1,key); + /* Ignore negative values */ + value = (f_1 < 0.0) ? 0 : (ulonglong) f_1; break; } case HA_KEYTYPE_LONGLONG: + s_value= sint8korr(key); + break; case HA_KEYTYPE_ULONGLONG: value= uint8korr(key); break; default: - value= 0; /* Error */ + DBUG_ASSERT(0); + value=0; /* Error */ break; } - set_if_bigger(info->s->auto_increment, value); + + /* + The following code works becasue if s_value < 0 then value is 0 + and if s_value == 0 then value will contain either s_value or the + correct value. + */ + set_if_bigger(info->s->auto_increment, + (s_value > 0) ? (ulonglong) s_value : value); } diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 2f61b4838ee..6160dd88fa5 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -407,6 +407,28 @@ a b c d e f g h dd 1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00 2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00 drop table t1, t2; +create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10)); +create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `ifnull(a,a)` tinyint(4) default NULL, + `ifnull(b,b)` smallint(6) default NULL, + `ifnull(c,c)` mediumint(9) default NULL, + `ifnull(d,d)` int(11) default NULL, + `ifnull(e,e)` bigint(20) default NULL, + `ifnull(f,f)` float(3,2) default NULL, + `ifnull(g,g)` double(4,3) default NULL, + `ifnull(h,h)` decimal(5,4) default NULL, + `ifnull(i,i)` year(4) default NULL, + `ifnull(j,j)` date default NULL, + `ifnull(k,k)` datetime NOT NULL default '0000-00-00 00:00:00', + `ifnull(l,l)` datetime default NULL, + `ifnull(m,m)` char(1) default NULL, + `ifnull(n,n)` char(3) default NULL, + `ifnull(o,o)` char(10) default NULL +) TYPE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2; create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14'); insert into t1 values ('','',0,0.0); describe t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 54166c3b0dc..23d7cc8c347 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -318,11 +318,17 @@ select addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd from t1; explain t2; - select * from t2; - drop table t1, t2; +create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10)); +create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1; +show create table t2; +drop table t1,t2; + +# +# Test of default() +# create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14'); insert into t1 values ('','',0,0.0); describe t1; diff --git a/sql/field.h b/sql/field.h index 0b6ba7dde09..508fbad41a1 100644 --- a/sql/field.h +++ b/sql/field.h @@ -327,11 +327,6 @@ public: unireg_check_arg, field_name_arg, table_arg, dec_arg, zero_arg,unsigned_arg) {} - Field_decimal(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg,bool unsigned_arg) - :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,unsigned_arg) - {} enum_field_types type() const { return FIELD_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } @@ -362,11 +357,6 @@ public: unireg_check_arg, field_name_arg, table_arg, 0, zero_arg,unsigned_arg) {} - Field_tiny(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg,bool unsigned_arg) - :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,unsigned_arg) - {} enum Item_result result_type () const { return INT_RESULT; } enum_field_types type() const { return FIELD_TYPE_TINY;} enum ha_base_keytype key_type() const @@ -608,13 +598,9 @@ public: :Field_str(ptr_arg, len_arg, null, 1, unireg_check_arg, field_name_arg, table_arg, cs) {} - Field_null(uint32 len_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str((char*) 0, len_arg, null, 1, - NONE, field_name_arg, table_arg, cs) - {} enum_field_types type() const { return FIELD_TYPE_NULL;} - int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } + int store(const char *to, uint length, CHARSET_INFO *cs) + { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; } int store(longlong nr) { null[0]=1; return 0; } void reset(void) {} @@ -684,10 +670,6 @@ public: :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg, 1, 1) {} - Field_year(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg) - :Field_tiny(len_arg,maybe_null_arg,field_name_arg,table_arg,1) - {} enum_field_types type() const { return FIELD_TYPE_YEAR;} int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); diff --git a/sql/item.cc b/sql/item.cc index 9af2c300202..072a7e5878f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -995,35 +995,42 @@ enum_field_types Item::field_type() const Field *Item::tmp_table_field_from_field_type(TABLE *table) { - switch (field_type()) - { + /* + The field functions defines a field to be not null if null_ptr is not 0 + */ + uchar *null_ptr= maybe_null ? (uchar*) "" : 0; + + switch (field_type()) { case MYSQL_TYPE_DECIMAL: - return new Field_decimal(max_length, maybe_null, name, table, - unsigned_flag); + return new Field_decimal((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, decimals, 0, unsigned_flag); case MYSQL_TYPE_TINY: - return new Field_tiny(max_length, maybe_null, name, table, - unsigned_flag); + return new Field_tiny((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, 0, unsigned_flag); case MYSQL_TYPE_SHORT: - return new Field_short(max_length, maybe_null, name, table, - unsigned_flag); + return new Field_short((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, 0, unsigned_flag); case MYSQL_TYPE_LONG: - return new Field_long(max_length, maybe_null, name, table, - unsigned_flag); - case MYSQL_TYPE_FLOAT: - return new Field_float(max_length, maybe_null, name, table, decimals); - case MYSQL_TYPE_DOUBLE: - return new Field_double(max_length, maybe_null, name, table, decimals); - case MYSQL_TYPE_NULL: - return new Field_null(max_length, name, table, &my_charset_bin); + return new Field_long((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, 0, unsigned_flag); #ifdef HAVE_LONG_LONG case MYSQL_TYPE_LONGLONG: - return new Field_longlong(max_length, maybe_null, name, table, - unsigned_flag); + return new Field_longlong((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, 0, unsigned_flag); #endif + case MYSQL_TYPE_FLOAT: + return new Field_float((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, decimals, 0, unsigned_flag); + case MYSQL_TYPE_DOUBLE: + return new Field_double((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, decimals, 0, unsigned_flag); + case MYSQL_TYPE_NULL: + return new Field_null((char*) 0, max_length, Field::NONE, + name, table, &my_charset_bin); case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_INT24: - return new Field_long(max_length, maybe_null, name, table, - unsigned_flag); + return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table, 0, unsigned_flag); case MYSQL_TYPE_DATE: return new Field_date(maybe_null, name, table, &my_charset_bin); case MYSQL_TYPE_TIME: @@ -1032,34 +1039,38 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) case MYSQL_TYPE_DATETIME: return new Field_datetime(maybe_null, name, table, &my_charset_bin); case MYSQL_TYPE_YEAR: - return new Field_year(max_length, maybe_null, name, table); + return new Field_year((char*) 0, max_length, null_ptr, 0, Field::NONE, + name, table); + default: + /* This case should never be choosen */ + DBUG_ASSERT(0); + /* If something goes awfully wrong, it's better to get a string than die */ case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: - return new Field_long(max_length, maybe_null, name, table, - unsigned_flag); + case MYSQL_TYPE_VAR_STRING: + if (max_length > 255) + break; // If blob + return new Field_varstring(max_length, maybe_null, name, table, + collation.collation); + case MYSQL_TYPE_STRING: + if (max_length > 255) // If blob + break; + return new Field_string(max_length, maybe_null, name, table, + collation.collation); case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_GEOMETRY: - return new Field_blob(max_length, maybe_null, name, table, collation.collation); - case MYSQL_TYPE_VAR_STRING: - if (max_length > 255) - return new Field_blob(max_length, maybe_null, name, table, collation.collation); - else - return new Field_varstring(max_length, maybe_null, name, table, collation.collation); - case MYSQL_TYPE_STRING: - if (max_length > 255) - return new Field_blob(max_length, maybe_null, name, table, collation.collation); - else - return new Field_string(max_length, maybe_null, name, table, collation.collation); - default: - // This case should never be choosen - DBUG_ASSERT(0); - return 0; + break; // Blob handled outside of case } + + /* blob is special as it's generated for both blobs and long strings */ + return new Field_blob(max_length, maybe_null, name, table, + collation.collation); } + /* ARGSUSED */ void Item_field::make_field(Send_field *tmp_field) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 805e6860f65..49f0b753549 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2787,6 +2787,9 @@ int main(int argc, char **argv) int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name, "MySQLShutdown"), 10); + /* Must be initialized early for comparison of service name */ + system_charset_info= &my_charset_utf8_general_ci; + if (Service.GetOS()) /* true NT family */ { char file_path[FN_REFLEN]; diff --git a/vio/vio.c b/vio/vio.c index 05bfb220986..a356d8edeff 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -55,6 +55,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, vio->in_addr =vio_in_addr; vio->vioblocking =vio_blocking; vio->is_blocking =vio_is_blocking; + vio->timeout =vio_ignore_timeout; } else /* default is VIO_TYPE_TCPIP */ #endif @@ -73,6 +74,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, vio->in_addr =vio_in_addr; vio->vioblocking =vio_blocking; vio->is_blocking =vio_is_blocking; + vio->timeout =vio_ignore_timeout; } else #endif diff --git a/vio/vio_priv.h b/vio/vio_priv.h index 66a9bde4e0d..9a925a2c4c9 100644 --- a/vio/vio_priv.h +++ b/vio/vio_priv.h @@ -23,6 +23,8 @@ #include <m_string.h> #include <violite.h> +void vio_ignore_timeout(Vio *vio, uint timeout); + #ifdef HAVE_OPENSSL #include "my_net.h" /* needed because of struct in_addr */ diff --git a/vio/viosocket.c b/vio/viosocket.c index 9d5c7c0d890..8dea06d4adf 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -355,6 +355,13 @@ int vio_close_pipe(Vio * vio) DBUG_RETURN(r); } + +void vio_ignore_timeout(Vio *vio __attribute__((unused)), + uint timeout __attribute__((unused))) +{ +} + + #ifdef HAVE_SMEM int vio_read_shared_memory(Vio * vio, gptr buf, int size) |