diff options
author | He Zhenxing <zhenxing.he@sun.com> | 2010-06-01 17:03:55 +0800 |
---|---|---|
committer | He Zhenxing <zhenxing.he@sun.com> | 2010-06-01 17:03:55 +0800 |
commit | bee85d74eb2be11099d363e1c721191a18560739 (patch) | |
tree | d51ab5bf961beaa538cc365c73bd776f6c0d1c47 | |
parent | 84889d030cc35ed7c61ba4b140c6445a0eb76548 (diff) | |
parent | 9c960ecff1a98baf9b1c2561736cd6b2e5214cc2 (diff) | |
download | mariadb-git-bee85d74eb2be11099d363e1c721191a18560739.tar.gz |
Auto merge from trunk
-rw-r--r-- | libmysql/Makefile.shared | 2 | ||||
-rw-r--r-- | mysql-test/r/mdl_sync.result | 4 | ||||
-rw-r--r-- | mysql-test/r/merge.result | 7 | ||||
-rw-r--r-- | mysql-test/r/order_by.result | 29 | ||||
-rw-r--r-- | mysql-test/t/mdl_sync.test | 3 | ||||
-rw-r--r-- | mysql-test/t/merge.test | 9 | ||||
-rw-r--r-- | mysql-test/t/order_by.test | 24 | ||||
-rw-r--r-- | sql/field.cc | 8 | ||||
-rw-r--r-- | sql/item.cc | 20 | ||||
-rw-r--r-- | sql/item.h | 18 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 19 | ||||
-rw-r--r-- | sql/item_sum.h | 2 | ||||
-rw-r--r-- | sql/partition_info.cc | 26 | ||||
-rw-r--r-- | sql/sql_load.cc | 6 | ||||
-rw-r--r-- | storage/myisammrg/myrg_queue.c | 12 |
15 files changed, 149 insertions, 40 deletions
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 71649b83991..71a4fd867bd 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -56,7 +56,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \ my_file.lo my_read.lo my_write.lo errors.lo \ my_error.lo my_getwd.lo my_div.lo \ - mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\ + mf_pack.lo my_mess.lo mf_dirname.lo mf_fn_ext.lo\ mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \ mf_format.lo mf_path.lo mf_unixpath.lo my_fopen.lo \ my_symlink.lo my_fstream.lo mf_arr_appstr.lo \ diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index 8f236521f99..b78b8dadc77 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2390,8 +2390,8 @@ SHOW FULL COLUMNS FROM t1; SET DEBUG_SYNC= "now WAIT_FOR waiting"; SHOW FULL COLUMNS FROM t1; Field Type Collation Null Key Default Extra Privileges Comment -a char(255) latin1_swedish_ci YES NULL select,insert,update,references +a char(255) latin1_swedish_ci YES NULL # SET DEBUG_SYNC= "now SIGNAL completed"; Field Type Collation Null Key Default Extra Privileges Comment -a char(255) latin1_swedish_ci YES NULL select,insert,update,references +a char(255) latin1_swedish_ci YES NULL # DROP TABLE t1; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index ff9b1a84dbc..e46d8e75ab1 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -277,7 +277,7 @@ t3 CREATE TABLE `t3` ( drop table t3,t2,t1; create table t1 (a int not null, key(a)) engine=merge; select * from t1; -ERROR HY000: Got error 124 from storage engine +a drop table t1; create table t1 (a int not null, b int not null, key(a,b)); create table t2 (a int not null, b int not null, key(a,b)); @@ -988,6 +988,11 @@ m1 CREATE TABLE `m1` ( `a` int(11) DEFAULT NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1, m1; +CREATE TABLE t1(a INT, KEY(a)) ENGINE=merge; +SELECT MAX(a) FROM t1; +MAX(a) +NULL +DROP TABLE t1; CREATE TABLE t1(a INT); CREATE TABLE t2(a VARCHAR(10)); CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2); diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6827fd0bc76..fa5d8142baf 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1618,3 +1618,32 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer DROP TABLE t1, t2; End of 5.1 tests +# +# Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY +# when it should use index +# +CREATE TABLE t1 (i1 integer NOT NULL PRIMARY KEY); +CREATE TABLE t2 (i2 integer NOT NULL PRIMARY KEY); +CREATE TABLE t3 (i3 integer); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12); +INSERT INTO t2 SELECT * FROM t1; +EXPLAIN EXTENDED +SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 +LEFT JOIN t3 ON t2.i2 = t3.i3 +ORDER BY t1.i1 LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found +1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 5 240.00 Using index +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i1 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`i2` = `test`.`t1`.`i1`) order by `test`.`t1`.`i1` limit 5 +SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 +LEFT JOIN t3 ON t2.i2 = t3.i3 +ORDER BY t1.i1 LIMIT 5; +i1 i2 +1 1 +2 2 +3 3 +4 4 +5 5 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index dff29d2f6b6..0b4b9af5bc6 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -3479,9 +3479,10 @@ SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed"; connection default; SET DEBUG_SYNC= "now WAIT_FOR waiting"; +--replace_column 8 # SHOW FULL COLUMNS FROM t1; SET DEBUG_SYNC= "now SIGNAL completed"; - +--replace_column 8 # connection con1; --reap connection default; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index ab901185e43..a9d98da0403 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -126,7 +126,6 @@ drop table t3,t2,t1; # Test table without unions # create table t1 (a int not null, key(a)) engine=merge; ---error 1030 select * from t1; drop table t1; @@ -616,6 +615,14 @@ SHOW CREATE TABLE m1; DROP TABLE t1, m1; # +# BUG#35274 - merge table doesn't need any base tables, gives error 124 when +# key accessed +# +CREATE TABLE t1(a INT, KEY(a)) ENGINE=merge; +SELECT MAX(a) FROM t1; +DROP TABLE t1; + +# # BUG#32047 - 'Spurious' errors while opening MERGE tables # CREATE TABLE t1(a INT); diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 36b6015c5d8..2ea169d950d 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1468,3 +1468,27 @@ SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a; DROP TABLE t1, t2; --echo End of 5.1 tests + + +--echo # +--echo # Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY +--echo # when it should use index +--echo # + +CREATE TABLE t1 (i1 integer NOT NULL PRIMARY KEY); +CREATE TABLE t2 (i2 integer NOT NULL PRIMARY KEY); +CREATE TABLE t3 (i3 integer); + +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12); +INSERT INTO t2 SELECT * FROM t1; + +EXPLAIN EXTENDED +SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 + LEFT JOIN t3 ON t2.i2 = t3.i3 + ORDER BY t1.i1 LIMIT 5; + +SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 + LEFT JOIN t3 ON t2.i2 = t3.i3 + ORDER BY t1.i1 LIMIT 5; + +DROP TABLE t1, t2, t3; diff --git a/sql/field.cc b/sql/field.cc index fcabaeaa74d..ee7d91c1fb6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9125,7 +9125,7 @@ void Create_field::create_length_to_internal_length(void) void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, uint32 length_arg, uint32 decimals_arg, bool maybe_null, bool is_unsigned, - uint pack_length) + uint pack_length_arg) { DBUG_ENTER("Create_field::init_for_tmp_table"); @@ -9138,7 +9138,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, geom_type= Field::GEOM_GEOMETRY; DBUG_PRINT("enter", ("sql_type: %d, length: %u, pack_length: %u", - sql_type_arg, length_arg, pack_length)); + sql_type_arg, length_arg, pack_length_arg)); /* These pack flags are crafted to get it correctly through the @@ -9202,8 +9202,8 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, case MYSQL_TYPE_GEOMETRY: // If you are going to use the above types, you have to pass a // pack_length as parameter. Assert that is really done. - DBUG_ASSERT(pack_length != ~0U); - pack_flag|= pack_length_to_packflag(pack_length); + DBUG_ASSERT(pack_length_arg != ~0U); + pack_flag|= pack_length_to_packflag(pack_length_arg); break; default: /* Nothing */ diff --git a/sql/item.cc b/sql/item.cc index ff036a9fb54..c59a17a0ea3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. 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 @@ -3434,9 +3434,9 @@ Item_param::set_param_type_and_swap_value(Item_param *src) bool Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) { - Item *value= *it; + Item *arg= *it; - if (value->is_null()) + if (arg->is_null()) { set_null(); return FALSE; @@ -3444,12 +3444,12 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) null_value= FALSE; - switch (value->result_type()) { + switch (arg->result_type()) { case STRING_RESULT: { char str_buffer[STRING_BUFFER_USUAL_SIZE]; String sv_buffer(str_buffer, sizeof(str_buffer), &my_charset_bin); - String *sv= value->val_str(&sv_buffer); + String *sv= arg->val_str(&sv_buffer); if (!sv) return TRUE; @@ -3466,19 +3466,19 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) } case REAL_RESULT: - set_double(value->val_real()); + set_double(arg->val_real()); param_type= MYSQL_TYPE_DOUBLE; break; case INT_RESULT: - set_int(value->val_int(), value->max_length); + set_int(arg->val_int(), arg->max_length); param_type= MYSQL_TYPE_LONG; break; case DECIMAL_RESULT: { my_decimal dv_buf; - my_decimal *dv= value->val_decimal(&dv_buf); + my_decimal *dv= arg->val_decimal(&dv_buf); if (!dv) return TRUE; @@ -3498,8 +3498,8 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) return FALSE; } - item_result_type= value->result_type(); - item_type= value->type(); + item_result_type= arg->result_type(); + item_type= arg->type(); return FALSE; } diff --git a/sql/item.h b/sql/item.h index 8360fa61498..e441a6ff261 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1181,6 +1181,10 @@ public: collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); fix_char_length(max_char_length_arg); } + /* + Return TRUE if the item points to a column of an outer-joined table. + */ + virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; } }; @@ -1694,6 +1698,11 @@ public: int fix_outer_field(THD *thd, Field **field, Item **reference); virtual Item *update_value_transformer(uchar *select_arg); virtual void print(String *str, enum_query_type query_type); + bool is_outer_field() const + { + DBUG_ASSERT(fixed); + return field->table->pos_in_table_list->outer_join; + } Field::geometry_type get_geometry_type() const { DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY); @@ -2506,7 +2515,13 @@ public: DBUG_ASSERT(fixed); return (*ref)->get_time(ltime); } - bool basic_const_item() { return (*ref)->basic_const_item(); } + virtual bool basic_const_item() const { return (*ref)->basic_const_item(); } + bool is_outer_field() const + { + DBUG_ASSERT(fixed); + DBUG_ASSERT(ref); + return (*ref)->is_outer_field(); + } }; @@ -3367,6 +3382,7 @@ public: cmp_context= STRING_RESULT; } + virtual void store(Item *item) { Item_cache::store(item); } void store(Item *item, longlong val_arg); double val_real(); longlong val_int(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 19e8385539f..3c871bc0663 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5466,7 +5466,21 @@ void Item_equal::update_const() Item *item; while ((item= it++)) { - if (item->const_item()) + if (item->const_item() && + /* + Don't propagate constant status of outer-joined column. + Such a constant status here is a result of: + a) empty outer-joined table: in this case such a column has a + value of NULL; but at the same time other arguments of + Item_equal don't have to be NULLs and the value of the whole + multiple equivalence expression doesn't have to be NULL or FALSE + because of the outer join nature; + or + b) outer-joined table contains only 1 row: the result of + this column is equal to a row field value *or* NULL. + Both values are inacceptable as Item_equal constants. + */ + !item->is_outer_field()) { it.remove(); add(item); @@ -5505,7 +5519,8 @@ void Item_equal::update_used_tables() { item->update_used_tables(); used_tables_cache|= item->used_tables(); - const_item_cache&= item->const_item(); + /* see commentary at Item_equal::update_const() */ + const_item_cache&= item->const_item() && !item->is_outer_field(); } } diff --git a/sql/item_sum.h b/sql/item_sum.h index 5f2c4f166e6..c76f3102003 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -303,6 +303,8 @@ class st_select_lex; class Item_sum :public Item_result_field { + friend class Aggregator_distinct; + protected: /** Aggregator class instance. Not set initially. Allocated only after diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 7be10ecde2c..a689d53d953 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2006-2008 MySQL AB, Sun Microsystems Inc. 2008-2009 +/* Copyright (c) 2006, 2010 Oracle and/or its affiliates. All rights reserved. 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 @@ -603,12 +603,12 @@ bool partition_info::check_engine_mix(handlerton *engine_type, { handlerton *old_engine_type= engine_type; bool first= TRUE; - uint num_parts= partitions.elements; + uint n_parts= partitions.elements; DBUG_ENTER("partition_info::check_engine_mix"); DBUG_PRINT("info", ("in: engine_type = %s, table_engine_set = %u", ha_resolve_storage_engine_name(engine_type), table_engine_set)); - if (num_parts) + if (n_parts) { List_iterator<partition_element> part_it(partitions); uint i= 0; @@ -621,7 +621,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type, if (is_sub_partitioned() && part_elem->subpartitions.elements) { - uint num_subparts= part_elem->subpartitions.elements; + uint n_subparts= part_elem->subpartitions.elements; uint j= 0; List_iterator<partition_element> sub_it(part_elem->subpartitions); do @@ -633,7 +633,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type, if (check_engine_condition(sub_elem, table_engine_set, &engine_type, &first)) goto error; - } while (++j < num_subparts); + } while (++j < n_subparts); /* ensure that the partition also has correct engine */ if (check_engine_condition(part_elem, table_engine_set, &engine_type, &first)) @@ -642,7 +642,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type, else if (check_engine_condition(part_elem, table_engine_set, &engine_type, &first)) goto error; - } while (++i < num_parts); + } while (++i < n_parts); } DBUG_PRINT("info", ("engine_type = %s", ha_resolve_storage_engine_name(engine_type))); @@ -1315,15 +1315,15 @@ end: RETURN VALUES */ -void partition_info::print_no_partition_found(TABLE *table) +void partition_info::print_no_partition_found(TABLE *table_arg) { char buf[100]; char *buf_ptr= (char*)&buf; TABLE_LIST table_list; bzero(&table_list, sizeof(table_list)); - table_list.db= table->s->db.str; - table_list.table_name= table->s->table_name.str; + table_list.db= table_arg->s->db.str; + table_list.table_name= table_arg->s->table_name.str; if (check_single_table_access(current_thd, SELECT_ACL, &table_list, TRUE)) @@ -1337,13 +1337,13 @@ void partition_info::print_no_partition_found(TABLE *table) buf_ptr= (char*)"from column_list"; else { - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); + my_bitmap_map *old_map= dbug_tmp_use_all_columns(table_arg, table_arg->read_set); if (part_expr->null_value) buf_ptr= (char*)"NULL"; else longlong2str(err_value, buf, part_expr->unsigned_flag ? 10 : -10); - dbug_tmp_restore_column_map(table->read_set, old_map); + dbug_tmp_restore_column_map(table_arg->read_set, old_map); } my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr); } @@ -2003,7 +2003,7 @@ bool partition_info::fix_column_value_functions(THD *thd, part_elem_value *val, uint part_id) { - uint num_columns= part_field_list.elements; + uint n_columns= part_field_list.elements; bool result= FALSE; uint i; part_column_list_val *col_val= val->col_val_array; @@ -2013,7 +2013,7 @@ bool partition_info::fix_column_value_functions(THD *thd, { DBUG_RETURN(FALSE); } - for (i= 0; i < num_columns; col_val++, i++) + for (i= 0; i < n_columns; col_val++, i++) { Item *column_item= col_val->item_expression; Field *field= part_field_array[i]; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 6054bb0ac23..2c42f29ae71 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. 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 @@ -1708,7 +1708,7 @@ bool READ_INFO::find_start_of_fields() /* Clear taglist from tags with a specified level */ -int READ_INFO::clear_level(int level) +int READ_INFO::clear_level(int level_arg) { DBUG_ENTER("READ_INFO::read_xml clear_level"); List_iterator<XML_TAG> xmlit(taglist); @@ -1717,7 +1717,7 @@ int READ_INFO::clear_level(int level) while ((tag= xmlit++)) { - if(tag->level >= level) + if(tag->level >= level_arg) { xmlit.remove(); delete tag; diff --git a/storage/myisammrg/myrg_queue.c b/storage/myisammrg/myrg_queue.c index d2579053784..2c447083558 100644 --- a/storage/myisammrg/myrg_queue.c +++ b/storage/myisammrg/myrg_queue.c @@ -65,7 +65,17 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag) } } else - my_errno= error= HA_ERR_WRONG_INDEX; + { + /* + inx may be bigger than info->keys if there are no underlying tables + defined. In this case we should return empty result. As we check for + underlying tables conformance when we open a table, we may not enter + this branch with underlying table that has less keys than merge table + have. + */ + DBUG_ASSERT(!info->tables); + error= my_errno= HA_ERR_END_OF_FILE; + } return error; } |