summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc72
1 files changed, 44 insertions, 28 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ba503f18855..76f4788c1cf 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -126,12 +126,9 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const char *funcname,
many cases.
*/
set_handler(items[0]->type_handler()->type_handler_for_comparison());
- m_vers_trx_id= items[0]->vers_trx_id();
for (uint i= 1 ; i < nitems ; i++)
{
unsigned_count+= items[i]->unsigned_flag;
- if (!m_vers_trx_id)
- m_vers_trx_id= items[i]->vers_trx_id();
if (aggregate_for_comparison(items[i]->type_handler()->
type_handler_for_comparison()))
{
@@ -423,7 +420,8 @@ void Item_func::convert_const_compared_to_int_field(THD *thd)
args[field= 1]->real_item()->type() == FIELD_ITEM)
{
Item_field *field_item= (Item_field*) (args[field]->real_item());
- if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && !field_item->vers_trx_id()) ||
+ if (((field_item->field_type() == MYSQL_TYPE_LONGLONG &&
+ field_item->type_handler() != &type_handler_vers_trx_id) ||
field_item->field_type() == MYSQL_TYPE_YEAR))
convert_const_to_int(thd, field_item, &args[!field]);
}
@@ -1294,6 +1292,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
}
eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func;
+ with_param= args[0]->with_param || args[1]->with_param;
with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item()))
{
@@ -1342,6 +1341,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
m_with_subquery= true;
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
+ with_param= args[0]->with_param || args[1]->with_param;
used_tables_and_const_cache_join(args[1]);
fixed= 1;
return FALSE;
@@ -1891,6 +1891,7 @@ void Item_func_interval::fix_length_and_dec()
used_tables_and_const_cache_join(row);
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
+ with_param= with_param || row->with_param;
with_field= with_field || row->with_field;
}
@@ -2831,7 +2832,7 @@ Item_func_nullif::time_op(MYSQL_TIME *ltime)
bool
Item_func_nullif::is_null()
{
- return (null_value= (!compare() ? 1 : args[2]->null_value));
+ return (null_value= (!compare() ? 1 : args[2]->is_null()));
}
void Item_func_case::reorder_args(uint start)
@@ -4304,7 +4305,7 @@ bool cmp_item_row::prepare_comparators(THD *thd, Item **args, uint arg_count)
bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd)
{
uint cols= args[0]->cols();
- if (!(array= new (thd->mem_root) in_row(thd, arg_count-1, 0)))
+ if (unlikely(!(array= new (thd->mem_root) in_row(thd, arg_count-1, 0))))
return true;
cmp_item_row *cmp= &((in_row*)array)->tmp;
if (cmp->alloc_comparators(thd, cols) ||
@@ -4315,7 +4316,7 @@ bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd)
Call store_value() to setup others.
*/
cmp->store_value(args[0]);
- if (thd->is_fatal_error) // OOM
+ if (unlikely(thd->is_fatal_error)) // OOM
return true;
fix_in_vector();
return false;
@@ -4528,6 +4529,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
List_iterator<Item> li(list);
Item *item;
uchar buff[sizeof(char*)]; // Max local vars in function
+ longlong is_and_cond= functype() == Item_func::COND_AND_FUNC;
not_null_tables_cache= 0;
used_tables_and_const_cache_init();
@@ -4590,26 +4592,33 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
const_cond might evaluate to true (regardless of whether some tables
were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
+ if (thd->is_error())
+ return TRUE;
}
else
{
@@ -4621,6 +4630,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
}
with_sum_func|= item->with_sum_func;
+ with_param|= item->with_param;
with_field|= item->with_field;
m_with_subquery|= item->with_subquery();
with_window_func|= item->with_window_func;
@@ -4636,30 +4646,36 @@ bool
Item_cond::eval_not_null_tables(void *opt_arg)
{
Item *item;
+ longlong is_and_cond= functype() == Item_func::COND_AND_FUNC;
List_iterator<Item> li(list);
not_null_tables_cache= (table_map) 0;
and_tables_cache= ~(table_map) 0;
while ((item=li++))
{
table_map tmp_table_map;
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
- some_cond_or might be true regardless of what tables are
- NULL-complemented.
+ const_cond might evaluate to true (regardless of whether some tables
+ were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
}
@@ -5439,7 +5455,7 @@ bool Regexp_processor_pcre::compile(String *pattern, bool send_error)
m_pcre= pcre_compile(pattern->c_ptr_safe(), m_library_flags,
&pcreErrorStr, &pcreErrorOffset, NULL);
- if (m_pcre == NULL)
+ if (unlikely(m_pcre == NULL))
{
if (send_error)
{
@@ -5458,7 +5474,7 @@ bool Regexp_processor_pcre::compile(Item *item, bool send_error)
char buff[MAX_FIELD_WIDTH];
String tmp(buff, sizeof(buff), &my_charset_bin);
String *pattern= item->val_str(&tmp);
- if (item->null_value || compile(pattern, send_error))
+ if (unlikely(item->null_value) || (unlikely(compile(pattern, send_error))))
return true;
return false;
}
@@ -5577,7 +5593,7 @@ int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code,
int rc= pcre_exec(code, extra, subject, length,
startoffset, options, ovector, ovecsize);
DBUG_EXECUTE_IF("pcre_exec_error_123", rc= -123;);
- if (rc < PCRE_ERROR_NOMATCH)
+ if (unlikely(rc < PCRE_ERROR_NOMATCH))
pcre_exec_warn(rc);
return rc;
}
@@ -5857,8 +5873,8 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
{
- register int bcShift;
- register int turboShift;
+ int bcShift;
+ int turboShift;
int shift = pattern_len;
int j = 0;
int u = 0;
@@ -5872,7 +5888,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
{
while (j <= tlmpl)
{
- register int i= plm1;
+ int i= plm1;
while (i >= 0 && pattern[i] == text[i + j])
{
i--;
@@ -5882,7 +5898,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
if (i < 0)
return 1;
- register const int v = plm1 - i;
+ const int v= plm1 - i;
turboShift = u - v;
bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
shift = MY_MAX(turboShift, bcShift);
@@ -5903,7 +5919,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
{
while (j <= tlmpl)
{
- register int i = plm1;
+ int i= plm1;
while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
{
i--;
@@ -5913,7 +5929,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
if (i < 0)
return 1;
- register const int v = plm1 - i;
+ const int v= plm1 - i;
turboShift = u - v;
bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
shift = MY_MAX(turboShift, bcShift);