diff options
author | Michael Widenius <monty@askmonty.org> | 2010-05-13 14:00:53 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-05-13 14:00:53 +0300 |
commit | 6659ad49fef7adf8fdf4db78403bbb45accc169b (patch) | |
tree | e4f9c37644dd4dd5e9755e703e2087406d367f02 | |
parent | 8b2abdcf41da724c3685be85611ace237f085374 (diff) | |
download | mariadb-git-6659ad49fef7adf8fdf4db78403bbb45accc169b.tar.gz |
Fixes after last merge of MySQL 5.1
- INSERT with RAND() doesn't require row based logging again
- Some bugs fixed in opt_range() where we table->key_read was wrongly used
.bzrignore:
Ignore new xtstat binary
mysql-test/r/index_merge_myisam.result:
Update results (old result was wrong)
mysql-test/suite/binlog/r/binlog_stm_binlog.result:
Added drop table first
mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result:
Added test for when RAND() requires row based logging
mysql-test/suite/binlog/t/binlog_stm_binlog.test:
Added drop table first
mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test:
Added test for when RAND() requires row based logging
scripts/make_binary_distribution.sh:
Removed type from last commit
sql/item_create.cc:
Don't require row based logging when using RAND() with INSERT
sql/opt_range.cc:
Revert wrong patch from Oracle:
- As QUICK_RANGE_SELECT uses it's own 'file' handler to the tables, one can't use 'table->key_read' as a flag to detect if index only read (keyread) is used or not
- Don't set keyread if keyread is already enabled
- Don't disable key read, if we didn't enable it ourselves
- Simplify code (and ensure that we do proper cleanup of index only read)
sql/opt_range.h:
Added flags to detect if the range optimizer enabled index only read (key read) or not
sql/opt_sum.cc:
Use our more optimized macros
sql/sql_lex.h:
Added 'readable' function to check if we are in a sub query function or not (not normal query or sub query in FROM clause)
sql/sql_select.cc:
Use our more optimized keyread macros
Added ASSERTS early
Simplify code on eliminate_item_equal()
Fixed that substitute_for_best_equal_field() doesn't core dump in case of out of memory conditions.
Removed not needed test for 'field->maybe_null()'
Replaced master_unit()->item with is_subquery_function() (More readable)
sql/sql_update.cc:
Use our more optimized keyread macros
sql/table.cc:
Use our more optimized keyread macros
sql/table.h:
Use separate functions to enable/disable Index only reads
- Safer, more readable, better logging and faster.
-rw-r--r-- | .bzrignore | 1 | ||||
-rw-r--r-- | mysql-test/r/index_merge_myisam.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_stm_binlog.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result | 13 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_stm_binlog.test | 10 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test | 16 | ||||
-rw-r--r-- | scripts/make_binary_distribution.sh | 2 | ||||
-rw-r--r-- | sql/item_create.cc | 5 | ||||
-rw-r--r-- | sql/opt_range.cc | 69 | ||||
-rw-r--r-- | sql/opt_range.h | 4 | ||||
-rw-r--r-- | sql/opt_sum.cc | 6 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 79 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/table.cc | 4 | ||||
-rw-r--r-- | sql/table.h | 20 |
16 files changed, 161 insertions, 83 deletions
diff --git a/.bzrignore b/.bzrignore index 34e7c1cd1c1..a5358590417 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1927,3 +1927,4 @@ libmysqld/opt_table_elimination.cc libmysqld/ha_federatedx.cc tmp libmysqld/debug_sync.cc +storage/pbxt/bin/xtstat diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index c4e6a6d3f9c..182455f8c06 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -286,7 +286,7 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 -2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where; Using index +2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where create table t3 like t0; insert into t3 select * from t0; alter table t3 add key9 int not null, add index i9(key9); diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index eebcfceaa25..a7f79e53895 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -1,3 +1,4 @@ +drop table if exists t1; create table t1 (a int, b int) engine=innodb; begin; insert into t1 values (1,2); @@ -5,10 +6,11 @@ commit; show binlog events; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: #, Binlog ver: # -master-bin.000001 106 Query 1 213 use `test`; create table t1 (a int, b int) engine=innodb -master-bin.000001 213 Query 1 281 BEGIN -master-bin.000001 281 Query 1 371 use `test`; insert into t1 values (1,2) -master-bin.000001 371 Xid 1 398 COMMIT /* XID */ +master-bin.000001 106 Query 1 192 use `test`; drop table if exists t1 +master-bin.000001 192 Query 1 299 use `test`; create table t1 (a int, b int) engine=innodb +master-bin.000001 299 Query 1 367 BEGIN +master-bin.000001 367 Query 1 457 use `test`; insert into t1 values (1,2) +master-bin.000001 457 Xid 1 484 COMMIT /* XID */ drop table t1; drop table if exists t1, t2; reset master; diff --git a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result index edbd878982b..eb056468f60 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result +++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result @@ -48,3 +48,16 @@ SET GLOBAL log_warnings = @old_log_warnings; # Count the number of times the "Unsafe" message was printed # to the error log. Occurrences: 1 +create table t1 (n1 int, n2 int, n3 int, +key (n1, n2, n3), +key (n2, n3, n1), +key (n3, n1, n2)); +insert into t1 values (1,1,1); +insert into t1 values (RAND()*1000+10, RAND()*1000+10, RAND()*1000+10); +update t1 set n1=rand() where n1=1; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +delete from t1 where n2=1 + rand()*0; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +drop table t1; diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog.test b/mysql-test/suite/binlog/t/binlog_stm_binlog.test index 280b7a3aef9..a8afe4d3b8c 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_binlog.test +++ b/mysql-test/suite/binlog/t/binlog_stm_binlog.test @@ -1,3 +1,10 @@ +-- source include/not_embedded.inc +-- source include/have_binlog_format_mixed.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + # REQUIREMENT # replace_regex should replace output of SHOW BINLOG EVENTS @@ -12,7 +19,4 @@ drop table t1; # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/not_embedded.inc --- source include/have_binlog_format_mixed.inc -- source extra/binlog_tests/binlog.test - diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test index 21c11d5a3df..d09f4e433ac 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -115,3 +115,19 @@ perl; print "Occurrences: $count\n"; close(FILE); EOF + +# +# Check how RAND() can be used with replication +# + +create table t1 (n1 int, n2 int, n3 int, + key (n1, n2, n3), + key (n2, n3, n1), + key (n3, n1, n2)); +insert into t1 values (1,1,1); +# This should work fine +insert into t1 values (RAND()*1000+10, RAND()*1000+10, RAND()*1000+10); +# This should need row based logging. +update t1 set n1=rand() where n1=1; +delete from t1 where n2=1 + rand()*0; +drop table t1; diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 44505adf6e1..eb2cc94afe9 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -276,7 +276,7 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; then # Do a install that we later are to pack. Use the same paths as in # the build for the relevant directories. # ---------------------------------------------------------------------- - set -x -v + @MAKE@ DESTDIR=$BASE install \ pkglibdir=@pkglibdir@ \ pkgincludedir=@pkgincludedir@ \ diff --git a/sql/item_create.cc b/sql/item_create.cc index 8541557c011..2e72ab24fb0 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4185,8 +4185,11 @@ Create_func_rand::create_native(THD *thd, LEX_STRING name, into a table, the order in which the rows are modified may differ between master and slave, because the order is undefined. Hence, the statement is unsafe to log in statement format. + + For normal INSERT's this is howevever safe */ - thd->lex->set_stmt_unsafe(); + if (thd->lex->sql_command != SQLCOM_INSERT) + thd->lex->set_stmt_unsafe(); switch (arg_count) { case 0: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 280154c0b52..160175f9ee3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1100,7 +1100,7 @@ QUICK_SELECT_I::QUICK_SELECT_I() QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc, MEM_ROOT *parent_alloc) - :dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0) + :dont_free(0),doing_key_read(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0) { my_bitmap_map *bitmap; DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT"); @@ -1171,7 +1171,8 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT() if (file) { range_end(); - head->set_keyread(FALSE); + if (doing_key_read) + file->extra(HA_EXTRA_NO_KEYREAD); if (free_file) { DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file, @@ -1311,6 +1312,7 @@ int QUICK_ROR_INTERSECT_SELECT::init() int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) { handler *save_file= file, *org_file; + my_bool org_key_read; THD *thd; DBUG_ENTER("QUICK_RANGE_SELECT::init_ror_merged_scan"); @@ -1370,12 +1372,17 @@ end: The now bitmap is stored in 'column_bitmap' which is used in ::get_next() */ org_file= head->file; + org_key_read= head->key_read; head->file= file; - /* We don't have to set 'head->keyread' here as the 'file' is unique */ + head->key_read= 0; if (!head->no_keyread) + { + doing_key_read= 1; head->mark_columns_used_by_index(index); + } head->prepare_for_position(); head->file= org_file; + head->key_read= org_key_read; bitmap_copy(&column_bitmap, head->read_set); head->column_bitmaps_set(&column_bitmap, &column_bitmap); @@ -8154,12 +8161,15 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects); QUICK_RANGE_SELECT* cur_quick; int result; - Unique *unique; + Unique *unique= 0; handler *file= head->file; DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge"); /* We're going to just read rowids. */ - head->set_keyread(TRUE); + if (!head->key_read) + { + head->enable_keyread(); + } head->prepare_for_position(); cur_quick_it.rewind(); @@ -8171,13 +8181,13 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() reset here. */ if (cur_quick->init() || cur_quick->reset()) - DBUG_RETURN(1); + goto err; unique= new Unique(refpos_order_cmp, (void *)file, file->ref_length, thd->variables.sortbuff_size); if (!unique) - DBUG_RETURN(1); + goto err; for (;;) { while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE) @@ -8190,10 +8200,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (cur_quick->file->inited != handler::NONE) cur_quick->file->ha_index_end(); if (cur_quick->init() || cur_quick->reset()) - { - delete unique; - DBUG_RETURN(1); - } + goto err; } if (result) @@ -8201,29 +8208,21 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (result != HA_ERR_END_OF_FILE) { cur_quick->range_end(); - delete unique; - DBUG_RETURN(result); + goto err; } break; } if (thd->killed) - { - delete unique; - DBUG_RETURN(1); - } + goto err; /* skip row if it will be retrieved by clustered PK scan */ if (pk_quick_select && pk_quick_select->row_in_ranges()) continue; cur_quick->file->position(cur_quick->record); - result= unique->unique_add((char*)cur_quick->file->ref); - if (result) - { - delete unique; - DBUG_RETURN(1); - } + if (unique->unique_add((char*)cur_quick->file->ref)) + goto err; } /* @@ -8234,10 +8233,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() result= unique->get(head); delete unique; doing_pk_scan= FALSE; - /* index_merge currently doesn't support "using index" at all */ - head->set_keyread(FALSE); + /* + index_merge currently doesn't support "using index" at all + */ + head->disable_keyread(); init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); DBUG_RETURN(result); + +err: + delete unique; + head->disable_keyread(); + DBUG_RETURN(1); } @@ -10308,7 +10314,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, :join(join_arg), index_info(index_info_arg), group_prefix_len(group_prefix_len_arg), group_key_parts(group_key_parts_arg), have_min(have_min_arg), - have_max(have_max_arg), seen_first_key(FALSE), + have_max(have_max_arg), seen_first_key(FALSE), doing_key_read(FALSE), min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg), key_infix_len(key_infix_len_arg), min_functions_it(NULL), max_functions_it(NULL) @@ -10439,7 +10445,12 @@ QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT() { DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT"); if (file->inited != handler::NONE) + { + DBUG_ASSERT(file == head->file); + if (doing_key_read) + head->disable_keyread(); file->ha_index_end(); + } if (min_max_arg_part) delete_dynamic(&min_max_ranges); free_root(&alloc,MYF(0)); @@ -10622,7 +10633,11 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) int result; DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset"); - head->set_keyread(TRUE); /* We need only the key attributes */ + if (!head->key_read) + { + doing_key_read= 1; + head->enable_keyread(); /* We need only the key attributes */ + } if ((result= file->ha_index_init(index,1))) DBUG_RETURN(result); if (quick_prefix_select && quick_prefix_select->reset()) diff --git a/sql/opt_range.h b/sql/opt_range.h index 6a0234e62fe..ad2eddba4f0 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -280,6 +280,8 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I { protected: bool next,dont_free,in_ror_merged_scan; + /* true if we enabled key only reads */ + bool doing_key_read; public: int error; protected: @@ -623,6 +625,8 @@ private: bool have_min; /* Specify whether we are computing */ bool have_max; /* a MIN, a MAX, or both. */ bool seen_first_key; /* Denotes whether the first key was retrieved.*/ + bool doing_key_read; /* true if we enabled key only reads */ + KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */ /* of all MIN/MAX functions. */ uint min_max_arg_len; /* The length of the MIN/MAX argument field */ diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 58906c7acab..2bd757ee201 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -326,7 +326,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) if (!error && reckey_in_range(0, &ref, item_field->field, conds, range_fl, prefix_len)) error= HA_ERR_KEY_NOT_FOUND; - table->set_keyread(FALSE); + table->disable_keyread(); table->file->ha_index_end(); if (error) { @@ -409,7 +409,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) if (!error && reckey_in_range(1, &ref, item_field->field, conds, range_fl, prefix_len)) error= HA_ERR_KEY_NOT_FOUND; - table->set_keyread(FALSE); + table->disable_keyread(); table->file->ha_index_end(); if (error) { @@ -902,7 +902,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, converted (for example to upper case) */ if (field->part_of_key.is_set(idx)) - table->set_keyread(TRUE); + table->enable_keyread(); return 1; } } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 90a7c66e0d0..f9838c26cb5 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -744,6 +744,7 @@ public: { return master_unit()->return_after_parsing(); } + inline bool is_subquery_function() { return master_unit()->item != 0; } void mark_as_dependent(st_select_lex *last, Item *dependency); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7d62a3808eb..3548fbf5da3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009-2010 Monty Program 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 @@ -6760,7 +6761,7 @@ make_join_readinfo(JOIN *join, ulonglong options) case JT_CONST: // Only happens with left join if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) - table->set_keyread(TRUE); + table->enable_keyread(); break; case JT_ALL: /* @@ -6827,7 +6828,7 @@ make_join_readinfo(JOIN *join, ulonglong options) if (tab->select && tab->select->quick && tab->select->quick->index != MAX_KEY && //not index_merge table->covering_keys.is_set(tab->select->quick->index)) - table->set_keyread(TRUE); + table->enable_keyread(); else if (!table->covering_keys.is_clear_all() && !(tab->select && tab->select->quick)) { // Only read index tree @@ -6911,7 +6912,7 @@ void JOIN_TAB::cleanup() limit= 0; if (table) { - table->set_keyread(FALSE); + table->disable_keyread(); table->file->ha_index_or_rnd_end(); /* We need to reset this for next select @@ -8275,6 +8276,8 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, Item *item_const= item_equal->get_const(); Item_equal_iterator it(*item_equal); Item *head; + DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM); + if (item_const) head= item_const; else @@ -8310,27 +8313,30 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, return 0; eq_item->set_cmp_func(); eq_item->quick_fix_field(); - } + } } - if (!cond && !eq_list.head()) + if (!cond) { - if (!eq_item) - return new Item_int((longlong) 1,1); - return eq_item; - } - - if (eq_item) + if (eq_list.is_empty()) + { + if (eq_item) + return eq_item; + return new Item_int((longlong) 1, 1); + } + /* eq_item is always set if list is not empty */ + DBUG_ASSERT(eq_item); eq_list.push_back(eq_item); - if (!cond) - cond= new Item_cond_and(eq_list); + if (!(cond= new Item_cond_and(eq_list))) + return 0; // Error + } else { - DBUG_ASSERT(cond->type() == Item::COND_ITEM); - if (eq_list.elements) + if (eq_item) + eq_list.push_back(eq_item); + if (!eq_list.is_empty()) ((Item_cond *) cond)->add_at_head(&eq_list); } - cond->quick_fix_field(); cond->update_used_tables(); @@ -8371,6 +8377,7 @@ static COND* substitute_for_best_equal_field(COND *cond, void *table_join_idx) { Item_equal *item_equal; + COND *org_cond= cond; // Return this in case of fatal error if (cond->type() == Item::COND_ITEM) { @@ -8394,7 +8401,7 @@ static COND* substitute_for_best_equal_field(COND *cond, Item *item; while ((item= li++)) { - Item *new_item =substitute_for_best_equal_field(item, cond_equal, + Item *new_item= substitute_for_best_equal_field(item, cond_equal, table_join_idx); /* This works OK with PS/SP re-execution as changes are made to @@ -8413,6 +8420,8 @@ static COND* substitute_for_best_equal_field(COND *cond, // This occurs when eliminate_item_equal() founds that cond is // always false and substitutes it with Item_int 0. // Due to this, value of item_equal will be 0, so just return it. + if (!cond) + return org_cond; // Error if (cond->type() != Item::COND_ITEM) break; } @@ -8429,7 +8438,8 @@ static COND* substitute_for_best_equal_field(COND *cond, item_equal->sort(&compare_fields_by_table_order, table_join_idx); if (cond_equal && cond_equal->current_level.head() == item_equal) cond_equal= 0; - return eliminate_item_equal(0, cond_equal, item_equal); + cond= eliminate_item_equal(0, cond_equal, item_equal); + return cond ? cond : org_cond; } else cond->transform(&Item::replace_equal_field, 0); @@ -11981,11 +11991,11 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos) !table->no_keyread && (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY) { - table->set_keyread(TRUE); + table->enable_keyread(); tab->index= tab->ref.key; } error=join_read_const(tab); - table->set_keyread(FALSE); + table->disable_keyread(); if (error) { tab->info="unique row not found"; @@ -12367,8 +12377,9 @@ join_read_first(JOIN_TAB *tab) { int error= 0; TABLE *table=tab->table; - if (table->covering_keys.is_set(tab->index) && !table->no_keyread) - table->set_keyread(TRUE); + if (table->covering_keys.is_set(tab->index) && !table->no_keyread && + !table->key_read) + table->enable_keyread(); tab->table->status=0; tab->read_record.read_record=join_read_next; tab->read_record.table=table; @@ -12404,8 +12415,9 @@ join_read_last(JOIN_TAB *tab) { TABLE *table=tab->table; int error= 0; - if (table->covering_keys.is_set(tab->index) && !table->no_keyread) - table->set_keyread(TRUE); + if (table->covering_keys.is_set(tab->index) && !table->no_keyread && + !table->key_read) + table->enable_keyread(); tab->table->status=0; tab->read_record.read_record=join_read_prev; tab->read_record.table=table; @@ -13868,7 +13880,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, and best_key doesn't, then revert the decision. */ if (!table->covering_keys.is_set(best_key)) - table->set_keyread(FALSE); + table->disable_keyread(); if (!quick_created) { tab->index= best_key; @@ -13880,8 +13892,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, delete select->quick; select->quick= 0; } - if (table->covering_keys.is_set(best_key)) - table->set_keyread(TRUE); + if (table->covering_keys.is_set(best_key) && ! table->key_read) + table->enable_keyread(); table->file->ha_index_or_rnd_end(); if (join->select_options & SELECT_DESCRIBE) { @@ -14056,7 +14068,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, and in index_merge 'Only index' cannot be used */ if (((uint) tab->ref.key != select->quick->index)) - table->set_keyread(FALSE); + table->disable_keyread(); } else { @@ -14112,7 +14124,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, tab->type=JT_ALL; // Read with normal read_record tab->read_first_record= join_init_read_record; tab->join->examined_rows+=examined_rows; - table->set_keyread(FALSE); // Restore if we used indexes + table->disable_keyread(); // Restore if we used indexes DBUG_RETURN(table->sort.found_records == HA_POS_ERROR); err: DBUG_RETURN(-1); @@ -14657,12 +14669,15 @@ store_record_in_cache(JOIN_CACHE *cache) { uchar *str,*end; Field *field= copy->field; - if (field && field->maybe_null() && field->is_null()) + if (field && field->is_null()) end= str= copy->str; else + { for (str=copy->str,end= str+copy->length; end > str && end[-1] == ' ' ; - end--) ; + end--) + ; + } length=(uint) (end-str); memcpy(pos+2, str, length); int2store(pos, length); @@ -17342,7 +17357,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) else str->append(','); - if (master_unit()->item && item->is_autogenerated_name) + if (is_subquery_function() && item->is_autogenerated_name) { /* Do not print auto-generated aliases in subqueries. It has no purpose diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 1d1f9dedf22..d90480732cd 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -841,7 +841,7 @@ int mysql_update(THD *thd, err: delete select; free_underlaid_joins(thd, select_lex); - table->set_keyread(FALSE); + table->disable_keyread(); thd->abort_on_warning= 0; DBUG_RETURN(1); } diff --git a/sql/table.cc b/sql/table.cc index 7bfdc8d184e..0c3b863786a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4395,7 +4395,7 @@ void st_table::mark_columns_used_by_index(uint index) MY_BITMAP *bitmap= &tmp_set; DBUG_ENTER("st_table::mark_columns_used_by_index"); - set_keyread(TRUE); + enable_keyread(); bitmap_clear_all(bitmap); mark_columns_used_by_index_no_reset(index, bitmap); column_bitmaps_set(bitmap, bitmap); @@ -4418,7 +4418,7 @@ void st_table::restore_column_maps_after_mark_index() { DBUG_ENTER("st_table::restore_column_maps_after_mark_index"); - set_keyread(FALSE); + disable_keyread(); default_column_bitmaps(); file->column_bitmaps_signal(); DBUG_VOID_RETURN; diff --git a/sql/table.h b/sql/table.h index e43e6e5950f..8588f3c94c3 100644 --- a/sql/table.h +++ b/sql/table.h @@ -905,19 +905,23 @@ struct st_table { inline bool needs_reopen_or_name_lock() { return s->version != refresh_version; } bool is_children_attached(void); - inline void set_keyread(bool flag) + inline void enable_keyread() { - DBUG_ASSERT(file); - if (flag && !key_read) - { - key_read= 1; - file->extra(HA_EXTRA_KEYREAD); - } - else if (!flag && key_read) + DBUG_ENTER("enable_keyread"); + DBUG_ASSERT(key_read == 0); + key_read= 1; + file->extra(HA_EXTRA_KEYREAD); + DBUG_VOID_RETURN; + } + inline void disable_keyread() + { + DBUG_ENTER("disable_keyread"); + if (key_read) { key_read= 0; file->extra(HA_EXTRA_NO_KEYREAD); } + DBUG_VOID_RETURN; } }; |