summaryrefslogtreecommitdiff
path: root/sql/sql_tvc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_tvc.cc')
-rw-r--r--sql/sql_tvc.cc66
1 files changed, 60 insertions, 6 deletions
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 763fd8ec45b..df774a5d8dd 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -22,6 +22,37 @@
#include "sql_explain.h"
#include "sql_parse.h"
#include "sql_cte.h"
+#include "my_json_writer.h"
+
+
+/**
+ @brief
+ Walk through all VALUES items.
+ @param
+ @param processor - the processor to call for each Item
+ @param walk_qubquery - if should dive into subquery items
+ @param argument - the argument to pass recursively
+ @retval
+ true on error
+ false on success
+*/
+bool table_value_constr::walk_values(Item_processor processor,
+ bool walk_subquery,
+ void *argument)
+{
+ List_iterator_fast<List_item> list_item_it(lists_of_values);
+ while (List_item *list= list_item_it++)
+ {
+ List_iterator_fast<Item> item_it(*list);
+ while (Item *item= item_it++)
+ {
+ if (item->walk(&Item::unknown_splocal_processor, false, argument))
+ return true;
+ }
+ }
+ return false;
+}
+
/**
@brief
@@ -394,9 +425,10 @@ bool table_value_constr::exec(SELECT_LEX *sl)
while ((elem= li++))
{
- if (send_records >= sl->master_unit()->select_limit_cnt)
+ if (send_records >= sl->master_unit()->lim.get_select_limit())
break;
- int rc= result->send_data(*elem);
+ int rc=
+ result->send_data_with_check(*elem, sl->master_unit(), send_records);
if (!rc)
send_records++;
else if (rc > 0)
@@ -655,7 +687,7 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
wrapper_sl->set_linkage(tvc_sl->get_linkage());
wrapper_sl->parsing_place= SELECT_LIST;
item= new (thd->mem_root) Item_field(thd, &wrapper_sl->context,
- NULL, NULL, &star_clex_str);
+ star_clex_str);
if (item == NULL || add_item_to_list(thd, item))
goto err;
(wrapper_sl->with_wild)++;
@@ -759,6 +791,7 @@ st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl)
{
wrapper_sl->master_unit()->union_distinct= wrapper_sl;
}
+ wrapper_sl->distinct= tvc_sl->distinct;
thd->lex->current_select= wrapper_sl;
return wrapper_sl;
}
@@ -871,6 +904,10 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
if (!transform_into_subq)
return this;
+ Json_writer_object trace_wrapper(thd);
+ Json_writer_object trace_conv(thd, "in_to_subquery_conversion");
+ trace_conv.add("item", this);
+
transform_into_subq= false;
List<List_item> values;
@@ -890,13 +927,29 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
uint32 length= max_length_of_left_expr();
if (!length || length > tmp_table_max_key_length() ||
args[0]->cols() > tmp_table_max_key_parts())
+ {
+ trace_conv.add("done", false);
+ trace_conv.add("reason", "key is too long");
return this;
-
+ }
+
for (uint i=1; i < arg_count; i++)
{
- if (!args[i]->const_item() || cmp_row_types(args[0], args[i]))
+ if (!args[i]->const_item())
+ {
+ trace_conv.add("done", false);
+ trace_conv.add("reason", "non-constant element in the IN-list");
return this;
+ }
+
+ if (cmp_row_types(args[0], args[i]))
+ {
+ trace_conv.add("done", false);
+ trace_conv.add("reason", "type mismatch");
+ return this;
+ }
}
+ Json_writer_array trace_nested_obj(thd, "conversion");
Query_arena backup;
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
@@ -913,7 +966,7 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
sq_select= lex->current_select;
sq_select->parsing_place= SELECT_LIST;
item= new (thd->mem_root) Item_field(thd, &sq_select->context,
- NULL, NULL, &star_clex_str);
+ star_clex_str);
if (item == NULL || add_item_to_list(thd, item))
goto err;
(sq_select->with_wild)++;
@@ -988,6 +1041,7 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
goto err;
parent_select->curr_tvc_name++;
+
return sq;
err: