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.
This commit is contained in:
parent
8b2abdcf41
commit
6659ad49fe
@ -1927,3 +1927,4 @@ libmysqld/opt_table_elimination.cc
|
||||
libmysqld/ha_federatedx.cc
|
||||
tmp
|
||||
libmysqld/debug_sync.cc
|
||||
storage/pbxt/bin/xtstat
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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@ \
|
||||
|
@ -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:
|
||||
|
@ -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())
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 (!eq_item)
|
||||
return new Item_int((longlong) 1,1);
|
||||
return eq_item;
|
||||
}
|
||||
|
||||
if (eq_item)
|
||||
eq_list.push_back(eq_item);
|
||||
if (!cond)
|
||||
cond= new Item_cond_and(eq_list);
|
||||
{
|
||||
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= 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
20
sql/table.h
20
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user