summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorpem@mysql.com <>2005-11-28 20:14:12 +0100
committerpem@mysql.com <>2005-11-28 20:14:12 +0100
commitb2a9961abfb6b67ced064f5f1cab416e9b04ddce (patch)
tree0ba4502a6a4c3cdf74957b0ba578ccf99236f07b /sql/item.cc
parentc171f8c6c64a57f391ffe64beb75fe554d096c2c (diff)
parentba8d1f134ad70e715af9ea3da4a98a62de2d5d9b (diff)
downloadmariadb-git-b2a9961abfb6b67ced064f5f1cab416e9b04ddce.tar.gz
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/usr/home/pem/mysql-5.1-new
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc38
1 files changed, 21 insertions, 17 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 1c2016049ad..848096e71dc 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -700,23 +700,15 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
{
if (const_item())
{
- Item_string *conv;
uint cnv_errors;
- char buf[MAX_FIELD_WIDTH];
- String tmp(buf, sizeof(buf), &my_charset_bin);
- String cstr, *ostr= val_str(&tmp);
- /*
- As safe_charset_converter is not executed for
- a parameter bound to NULL, ostr should never be 0.
- */
- cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &cnv_errors);
- if (cnv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
- cstr.charset(),
- collation.derivation)))
- return NULL;
- conv->str_value.copy();
- conv->str_value.mark_as_const();
- return conv;
+ String *ostr= val_str(&cnvstr);
+ cnvitem->str_value.copy(ostr->ptr(), ostr->length(),
+ ostr->charset(), tocs, &cnv_errors);
+ if (cnv_errors)
+ return NULL;
+ cnvitem->str_value.mark_as_const();
+ cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen;
+ return cnvitem;
}
return NULL;
}
@@ -2105,6 +2097,8 @@ Item_param::Item_param(unsigned pos_in_query_arg) :
value is set.
*/
maybe_null= 1;
+ cnvitem= new Item_string("", 0, &my_charset_bin, DERIVATION_COERCIBLE);
+ cnvstr.set(cnvbuf, sizeof(cnvbuf), &my_charset_bin);
}
@@ -5302,7 +5296,7 @@ Item_result item_cmp_type(Item_result a,Item_result b)
void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
{
Item *item= *ref;
- Item *new_item;
+ Item *new_item= NULL;
if (item->basic_const_item())
return; // Can't be better
Item_result res_type=item_cmp_type(comp_item->result_type(),
@@ -5335,7 +5329,16 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
break;
}
case ROW_RESULT:
+ if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
{
+ /*
+ Substitute constants only in Item_rows. Don't affect other Items
+ with ROW_RESULT (eg Item_singlerow_subselect).
+
+ For such Items more optimal is to detect if it is constant and replace
+ it with Item_row. This would optimize queries like this:
+ SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
+ */
Item_row *item_row= (Item_row*) item;
Item_row *comp_item_row= (Item_row*) comp_item;
uint col;
@@ -5353,6 +5356,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col));
break;
}
+ /* Fallthrough */
case REAL_RESULT:
{ // It must REAL_RESULT
double result= item->val_real();