Commit 25a2c4a7 authored by monty@mysql.com's avatar monty@mysql.com

Cleanup during review

Simple optimization for 2 argument usage to function of variable arguments
Fix stack overrun when using 1+1+1+1+1+1+1+....
Update crash-me results for 5.0
Don't call post_open if pre_open() fails (optimization)
parent a69f4321
......@@ -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.
......
......@@ -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
......
......@@ -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;
......
......@@ -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)))
......
......@@ -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
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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);
......
......@@ -211,15 +211,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;
}
}
......
......@@ -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
......
......@@ -1904,21 +1904,21 @@ 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);
c->post_open(thd, (lex_keeper ? TRUE : FALSE));
c->post_open(thd, res ? FALSE : TRUE);
}
}
DBUG_RETURN(res);
}
int
sp_instr_copen::exec_core(THD *thd, uint *nextp)
{
......
......@@ -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;
}
......
......@@ -4502,7 +4502,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)))
......@@ -4510,8 +4511,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))
{
......
......@@ -955,32 +955,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;
......@@ -5219,7 +5222,10 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
tmp= new Item_func_trig_cond(tmp, &tab->found);
}
if (tmp)
{
tmp->quick_fix_field();
tmp->update_used_tables();
}
return tmp;
}
......@@ -5376,6 +5382,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
......@@ -5397,7 +5405,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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment