summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorGalina Shalygina <galashalygina@gmail.com>2016-05-01 22:29:47 +0300
committerGalina Shalygina <galashalygina@gmail.com>2016-08-23 00:39:12 +0300
commiteb2c1474752a5f743db638d5b06612c9e3f07f74 (patch)
tree2cbdafbe8617bf72f8addf3cfcdd53b10c7cbe8e /sql/item.cc
parent8b94aec11af19fc711ed48f13410986814bc51a0 (diff)
downloadmariadb-git-eb2c1474752a5f743db638d5b06612c9e3f07f74.tar.gz
The consolidated patch for mdev-9197.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc204
1 files changed, 204 insertions, 0 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 65fb00d4757..6c24cf2d073 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -479,6 +479,7 @@ Item::Item(THD *thd):
}
}
+
/**
Constructor used by Item_field, Item_ref & aggregate (sum)
functions.
@@ -2161,6 +2162,73 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
}
+/**
+ @brief
+ Building clone for Item_func_or_sum
+
+ @param thd thread handle
+ @param mem_root part of the memory for the clone
+
+ @details
+ This method gets copy of the current item and also
+ build clones for its referencies. For the referencies
+ build_copy is called again.
+
+ @retval
+ clone of the item
+ 0 if an error occured
+*/
+
+Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
+{
+ Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd, mem_root);
+ if (!copy)
+ return 0;
+ if (arg_count > 2)
+ copy->args=
+ (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
+ else if (arg_count > 0)
+ copy->args= copy->tmp_arg;
+ for (uint i= 0; i < arg_count; i++)
+ {
+ Item *arg_clone= args[i]->build_clone(thd, mem_root);
+ if (!arg_clone)
+ return 0;
+ copy->args[i]= arg_clone;
+ }
+ return copy;
+}
+
+
+/**
+ @brief
+ Building clone for Item_ref
+
+ @param thd thread handle
+ @param mem_root part of the memory for the clone
+
+ @details
+ This method gets copy of the current item and also
+ builds clone for its reference.
+
+ @retval
+ clone of the item
+ 0 if an error occured
+*/
+
+Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root)
+{
+ Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
+ if (!copy)
+ return 0;
+ Item *item_clone= (* ref)->build_clone(thd, mem_root);
+ if (!item_clone)
+ return 0;
+ *copy->ref= item_clone;
+ return copy;
+}
+
+
void Item_ident_for_show::make_field(THD *thd, Send_field *tmp_field)
{
tmp_field->table_name= tmp_field->org_table_name= table_name;
@@ -6554,6 +6622,85 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg)
}
+Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
+{
+ st_select_lex *sl= (st_select_lex *)arg;
+ table_map map= sl->master_unit()->derived->table->map;
+ if (!((Item_field*)this)->item_equal)
+ {
+ if (used_tables() == map)
+ {
+ Item_ref *rf=
+ new (thd->mem_root) Item_ref(thd, &sl->context,
+ NullS, NullS,
+ ((Item_field*) this)->field_name);
+ if (!rf)
+ return 0;
+ return rf;
+ }
+ }
+ else
+ {
+ Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
+ Item_equal_fields_iterator li(*cond);
+ Item *item;
+ while ((item=li++))
+ {
+ if (item->used_tables() == map && item->type() == FIELD_ITEM)
+ {
+ Item_ref *rf=
+ new (thd->mem_root) Item_ref(thd, &sl->context,
+ NullS, NullS,
+ ((Item_field*) item)->field_name);
+ if (!rf)
+ return 0;
+ return rf;
+ }
+ }
+ }
+ return this;
+}
+
+
+Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
+{
+ st_select_lex *sl= (st_select_lex *)arg;
+ List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields);
+ Grouping_tmp_field *field;
+ table_map map= sl->master_unit()->derived->table->map;
+ if (used_tables() == map)
+ {
+ while ((field=li++))
+ {
+ if (((Item_field*) this)->field == field->tmp_field)
+ return field->producing_item->build_clone(thd, thd->mem_root);
+ }
+ }
+ else if (((Item_field*)this)->item_equal)
+ {
+ Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
+ Item_equal_fields_iterator it(*cond);
+ Item *item;
+ while ((item=it++))
+ {
+ if (item->used_tables() == map && item->type() == FIELD_ITEM)
+ {
+ Item_field *field_item= (Item_field *) item;
+ li.rewind();
+ while ((field=li++))
+ {
+ if (field_item->field == field->tmp_field)
+ {
+ return field->producing_item->build_clone(thd, thd->mem_root);
+ }
+ }
+ }
+ }
+ }
+ return this;
+}
+
+
void Item_field::print(String *str, enum_query_type query_type)
{
if (field && field->table->const_table)
@@ -9722,5 +9869,62 @@ const char *dbug_print_item(Item *item)
return "Couldn't fit into buffer";
}
+
#endif /*DBUG_OFF*/
+bool Item_field::exclusive_dependence_on_table_processor(uchar *map)
+{
+ table_map tab_map= *((table_map *) map);
+ return !((used_tables() == tab_map ||
+ (item_equal && item_equal->used_tables() & tab_map)));
+}
+
+bool Item_field::exclusive_dependence_on_grouping_fields_processor(uchar *arg)
+{
+ st_select_lex *sl= (st_select_lex *)arg;
+ List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields);
+ Grouping_tmp_field *field;
+ table_map map= sl->master_unit()->derived->table->map;
+ if (used_tables() == map)
+ {
+ while ((field=li++))
+ {
+ if (((Item_field*) this)->field == field->tmp_field)
+ return false;
+ }
+ }
+ else if (((Item_field*)this)->item_equal)
+ {
+ Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal;
+ Item_equal_fields_iterator it(*cond);
+ Item *item;
+ while ((item=it++))
+ {
+ if (item->used_tables() == map && item->type() == FIELD_ITEM)
+ {
+ li.rewind();
+ while ((field=li++))
+ {
+ if (((Item_field *)item)->field == field->tmp_field)
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+/*Item *Item::get_copy(THD *thd, MEM_ROOT *mem_root)
+{
+ dbug_print_item(this);
+ DBUG_ASSERT(0);
+ return 0;
+}*/
+
+
+void Item::register_in(THD *thd)
+{
+ next= thd->free_list;
+ thd->free_list= this;
+}