This commit is contained in:
monty@mysql.com 2005-06-05 17:19:50 +03:00
commit 4b7882dc73
36 changed files with 7447 additions and 6220 deletions

View File

@ -1657,11 +1657,12 @@ int mysql_real_query_for_lazy(const char *buf, int length)
{
for (uint retry=0;; retry++)
{
int error;
if (!mysql_real_query(&mysql,buf,length))
return 0;
int error= put_error(&mysql);
error= put_error(&mysql);
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
!opt_reconnect)
!opt_reconnect)
return error;
if (reconnect())
return error;
@ -2314,22 +2315,23 @@ print_table_data_vertically(MYSQL_RES *result)
}
}
/* print_warnings should be called right after executing a statement */
static void
print_warnings()
static void print_warnings()
{
char query[30];
const char *query;
MYSQL_RES *result;
MYSQL_ROW cur;
my_ulonglong num_rows;
/* Get the warnings */
strmov(query,"show warnings");
mysql_real_query_for_lazy(query,strlen(query));
query= "show warnings";
mysql_real_query_for_lazy(query, strlen(query));
mysql_store_result_for_lazy(&result);
/* Bail out when no warnings */
my_ulonglong num_rows = mysql_num_rows(result);
if (num_rows == 0)
if (!(num_rows= mysql_num_rows(result)))
{
mysql_free_result(result);
return;
@ -2343,13 +2345,12 @@ print_warnings()
mysql_free_result(result);
}
static const char
*array_value(const char **array, char key)
static const char *array_value(const char **array, char key)
{
int x;
for (x= 0; array[x]; x+= 2)
if (*array[x] == key)
return array[x + 1];
for (; *array; array+= 2)
if (**array == key)
return array[1];
return 0;
}

View File

@ -1738,7 +1738,7 @@ myodbc_remove_escape(MYSQL *mysql,char *name)
/* Default number of rows fetched per one COM_FETCH command. */
#define DEFAULT_PREFETCH_ROWS 1UL
#define DEFAULT_PREFETCH_ROWS (ulong) 1
/*
These functions are called by function pointer MYSQL_STMT::read_row_func.

View File

@ -887,7 +887,7 @@ report_stats () {
found_error=0
# Find errors
for i in "^Warning:" "^Error:" "^==.* at 0x"
for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning"
do
if $GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings
then

View File

@ -1,4 +1,4 @@
drop table if exists t1,t11,t12,t2;
drop table if exists t1,t2,t3,t11,t12;
CREATE TABLE t1 (a tinyint(3), b tinyint(5));
INSERT INTO t1 VALUES (1,1);
INSERT LOW_PRIORITY INTO t1 VALUES (1,2);
@ -172,3 +172,23 @@ a
0
2
DROP TABLE t1;
CREATE TABLE t1 (a int not null,b int not null);
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
a b a b a b
1 1 1 1 1 1
2 1 2 2 2 1
1 3 1 1 1 3
explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index
1 SIMPLE t3 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t3;
a b
drop table t1,t2,t3;

View File

@ -1,3 +1,4 @@
DROP TABLE IF EXISTS t0,t1,t2;
show variables where variable_name like "skip_show_database";
Variable_name Value
skip_show_database OFF

View File

@ -3,7 +3,7 @@
#
--disable_warnings
drop table if exists t1,t11,t12,t2;
drop table if exists t1,t2,t3,t11,t12;
--enable_warnings
CREATE TABLE t1 (a tinyint(3), b tinyint(5));
INSERT INTO t1 VALUES (1,1);
@ -152,3 +152,20 @@ INSERT INTO t1 VALUES (0),(1),(2);
DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1;
SELECT * FROM t1;
DROP TABLE t1;
#
# Test of multi-delete where we are not scanning the first table
#
CREATE TABLE t1 (a int not null,b int not null);
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
# This should be empty
select * from t3;
drop table t1,t2,t3;

View File

@ -4,6 +4,11 @@
# Test for information_schema.schemata &
# show databases
--disable_warnings
DROP TABLE IF EXISTS t0,t1,t2;
--enable_warnings
show variables where variable_name like "skip_show_database";
grant select, update, execute on test.* to mysqltest_2@localhost;
grant select, update on test.* to mysqltest_1@localhost;

View File

@ -911,7 +911,9 @@ DROP TABLE t1;
# Bug #10465
#
--disable_warnings
CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB;
--enable_warnings
INSERT INTO t1 (GRADE) VALUES (151),(252),(343);
SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300;
SELECT GRADE FROM t1 WHERE GRADE= 151;

View File

@ -39,10 +39,11 @@
DESCRIPTION
This function prepares memory root for further use, sets initial size of
chunk for memory allocation and pre-allocates first block if specified.
Altough error can happen during execution of this function if pre_alloc_size
is non-0 it won't be reported. Instead it will be reported as error in first
alloc_root() on this memory root.
Altough error can happen during execution of this function if
pre_alloc_size is non-0 it won't be reported. Instead it will be
reported as error in first alloc_root() on this memory root.
*/
void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size __attribute__((unused)))
{
@ -71,6 +72,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
DBUG_VOID_RETURN;
}
/*
SYNOPSIS
reset_root_defaults()
@ -86,7 +88,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
reuse one of existing blocks as prealloc block, or malloc new one of
requested size. If no blocks can be reused, all unused blocks are freed
before allocation.
*/
*/
void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size __attribute__((unused)))

View File

@ -684,8 +684,10 @@ void thr_unlock(THR_LOCK_DATA *data)
lock->read.last=data->prev;
else if (lock_type == TL_WRITE_DELAYED && data->cond)
{
/* This only happens in extreme circumstances when a
write delayed lock that is waiting for a lock */
/*
This only happens in extreme circumstances when a
write delayed lock that is waiting for a lock
*/
lock->write_wait.last=data->prev; /* Put it on wait queue */
}
else

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5592,8 +5592,8 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index;
const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation();
NdbIndexScanOperation* scanOp= 0;
for(; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer;
multi_range_curr++)
for (; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer;
multi_range_curr++)
{
switch(index_type){
case PRIMARY_KEY_INDEX:
@ -5730,7 +5730,7 @@ ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
int range_no;
ulong reclength= table->s->reclength;
const NdbOperation* op= m_current_multi_operation;
for(;multi_range_curr < m_multi_range_defined; multi_range_curr++)
for (;multi_range_curr < m_multi_range_defined; multi_range_curr++)
{
if (multi_range_curr->range_flag & UNIQUE_RANGE)
{

View File

@ -2248,9 +2248,8 @@ bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
SELECT_LEX_UNIT::item set only for subqueries, so test of it presence
can be barrier to stop before derived table SELECT or very outer SELECT
*/
for(;
cursel->master_unit()->item;
cursel= cursel->outer_select())
for (; cursel->master_unit()->item;
cursel= cursel->outer_select())
{
Item_subselect *subselect_item= cursel->master_unit()->item;
subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
@ -2530,9 +2529,8 @@ void mark_select_range_as_dependent(THD *thd,
resolving)
*/
SELECT_LEX *previous_select= current_sel;
for(;
previous_select->outer_select() != last_select;
previous_select= previous_select->outer_select())
for (; previous_select->outer_select() != last_select;
previous_select= previous_select->outer_select())
{
Item_subselect *prev_subselect_item=
previous_select->master_unit()->item;

View File

@ -284,7 +284,9 @@ public:
Item(THD *thd, Item *item);
virtual ~Item()
{
#ifdef EXTRA_DEBUG
name=0;
#endif
} /*lint -e1509 */
void set_name(const char *str,uint length, CHARSET_INFO *cs);
void rename(char *new_name);

View File

@ -213,15 +213,16 @@ void Item_func::set_arguments(List<Item> &list)
{
allowed_arg_cols= 1;
arg_count=list.elements;
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
args= tmp_arg; // If 2 arguments
if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
uint i=0;
List_iterator_fast<Item> li(list);
Item *item;
Item **save_args= args;
while ((item=li++))
{
args[i++]= item;
*(save_args++)= item;
with_sum_func|=item->with_sum_func;
}
}

View File

@ -772,9 +772,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
Comp_creator *func)
{
Item_subselect::trans_res result= RES_ERROR;
DBUG_ENTER("Item_in_subselect::single_value_transformer");
SELECT_LEX *select_lex= join->select_lex;
DBUG_ENTER("Item_in_subselect::single_value_transformer");
/*
Check that the right part of the subselect contains no more than one
@ -1646,7 +1645,7 @@ void subselect_uniquesubquery_engine::exclude()
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
{
table_map map= 0;
for(; table; table= table->next_leaf)
for (; table; table= table->next_leaf)
{
TABLE *tbl= table->table;
if (tbl && tbl->const_table)

View File

@ -242,8 +242,12 @@ Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
case REAL_RESULT:
sum= item->sum;
break;
case STRING_RESULT: // This can happen with ROLLUP. Note that the value is already
break; // copied at function call.
case STRING_RESULT:
/*
This can happen with ROLLUP. Note that the value is already
copied at function call.
*/
break;
case ROW_RESULT:
default:
DBUG_ASSERT(0);

View File

@ -94,7 +94,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define MAX_FIELDS_BEFORE_HASH 32
#define USER_VARS_HASH_SIZE 16
#define STACK_MIN_SIZE 8192 // Abort if less stack during eval.
#define STACK_BUFF_ALLOC 64 // For stack overrun checks
#define STACK_BUFF_ALLOC 256 // For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif

View File

@ -398,7 +398,7 @@ TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
static int get_index_merge_params(PARAM *param, key_map& needed_reg,
SEL_IMERGE *imerge, double *read_time,
ha_rows* imerge_rows);
inline double get_index_only_read_time(const PARAM* param, ha_rows records,
static double get_index_only_read_time(const PARAM* param, ha_rows records,
int keynr);
#ifndef DBUG_OFF
@ -1117,6 +1117,7 @@ int QUICK_ROR_UNION_SELECT::init()
val1 First merged select
val2 Second merged select
*/
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, byte *val1, byte *val2)
{
QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
@ -1584,7 +1585,7 @@ static int fill_used_fields_bitmap(PARAM *param)
KEY_PART_INFO *key_part= param->table->key_info[pk].key_part;
KEY_PART_INFO *key_part_end= key_part +
param->table->key_info[pk].key_parts;
for(;key_part != key_part_end; ++key_part)
for (;key_part != key_part_end; ++key_part)
{
bitmap_clear_bit(&param->needed_fields, key_part->fieldnr);
}
@ -1748,18 +1749,20 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
double best_read_time= read_time;
if (cond)
tree= get_mm_tree(&param,cond);
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
{
records=0L; /* Return -1 from this function. */
read_time= (double) HA_POS_ERROR;
goto free_mem;
if ((tree= get_mm_tree(&param,cond)))
{
if (tree->type == SEL_TREE::IMPOSSIBLE)
{
records=0L; /* Return -1 from this function. */
read_time= (double) HA_POS_ERROR;
goto free_mem;
}
if (tree->type != SEL_TREE::KEY &&
tree->type != SEL_TREE::KEY_SMALLER)
goto free_mem;
}
}
else if (tree && tree->type != SEL_TREE::KEY &&
tree->type != SEL_TREE::KEY_SMALLER)
goto free_mem;
/*
Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
@ -2250,7 +2253,7 @@ skip_to_ror_scan:
clustered index)
*/
inline double get_index_only_read_time(const PARAM* param, ha_rows records,
static double get_index_only_read_time(const PARAM* param, ha_rows records,
int keynr)
{
double read_time;
@ -2296,6 +2299,7 @@ typedef struct st_ror_scan_info
param Parameter from test_quick_select function
idx Index of key in param->keys
sel_arg Set of intervals for a given key
RETURN
NULL - out of memory
ROR scan structure containing a scan for {idx, sel_arg}
@ -2308,19 +2312,20 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
uchar *bitmap_buf;
uint keynr;
DBUG_ENTER("make_ror_scan");
if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
sizeof(ROR_SCAN_INFO))))
DBUG_RETURN(NULL);
ror_scan->idx= idx;
ror_scan->keynr= keynr= param->real_keynr[idx];
ror_scan->key_rec_length= param->table->key_info[keynr].key_length +
param->table->file->ref_length;
ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
param->table->file->ref_length);
ror_scan->sel_arg= sel_arg;
ror_scan->records= param->table->quick_rows[keynr];
if (!(bitmap_buf= (uchar*)alloc_root(param->mem_root,
param->fields_bitmap_size)))
param->fields_bitmap_size)))
DBUG_RETURN(NULL);
if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
@ -2331,14 +2336,10 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
KEY_PART_INFO *key_part_end= key_part +
param->table->key_info[keynr].key_parts;
uint n_used_covered= 0;
for (;key_part != key_part_end; ++key_part)
{
if (bitmap_is_set(&param->needed_fields, key_part->fieldnr))
{
n_used_covered++;
bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr);
}
}
ror_scan->index_read_cost=
get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr],
@ -2359,6 +2360,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
0 a = b
1 a > b
*/
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
{
double val1= rows2double((*a)->records) * (*a)->key_rec_length;
@ -2382,6 +2384,7 @@ static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
0 a = b
1 a > b
*/
static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
{
if ((*a)->used_fields_covered > (*b)->used_fields_covered)
@ -2399,6 +2402,7 @@ static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
return 0;
}
/* Auxiliary structure for incremental ROR-intersection creation */
typedef struct
{
@ -2464,6 +2468,8 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
dst->index_scan_costs= src->index_scan_costs;
dst->total_cost= src->total_cost;
}
/*
Get selectivity of a ROR scan wrt ROR-intersection.
@ -2481,7 +2487,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
where k_ij may be the same as any k_pq (i.e. keys may have common parts).
A full row is retrieved iff entire cond holds.
A full row is retrieved if entire condition holds.
The recursive procedure for finding P(cond) is as follows:
@ -2492,7 +2498,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
Here R may still contain condition(s) equivalent to k_11=c_11.
Nevertheless, the following holds:
P(k_11=c_11 AND R) = P(k_11=c_11) * P(R|k_11=c_11).
P(k_11=c_11 AND R) = P(k_11=c_11) * P(R | k_11=c_11).
Mark k_11 as fixed field (and satisfied condition) F, save P(F),
save R to be cond and proceed to recursion step.
@ -2539,7 +2545,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
( this is result of application of option b) of the recursion step for
parts of a single key).
Since it is reasonable to expect that most of the fields are not marked
as fixed, we calcualate (3) as
as fixed, we calculate (3) as
n_{i1} n_{i_2}
(3) = n_{max_key_part} / ( --------- * --------- * .... )
@ -2573,33 +2579,32 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
max_range.key= (byte*) key_val;
max_range.flag= HA_READ_AFTER_KEY;
ha_rows prev_records= info->param->table->file->records;
int i;
DBUG_ENTER("ror_intersect_selectivity");
for(i= 0, sel_arg= scan->sel_arg; sel_arg;
i++, sel_arg= sel_arg->next_key_part)
for (sel_arg= scan->sel_arg; sel_arg;
sel_arg= sel_arg->next_key_part)
{
DBUG_PRINT("info",("sel_arg step"));
cur_covered= test(bitmap_is_set(&info->covered_fields,
(key_part + i)->fieldnr));
key_part[sel_arg->part].fieldnr));
if (cur_covered != prev_covered)
{
/* create (part1val, ..., part{n-1}val) tuple. */
{
if (!tuple_arg)
{
tuple_arg= scan->sel_arg;
tuple_arg->store_min(key_part->length, &key_ptr, 0);
}
while (tuple_arg->next_key_part != sel_arg)
{
tuple_arg= tuple_arg->next_key_part;
tuple_arg->store_min(key_part->length, &key_ptr, 0);
}
}
ha_rows records;
if (!tuple_arg)
{
tuple_arg= scan->sel_arg;
/* Here we use the length of the first key part */
tuple_arg->store_min(key_part->length, &key_ptr, 0);
}
while (tuple_arg->next_key_part != sel_arg)
{
tuple_arg= tuple_arg->next_key_part;
tuple_arg->store_min(key_part[tuple_arg->part].length, &key_ptr, 0);
}
min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val);
records= info->param->table->file->
records_in_range(scan->keynr, &min_range, &max_range);
records= (info->param->table->file->
records_in_range(scan->keynr, &min_range, &max_range));
if (cur_covered)
{
/* uncovered -> covered */
@ -2627,6 +2632,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
DBUG_RETURN(selectivity_mult);
}
/*
Check if adding a ROR scan to a ROR-intersection reduces its cost of
ROR-intersection and if yes, update parameters of ROR-intersection,
@ -2664,7 +2670,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
*/
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
{
double selectivity_mult= 1.0;
@ -3220,11 +3226,11 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
quick_imerge->records= records;
quick_imerge->read_time= read_cost;
for(TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
range_scan++)
for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
range_scan++)
{
if (!(quick= (QUICK_RANGE_SELECT*)
((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))||
((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))||
quick_imerge->push_quick_back(quick))
{
delete quick;
@ -3253,7 +3259,7 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
"creating ROR-intersect",
first_scan, last_scan););
alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
for(; first_scan != last_scan;++first_scan)
for (; first_scan != last_scan;++first_scan)
{
if (!(quick= get_quick_select(param, (*first_scan)->idx,
(*first_scan)->sel_arg, alloc)) ||
@ -3295,7 +3301,7 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
*/
if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->thd, param->table)))
{
for(scan= first_ror; scan != last_ror; scan++)
for (scan= first_ror; scan != last_ror; scan++)
{
if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) ||
quick_roru->push_quick_back(quick))
@ -4198,7 +4204,7 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
clone_flag=swap_clone_flag(clone_flag);
}
// If one of the key is MAYBE_KEY then the found region may be smaller
/* If one of the key is MAYBE_KEY then the found region may be smaller */
if (key2->type == SEL_ARG::MAYBE_KEY)
{
if (key1->use_count > 1)
@ -5331,8 +5337,8 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part;
KEY_PART_INFO *pk_part_end= pk_part +
param->table->key_info[pk_number].key_parts;
for(;(key_part!=key_part_end) && (pk_part != pk_part_end);
++key_part, ++pk_part)
for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
++key_part, ++pk_part)
{
if ((key_part->field != pk_part->field) ||
(key_part->length != pk_part->length))
@ -7325,8 +7331,8 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DESCRIPTION
Test conditions (NGA1, NGA2) from get_best_group_min_max(). Namely,
for each keypart field NGF_i not in GROUP-BY, check that there is a constant
equality predicate among conds with the form (NGF_i = const_ci) or
for each keypart field NGF_i not in GROUP-BY, check that there is a
constant equality predicate among conds with the form (NGF_i = const_ci) or
(const_ci = NGF_i).
Thus all the NGF_i attributes must fill the 'gap' between the last group-by
attribute and the MIN/MAX attribute in the index (if present). If these
@ -7959,7 +7965,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
max_used_key_length= real_prefix_len;
if (min_max_ranges.elements > 0)
{
QUICK_RANGE *cur_range= 0;
QUICK_RANGE *cur_range;
if (have_min)
{ /* Check if the right-most range has a lower boundary. */
get_dynamic(&min_max_ranges, (gptr)&cur_range,
@ -7967,7 +7973,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
if (!(cur_range->flag & NO_MIN_RANGE))
{
max_used_key_length+= min_max_arg_len;
++used_key_parts;
used_key_parts++;
return;
}
}
@ -7977,7 +7983,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
if (!(cur_range->flag & NO_MAX_RANGE))
{
max_used_key_length+= min_max_arg_len;
++used_key_parts;
used_key_parts++;
return;
}
}
@ -7994,7 +8000,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
usable key length.
*/
max_used_key_length+= min_max_arg_len;
++used_key_parts;
used_key_parts++;
}
}
@ -8691,7 +8697,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
char buff[1024];
String tmp(buff,sizeof(buff),&my_charset_bin);
tmp.length(0);
for(;start != end; start++)
for (;start != end; start++)
{
if (tmp.length())
tmp.append(',');

View File

@ -475,7 +475,7 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str)
{
char *write_pos= str->str;
for(; ptr < eol; ptr++, write_pos++)
for (; ptr < eol; ptr++, write_pos++)
{
char c= *ptr;
if (c == '\\')
@ -635,7 +635,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root,
File_option *parameter= parameters+first_param,
*parameters_end= parameters+required;
int len= 0;
for(; parameter < parameters_end; parameter++)
for (; parameter < parameters_end; parameter++)
{
len= parameter->name.length;
// check length

View File

@ -1904,33 +1904,33 @@ sp_instr_copen::execute(THD *thd, uint *nextp)
else
{
sp_lex_keeper *lex_keeper= c->pre_open(thd);
if (!lex_keeper)
if (!lex_keeper) // cursor already open or OOM
{
res= -1;
*nextp= m_ip+1;
}
else
res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
/*
Work around the fact that errors in selects are not returned properly
(but instead converted into a warning), so if a condition handler
caught, we have lost the result code.
*/
if (!res)
{
uint dummy1, dummy2;
res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
/*
Work around the fact that errors in selects are not returned properly
(but instead converted into a warning), so if a condition handler
caught, we have lost the result code.
*/
if (!res)
{
uint dummy1, dummy2;
if (thd->spcont->found_handler(&dummy1, &dummy2))
res= -1;
if (thd->spcont->found_handler(&dummy1, &dummy2))
res= -1;
}
c->post_open(thd, res ? FALSE : TRUE);
}
c->post_open(thd, (lex_keeper && !res ? TRUE : FALSE));
}
DBUG_RETURN(res);
}
int
sp_instr_copen::exec_core(THD *thd, uint *nextp)
{

View File

@ -168,8 +168,22 @@ sp_rcontext::pop_cursors(uint count)
*
*/
// We have split this in two to make it easy for sp_instr_copen
// to reuse the sp_instr::exec_stmt() code.
/*
pre_open cursor
SYNOPSIS
pre_open()
THD Thread handler
NOTES
We have to open cursor in two steps to make it easy for sp_instr_copen
to reuse the sp_instr::exec_stmt() code.
If this function returns 0, post_open should not be called
RETURN
0 ERROR
*/
sp_lex_keeper*
sp_cursor::pre_open(THD *thd)
{
@ -179,32 +193,31 @@ sp_cursor::pre_open(THD *thd)
MYF(0));
return NULL;
}
bzero((char *)&m_mem_root, sizeof(m_mem_root));
init_alloc_root(&m_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
if ((m_prot= new Protocol_cursor(thd, &m_mem_root)) == NULL)
return NULL;
m_oprot= thd->protocol; // Save the original protocol
thd->protocol= m_prot;
/* Save for execution. Will be restored in post_open */
m_oprot= thd->protocol;
m_nseof= thd->net.no_send_eof;
/* Change protocol for execution */
thd->protocol= m_prot;
thd->net.no_send_eof= TRUE;
return m_lex_keeper;
}
void
sp_cursor::post_open(THD *thd, my_bool was_opened)
{
thd->net.no_send_eof= m_nseof; // Restore the originals
thd->protocol= m_oprot;
if (was_opened)
{
m_isopen= was_opened;
if ((m_isopen= was_opened))
m_current_row= m_prot->data;
}
}
int
sp_cursor::close(THD *thd)
{
@ -217,6 +230,7 @@ sp_cursor::close(THD *thd)
return 0;
}
void
sp_cursor::destroy()
{
@ -225,7 +239,6 @@ sp_cursor::destroy()
delete m_prot;
m_prot= NULL;
free_root(&m_mem_root, MYF(0));
bzero((char *)&m_mem_root, sizeof(m_mem_root));
}
m_isopen= FALSE;
}

View File

@ -753,7 +753,7 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list)
t_name= table->table_name;
DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
for(;;)
for (;;)
{
if (!(res= find_table_in_global_list(table_list, d_name, t_name)) ||
(!res->table || res->table != table->table) &&

View File

@ -81,7 +81,7 @@ public:
if (sizeof(buffer) >= 8)
return uint8korr(buffer);
DBUG_ASSERT(sizeof(buffer) >= 4);
uint4korr(buffer);
return (ulonglong) uint4korr(buffer);
}
};

View File

@ -1855,7 +1855,8 @@ class multi_delete :public select_result_interceptor
ha_rows deleted, found;
uint num_of_tables;
int error;
bool do_delete, transactional_tables, normal_tables;
bool do_delete, transactional_tables, normal_tables, delete_while_scanning;
public:
multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables);
~multi_delete();
@ -1863,7 +1864,7 @@ public:
bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
int do_deletes (bool from_send_error);
int do_deletes();
bool send_eof();
};

View File

@ -410,7 +410,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
num_of_tables(num_of_tables_arg), error(0),
do_delete(0), transactional_tables(0), normal_tables(0)
{
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
}
@ -440,6 +440,7 @@ multi_delete::initialize_tables(JOIN *join)
tables_to_delete_from|= walk->table->map;
walk= delete_tables;
delete_while_scanning= 1;
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
tab < end;
tab++)
@ -459,10 +460,25 @@ multi_delete::initialize_tables(JOIN *join)
else
normal_tables= 1;
}
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
walk == delete_tables)
{
/*
We are not deleting from the table we are scanning. In this
case send_data() shouldn't delete any rows a we may touch
the rows in the deleted table many times
*/
delete_while_scanning= 0;
}
}
walk= delete_tables;
tempfiles_ptr= tempfiles;
for (walk= walk->next_local ;walk ;walk= walk->next_local)
if (delete_while_scanning)
{
table_being_deleted= delete_tables;
walk= walk->next_local;
}
for (;walk ;walk= walk->next_local)
{
TABLE *table=walk->table;
*tempfiles_ptr++= new Unique (refpos_order_cmp,
@ -481,12 +497,12 @@ multi_delete::~multi_delete()
table_being_deleted;
table_being_deleted= table_being_deleted->next_local)
{
TABLE *t=table_being_deleted->table;
free_io_cache(t); // Alloced by unique
t->no_keyread=0;
TABLE *table= table_being_deleted->table;
free_io_cache(table); // Alloced by unique
table->no_keyread=0;
}
for (uint counter= 0; counter < num_of_tables-1; counter++)
for (uint counter= 0; counter < num_of_tables; counter++)
{
if (tempfiles[counter])
delete tempfiles[counter];
@ -496,14 +512,15 @@ multi_delete::~multi_delete()
bool multi_delete::send_data(List<Item> &values)
{
int secure_counter= -1;
int secure_counter= delete_while_scanning ? -1 : 0;
TABLE_LIST *del_table;
DBUG_ENTER("multi_delete::send_data");
for (table_being_deleted= delete_tables;
table_being_deleted;
table_being_deleted= table_being_deleted->next_local, secure_counter++)
for (del_table= delete_tables;
del_table;
del_table= del_table->next_local, secure_counter++)
{
TABLE *table=table_being_deleted->table;
TABLE *table= del_table->table;
/* Check if we are using outer join and we didn't find the row */
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
@ -514,7 +531,8 @@ bool multi_delete::send_data(List<Item> &values)
if (secure_counter < 0)
{
/* If this is the table we are scanning */
/* We are scanning the current table */
DBUG_ASSERT(del_table == table_being_deleted);
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
@ -528,8 +546,7 @@ bool multi_delete::send_data(List<Item> &values)
TRG_ACTION_AFTER, FALSE))
DBUG_RETURN(1);
}
else if (!table_being_deleted->next_local ||
table_being_deleted->table->file->has_transactions())
else
{
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
@ -540,7 +557,7 @@ bool multi_delete::send_data(List<Item> &values)
error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
if (error)
{
error=-1;
error= 1; // Fatal error
DBUG_RETURN(1);
}
}
@ -563,22 +580,24 @@ void multi_delete::send_error(uint errcode,const char *err)
/* Something already deleted so we have to invalidate cache */
query_cache_invalidate3(thd, delete_tables, 1);
/* Below can happen when thread is killed early ... */
if (!table_being_deleted)
table_being_deleted=delete_tables;
/*
If rows from the first table only has been deleted and it is
transactional, just do rollback.
The same if all tables are transactional, regardless of where we are.
In all other cases do attempt deletes ...
*/
if ((table_being_deleted->table->file->has_transactions() &&
table_being_deleted == delete_tables) || !normal_tables)
if ((table_being_deleted == delete_tables &&
table_being_deleted->table->file->has_transactions()) ||
!normal_tables)
ha_rollback_stmt(thd);
else if (do_delete)
{
VOID(do_deletes(1));
/*
We have to execute the recorded do_deletes() and write info into the
error log
*/
error= 1;
send_eof();
}
DBUG_VOID_RETURN;
}
@ -591,27 +610,20 @@ void multi_delete::send_error(uint errcode,const char *err)
1 error
*/
int multi_delete::do_deletes(bool from_send_error)
int multi_delete::do_deletes()
{
int local_error= 0, counter= 0;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
if (from_send_error)
{
/* Found out table number for 'table_being_deleted*/
for (TABLE_LIST *aux= delete_tables;
aux != table_being_deleted;
aux= aux->next_local)
counter++;
}
else
table_being_deleted = delete_tables;
do_delete= 0;
do_delete= 0; // Mark called
if (!found)
DBUG_RETURN(0);
for (table_being_deleted= table_being_deleted->next_local;
table_being_deleted;
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
delete_tables);
for (; table_being_deleted;
table_being_deleted= table_being_deleted->next_local, counter++)
{
TABLE *table = table_being_deleted->table;
@ -673,7 +685,7 @@ bool multi_delete::send_eof()
thd->proc_info="deleting from reference tables";
/* Does deletes for the last n - 1 tables, returns 0 if ok */
int local_error= do_deletes(0); // returns 0 if success
int local_error= do_deletes(); // returns 0 if success
/* reset used flags */
thd->proc_info="end";

View File

@ -128,7 +128,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
/* it is join view => we need to find table for update */
List_iterator_fast<Item> it(fields);
Item *item;
TABLE_LIST *tbl= 0;
TABLE_LIST *tbl= 0; // reset for call to check_single_table()
table_map map= 0;
while ((item= it++))
@ -1012,6 +1012,7 @@ ok_or_after_trg_err:
err:
info->last_errno= error;
thd->lex->current_select->no_error= 0; // Give error
table->file->print_error(error,MYF(0));
before_trg_err:

View File

@ -4537,7 +4537,8 @@ unsent_create_error:
send_ok(thd);
break;
}
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
if (thd->transaction.xa_state == XA_IDLE &&
thd->lex->xa_opt == XA_ONE_PHASE)
{
int r;
if ((r= ha_commit(thd)))
@ -4545,8 +4546,8 @@ unsent_create_error:
else
send_ok(thd);
}
else
if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
else if (thd->transaction.xa_state == XA_PREPARED &&
thd->lex->xa_opt == XA_NONE)
{
if (wait_if_global_read_lock(thd, 0, 0))
{

View File

@ -957,32 +957,35 @@ JOIN::optimize()
#endif
DBUG_EXECUTE("info",TEST_join(this););
/*
Because filesort always does a full table scan or a quick range scan
we must add the removed reference to the select for the table.
We only need to do this when we have a simple_order or simple_group
as in other cases the join is done before the sort.
*/
if (const_tables != tables &&
(order || group_list) &&
join_tab[const_tables].type != JT_ALL &&
join_tab[const_tables].type != JT_FT &&
join_tab[const_tables].type != JT_REF_OR_NULL &&
(order && simple_order || group_list && simple_group))
{
if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
DBUG_RETURN(1);
}
if (!(select_options & SELECT_BIG_RESULT) &&
((group_list && const_tables != tables &&
(!simple_group ||
!test_if_skip_sort_order(&join_tab[const_tables], group_list,
unit->select_limit_cnt, 0))) ||
select_distinct) &&
tmp_table_param.quick_group && !procedure)
if (const_tables != tables)
{
need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
/*
Because filesort always does a full table scan or a quick range scan
we must add the removed reference to the select for the table.
We only need to do this when we have a simple_order or simple_group
as in other cases the join is done before the sort.
*/
if ((order || group_list) &&
join_tab[const_tables].type != JT_ALL &&
join_tab[const_tables].type != JT_FT &&
join_tab[const_tables].type != JT_REF_OR_NULL &&
(order && simple_order || group_list && simple_group))
{
if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
DBUG_RETURN(1);
}
if (!(select_options & SELECT_BIG_RESULT) &&
((group_list &&
(!simple_group ||
!test_if_skip_sort_order(&join_tab[const_tables], group_list,
unit->select_limit_cnt, 0))) ||
select_distinct) &&
tmp_table_param.quick_group && !procedure)
{
need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
}
}
tmp_having= having;
@ -5381,6 +5384,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
JOIN_TAB *first_inner_tab= tab->first_inner;
table_map current_map= tab->table->map;
bool use_quick_range=0;
COND *tmp;
/*
Following force including random expression in last table condition.
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
@ -5402,7 +5407,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
join->best_positions[i].records_read= rows2double(tab->quick->records);
}
COND *tmp= NULL;
tmp= NULL;
if (cond)
tmp= make_cond_for_table(cond,used_tables,current_map);
if (cond && !tmp && tab->quick)
@ -13610,7 +13615,7 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
(*table)->print(thd, str);
TABLE_LIST **end= table + tables->elements;
for(TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
{
TABLE_LIST *curr= *tbl;
if (curr->outer_join)

View File

@ -1265,7 +1265,7 @@ static bool show_status_array(THD *thd, const char *wild,
name_buffer, wild)))
{
char *value=variables->value;
const char *pos, *end;
const char *pos, *end; // We assign a lot of const's
long nr;
if (show_type == SHOW_SYS)
{
@ -1336,8 +1336,8 @@ static bool show_status_array(THD *thd, const char *wild,
case SHOW_SLAVE_RETRIED_TRANS:
{
/*
TODO: in 5.1 with multimaster, have one such counter per line in SHOW
SLAVE STATUS, and have the sum over all lines here.
TODO: in 5.1 with multimaster, have one such counter per line in
SHOW SLAVE STATUS, and have the sum over all lines here.
*/
pthread_mutex_lock(&LOCK_active_mi);
pthread_mutex_lock(&active_mi->rli.data_lock);
@ -1359,7 +1359,11 @@ static bool show_status_array(THD *thd, const char *wild,
}
else
{
for (int i= 1; i < MAX_SLAVE_ERROR; i++)
/* 10 is enough assuming errors are max 4 digits */
int i;
for (i= 1;
i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10;
i++)
{
if (bitmap_is_set(bitmap, i))
{
@ -1369,6 +1373,8 @@ static bool show_status_array(THD *thd, const char *wild,
}
if (end != buff)
end--; // Remove last ','
if (i < MAX_SLAVE_ERROR)
end= strmov((char*) end, "..."); // Couldn't show all errors
}
break;
}

View File

@ -710,7 +710,7 @@ bool mysql_multi_update_prepare(THD *thd)
tl->table->reginfo.lock_type= tl->lock_type;
}
}
for(tl= table_list; tl; tl= tl->next_local)
for (tl= table_list; tl; tl= tl->next_local)
{
/* Check access privileges for table */
if (!tl->derived)

View File

@ -2164,16 +2164,12 @@ bool st_table_list::check_single_table(st_table_list **table, table_map map,
{
if (*table)
return TRUE;
else
{
*table= tbl;
tbl->check_option= view->check_option;
}
*table= tbl;
tbl->check_option= view->check_option;
}
}
else
if (tbl->check_single_table(table, map, view))
return TRUE;
else if (tbl->check_single_table(table, map, view))
return TRUE;
}
return FALSE;
}

View File

@ -436,10 +436,7 @@ typedef struct st_table_list
bool skip_temporary; /* this table shouldn't be temporary */
/* TRUE if this merged view contain auto_increment field */
bool contain_auto_increment;
#if 0
#else
bool multitable_view; /* TRUE iff this is multitable view */
#endif
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */

View File

@ -178,7 +178,7 @@ static double get_merge_many_buffs_cost(uint *buffer,
Set initial state: first maxbuffer sequences contain max_n_elems elements
each, last sequence contains last_n_elems elements.
*/
for(i = 0; i < (int)maxbuffer; i++)
for (i = 0; i < (int)maxbuffer; i++)
buff_elems[i]= max_n_elems;
buff_elems[maxbuffer]= last_n_elems;

View File

@ -1549,15 +1549,19 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
}
else
{
while (unlikely(*buf1 == 0) && buf1 >= to->buf)
buf1--;
if (buf1 < to->buf)
for (;;)
{
decimal_make_zero(to);
return E_DEC_OK;
if (likely(*buf1))
break;
if (buf1-- == to->buf)
{
decimal_make_zero(to);
return E_DEC_OK;
}
}
}
if (scale<0) scale=0;
if (scale<0)
scale=0;
done:
to->frac=scale;
@ -1727,11 +1731,14 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
buf1++, buf2++;
if (buf1 <= end1)
{
if (buf2 <= end2)
carry= *buf2 > *buf1;
else
carry= 0;
}
else
{
if (buf2 <= end2)
carry=1;
else /* short-circuit everything: from1 == from2 */
@ -1741,6 +1748,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
decimal_make_zero(to);
return E_DEC_OK;
}
}
}
if (to == 0) /* decimal_cmp() */
@ -1937,10 +1945,18 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
dec1 *buf= to->buf;
dec1 *end= to->buf + intg0 + frac0;
for (; (buf<end) && !*buf; buf++);
if (buf == end)
/* So we got decimal zero */
decimal_make_zero(to);
DBUG_ASSERT(buf != end);
for (;;)
{
if (*buf)
break;
if (++buf == end)
{
/* We got decimal zero */
decimal_make_zero(to);
break;
}
}
}
return error;
}