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 diff is collapsed.
This diff is collapsed.
......@@ -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