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:
parent
e253b7815a
commit
a69f432115
@ -1657,9 +1657,10 @@ 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)
|
||||
return error;
|
||||
@ -2237,22 +2238,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");
|
||||
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;
|
||||
@ -2266,13 +2268,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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
can be barrier to stop before derived table SELECT or very outer SELECT
|
||||
*/
|
||||
for(;
|
||||
cursel->master_unit()->item;
|
||||
for (; cursel->master_unit()->item;
|
||||
cursel= cursel->outer_select())
|
||||
{
|
||||
Item_subselect *subselect_item= cursel->master_unit()->item;
|
||||
@ -2528,8 +2527,7 @@ void mark_select_range_as_dependent(THD *thd,
|
||||
resolving)
|
||||
*/
|
||||
SELECT_LEX *previous_select= current_sel;
|
||||
for(;
|
||||
previous_select->outer_select() != last_select;
|
||||
for (; previous_select->outer_select() != last_select;
|
||||
previous_select= previous_select->outer_select())
|
||||
{
|
||||
Item_subselect *prev_subselect_item=
|
||||
|
@ -240,8 +240,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);
|
||||
|
@ -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,
|
||||
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
|
||||
@ -1115,6 +1115,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;
|
||||
@ -1746,18 +1747,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(¶m,cond);
|
||||
|
||||
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
|
||||
{
|
||||
if ((tree= get_mm_tree(¶m,cond)))
|
||||
{
|
||||
if (tree->type == SEL_TREE::IMPOSSIBLE)
|
||||
{
|
||||
records=0L; /* Return -1 from this function. */
|
||||
read_time= (double) HA_POS_ERROR;
|
||||
goto free_mem;
|
||||
}
|
||||
else if (tree && tree->type != SEL_TREE::KEY &&
|
||||
if (tree->type != SEL_TREE::KEY &&
|
||||
tree->type != SEL_TREE::KEY_SMALLER)
|
||||
goto free_mem;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
|
||||
@ -2248,7 +2251,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;
|
||||
@ -2294,6 +2297,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}
|
||||
@ -2306,14 +2310,15 @@ 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];
|
||||
|
||||
@ -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_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(¶m->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],
|
||||
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
|
||||
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;
|
||||
@ -2380,6 +2382,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)
|
||||
@ -2397,6 +2400,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
|
||||
{
|
||||
@ -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->total_cost= src->total_cost;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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).
|
||||
|
||||
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:
|
||||
|
||||
@ -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
|
||||
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} / ( --------- * --------- * .... )
|
||||
@ -2571,33 +2577,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. */
|
||||
{
|
||||
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->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);
|
||||
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 */
|
||||
@ -2625,6 +2630,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,
|
||||
@ -4196,7 +4202,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)
|
||||
@ -7323,8 +7329,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
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
if (sizeof(buffer) >= 8)
|
||||
return uint8korr(buffer);
|
||||
DBUG_ASSERT(sizeof(buffer) >= 4);
|
||||
uint4korr(buffer);
|
||||
return (ulonglong) uint4korr(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -2164,15 +2164,11 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (tbl->check_single_table(table, map, view))
|
||||
else if (tbl->check_single_table(table, map, view))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -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) */
|
||||
|
@ -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 (;;)
|
||||
{
|
||||
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 */
|
||||
@ -1742,6 +1749,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
||||
return E_DEC_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (to == 0) /* decimal_cmp() */
|
||||
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 *end= to->buf + intg0 + frac0;
|
||||
for (; (buf<end) && !*buf; buf++);
|
||||
if (buf == end)
|
||||
/* So we got decimal zero */
|
||||
DBUG_ASSERT(buf != end);
|
||||
for (;;)
|
||||
{
|
||||
if (*buf)
|
||||
break;
|
||||
if (++buf == end)
|
||||
{
|
||||
/* We got decimal zero */
|
||||
decimal_make_zero(to);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user