Code cleanups during code reviews

Ensure we get error if INSERT IGNORE ... SELECT fails
Fixed wrong key_part->key_length usage in index_merge
This commit is contained in:
monty@mysql.com 2005-06-01 16:35:09 +03:00
parent e253b7815a
commit a69f432115
19 changed files with 144 additions and 113 deletions

View File

@ -1657,9 +1657,10 @@ int mysql_real_query_for_lazy(const char *buf, int length)
{ {
for (uint retry=0;; retry++) for (uint retry=0;; retry++)
{ {
int error;
if (!mysql_real_query(&mysql,buf,length)) if (!mysql_real_query(&mysql,buf,length))
return 0; return 0;
int error= put_error(&mysql); error= put_error(&mysql);
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
!opt_reconnect) !opt_reconnect)
return error; return error;
@ -2237,22 +2238,23 @@ print_table_data_vertically(MYSQL_RES *result)
} }
} }
/* print_warnings should be called right after executing a statement */ /* 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_RES *result;
MYSQL_ROW cur; MYSQL_ROW cur;
my_ulonglong num_rows;
/* Get the warnings */ /* Get the warnings */
strmov(query,"show warnings"); query= "show warnings";
mysql_real_query_for_lazy(query,strlen(query)); mysql_real_query_for_lazy(query, strlen(query));
mysql_store_result_for_lazy(&result); mysql_store_result_for_lazy(&result);
/* Bail out when no warnings */ /* Bail out when no warnings */
my_ulonglong num_rows = mysql_num_rows(result); if (!(num_rows= mysql_num_rows(result)))
if (num_rows == 0)
{ {
mysql_free_result(result); mysql_free_result(result);
return; return;
@ -2266,13 +2268,12 @@ print_warnings()
mysql_free_result(result); 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 (; *array; array+= 2)
for (x= 0; array[x]; x+= 2) if (**array == key)
if (*array[x] == key) return array[1];
return array[x + 1];
return 0; return 0;
} }

View File

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

View File

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

View File

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

View File

@ -2246,8 +2246,7 @@ 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 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 can be barrier to stop before derived table SELECT or very outer SELECT
*/ */
for(; for (; cursel->master_unit()->item;
cursel->master_unit()->item;
cursel= cursel->outer_select()) cursel= cursel->outer_select())
{ {
Item_subselect *subselect_item= cursel->master_unit()->item; Item_subselect *subselect_item= cursel->master_unit()->item;
@ -2528,8 +2527,7 @@ void mark_select_range_as_dependent(THD *thd,
resolving) resolving)
*/ */
SELECT_LEX *previous_select= current_sel; SELECT_LEX *previous_select= current_sel;
for(; for (; previous_select->outer_select() != last_select;
previous_select->outer_select() != last_select;
previous_select= previous_select->outer_select()) previous_select= previous_select->outer_select())
{ {
Item_subselect *prev_subselect_item= Item_subselect *prev_subselect_item=

View File

@ -1646,7 +1646,7 @@ void subselect_uniquesubquery_engine::exclude()
table_map subselect_engine::calc_const_tables(TABLE_LIST *table) table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
{ {
table_map map= 0; table_map map= 0;
for(; table; table= table->next_leaf) for (; table; table= table->next_leaf)
{ {
TABLE *tbl= table->table; TABLE *tbl= table->table;
if (tbl && tbl->const_table) if (tbl && tbl->const_table)

View File

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

View File

@ -396,7 +396,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, static int get_index_merge_params(PARAM *param, key_map& needed_reg,
SEL_IMERGE *imerge, double *read_time, SEL_IMERGE *imerge, double *read_time,
ha_rows* imerge_rows); 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); int keynr);
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -1115,6 +1115,7 @@ int QUICK_ROR_UNION_SELECT::init()
val1 First merged select val1 First merged select
val2 Second merged select val2 Second merged select
*/ */
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, byte *val1, byte *val2) int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, byte *val1, byte *val2)
{ {
QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg; QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
@ -1582,7 +1583,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= param->table->key_info[pk].key_part;
KEY_PART_INFO *key_part_end= key_part + KEY_PART_INFO *key_part_end= key_part +
param->table->key_info[pk].key_parts; 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); bitmap_clear_bit(&param->needed_fields, key_part->fieldnr);
} }
@ -1746,18 +1747,20 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
double best_read_time= read_time; double best_read_time= read_time;
if (cond) if (cond)
tree= get_mm_tree(&param,cond); {
if ((tree= get_mm_tree(&param,cond)))
if (tree && tree->type == SEL_TREE::IMPOSSIBLE) {
if (tree->type == SEL_TREE::IMPOSSIBLE)
{ {
records=0L; /* Return -1 from this function. */ records=0L; /* Return -1 from this function. */
read_time= (double) HA_POS_ERROR; read_time= (double) HA_POS_ERROR;
goto free_mem; goto free_mem;
} }
else if (tree && tree->type != SEL_TREE::KEY && if (tree->type != SEL_TREE::KEY &&
tree->type != SEL_TREE::KEY_SMALLER) tree->type != SEL_TREE::KEY_SMALLER)
goto free_mem; goto free_mem;
}
}
/* /*
Try to construct a QUICK_GROUP_MIN_MAX_SELECT. Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
@ -2248,7 +2251,7 @@ skip_to_ror_scan:
clustered index) 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) int keynr)
{ {
double read_time; double read_time;
@ -2294,6 +2297,7 @@ typedef struct st_ror_scan_info
param Parameter from test_quick_select function param Parameter from test_quick_select function
idx Index of key in param->keys idx Index of key in param->keys
sel_arg Set of intervals for a given key sel_arg Set of intervals for a given key
RETURN RETURN
NULL - out of memory NULL - out of memory
ROR scan structure containing a scan for {idx, sel_arg} ROR scan structure containing a scan for {idx, sel_arg}
@ -2306,14 +2310,15 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
uchar *bitmap_buf; uchar *bitmap_buf;
uint keynr; uint keynr;
DBUG_ENTER("make_ror_scan"); DBUG_ENTER("make_ror_scan");
if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root, if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
sizeof(ROR_SCAN_INFO)))) sizeof(ROR_SCAN_INFO))))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
ror_scan->idx= idx; ror_scan->idx= idx;
ror_scan->keynr= keynr= param->real_keynr[idx]; ror_scan->keynr= keynr= param->real_keynr[idx];
ror_scan->key_rec_length= param->table->key_info[keynr].key_length + ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
param->table->file->ref_length; param->table->file->ref_length);
ror_scan->sel_arg= sel_arg; ror_scan->sel_arg= sel_arg;
ror_scan->records= param->table->quick_rows[keynr]; ror_scan->records= param->table->quick_rows[keynr];
@ -2329,15 +2334,11 @@ 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= param->table->key_info[keynr].key_part;
KEY_PART_INFO *key_part_end= key_part + KEY_PART_INFO *key_part_end= key_part +
param->table->key_info[keynr].key_parts; param->table->key_info[keynr].key_parts;
uint n_used_covered= 0;
for (;key_part != key_part_end; ++key_part) for (;key_part != key_part_end; ++key_part)
{ {
if (bitmap_is_set(&param->needed_fields, key_part->fieldnr)) if (bitmap_is_set(&param->needed_fields, key_part->fieldnr))
{
n_used_covered++;
bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr); bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr);
} }
}
ror_scan->index_read_cost= ror_scan->index_read_cost=
get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr], get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr],
ror_scan->keynr); ror_scan->keynr);
@ -2357,6 +2358,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
0 a = b 0 a = b
1 a > b 1 a > b
*/ */
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b) static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
{ {
double val1= rows2double((*a)->records) * (*a)->key_rec_length; double val1= rows2double((*a)->records) * (*a)->key_rec_length;
@ -2380,6 +2382,7 @@ static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
0 a = b 0 a = b
1 a > b 1 a > b
*/ */
static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** 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) if ((*a)->used_fields_covered > (*b)->used_fields_covered)
@ -2397,6 +2400,7 @@ static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
return 0; return 0;
} }
/* Auxiliary structure for incremental ROR-intersection creation */ /* Auxiliary structure for incremental ROR-intersection creation */
typedef struct typedef struct
{ {
@ -2462,6 +2466,8 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
dst->index_scan_costs= src->index_scan_costs; dst->index_scan_costs= src->index_scan_costs;
dst->total_cost= src->total_cost; dst->total_cost= src->total_cost;
} }
/* /*
Get selectivity of a ROR scan wrt ROR-intersection. Get selectivity of a ROR scan wrt ROR-intersection.
@ -2479,7 +2485,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). 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: The recursive procedure for finding P(cond) is as follows:
@ -2490,7 +2496,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. Here R may still contain condition(s) equivalent to k_11=c_11.
Nevertheless, the following holds: 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), Mark k_11 as fixed field (and satisfied condition) F, save P(F),
save R to be cond and proceed to recursion step. save R to be cond and proceed to recursion step.
@ -2537,7 +2543,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 ( this is result of application of option b) of the recursion step for
parts of a single key). parts of a single key).
Since it is reasonable to expect that most of the fields are not marked 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} n_{i1} n_{i_2}
(3) = n_{max_key_part} / ( --------- * --------- * .... ) (3) = n_{max_key_part} / ( --------- * --------- * .... )
@ -2571,33 +2577,32 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
max_range.key= (byte*) key_val; max_range.key= (byte*) key_val;
max_range.flag= HA_READ_AFTER_KEY; max_range.flag= HA_READ_AFTER_KEY;
ha_rows prev_records= info->param->table->file->records; ha_rows prev_records= info->param->table->file->records;
int i;
DBUG_ENTER("ror_intersect_selectivity"); 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")); DBUG_PRINT("info",("sel_arg step"));
cur_covered= test(bitmap_is_set(&info->covered_fields, cur_covered= test(bitmap_is_set(&info->covered_fields,
(key_part + i)->fieldnr)); key_part[sel_arg->part].fieldnr));
if (cur_covered != prev_covered) if (cur_covered != prev_covered)
{ {
/* create (part1val, ..., part{n-1}val) tuple. */ /* create (part1val, ..., part{n-1}val) tuple. */
{ ha_rows records;
if (!tuple_arg) if (!tuple_arg)
{ {
tuple_arg= scan->sel_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); tuple_arg->store_min(key_part->length, &key_ptr, 0);
} }
while (tuple_arg->next_key_part != sel_arg) while (tuple_arg->next_key_part != sel_arg)
{ {
tuple_arg= tuple_arg->next_key_part; tuple_arg= tuple_arg->next_key_part;
tuple_arg->store_min(key_part->length, &key_ptr, 0); tuple_arg->store_min(key_part[tuple_arg->part].length, &key_ptr, 0);
} }
}
ha_rows records;
min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val); min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val);
records= info->param->table->file-> records= (info->param->table->file->
records_in_range(scan->keynr, &min_range, &max_range); records_in_range(scan->keynr, &min_range, &max_range));
if (cur_covered) if (cur_covered)
{ {
/* uncovered -> covered */ /* uncovered -> covered */
@ -2625,6 +2630,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
DBUG_RETURN(selectivity_mult); DBUG_RETURN(selectivity_mult);
} }
/* /*
Check if adding a ROR scan to a ROR-intersection reduces its cost of Check if adding a ROR scan to a ROR-intersection reduces its cost of
ROR-intersection and if yes, update parameters of ROR-intersection, ROR-intersection and if yes, update parameters of ROR-intersection,
@ -3218,7 +3224,7 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
quick_imerge->records= records; quick_imerge->records= records;
quick_imerge->read_time= read_cost; quick_imerge->read_time= read_cost;
for(TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end; for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
range_scan++) range_scan++)
{ {
if (!(quick= (QUICK_RANGE_SELECT*) if (!(quick= (QUICK_RANGE_SELECT*)
@ -3251,7 +3257,7 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
"creating ROR-intersect", "creating ROR-intersect",
first_scan, last_scan);); first_scan, last_scan););
alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc; 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, if (!(quick= get_quick_select(param, (*first_scan)->idx,
(*first_scan)->sel_arg, alloc)) || (*first_scan)->sel_arg, alloc)) ||
@ -3293,7 +3299,7 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
*/ */
if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->thd, param->table))) 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)) || if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) ||
quick_roru->push_quick_back(quick)) quick_roru->push_quick_back(quick))
@ -4196,7 +4202,7 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
clone_flag=swap_clone_flag(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 (key2->type == SEL_ARG::MAYBE_KEY)
{ {
if (key1->use_count > 1) if (key1->use_count > 1)
@ -5329,7 +5335,7 @@ 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= param->table->key_info[pk_number].key_part;
KEY_PART_INFO *pk_part_end= pk_part + KEY_PART_INFO *pk_part_end= pk_part +
param->table->key_info[pk_number].key_parts; param->table->key_info[pk_number].key_parts;
for(;(key_part!=key_part_end) && (pk_part != pk_part_end); for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
++key_part, ++pk_part) ++key_part, ++pk_part)
{ {
if ((key_part->field != pk_part->field) || if ((key_part->field != pk_part->field) ||
@ -7323,8 +7329,8 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DESCRIPTION DESCRIPTION
Test conditions (NGA1, NGA2) from get_best_group_min_max(). Namely, 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 for each keypart field NGF_i not in GROUP-BY, check that there is a
equality predicate among conds with the form (NGF_i = const_ci) or constant equality predicate among conds with the form (NGF_i = const_ci) or
(const_ci = NGF_i). (const_ci = NGF_i).
Thus all the NGF_i attributes must fill the 'gap' between the last group-by 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 attribute and the MIN/MAX attribute in the index (if present). If these
@ -8689,7 +8695,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
char buff[1024]; char buff[1024];
String tmp(buff,sizeof(buff),&my_charset_bin); String tmp(buff,sizeof(buff),&my_charset_bin);
tmp.length(0); tmp.length(0);
for(;start != end; start++) for (;start != end; start++)
{ {
if (tmp.length()) if (tmp.length())
tmp.append(','); tmp.append(',');

View File

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

View File

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

View File

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

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

View File

@ -13520,7 +13520,7 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
(*table)->print(thd, str); (*table)->print(thd, str);
TABLE_LIST **end= table + tables->elements; 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; TABLE_LIST *curr= *tbl;
if (curr->outer_join) if (curr->outer_join)

View File

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

View File

@ -710,7 +710,7 @@ bool mysql_multi_update_prepare(THD *thd)
tl->table->reginfo.lock_type= tl->lock_type; 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 */ /* Check access privileges for table */
if (!tl->derived) if (!tl->derived)

View File

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

View File

@ -436,10 +436,7 @@ typedef struct st_table_list
bool skip_temporary; /* this table shouldn't be temporary */ bool skip_temporary; /* this table shouldn't be temporary */
/* TRUE if this merged view contain auto_increment field */ /* TRUE if this merged view contain auto_increment field */
bool contain_auto_increment; bool contain_auto_increment;
#if 0
#else
bool multitable_view; /* TRUE iff this is multitable view */ bool multitable_view; /* TRUE iff this is multitable view */
#endif
/* FRMTYPE_ERROR if any type is acceptable */ /* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type; enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */ 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 Set initial state: first maxbuffer sequences contain max_n_elems elements
each, last sequence contains last_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[i]= max_n_elems;
buff_elems[maxbuffer]= last_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 else
{ {
while (unlikely(*buf1 == 0) && buf1 >= to->buf) for (;;)
buf1--; {
if (buf1 < to->buf) if (likely(*buf1))
break;
if (buf1-- == to->buf)
{ {
decimal_make_zero(to); decimal_make_zero(to);
return E_DEC_OK; return E_DEC_OK;
} }
} }
if (scale<0) scale=0; }
if (scale<0)
scale=0;
done: done:
to->frac=scale; 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) while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2)
buf1++, buf2++; buf1++, buf2++;
if (buf1 <= end1) if (buf1 <= end1)
{
if (buf2 <= end2) if (buf2 <= end2)
carry= *buf2 > *buf1; carry= *buf2 > *buf1;
else else
carry= 0; carry= 0;
}
else else
{
if (buf2 <= end2) if (buf2 <= end2)
carry=1; carry=1;
else /* short-circuit everything: from1 == from2 */ else /* short-circuit everything: from1 == from2 */
@ -1742,6 +1749,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
return E_DEC_OK; return E_DEC_OK;
} }
} }
}
if (to == 0) /* decimal_cmp() */ if (to == 0) /* decimal_cmp() */
return carry == from1->sign ? 1 : -1; return carry == from1->sign ? 1 : -1;
@ -1937,10 +1945,18 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
{ {
dec1 *buf= to->buf; dec1 *buf= to->buf;
dec1 *end= to->buf + intg0 + frac0; dec1 *end= to->buf + intg0 + frac0;
for (; (buf<end) && !*buf; buf++); DBUG_ASSERT(buf != end);
if (buf == end) for (;;)
/* So we got decimal zero */ {
if (*buf)
break;
if (++buf == end)
{
/* We got decimal zero */
decimal_make_zero(to); decimal_make_zero(to);
break;
}
}
} }
return error; return error;
} }