summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc80
1 files changed, 67 insertions, 13 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 099e6b977d6..ecbe2d22fa4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -62,10 +62,10 @@ Item::Item():
*/
if (thd->lex->current_select)
{
- SELECT_LEX_NODE::enum_parsing_place place=
+ enum_parsing_place place=
thd->lex->current_select->parsing_place;
- if (place == SELECT_LEX_NODE::SELECT_LIST ||
- place == SELECT_LEX_NODE::IN_HAVING)
+ if (place == SELECT_LIST ||
+ place == IN_HAVING)
thd->lex->current_select->select_n_having_items++;
}
}
@@ -179,10 +179,17 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
name_length= 0;
return;
}
- while (length && !my_isgraph(cs,*str))
- { // Fix problem with yacc
- length--;
- str++;
+ if (cs->ctype)
+ {
+ /*
+ This will probably need a better implementation in the future:
+ a function in CHARSET_INFO structure.
+ */
+ while (length && !my_isgraph(cs,*str))
+ { // Fix problem with yacc
+ length--;
+ str++;
+ }
}
if (!my_charset_same(cs, system_charset_info))
{
@@ -291,8 +298,9 @@ Item_splocal::type() const
}
-bool DTCollation::aggregate(DTCollation &dt)
+bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion)
{
+ nagg++;
if (!my_charset_same(collation, dt.collation))
{
/*
@@ -306,15 +314,39 @@ bool DTCollation::aggregate(DTCollation &dt)
if (derivation <= dt.derivation)
; // Do nothing
else
- set(dt);
+ {
+ set(dt);
+ strong= nagg;
+ }
}
else if (dt.collation == &my_charset_bin)
{
if (dt.derivation <= derivation)
+ {
set(dt);
+ strong= nagg;
+ }
else
; // Do nothing
}
+ else if (superset_conversion)
+ {
+ if (derivation < dt.derivation &&
+ collation->state & MY_CS_UNICODE)
+ ; // Do nothing
+ else if (dt.derivation < derivation &&
+ dt.collation->state & MY_CS_UNICODE)
+ {
+ set(dt);
+ strong= nagg;
+ }
+ else
+ {
+ // Cannot convert to superset
+ set(0, DERIVATION_NONE);
+ return 1;
+ }
+ }
else
{
set(0, DERIVATION_NONE);
@@ -328,6 +360,7 @@ bool DTCollation::aggregate(DTCollation &dt)
else if (dt.derivation < derivation)
{
set(dt);
+ strong= nagg;
}
else
{
@@ -979,7 +1012,7 @@ double Item_param::val()
This works for example when user says SELECT ?+0.0 and supplies
time value for the placeholder.
*/
- return (double) TIME_to_ulonglong(&value.time);
+ return ulonglong2double(TIME_to_ulonglong(&value.time));
case NULL_VALUE:
return 0.0;
default:
@@ -1312,12 +1345,24 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
table_list= (last= sl)->get_table_list();
if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
{
- // it is primary INSERT st_select_lex => skip first table resolving
+ /*
+ it is primary INSERT st_select_lex => skip first table
+ resolving
+ */
table_list= table_list->next_local;
}
Item_subselect *prev_subselect_item= prev_unit->item;
- if ((tmp= find_field_in_tables(thd, this,
+ enum_parsing_place place= prev_subselect_item->parsing_place;
+ /*
+ check table fields only if subquery used somewhere out of HAVING
+ or SELECT list or outer SELECT do not use groupping (i.e. tables
+ are accessable)
+ */
+ if (((place != IN_HAVING &&
+ place != SELECT_LIST) ||
+ (sl->with_sum_func == 0 && sl->group_list.elements == 0)) &&
+ (tmp= find_field_in_tables(thd, this,
table_list, ref,
0, 1)) != not_found_field)
{
@@ -2029,7 +2074,16 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
// it is primary INSERT st_select_lex => skip first table resolving
table_list= table_list->next_local;
}
- if ((tmp= find_field_in_tables(thd, this,
+ enum_parsing_place place= prev_subselect_item->parsing_place;
+ /*
+ Check table fields only if subquery used somewhere out of HAVING
+ or SELECT list or outer SELECT do not use groupping (i.e. tables
+ are accessable)
+ */
+ if (((place != IN_HAVING &&
+ place != SELECT_LIST) ||
+ (sl->with_sum_func == 0 && sl->group_list.elements == 0)) &&
+ (tmp= find_field_in_tables(thd, this,
table_list, reference,
0, 1)) != not_found_field)
{