1 /* Copyright (c) 2017, MariaDB
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16 #include "mariadb.h"
17 #include "sql_list.h"
18 #include "sql_tvc.h"
19 #include "sql_class.h"
20 #include "opt_range.h"
21 #include "sql_select.h"
22 #include "sql_explain.h"
23 #include "sql_parse.h"
24 #include "sql_cte.h"
25
26 /**
27 @brief
28 Fix fields for TVC values
29
30 @param
31 @param thd The context of the statement
32 @param li The iterator on the list of lists
33
34 @details
35 Call fix_fields procedure for TVC values.
36
37 @retval
38 true if an error was reported
39 false otherwise
40 */
41
fix_fields_for_tvc(THD * thd,List_iterator_fast<List_item> & li)42 bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li)
43 {
44 DBUG_ENTER("fix_fields_for_tvc");
45 List_item *lst;
46 li.rewind();
47
48 while ((lst= li++))
49 {
50 List_iterator<Item> it(*lst);
51 Item *item;
52
53 while ((item= it++))
54 {
55 /*
56 Some items have already been fixed.
57 For example Item_splocal items get fixed in
58 Item_splocal::append_for_log(), which is called from subst_spvars()
59 while replacing their values to NAME_CONST()s.
60 So fix only those that have not been.
61 */
62 if (item->fix_fields_if_needed_for_scalar(thd, it.ref()) ||
63 item->check_is_evaluable_expression_or_error())
64 DBUG_RETURN(true);
65 }
66 }
67 DBUG_RETURN(false);
68 }
69
70
71 /**
72 @brief
73 Defines types of matrix columns elements where matrix rows are defined by
74 some lists of values.
75
76 @param
77 @param thd The context of the statement
78 @param li The iterator on the list of lists
79 @param holders The structure where types of matrix columns are stored
80 @param first_list_el_count Count of the list values. It should be the same
81 for each list of lists elements. It contains
82 number of elements of the first list from list of
83 lists.
84
85 @details
86 For each list list_a from list of lists the procedure gets its elements
87 types and aggregates them with the previous ones stored in holders. If
88 list_a is the first one in the list of lists its elements types are put in
89 holders. The errors can be reported when count of list_a elements is
90 different from the first_list_el_count. Also error can be reported whe
91 n aggregation can't be made.
92
93 @retval
94 true if an error was reported
95 false otherwise
96 */
97
join_type_handlers_for_tvc(THD * thd,List_iterator_fast<List_item> & li,Type_holder * holders,uint first_list_el_count)98 bool join_type_handlers_for_tvc(THD *thd, List_iterator_fast<List_item> &li,
99 Type_holder *holders, uint first_list_el_count)
100 {
101 DBUG_ENTER("join_type_handlers_for_tvc");
102 List_item *lst;
103 li.rewind();
104 bool first= true;
105
106 while ((lst= li++))
107 {
108 List_iterator_fast<Item> it(*lst);
109 Item *item;
110
111 if (first_list_el_count != lst->elements)
112 {
113 my_message(ER_WRONG_NUMBER_OF_VALUES_IN_TVC,
114 ER_THD(thd, ER_WRONG_NUMBER_OF_VALUES_IN_TVC),
115 MYF(0));
116 DBUG_RETURN(true);
117 }
118 for (uint pos= 0; (item=it++); pos++)
119 {
120 const Type_handler *item_type_handler= item->real_type_handler();
121 if (first)
122 holders[pos].set_handler(item_type_handler);
123 else if (holders[pos].aggregate_for_result(item_type_handler))
124 {
125 my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
126 holders[pos].type_handler()->name().ptr(),
127 item_type_handler->name().ptr(),
128 "TABLE VALUE CONSTRUCTOR");
129 DBUG_RETURN(true);
130 }
131 }
132 first= false;
133 }
134 DBUG_RETURN(false);
135 }
136
137
138 /**
139 @brief
140 Define attributes of matrix columns elements where matrix rows are defined
141 by some lists of values.
142
143 @param
144 @param thd The context of the statement
145 @param li The iterator on the list of lists
146 @param holders The structure where names of matrix columns are stored
147 @param count_of_lists Count of list of lists elements
148 @param first_list_el_count Count of the list values. It should be the same
149 for each list of lists elements. It contains
150 number of elements of the first list from list
151 of lists.
152
153 @details
154 For each list list_a from list of lists the procedure gets its elements
155 attributes and aggregates them with the previous ones stored in holders.
156 The errors can be reported when aggregation can't be made.
157
158 @retval
159 true if an error was reported
160 false otherwise
161 */
162
get_type_attributes_for_tvc(THD * thd,List_iterator_fast<List_item> & li,Type_holder * holders,uint count_of_lists,uint first_list_el_count)163 bool get_type_attributes_for_tvc(THD *thd,
164 List_iterator_fast<List_item> &li,
165 Type_holder *holders, uint count_of_lists,
166 uint first_list_el_count)
167 {
168 DBUG_ENTER("get_type_attributes_for_tvc");
169 List_item *lst;
170 li.rewind();
171
172 for (uint pos= 0; pos < first_list_el_count; pos++)
173 {
174 if (holders[pos].alloc_arguments(thd, count_of_lists))
175 DBUG_RETURN(true);
176 }
177
178 while ((lst= li++))
179 {
180 List_iterator_fast<Item> it(*lst);
181 Item *item;
182 for (uint holder_pos= 0 ; (item= it++); holder_pos++)
183 {
184 DBUG_ASSERT(item->fixed);
185 holders[holder_pos].add_argument(item);
186 }
187 }
188
189 for (uint pos= 0; pos < first_list_el_count; pos++)
190 {
191 if (holders[pos].aggregate_attributes(thd))
192 DBUG_RETURN(true);
193 }
194 DBUG_RETURN(false);
195 }
196
197
198 /**
199 @brief
200 Prepare of TVC
201
202 @param
203 @param thd The context of the statement
204 @param sl The select where this TVC is defined
205 @param tmp_result Structure that contains the information
206 about where to send the result of the query
207 @param unit_arg The union where sl is defined
208
209 @details
210 Gets types and attributes of values of this TVC that will be used
211 for temporary table creation for this TVC. It creates Item_type_holders
212 for each element of the first list from list of lists (VALUES from tvc),
213 using its elements name, defined type and attribute.
214
215 @retval
216 true if an error was reported
217 false otherwise
218 */
219
prepare(THD * thd,SELECT_LEX * sl,select_result * tmp_result,st_select_lex_unit * unit_arg)220 bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
221 select_result *tmp_result,
222 st_select_lex_unit *unit_arg)
223 {
224 DBUG_ENTER("table_value_constr::prepare");
225 select_lex->in_tvc= true;
226 List_iterator_fast<List_item> li(lists_of_values);
227
228 List_item *first_elem= li++;
229 uint cnt= first_elem->elements;
230 Type_holder *holders;
231
232 if (cnt == 0)
233 {
234 my_error(ER_EMPTY_ROW_IN_TVC, MYF(0));
235 DBUG_RETURN(true);
236 }
237
238 if (fix_fields_for_tvc(thd, li))
239 DBUG_RETURN(true);
240
241 if (!(holders= new (thd->stmt_arena->mem_root) Type_holder[cnt]) ||
242 join_type_handlers_for_tvc(thd, li, holders, cnt) ||
243 get_type_attributes_for_tvc(thd, li, holders,
244 lists_of_values.elements, cnt))
245 DBUG_RETURN(true);
246
247 List_iterator_fast<Item> it(*first_elem);
248 Item *item;
249 Query_arena *arena, backup;
250 arena=thd->activate_stmt_arena_if_needed(&backup);
251
252 sl->item_list.empty();
253 for (uint pos= 0; (item= it++); pos++)
254 {
255 /* Error's in 'new' will be detected after loop */
256 Item_type_holder *new_holder= new (thd->mem_root)
257 Item_type_holder(thd, item, holders[pos].type_handler(),
258 &holders[pos]/*Type_all_attributes*/,
259 holders[pos].get_maybe_null());
260 new_holder->fix_fields(thd, 0);
261 sl->item_list.push_back(new_holder);
262 }
263 if (arena)
264 thd->restore_active_arena(arena, &backup);
265
266 if (unlikely(thd->is_fatal_error))
267 DBUG_RETURN(true); // out of memory
268
269 result= tmp_result;
270
271 if (result && result->prepare(sl->item_list, unit_arg))
272 DBUG_RETURN(true);
273
274 /*
275 setup_order() for a TVC is not called when the following is true
276 (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
277 */
278
279 thd->where="order clause";
280 ORDER *order= sl->order_list.first;
281 for (; order; order=order->next)
282 {
283 Item *order_item= *order->item;
284 if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
285 {
286 uint count= 0;
287 if (order->counter_used)
288 count= order->counter; // counter was once resolved
289 else
290 count= (uint) order_item->val_int();
291 if (!count || count > first_elem->elements)
292 {
293 my_error(ER_BAD_FIELD_ERROR, MYF(0),
294 order_item->full_name(), thd->where);
295 DBUG_RETURN(true);
296 }
297 order->in_field_list= 1;
298 order->counter= count;
299 order->counter_used= 1;
300 }
301 }
302
303 select_lex->in_tvc= false;
304 DBUG_RETURN(false);
305 }
306
307
308 /**
309 Save Query Plan Footprint
310 */
311
save_explain_data_intern(THD * thd,Explain_query * output)312 int table_value_constr::save_explain_data_intern(THD *thd,
313 Explain_query *output)
314 {
315 const char *message= "No tables used";
316 DBUG_ENTER("table_value_constr::save_explain_data_intern");
317 DBUG_PRINT("info", ("Select %p, type %s, message %s",
318 select_lex, select_lex->type,
319 message));
320 DBUG_ASSERT(have_query_plan == QEP_AVAILABLE);
321
322 /* There should be no attempts to save query plans for merged selects */
323 DBUG_ASSERT(!select_lex->master_unit()->derived ||
324 select_lex->master_unit()->derived->is_materialized_derived() ||
325 select_lex->master_unit()->derived->is_with_table());
326
327 explain= new (output->mem_root) Explain_select(output->mem_root,
328 thd->lex->analyze_stmt);
329 if (!explain)
330 DBUG_RETURN(1);
331
332 select_lex->set_explain_type(true);
333
334 explain->select_id= select_lex->select_number;
335 explain->select_type= select_lex->type;
336 explain->linkage= select_lex->linkage;
337 explain->using_temporary= false;
338 explain->using_filesort= false;
339 /* Setting explain->message means that all other members are invalid */
340 explain->message= message;
341
342 if (select_lex->master_unit()->derived)
343 explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED;
344
345 for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit();
346 unit;
347 unit= unit->next_unit())
348 {
349 explain->add_child(unit->first_select()->select_number);
350 }
351
352 output->add_node(explain);
353
354 if (select_lex->is_top_level_node())
355 output->query_plan_ready();
356
357 DBUG_RETURN(0);
358 }
359
360
361 /**
362 Optimization of TVC
363 */
364
optimize(THD * thd)365 bool table_value_constr::optimize(THD *thd)
366 {
367 create_explain_query_if_not_exists(thd->lex, thd->mem_root);
368 have_query_plan= QEP_AVAILABLE;
369
370 if (select_lex->select_number != UINT_MAX &&
371 select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
372 have_query_plan != QEP_NOT_PRESENT_YET &&
373 thd->lex->explain && // for "SET" command in SPs.
374 (!thd->lex->explain->get_select(select_lex->select_number)))
375 {
376 if (save_explain_data_intern(thd, thd->lex->explain))
377 return true;
378 }
379
380 if (select_lex->optimize_unflattened_subqueries(true))
381 return true;
382
383 return false;
384 }
385
386
387 /**
388 Execute of TVC
389 */
390
exec(SELECT_LEX * sl)391 bool table_value_constr::exec(SELECT_LEX *sl)
392 {
393 DBUG_ENTER("table_value_constr::exec");
394 List_iterator_fast<List_item> li(lists_of_values);
395 List_item *elem;
396 ha_rows send_records= 0;
397
398 if (select_options & SELECT_DESCRIBE)
399 DBUG_RETURN(false);
400
401 if (result->send_result_set_metadata(sl->item_list,
402 Protocol::SEND_NUM_ROWS |
403 Protocol::SEND_EOF))
404 {
405 DBUG_RETURN(true);
406 }
407
408 while ((elem= li++))
409 {
410 if (send_records >= sl->master_unit()->select_limit_cnt)
411 break;
412 int rc= result->send_data(*elem);
413 if (!rc)
414 send_records++;
415 else if (rc > 0)
416 DBUG_RETURN(true);
417 }
418
419 if (result->send_eof())
420 DBUG_RETURN(true);
421
422 DBUG_RETURN(false);
423 }
424
425
426 /**
427 @brief
428 Print list
429
430 @param str The reference on the string representation of the list
431 @param list The list that needed to be print
432 @param query_type The mode of printing
433
434 @details
435 The method saves a string representation of list in the
436 string str.
437 */
438
print_list_item(String * str,List_item * list,enum_query_type query_type)439 void print_list_item(String *str, List_item *list,
440 enum_query_type query_type)
441 {
442 bool is_first_elem= true;
443 List_iterator_fast<Item> it(*list);
444 Item *item;
445
446 str->append('(');
447
448 while ((item= it++))
449 {
450 if (is_first_elem)
451 is_first_elem= false;
452 else
453 str->append(',');
454
455 item->print(str, query_type);
456 }
457
458 str->append(')');
459 }
460
461
462 /**
463 @brief
464 Print this TVC
465
466 @param thd The context of the statement
467 @param str The reference on the string representation of this TVC
468 @param query_type The mode of printing
469
470 @details
471 The method saves a string representation of this TVC in the
472 string str.
473 */
474
print(THD * thd,String * str,enum_query_type query_type)475 void table_value_constr::print(THD *thd, String *str,
476 enum_query_type query_type)
477 {
478 DBUG_ASSERT(thd);
479
480 str->append(STRING_WITH_LEN("values "));
481
482 bool is_first_elem= true;
483 List_iterator_fast<List_item> li(lists_of_values);
484 List_item *list;
485
486 while ((list= li++))
487 {
488 if (is_first_elem)
489 is_first_elem= false;
490 else
491 str->append(',');
492
493 print_list_item(str, list, query_type);
494 }
495 if (select_lex->order_list.elements)
496 {
497 str->append(STRING_WITH_LEN(" order by "));
498 select_lex->print_order(str, select_lex->order_list.first, query_type);
499 }
500 select_lex->print_limit(thd, str, query_type);
501 }
502
503
504 /**
505 @brief
506 Create list of lists for TVC from the list of this IN predicate
507
508 @param thd The context of the statement
509 @param values TVC list of values
510
511 @details
512 The method uses the list of values of this IN predicate to build
513 an equivalent list of values that can be used in TVC.
514
515 E.g.:
516
517 <value_list> = 5,2,7
518 <transformed_value_list> = (5),(2),(7)
519
520 <value_list> = (5,2),(7,1)
521 <transformed_value_list> = (5,2),(7,1)
522
523 @retval
524 false if the method succeeds
525 true otherwise
526 */
527
create_value_list_for_tvc(THD * thd,List<List<Item>> * values)528 bool Item_func_in::create_value_list_for_tvc(THD *thd,
529 List< List<Item> > *values)
530 {
531 bool is_list_of_rows= args[1]->type() == Item::ROW_ITEM;
532
533 for (uint i=1; i < arg_count; i++)
534 {
535 char col_name[8];
536 List<Item> *tvc_value;
537 if (!(tvc_value= new (thd->mem_root) List<Item>()))
538 return true;
539
540 if (is_list_of_rows)
541 {
542 Item_row *row_list= (Item_row *)(args[i]->build_clone(thd));
543
544 if (!row_list)
545 return true;
546
547 for (uint j=0; j < row_list->cols(); j++)
548 {
549 if (i == 1)
550 {
551 sprintf(col_name, "_col_%i", j+1);
552 row_list->element_index(j)->set_name(thd, col_name, strlen(col_name),
553 thd->charset());
554 }
555 if (tvc_value->push_back(row_list->element_index(j),
556 thd->mem_root))
557 return true;
558 }
559 }
560 else
561 {
562 if (i == 1)
563 {
564 sprintf(col_name, "_col_%i", 1);
565 args[i]->set_name(thd, col_name, strlen(col_name), thd->charset());
566 }
567 Item *arg_clone= args[i]->build_clone(thd);
568 if (!arg_clone || tvc_value->push_back(arg_clone))
569 return true;
570 }
571
572 if (values->push_back(tvc_value, thd->mem_root))
573 return true;
574 }
575 return false;
576 }
577
578
579 /**
580 @brief
581 Create name for the derived table defined by TVC
582
583 @param thd The context of the statement
584 @param parent_select The SELECT where derived table is used
585 @param alias The returned created name
586
587 @details
588 Create name for the derived table using current TVC number
589 for this parent_select stored in parent_select
590
591 @retval
592 true if creation fails
593 false otherwise
594 */
595
create_tvc_name(THD * thd,st_select_lex * parent_select,LEX_CSTRING * alias)596 static bool create_tvc_name(THD *thd, st_select_lex *parent_select,
597 LEX_CSTRING *alias)
598 {
599 char buff[6];
600
601 alias->length= my_snprintf(buff, sizeof(buff),
602 "tvc_%u",
603 parent_select ? parent_select->curr_tvc_name : 0);
604 alias->str= thd->strmake(buff, alias->length);
605 if (!alias->str)
606 return true;
607
608 return false;
609 }
610
611
612 /**
613 @brief
614 Check whether TVC used in unit is to be wrapped into select
615
616 @details
617 TVC used in unit that contains more than one members is to be wrapped
618 into select if it is tailed with ORDER BY ... LIMIT n [OFFSET m]
619
620 @retval
621 true if TVC is to be wrapped
622 false otherwise
623 */
624
to_be_wrapped_as_with_tail()625 bool table_value_constr::to_be_wrapped_as_with_tail()
626 {
627 return select_lex->master_unit()->first_select()->next_select() &&
628 select_lex->order_list.elements && select_lex->explicit_limit;
629 }
630
631
632 /**
633 @brief
634 Wrap table value constructor into a select
635
636 @param thd The context handler
637 @param tvc_sl The TVC to wrap
638 @parent_select The parent select if tvc_sl used in a subquery
639
640 @details
641 The function wraps the TVC tvc_sl into a select:
642 the function transforms the TVC of the form VALUES (v1), ... (vn) into
643 the select of the form
644 SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
645
646 @retval pointer to the result of of the transformation if successful
647 NULL - otherwise
648 */
649
650 static
wrap_tvc(THD * thd,st_select_lex * tvc_sl,st_select_lex * parent_select)651 st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
652 st_select_lex *parent_select)
653 {
654 LEX *lex= thd->lex;
655 select_result *save_result= lex->result;
656 uint8 save_derived_tables= lex->derived_tables;
657 thd->lex->result= NULL;
658
659 Query_arena backup;
660 Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
661
662 Item *item;
663 SELECT_LEX *wrapper_sl;
664 SELECT_LEX_UNIT *derived_unit;
665
666 /*
667 Create SELECT_LEX wrapper_sl of the select used in the result
668 of the transformation
669 */
670 if (!(wrapper_sl= new (thd->mem_root) SELECT_LEX()))
671 goto err;
672 wrapper_sl->select_number= ++thd->lex->stmt_lex->current_select_number;
673 wrapper_sl->parent_lex= lex; /* Used in init_query. */
674 wrapper_sl->init_query();
675 wrapper_sl->init_select();
676
677 wrapper_sl->nest_level= tvc_sl->nest_level;
678 wrapper_sl->parsing_place= tvc_sl->parsing_place;
679 wrapper_sl->linkage= tvc_sl->linkage;
680 wrapper_sl->exclude_from_table_unique_test=
681 tvc_sl->exclude_from_table_unique_test;
682
683 lex->current_select= wrapper_sl;
684 item= new (thd->mem_root) Item_field(thd, &wrapper_sl->context,
685 NULL, NULL, &star_clex_str);
686 if (item == NULL || add_item_to_list(thd, item))
687 goto err;
688 (wrapper_sl->with_wild)++;
689
690 /* Include the newly created select into the global list of selects */
691 wrapper_sl->include_global((st_select_lex_node**)&lex->all_selects_list);
692
693 /* Substitute select node used of TVC for the newly created select */
694 tvc_sl->substitute_in_tree(wrapper_sl);
695
696 /*
697 Create a unit for the substituted select used for TVC and attach it
698 to the the wrapper select wrapper_sl as the only unit. The created
699 unit is the unit for the derived table tvc_x of the transformation.
700 */
701 if (!(derived_unit= new (thd->mem_root) SELECT_LEX_UNIT()))
702 goto err;
703 derived_unit->init_query();
704 derived_unit->thd= thd;
705 derived_unit->include_down(wrapper_sl);
706
707 /*
708 Attach the select used of TVC as the only slave to the unit for
709 the derived table tvc_x of the transformation
710 */
711 derived_unit->add_slave(tvc_sl);
712 tvc_sl->linkage= DERIVED_TABLE_TYPE;
713
714 /*
715 Generate the name of the derived table created for TVC and
716 add it to the FROM list of the wrapping select
717 */
718 Table_ident *ti;
719 LEX_CSTRING alias;
720 TABLE_LIST *derived_tab;
721 if (!(ti= new (thd->mem_root) Table_ident(derived_unit)) ||
722 create_tvc_name(thd, parent_select, &alias))
723 goto err;
724 if (!(derived_tab=
725 wrapper_sl->add_table_to_list(thd,
726 ti, &alias, 0,
727 TL_READ, MDL_SHARED_READ)))
728 goto err;
729 wrapper_sl->add_joined_table(derived_tab);
730 wrapper_sl->add_where_field(derived_unit->first_select());
731 wrapper_sl->context.table_list= wrapper_sl->table_list.first;
732 wrapper_sl->context.first_name_resolution_table= wrapper_sl->table_list.first;
733 wrapper_sl->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE;
734 lex->derived_tables|= DERIVED_SUBQUERY;
735
736 if (arena)
737 thd->restore_active_arena(arena, &backup);
738 lex->result= save_result;
739 return wrapper_sl;
740
741 err:
742 if (arena)
743 thd->restore_active_arena(arena, &backup);
744 lex->result= save_result;
745 lex->derived_tables= save_derived_tables;
746 return 0;
747 }
748
749
750 /**
751 @brief
752 Wrap TVC with ORDER BY ... LIMIT tail into a select
753
754 @param thd The context handler
755 @param tvc_sl The TVC to wrap
756
757 @details
758 The function wraps the TVC tvc_sl into a select:
759 the function transforms the TVC with tail of the form
760 VALUES (v1), ... (vn) ORDER BY ... LIMIT n [OFFSET m]
761 into the select with the same tail of the form
762 SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
763 ORDER BY ... LIMIT n [OFFSET m]
764
765 @retval pointer to the result of of the transformation if successful
766 NULL - otherwise
767 */
768
wrap_tvc_with_tail(THD * thd,st_select_lex * tvc_sl)769 st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl)
770 {
771 st_select_lex *wrapper_sl= wrap_tvc(thd, tvc_sl, NULL);
772 if (!wrapper_sl)
773 return NULL;
774
775 wrapper_sl->order_list= tvc_sl->order_list;
776 wrapper_sl->select_limit= tvc_sl->select_limit;
777 wrapper_sl->offset_limit= tvc_sl->offset_limit;
778 wrapper_sl->braces= tvc_sl->braces;
779 wrapper_sl->explicit_limit= tvc_sl->explicit_limit;
780 tvc_sl->order_list.empty();
781 tvc_sl->select_limit= NULL;
782 tvc_sl->offset_limit= NULL;
783 tvc_sl->braces= 0;
784 tvc_sl->explicit_limit= false;
785 if (tvc_sl->select_number == 1)
786 {
787 tvc_sl->select_number= wrapper_sl->select_number;
788 wrapper_sl->select_number= 1;
789 }
790 if (tvc_sl->master_unit()->union_distinct == tvc_sl)
791 {
792 wrapper_sl->master_unit()->union_distinct= wrapper_sl;
793 }
794 thd->lex->current_select= wrapper_sl;
795 return wrapper_sl;
796 }
797
798
799 /**
800 @brief
801 Wrap TVC in a subselect into a select
802
803 @param thd The context handler
804 @param tvc_sl The TVC to wrap
805
806 @details
807 The function wraps the TVC tvc_sl used in a subselect into a select
808 the function transforms the TVC of the form VALUES (v1), ... (vn)
809 into the select the form
810 SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
811 and replaces the subselect with the result of the transformation.
812
813 @retval wrapping select if successful
814 0 otherwise
815 */
816
817 st_select_lex *
wrap_tvc_into_select(THD * thd,st_select_lex * tvc_sl)818 Item_subselect::wrap_tvc_into_select(THD *thd, st_select_lex *tvc_sl)
819 {
820 LEX *lex= thd->lex;
821 /* SELECT_LEX object where the transformation is performed */
822 SELECT_LEX *parent_select= lex->current_select;
823 SELECT_LEX *wrapper_sl= wrap_tvc(thd, tvc_sl, parent_select);
824 if (wrapper_sl)
825 {
826 if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
827 ((subselect_single_select_engine *) engine)->change_select(wrapper_sl);
828 }
829 lex->current_select= parent_select;
830 return wrapper_sl;
831 }
832
833
834 /*
835 @brief
836 Check whether the items are of comparable type or not
837
838 @details
839 This check are done because materialization is not performed
840 if the left expr and right expr are of the same types.
841 @see subquery_types_allow_materialization()
842
843 @retval
844 0 comparable
845 1 not comparable
846 */
847
cmp_row_types(Item * item1,Item * item2)848 static bool cmp_row_types(Item* item1, Item* item2)
849 {
850 uint n= item1->cols();
851 if (item2->check_cols(n))
852 return true;
853
854 for (uint i=0; i < n; i++)
855 {
856 Item *inner= item1->element_index(i);
857 Item *outer= item2->element_index(i);
858 if (!inner->type_handler()->subquery_type_allows_materialization(inner,
859 outer,
860 true))
861 return true;
862 }
863 return false;
864 }
865
866
867 /**
868 @brief
869 Transform IN predicate into IN subquery
870
871 @param thd The context of the statement
872 @param arg Not used
873
874 @details
875 The method transforms this IN predicate into in equivalent IN subquery:
876
877 <left_expr> IN (<value_list>)
878 =>
879 <left_expr> IN (SELECT * FROM (VALUES <transformed_value_list>) AS tvc_#)
880
881 E.g.:
882
883 <value_list> = 5,2,7
884 <transformed_value_list> = (5),(2),(7)
885
886 <value_list> = (5,2),(7,1)
887 <transformed_value_list> = (5,2),(7,1)
888
889 If the transformation succeeds the method returns the result IN subquery,
890 otherwise this IN predicate is returned.
891
892 @retval
893 pointer to the result of transformation if succeeded
894 pointer to this IN predicate otherwise
895 */
896
in_predicate_to_in_subs_transformer(THD * thd,uchar * arg)897 Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
898 uchar *arg)
899 {
900 if (!transform_into_subq)
901 return this;
902
903 transform_into_subq= false;
904
905 List<List_item> values;
906
907 LEX *lex= thd->lex;
908 /* SELECT_LEX object where the transformation is performed */
909 SELECT_LEX *parent_select= lex->current_select;
910 uint8 save_derived_tables= lex->derived_tables;
911
912 /*
913 Make sure that create_tmp_table will not fail due to too long keys.
914 Here the strategy would mainly use materialization, so we need to make
915 sure that the materialized table can be created.
916
917 The checks here are the same as in subquery_type_allows_materialization()
918 */
919 uint32 length= max_length_of_left_expr();
920 if (!length || length > tmp_table_max_key_length() ||
921 args[0]->cols() > tmp_table_max_key_parts())
922 return this;
923
924 for (uint i=1; i < arg_count; i++)
925 {
926 if (!args[i]->const_item() || cmp_row_types(args[i], args[0]))
927 return this;
928 }
929
930 Query_arena backup;
931 Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
932
933 /*
934 Create SELECT_LEX of the subquery SQ used in the result of transformation
935 */
936 if (mysql_new_select(lex, 1, NULL))
937 goto err;
938 mysql_init_select(lex);
939 /* Create item list as '*' for the subquery SQ */
940 Item *item;
941 SELECT_LEX *sq_select; // select for IN subquery;
942 sq_select= lex->current_select;
943 sq_select->parsing_place= SELECT_LIST;
944 item= new (thd->mem_root) Item_field(thd, &sq_select->context,
945 NULL, NULL, &star_clex_str);
946 if (item == NULL || add_item_to_list(thd, item))
947 goto err;
948 (sq_select->with_wild)++;
949 /*
950 Create derived table DT that will wrap TVC in the result of transformation
951 */
952 SELECT_LEX *tvc_select; // select for tvc
953 SELECT_LEX_UNIT *derived_unit; // unit for tvc_select
954 if (mysql_new_select(lex, 1, NULL))
955 goto err;
956 mysql_init_select(lex);
957 tvc_select= lex->current_select;
958 derived_unit= tvc_select->master_unit();
959 tvc_select->linkage= DERIVED_TABLE_TYPE;
960
961 /* Create TVC used in the transformation */
962 if (create_value_list_for_tvc(thd, &values))
963 goto err;
964 if (!(tvc_select->tvc=
965 new (thd->mem_root)
966 table_value_constr(values,
967 tvc_select,
968 tvc_select->options)))
969 goto err;
970
971 lex->current_select= sq_select;
972
973 /*
974 Create the name of the wrapping derived table and
975 add it to the FROM list of the subquery SQ
976 */
977 Table_ident *ti;
978 LEX_CSTRING alias;
979 TABLE_LIST *derived_tab;
980 if (!(ti= new (thd->mem_root) Table_ident(derived_unit)) ||
981 create_tvc_name(thd, parent_select, &alias))
982 goto err;
983 if (!(derived_tab=
984 sq_select->add_table_to_list(thd,
985 ti, &alias, 0,
986 TL_READ, MDL_SHARED_READ)))
987 goto err;
988 sq_select->add_joined_table(derived_tab);
989 sq_select->add_where_field(derived_unit->first_select());
990 sq_select->context.table_list= sq_select->table_list.first;
991 sq_select->context.first_name_resolution_table= sq_select->table_list.first;
992 sq_select->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE;
993 lex->derived_tables|= DERIVED_SUBQUERY;
994
995 sq_select->where= 0;
996 sq_select->set_braces(false);
997 derived_unit->set_with_clause(0);
998
999 /* Create IN subquery predicate */
1000 sq_select->parsing_place= parent_select->parsing_place;
1001 Item_in_subselect *in_subs;
1002 Item *sq;
1003 if (!(in_subs=
1004 new (thd->mem_root) Item_in_subselect(thd, args[0], sq_select)))
1005 goto err;
1006 in_subs->converted_from_in_predicate= TRUE;
1007 sq= in_subs;
1008 if (negated)
1009 sq= negate_expression(thd, in_subs);
1010 else
1011 in_subs->emb_on_expr_nest= emb_on_expr_nest;
1012
1013 if (arena)
1014 thd->restore_active_arena(arena, &backup);
1015 thd->lex->current_select= parent_select;
1016
1017 if (sq->fix_fields(thd, (Item **)&sq))
1018 goto err;
1019
1020 parent_select->curr_tvc_name++;
1021 return sq;
1022
1023 err:
1024 if (arena)
1025 thd->restore_active_arena(arena, &backup);
1026 lex->derived_tables= save_derived_tables;
1027 thd->lex->current_select= parent_select;
1028 return NULL;
1029 }
1030
1031
max_length_of_left_expr()1032 uint32 Item_func_in::max_length_of_left_expr()
1033 {
1034 uint n= args[0]->cols();
1035 uint32 length= 0;
1036 for (uint i=0; i < n; i++)
1037 length+= args[0]->element_index(i)->max_length;
1038 return length;
1039 }
1040
1041
1042 /**
1043 @brief
1044 Check if this IN-predicate can be transformed in IN-subquery
1045 with TVC
1046
1047 @param thd The context of the statement
1048
1049 @details
1050 Compare the number of elements in the list of
1051 values in this IN-predicate with the
1052 in_subquery_conversion_threshold special variable
1053
1054 @retval
1055 true if transformation can be made
1056 false otherwise
1057 */
1058
to_be_transformed_into_in_subq(THD * thd)1059 bool Item_func_in::to_be_transformed_into_in_subq(THD *thd)
1060 {
1061 uint values_count= arg_count-1;
1062
1063 if (args[1]->type() == Item::ROW_ITEM)
1064 values_count*= ((Item_row *)(args[1]))->cols();
1065
1066 if (thd->variables.in_subquery_conversion_threshold == 0 ||
1067 thd->variables.in_subquery_conversion_threshold > values_count)
1068 return false;
1069
1070 return true;
1071 }
1072
1073
1074 /**
1075 @brief
1076 Transform IN predicates into IN subqueries in WHERE and ON expressions
1077
1078 @param thd The context of the statement
1079
1080 @details
1081 For each IN predicate from AND parts of the WHERE condition and/or
1082 ON expressions of the SELECT for this join the method performs
1083 the intransformation into an equivalent IN sunquery if it's needed.
1084
1085 @retval
1086 false always
1087 */
1088
transform_in_predicates_into_in_subq(THD * thd)1089 bool JOIN::transform_in_predicates_into_in_subq(THD *thd)
1090 {
1091 DBUG_ENTER("JOIN::transform_in_predicates_into_in_subq");
1092 if (!select_lex->in_funcs.elements)
1093 DBUG_RETURN(false);
1094
1095 SELECT_LEX *save_current_select= thd->lex->current_select;
1096 enum_parsing_place save_parsing_place= select_lex->parsing_place;
1097 thd->lex->current_select= select_lex;
1098 if (conds)
1099 {
1100 select_lex->parsing_place= IN_WHERE;
1101 conds=
1102 conds->transform(thd,
1103 &Item::in_predicate_to_in_subs_transformer,
1104 (uchar*) 0);
1105 if (!conds)
1106 DBUG_RETURN(true);
1107 select_lex->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
1108 select_lex->where= conds;
1109 }
1110
1111 if (join_list)
1112 {
1113 TABLE_LIST *table;
1114 List_iterator<TABLE_LIST> li(*join_list);
1115 select_lex->parsing_place= IN_ON;
1116
1117 while ((table= li++))
1118 {
1119 if (table->on_expr)
1120 {
1121 table->on_expr=
1122 table->on_expr->transform(thd,
1123 &Item::in_predicate_to_in_subs_transformer,
1124 (uchar*) 0);
1125 if (!table->on_expr)
1126 DBUG_RETURN(true);
1127 table->prep_on_expr= table->on_expr ?
1128 table->on_expr->copy_andor_structure(thd) : 0;
1129 }
1130 }
1131 }
1132
1133 select_lex->in_funcs.empty();
1134 select_lex->parsing_place= save_parsing_place;
1135 thd->lex->current_select= save_current_select;
1136 DBUG_RETURN(false);
1137 }
1138
1139