Commit 0776999d authored by unknown's avatar unknown

Cleanup during review of new pushed code


include/my_global.h:
  Safer macros to avoid possible overflows
sql/item_cmpfunc.cc:
  Simple optimization
sql/sp_head.cc:
  Indentation fixes
  Remove not needed "else" levels
  Added error checking for 'new'
  Simpler reseting of thd->spcont in execute_procedure
sql/sql_base.cc:
  Faster new
sql/sql_lex.cc:
  Use 'TRUE' instead of 'true'
sql/sql_parse.cc:
  Faster new
sql/sql_view.cc:
  No need to set 'tables' as it's not used
sql/table.cc:
  Simpler DBUG_ASSERT()
parent 916e1938
...@@ -933,10 +933,10 @@ typedef char bool; /* Ordinary boolean values 0 1 */ ...@@ -933,10 +933,10 @@ typedef char bool; /* Ordinary boolean values 0 1 */
(ABSTIME).ts_nsec=0; \ (ABSTIME).ts_nsec=0; \
} }
#define set_timespec_nsec(ABSTIME,NSEC) \ #define set_timespec_nsec(ABSTIME,NSEC) \
{\ { \
ulonglong now= my_getsystime(); \ ulonglong now= my_getsystime() + (NSEC/100); \
(ABSTIME).ts_sec= (now / ULL(10000000)) + (NSEC / ULL(1000000000)); \ (ABSTIME).ts_sec= (now / ULL(10000000)); \
(ABSTIME).ts_nsec= (now % ULL(10000000)) * 100 + (NSEC % ULL(1000000000)); \ (ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
} }
#else #else
#define set_timespec(ABSTIME,SEC) \ #define set_timespec(ABSTIME,SEC) \
...@@ -948,9 +948,9 @@ typedef char bool; /* Ordinary boolean values 0 1 */ ...@@ -948,9 +948,9 @@ typedef char bool; /* Ordinary boolean values 0 1 */
} }
#define set_timespec_nsec(ABSTIME,NSEC) \ #define set_timespec_nsec(ABSTIME,NSEC) \
{\ {\
ulonglong now= my_getsystime(); \ ulonglong now= my_getsystime() + (NSEC/100); \
(ABSTIME).tv_sec= (now / ULL(10000000)) + (NSEC / ULL(1000000000)); \ (ABSTIME).tv_sec= (now / ULL(10000000)); \
(ABSTIME).tv_nsec= (now % ULL(10000000)) * 100 + (NSEC % ULL(1000000000)); \ (ABSTIME).tv_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
} }
#endif /* HAVE_TIMESPEC_TS_SEC */ #endif /* HAVE_TIMESPEC_TS_SEC */
#endif /* set_timespec */ #endif /* set_timespec */
......
...@@ -630,7 +630,7 @@ int Arg_comparator::compare_row() ...@@ -630,7 +630,7 @@ int Arg_comparator::compare_row()
owner->null_value= 0; owner->null_value= 0;
res= 0; // continue comparison (maybe we will meet explicit difference) res= 0; // continue comparison (maybe we will meet explicit difference)
} }
if (res) else if (res)
return res; return res;
} }
if (was_null) if (was_null)
...@@ -645,6 +645,7 @@ int Arg_comparator::compare_row() ...@@ -645,6 +645,7 @@ int Arg_comparator::compare_row()
return 0; return 0;
} }
int Arg_comparator::compare_e_row() int Arg_comparator::compare_e_row()
{ {
(*a)->bring_value(); (*a)->bring_value();
......
...@@ -127,15 +127,16 @@ sp_prepare_func_item(THD* thd, Item **it_addr) ...@@ -127,15 +127,16 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
/* Macro to switch arena in sp_eval_func_item */ /* Macro to switch arena in sp_eval_func_item */
#define CREATE_ON_CALLERS_ARENA(new_command, condition, backup_arena) do\ #define CREATE_ON_CALLERS_ARENA(new_command, condition, backup_arena) \
{\ do \
{ \
if (condition) \ if (condition) \
thd->set_n_backup_item_arena(thd->spcont->callers_arena,\ thd->set_n_backup_item_arena(thd->spcont->callers_arena, \
backup_arena);\ backup_arena); \
new_command;\ new_command; \
if (condition)\ if (condition) \
thd->restore_backup_item_arena(thd->spcont->callers_arena,\ thd->restore_backup_item_arena(thd->spcont->callers_arena, \
&backup_current_arena);\ &backup_current_arena); \
} while(0) } while(0)
/* /*
...@@ -174,10 +175,6 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, ...@@ -174,10 +175,6 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
/* QQ How do we do this? Is there some better way? */
if (type == MYSQL_TYPE_NULL)
goto return_null_item;
switch (sp_map_result_type(type)) { switch (sp_map_result_type(type)) {
case INT_RESULT: case INT_RESULT:
{ {
...@@ -188,35 +185,34 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, ...@@ -188,35 +185,34 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
DBUG_PRINT("info", ("INT_RESULT: null")); DBUG_PRINT("info", ("INT_RESULT: null"));
goto return_null_item; goto return_null_item;
} }
else
{
DBUG_PRINT("info", ("INT_RESULT: %d", i)); DBUG_PRINT("info", ("INT_RESULT: %d", i));
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_int(i), CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_int(i),
use_callers_arena, &backup_current_arena); use_callers_arena, &backup_current_arena);
}
break; break;
} }
case REAL_RESULT: case REAL_RESULT:
{ {
double d= it->val_real(); double d= it->val_real();
uint8 decimals;
uint32 max_length;
if (it->null_value) if (it->null_value)
{ {
DBUG_PRINT("info", ("REAL_RESULT: null")); DBUG_PRINT("info", ("REAL_RESULT: null"));
goto return_null_item; goto return_null_item;
} }
else
{ /*
/* There's some difference between Item::new_item() and the There's some difference between Item::new_item() and the
* constructor; the former crashes, the latter works... weird. */ constructor; the former crashes, the latter works... weird.
uint8 decimals= it->decimals; */
uint32 max_length= it->max_length; decimals= it->decimals;
max_length= it->max_length;
DBUG_PRINT("info", ("REAL_RESULT: %g", d)); DBUG_PRINT("info", ("REAL_RESULT: %g", d));
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_float(d), CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_float(d),
use_callers_arena, &backup_current_arena); use_callers_arena, &backup_current_arena);
it->decimals= decimals; it->decimals= decimals;
it->max_length= max_length; it->max_length= max_length;
}
break; break;
} }
case DECIMAL_RESULT: case DECIMAL_RESULT:
...@@ -224,13 +220,15 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, ...@@ -224,13 +220,15 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
my_decimal value, *val= it->val_decimal(&value); my_decimal value, *val= it->val_decimal(&value);
if (it->null_value) if (it->null_value)
goto return_null_item; goto return_null_item;
else
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_decimal(val), CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_decimal(val),
use_callers_arena, &backup_current_arena); use_callers_arena, &backup_current_arena);
#ifndef DBUG_OFF #ifndef DBUG_OFF
{
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
DBUG_PRINT("info", ("DECIMAL_RESULT: %s", dbug_decimal_as_string(dbug_buff, val))); DBUG_PRINT("info", ("DECIMAL_RESULT: %s",
dbug_decimal_as_string(dbug_buff, val)));
#endif #endif
}
break; break;
} }
case STRING_RESULT: case STRING_RESULT:
...@@ -239,21 +237,18 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, ...@@ -239,21 +237,18 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
String tmp(buffer, sizeof(buffer), it->collation.collation); String tmp(buffer, sizeof(buffer), it->collation.collation);
String *s= it->val_str(&tmp); String *s= it->val_str(&tmp);
if (it->null_value) if (type == MYSQL_TYPE_NULL || it->null_value)
{ {
DBUG_PRINT("info", ("default result: null")); DBUG_PRINT("info", ("STRING_RESULT: null"));
goto return_null_item; goto return_null_item;
} }
else DBUG_PRINT("info",("STRING_RESULT: %*s",
{
DBUG_PRINT("info",("default result: %*s",
s->length(), s->c_ptr_quick())); s->length(), s->c_ptr_quick()));
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize)
Item_string(thd->strmake(s->ptr(), Item_string(thd->strmake(s->ptr(),
s->length()), s->length(), s->length()), s->length(),
it->collation.collation), it->collation.collation),
use_callers_arena, &backup_current_arena); use_callers_arena, &backup_current_arena);
}
break; break;
} }
case ROW_RESULT: case ROW_RESULT:
...@@ -574,13 +569,10 @@ sp_head::destroy() ...@@ -574,13 +569,10 @@ sp_head::destroy()
/* /*
* This is only used for result fields from functions (both during This is only used for result fields from functions (both during
* fix_length_and_dec() and evaluation). fix_length_and_dec() and evaluation).
* */
* Since the current mem_root during a will be freed and the result
* field will be used by the caller, we have to put it in the caller's
* or main mem_root.
*/
Field * Field *
sp_head::make_field(uint max_length, const char *name, TABLE *dummy) sp_head::make_field(uint max_length, const char *name, TABLE *dummy)
{ {
...@@ -817,47 +809,49 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ...@@ -817,47 +809,49 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
sp_rcontext *octx = thd->spcont; sp_rcontext *octx = thd->spcont;
sp_rcontext *nctx = NULL; sp_rcontext *nctx = NULL;
uint i; uint i;
int ret; Item_null *nit;
int ret= -1; // Assume error
if (argcount != params) if (argcount != params)
{ {
/* /*
Need to use my_printf_error here, or it will not terminate the Need to use my_error here, or it will not terminate the
invoking query properly. invoking query properly.
*/ */
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
"FUNCTION", m_qname.str, params, argcount); "FUNCTION", m_qname.str, params, argcount);
DBUG_RETURN(-1); goto end;
} }
// QQ Should have some error checking here? (types, etc...) // QQ Should have some error checking here? (types, etc...)
nctx= new sp_rcontext(csize, hmax, cmax); if (!(nctx= new sp_rcontext(csize, hmax, cmax)))
goto end;
for (i= 0 ; i < argcount ; i++) for (i= 0 ; i < argcount ; i++)
{ {
sp_pvar_t *pvar = m_pcont->find_pvar(i); sp_pvar_t *pvar = m_pcont->find_pvar(i);
Item *it= sp_eval_func_item(thd, argp++, pvar->type, NULL, FALSE); Item *it= sp_eval_func_item(thd, argp++, pvar->type, NULL, FALSE);
if (it) if (!it)
goto end; // EOM error
nctx->push_item(it); nctx->push_item(it);
else
{
DBUG_RETURN(-1);
}
} }
/* /*
The rest of the frame are local variables which are all IN. The rest of the frame are local variables which are all IN.
Default all variables to null (those with default clauses will Default all variables to null (those with default clauses will
be set by an set instruction). be set by an set instruction).
*/ */
{
Item_null *nit= NULL; // Re-use this, and only create if needed nit= NULL; // Re-use this, and only create if needed
for (; i < csize ; i++) for (; i < csize ; i++)
{ {
if (! nit) if (! nit)
nit= new Item_null(); {
nctx->push_item(nit); if (!(nit= new Item_null()))
DBUG_RETURN(-1);
} }
nctx->push_item(nit);
} }
thd->spcont= nctx; thd->spcont= nctx;
...@@ -878,14 +872,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ...@@ -878,14 +872,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
} }
nctx->pop_all_cursors(); // To avoid memory leaks after an error nctx->pop_all_cursors(); // To avoid memory leaks after an error
delete nctx; delete nctx; // Doesn't do anything
thd->spcont= octx; thd->spcont= octx;
end:
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
static Item_func_get_user_var *
item_is_user_var(Item *it) static Item_func_get_user_var *item_is_user_var(Item *it)
{ {
if (it->type() == Item::FUNC_ITEM) if (it->type() == Item::FUNC_ITEM)
{ {
...@@ -897,19 +892,18 @@ item_is_user_var(Item *it) ...@@ -897,19 +892,18 @@ item_is_user_var(Item *it)
return NULL; return NULL;
} }
int
sp_head::execute_procedure(THD *thd, List<Item> *args) int sp_head::execute_procedure(THD *thd, List<Item> *args)
{ {
DBUG_ENTER("sp_head::execute_procedure");
DBUG_PRINT("info", ("procedure %s", m_name.str));
int ret= 0; int ret= 0;
uint csize = m_pcont->max_pvars(); uint csize = m_pcont->max_pvars();
uint params = m_pcont->current_pvars(); uint params = m_pcont->current_pvars();
uint hmax = m_pcont->max_handlers(); uint hmax = m_pcont->max_handlers();
uint cmax = m_pcont->max_cursors(); uint cmax = m_pcont->max_cursors();
sp_rcontext *octx = thd->spcont; sp_rcontext *save_spcont, *octx;
sp_rcontext *nctx = NULL; sp_rcontext *nctx = NULL;
my_bool is_tmp_octx = FALSE; // True if we have allocated a temporary octx DBUG_ENTER("sp_head::execute_procedure");
DBUG_PRINT("info", ("procedure %s", m_name.str));
if (args->elements != params) if (args->elements != params)
{ {
...@@ -918,17 +912,22 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -918,17 +912,22 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
save_spcont= octx= thd->spcont;
if (! octx) if (! octx)
{ // Create a temporary old context { // Create a temporary old context
octx= new sp_rcontext(csize, hmax, cmax); if (!(octx= new sp_rcontext(csize, hmax, cmax)))
is_tmp_octx= TRUE; DBUG_RETURN(-1);
thd->spcont= octx; thd->spcont= octx;
/* set callers_arena to thd, for upper-level function to work */ /* set callers_arena to thd, for upper-level function to work */
thd->spcont->callers_arena= thd; thd->spcont->callers_arena= thd;
} }
nctx= new sp_rcontext(csize, hmax, cmax); if (!(nctx= new sp_rcontext(csize, hmax, cmax)))
{
thd->spcont= save_spcont;
DBUG_RETURN(-1);
}
if (csize > 0 || hmax > 0 || cmax > 0) if (csize > 0 || hmax > 0 || cmax > 0)
{ {
...@@ -937,7 +936,6 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -937,7 +936,6 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
List_iterator<Item> li(*args); List_iterator<Item> li(*args);
Item *it; Item *it;
/* Evaluate SP arguments (i.e. get the values passed as parameters) */ /* Evaluate SP arguments (i.e. get the values passed as parameters) */
// QQ: Should do type checking? // QQ: Should do type checking?
DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str)); DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str));
...@@ -959,20 +957,25 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -959,20 +957,25 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (pvar->mode == sp_param_out) if (pvar->mode == sp_param_out)
{ {
if (! nit) if (! nit)
nit= new Item_null(); {
if (!(nit= new Item_null()))
{
ret= -1;
break;
}
}
nctx->push_item(nit); // OUT nctx->push_item(nit); // OUT
} }
else else
{ {
Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type, NULL, FALSE); Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type, NULL, FALSE);
if (it2) if (!it2)
nctx->push_item(it2); // IN or INOUT
else
{ {
ret= -1; // Eval failed ret= -1; // Eval failed
break; break;
} }
nctx->push_item(it2); // IN or INOUT
} }
} }
} }
...@@ -994,7 +997,13 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -994,7 +997,13 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
for (; i < csize ; i++) for (; i < csize ; i++)
{ {
if (! nit) if (! nit)
nit= new Item_null(); {
if (!(nit= new Item_null()))
{
ret= -1;
break;
}
}
nctx->push_item(nit); nctx->push_item(nit);
} }
} }
...@@ -1090,15 +1099,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -1090,15 +1099,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
} }
} }
if (is_tmp_octx) if (!save_spcont)
{ delete octx; // Does nothing
delete octx; /* call destructor */
octx= NULL;
}
nctx->pop_all_cursors(); // To avoid memory leaks after an error nctx->pop_all_cursors(); // To avoid memory leaks after an error
delete nctx; delete nctx; // Does nothing
thd->spcont= octx; thd->spcont= save_spcont;
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -3363,7 +3363,7 @@ static bool ...@@ -3363,7 +3363,7 @@ static bool
set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref) set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref)
{ {
Name_resolution_context *context; Name_resolution_context *context;
if (!(context= new Name_resolution_context)) if (!(context= new (thd->mem_root) Name_resolution_context))
return TRUE; return TRUE;
context->init(); context->init();
context->first_name_resolution_table= context->first_name_resolution_table=
......
...@@ -1520,7 +1520,7 @@ void st_select_lex_unit::print(String *str) ...@@ -1520,7 +1520,7 @@ void st_select_lex_unit::print(String *str)
if (union_all) if (union_all)
str->append("all ", 4); str->append("all ", 4);
else if (union_distinct == sl) else if (union_distinct == sl)
union_all= true; union_all= TRUE;
} }
if (sl->braces) if (sl->braces)
str->append('('); str->append('(');
......
...@@ -6420,7 +6420,7 @@ Name_resolution_context * ...@@ -6420,7 +6420,7 @@ Name_resolution_context *
make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op) make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
{ {
Name_resolution_context *on_context; Name_resolution_context *on_context;
if (!(on_context= new Name_resolution_context)) if (!(on_context= new (thd->mem_root) Name_resolution_context))
return NULL; return NULL;
on_context->init(); on_context->init();
on_context->first_name_resolution_table= on_context->first_name_resolution_table=
......
...@@ -310,7 +310,7 @@ bool mysql_create_view(THD *thd, ...@@ -310,7 +310,7 @@ bool mysql_create_view(THD *thd,
open_and_lock_tables can change the value of tables, open_and_lock_tables can change the value of tables,
e.g. it may happen if before the function call tables was equal to 0. e.g. it may happen if before the function call tables was equal to 0.
*/ */
for (tbl= tables= lex->query_tables; tbl; tbl= tbl->next_global) for (tbl= lex->query_tables; tbl; tbl= tbl->next_global)
{ {
/* is this table temporary and is not view? */ /* is this table temporary and is not view? */
if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view && if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view &&
......
...@@ -2518,12 +2518,9 @@ void Field_iterator_natural_join::set(TABLE_LIST *table_ref) ...@@ -2518,12 +2518,9 @@ void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
void Field_iterator_natural_join::next() void Field_iterator_natural_join::next()
{ {
cur_column_ref= (*column_ref_it)++; cur_column_ref= (*column_ref_it)++;
DBUG_ASSERT(cur_column_ref ? DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
(cur_column_ref->table_field ?
cur_column_ref->table_ref->table == cur_column_ref->table_ref->table ==
cur_column_ref->table_field->table : cur_column_ref->table_field->table);
TRUE) :
TRUE);
} }
...@@ -2695,9 +2692,8 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created) ...@@ -2695,9 +2692,8 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
nj_col= natural_join_it.column_ref(); nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col); DBUG_ASSERT(nj_col);
} }
DBUG_ASSERT(nj_col->table_field ? DBUG_ASSERT(!nj_col->table_field ||
nj_col->table_ref->table == nj_col->table_field->table : nj_col->table_ref->table == nj_col->table_field->table);
TRUE);
return nj_col; return nj_col;
} }
......
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