diff options
author | unknown <igor@rurik.mysql.com> | 2005-06-23 11:22:30 -0700 |
---|---|---|
committer | unknown <igor@rurik.mysql.com> | 2005-06-23 11:22:30 -0700 |
commit | e3cfd4ef0cda7cd46940454ab82f1a509d21cb92 (patch) | |
tree | 11a7803101cbf7b5a82af191b7a2e86927f5aab1 | |
parent | 85a7014de65c2475462852d253d9d6331572c107 (diff) | |
parent | d9a7e4e0dc2abb92f3328104f6b3394c25c355e3 (diff) | |
download | mariadb-git-e3cfd4ef0cda7cd46940454ab82f1a509d21cb92.tar.gz |
Manual merge
mysql-test/r/func_str.result:
Auto merged
mysql-test/t/func_str.test:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/sql_select.cc:
Auto merged
-rw-r--r-- | mysql-test/r/func_str.result | 11 | ||||
-rw-r--r-- | mysql-test/r/rpl_multi_update3.result | 81 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 14 | ||||
-rw-r--r-- | mysql-test/t/rpl_multi_update3.test | 133 | ||||
-rw-r--r-- | sql/field.cc | 28 | ||||
-rw-r--r-- | sql/item_subselect.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.h | 25 |
9 files changed, 273 insertions, 30 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 1c6a4393dfc..92ec76fb024 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -800,3 +800,14 @@ field(0,NULL,1,0) field("",NULL,"bar","") field(0.0,NULL,1.0,0.0) select field(NULL,1,2,NULL), field(NULL,1,2,0); field(NULL,1,2,NULL) field(NULL,1,2,0) 0 0 +CREATE TABLE t1 (str varchar(20) PRIMARY KEY); +CREATE TABLE t2 (num int primary key); +INSERT INTO t1 VALUES ('notnumber'); +INSERT INTO t2 VALUES (0), (1); +SELECT * FROM t1, t2 WHERE num=str; +str num +notnumber 0 +SELECT * FROM t1, t2 WHERE num=substring(str from 1 for 6); +str num +notnumber 0 +DROP TABLE t1,t2; diff --git a/mysql-test/r/rpl_multi_update3.result b/mysql-test/r/rpl_multi_update3.result index 708b230b19f..1b757b1400c 100644 --- a/mysql-test/r/rpl_multi_update3.result +++ b/mysql-test/r/rpl_multi_update3.result @@ -4,6 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; + +-------- Test for BUG#9361 -------- CREATE TABLE t1 ( a int unsigned not null auto_increment primary key, b int unsigned @@ -41,3 +43,82 @@ a b 1 6 2 6 drop table t1,t2; + +-------- Test 1 for BUG#9361 -------- +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +CREATE TABLE t1 ( +a1 char(30), +a2 int, +a3 int, +a4 char(30), +a5 char(30) +); +CREATE TABLE t2 ( +b1 int, +b2 char(30) +); +INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar'); +INSERT INTO t2 VALUES (1, 'baz'); +UPDATE t1 a, t2 +SET a.a1 = 'No' +WHERE a.a2 = +(SELECT b1 +FROM t2 +WHERE b2 = 'baz') +AND a.a3 IS NULL +AND a.a4 = 'foo' +AND a.a5 = 'bar'; +SELECT * FROM t1; +a1 a2 a3 a4 a5 +No 1 NULL foo bar +SELECT * FROM t2; +b1 b2 +1 baz +DROP TABLE t1, t2; + +-------- Test 2 for BUG#9361 -------- +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +CREATE TABLE t1 ( +i INT, +j INT, +x INT, +y INT, +z INT +); +CREATE TABLE t2 ( +i INT, +k INT, +x INT, +y INT, +z INT +); +CREATE TABLE t3 ( +j INT, +k INT, +x INT, +y INT, +z INT +); +INSERT INTO t1 VALUES ( 1, 2,13,14,15); +INSERT INTO t2 VALUES ( 1, 3,23,24,25); +INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36); +UPDATE t1 AS a +INNER JOIN t2 AS b +ON a.i = b.i +INNER JOIN t3 AS c +ON a.j = c.j AND b.k = c.k +SET a.x = b.x, +a.y = b.y, +a.z = ( +SELECT sum(z) +FROM t3 +WHERE y = 34 +) +WHERE b.x = 23; +SELECT * FROM t1; +i j x y z +1 2 23 24 71 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 728f0e2c084..e6bf9f81dd0 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -529,3 +529,17 @@ DROP TABLE t1, t2; # select field(0,NULL,1,0), field("",NULL,"bar",""), field(0.0,NULL,1.0,0.0); select field(NULL,1,2,NULL), field(NULL,1,2,0); + +# +# Bug #10124: access by integer index with a string key that is not a number +# + +CREATE TABLE t1 (str varchar(20) PRIMARY KEY); +CREATE TABLE t2 (num int primary key); +INSERT INTO t1 VALUES ('notnumber'); +INSERT INTO t2 VALUES (0), (1); + +SELECT * FROM t1, t2 WHERE num=str; +SELECT * FROM t1, t2 WHERE num=substring(str from 1 for 6); + +DROP TABLE t1,t2; diff --git a/mysql-test/t/rpl_multi_update3.test b/mysql-test/t/rpl_multi_update3.test index b8c8ed79532..80b0603eb60 100644 --- a/mysql-test/t/rpl_multi_update3.test +++ b/mysql-test/t/rpl_multi_update3.test @@ -1,7 +1,13 @@ +source include/master-slave.inc; + +############################################################################## +# # Let's verify that multi-update with a subselect does not cause the slave to crash # (BUG#10442) - -source include/master-slave.inc; +# +--disable_query_log +SELECT '-------- Test for BUG#9361 --------' as ""; +--enable_query_log CREATE TABLE t1 ( a int unsigned not null auto_increment primary key, @@ -25,10 +31,129 @@ UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ; SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; -save_master_pos; +sync_slave_with_master; connection slave; -sync_with_master; SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; +connection master; drop table t1,t2; + +############################################################################## +# +# Test for BUG#9361: +# Subselects should work inside multi-updates +# +--disable_query_log +SELECT '-------- Test 1 for BUG#9361 --------' as ""; +--enable_query_log + +connection master; + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +CREATE TABLE t1 ( + a1 char(30), + a2 int, + a3 int, + a4 char(30), + a5 char(30) +); + +CREATE TABLE t2 ( + b1 int, + b2 char(30) +); + +# Insert one row per table +INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar'); +INSERT INTO t2 VALUES (1, 'baz'); + +# This should update the row in t1 +UPDATE t1 a, t2 + SET a.a1 = 'No' + WHERE a.a2 = + (SELECT b1 + FROM t2 + WHERE b2 = 'baz') + AND a.a3 IS NULL + AND a.a4 = 'foo' + AND a.a5 = 'bar'; + +sync_slave_with_master; +connection slave; +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TABLE t1, t2; + +############################################################################## +# +# Second test for BUG#9361 +# + +--disable_query_log +SELECT '-------- Test 2 for BUG#9361 --------' as ""; +--enable_query_log + +connection master; + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +--enable_warnings + +CREATE TABLE t1 ( + i INT, + j INT, + x INT, + y INT, + z INT +); + +CREATE TABLE t2 ( + i INT, + k INT, + x INT, + y INT, + z INT +); + +CREATE TABLE t3 ( + j INT, + k INT, + x INT, + y INT, + z INT +); + +INSERT INTO t1 VALUES ( 1, 2,13,14,15); +INSERT INTO t2 VALUES ( 1, 3,23,24,25); +INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36); + +UPDATE t1 AS a +INNER JOIN t2 AS b + ON a.i = b.i +INNER JOIN t3 AS c + ON a.j = c.j AND b.k = c.k +SET a.x = b.x, + a.y = b.y, + a.z = ( + SELECT sum(z) + FROM t3 + WHERE y = 34 + ) +WHERE b.x = 23; + +sync_slave_with_master; +connection slave; + +SELECT * FROM t1; + +connection master; +DROP TABLE t1, t2, t3; diff --git a/sql/field.cc b/sql/field.cc index aeefe64ace3..81f695454ff 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3322,7 +3322,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) } else if (from+len != end && table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; + error= 2; store_tmp= (long) tmp; #ifdef WORDS_BIGENDIAN @@ -3584,7 +3584,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) } else if (from+len != end && table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; + error= 2; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { @@ -3806,7 +3806,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); - error= 1; + error= error ? 1 : 2; } Field_float::store(nr); return error; @@ -4093,7 +4093,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); - error= 1; + error= error ? 1 : 2; } Field_double::store(nr); return error; @@ -4495,6 +4495,8 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; } } + if (error > 1) + error= 2; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4791,7 +4793,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) if (str_to_time(from, len, <ime, &error)) { tmp=0L; - error= 1; + error= 2; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_TIME, 1); } @@ -4813,6 +4815,8 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) from, len, MYSQL_TIMESTAMP_TIME, !error); error= 1; } + if (error > 1) + error= 2; } if (ltime.neg) @@ -5149,7 +5153,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) &error) <= MYSQL_TIMESTAMP_ERROR) { tmp=0; - error= 1; + error= 2; } else tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day); @@ -5353,7 +5357,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) &error) <= MYSQL_TIMESTAMP_ERROR) { tmp=0L; - error= 1; + error= 2; } else tmp= l_time.day + l_time.month*32 + l_time.year*16*32; @@ -5836,7 +5840,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) from= tmpstr.ptr(); length= tmpstr.length(); if (conv_errors) - error= 1; + error= 2; } /* @@ -5860,7 +5864,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES); if (from != end) - error= 1; + error= 2; } if (error) { @@ -6242,7 +6246,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) table->in_use->abort_on_warning) error_code= ER_DATA_TOO_LONG; set_warning(level, error_code, 1); - return 1; + return 2; } return 0; } @@ -6822,7 +6826,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) from= tmpstr.ptr(); length= tmpstr.length(); if (conv_errors) - error= 1; + error= 2; } copy_length= max_data_length(); @@ -6837,7 +6841,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) copy_length, &well_formed_error); if (copy_length < length) - error= 1; + error= 2; Field_blob::store_length(copy_length); if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH) { // Must make a copy diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 393cb87c113..7ea72f3c858 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1487,7 +1487,7 @@ int subselect_uniquesubquery_engine::exec() TABLE *table= tab->table; for (store_key **copy=tab->ref.key_copy ; *copy ; copy++) { - if (tab->ref.key_err= (*copy)->copy()) + if ((tab->ref.key_err= (*copy)->copy()) & 1) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(1); @@ -1540,7 +1540,7 @@ int subselect_indexsubquery_engine::exec() for (store_key **copy=tab->ref.key_copy ; *copy ; copy++) { - if (tab->ref.key_err= (*copy)->copy()) + if ((tab->ref.key_err= (*copy)->copy()) & 1) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(1); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 33339cf0882..a60eb32564b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3272,7 +3272,6 @@ end_with_restore_list: if (first_table->view && !first_table->contain_auto_increment) thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it - break; } case SQLCOM_TRUNCATE: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1487dfbb436..2627f1a51d7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11766,10 +11766,12 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref) thd->count_cuted_fields= CHECK_FIELD_IGNORE; for (store_key **copy=ref->key_copy ; *copy ; copy++) { - if ((*copy)->copy()) + int res; + if ((res= (*copy)->copy())) { thd->count_cuted_fields= save_count_cuted_fields; - return 1; // Something went wrong + if ((res= res & 1)) + return res; // Something went wrong } } thd->count_cuted_fields= save_count_cuted_fields; diff --git a/sql/sql_select.h b/sql/sql_select.h index e5266944251..885b50016af 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -448,6 +448,7 @@ class store_key :public Sql_alloc char *null_ptr; char err; public: + enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV }; store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length) :null_ptr(null),err(0) { @@ -463,7 +464,7 @@ class store_key :public Sql_alloc ptr, (uchar*) null, 1); } virtual ~store_key() {} /* Not actually needed */ - virtual bool copy()=0; + virtual enum store_key_result copy()=0; virtual const char *name() const=0; }; @@ -484,10 +485,10 @@ class store_key_field: public store_key copy_field.set(to_field,from_field,0); } } - bool copy() + enum store_key_result copy() { copy_field.do_copy(©_field); - return err != 0; + return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK; } const char *name() const { return field_name; } }; @@ -504,9 +505,11 @@ public: null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? &err : NullS, length), item(item_arg) {} - bool copy() + enum store_key_result copy() { - return item->save_in_field_no_warnings(to_field, 1) || err != 0; + int res= item->save_in_field(to_field, 1); + return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res); + } const char *name() const { return "func"; } }; @@ -524,15 +527,19 @@ public: &err : NullS, length, item_arg), inited(0) { } - bool copy() + enum store_key_result copy() { + int res; if (!inited) { inited=1; - if (item->save_in_field(to_field, 1)) - err= 1; + if ((res= item->save_in_field(to_field, 1))) + { + if (!err) + err= res; + } } - return err != 0; + return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); } const char *name() const { return "const"; } }; |