diff options
Diffstat (limited to 'sql/sql_tvc.cc')
-rw-r--r-- | sql/sql_tvc.cc | 66 |
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: |