23 #include "my_global.h"
26 #include "sql_derived.h"
28 #include "sql_optimizer.h"
63 mysql_handle_derived(LEX *lex,
bool (*processor)(THD*, LEX*,
TABLE_LIST*))
66 if (lex->derived_tables)
68 lex->thd->derived_tables_processing= TRUE;
69 for (SELECT_LEX *sl= lex->all_selects_list;
71 sl= sl->next_select_in_list())
73 for (
TABLE_LIST *table_ref= sl->get_table_list();
75 table_ref= table_ref->next_local)
77 if ((res= mysql_handle_single_derived(lex, table_ref, processor)))
92 lex->thd->derived_tables_processing= FALSE;
111 mysql_handle_single_derived(LEX *lex,
TABLE_LIST *derived,
114 return (derived->is_view_or_derived() &&
115 (*processor)(lex->thd, lex, derived));
173 bool mysql_derived_prepare(THD *thd, LEX *lex,
TABLE_LIST *derived)
175 SELECT_LEX_UNIT *unit= derived->
get_unit();
176 ulonglong create_options;
177 DBUG_ENTER(
"mysql_derived_prepare");
182 SELECT_LEX *first_select= unit->first_select();
184 select_union *derived_result;
187 for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
188 sl->context.outer_context= 0;
190 if (!(derived_result=
new select_union))
193 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED;
195 if ((res= unit->prepare(thd, derived_result, 0)))
197 lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
198 if ((res= check_duplicate_names(unit->types, 0)))
201 create_options= (first_select->options | thd->variables.option_bits |
202 TMP_TABLE_ALL_COLUMNS);
213 if ((res= derived_result->create_result_table(thd, &unit->types, FALSE,
215 derived->alias, FALSE, FALSE)))
218 table= derived_result->table;
224 if (thd->is_error() &&
225 (thd->get_stmt_da()->sql_errno() == ER_BAD_FIELD_ERROR ||
226 thd->get_stmt_da()->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
227 thd->get_stmt_da()->sql_errno() == ER_SP_DOES_NOT_EXIST))
230 my_error(ER_VIEW_INVALID, MYF(0), derived->db,
231 derived->table_name);
243 free_tmp_table(thd, table);
244 delete derived_result;
248 derived->derived_result= derived_result;
249 derived->table=
table;
250 derived->table_name= table->s->table_name.str;
251 derived->table_name_length= table->s->table_name.length;
252 table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
253 #ifndef NO_EMBEDDED_ACCESS_CHECKS
254 if (derived->referencing_view)
255 table->grant= derived->grant;
259 derived->db= (
char *)
"";
260 derived->db_length= 0;
262 table->next= thd->derived_tables;
263 thd->derived_tables=
table;
289 bool mysql_derived_optimize(THD *thd, LEX *lex,
TABLE_LIST *derived)
291 SELECT_LEX_UNIT *unit= derived->
get_unit();
292 DBUG_ENTER(
"mysql_derived_optimize");
297 if (unit->optimize() || thd->is_error())
301 (mysql_derived_create(thd, lex, derived) ||
302 mysql_derived_materialize(thd, lex, derived)))
326 bool mysql_derived_create(THD *thd, LEX *lex,
TABLE_LIST *derived)
328 TABLE *table= derived->table;
329 SELECT_LEX_UNIT *unit= derived->
get_unit();
330 DBUG_ENTER(
"mysql_derived_create");
343 (derived->select_lex->join != NULL &&
344 (derived->select_lex->join->const_table_map & table->map)))
350 DBUG_ASSERT(table == NULL || table->reginfo.join_tab == NULL ||
351 table->reginfo.join_tab->type != JT_CONST ||
352 table->null_row == 1);
356 select_union *result= (select_union*)unit->get_result();
358 if (instantiate_tmp_table(table, table->key_info,
359 result->tmp_table_param.start_recinfo,
360 &result->tmp_table_param.recinfo,
361 (unit->first_select()->options |
362 thd->lex->select_lex.options |
363 thd->variables.option_bits |
364 TMP_TABLE_ALL_COLUMNS),
365 thd->variables.big_tables, &thd->opt_trace))
368 table->file->extra(HA_EXTRA_WRITE_CACHE);
369 table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
397 bool mysql_derived_materialize(THD *thd, LEX *lex,
TABLE_LIST *derived)
399 SELECT_LEX_UNIT *unit= derived->
get_unit();
401 DBUG_ENTER(
"mysql_derived_materialize");
403 DBUG_ASSERT(unit && derived->table && derived->table->
is_created());
405 select_union *derived_result= derived->derived_result;
407 if (unit->is_union())
414 SELECT_LEX *first_select= unit->first_select();
415 JOIN *join= first_select->join;
416 SELECT_LEX *save_current_select= lex->current_select;
417 lex->current_select= first_select;
421 unit->set_limit(first_select);
422 if (unit->select_limit_cnt == HA_POS_ERROR)
423 first_select->options&= ~OPTION_FOUND_ROWS;
427 lex->current_select= save_current_select;
436 if (derived_result->flush())
448 bool mysql_derived_cleanup(THD *thd, LEX *lex,
TABLE_LIST *derived)
450 DBUG_ENTER(
"mysql_derived_cleanup");
451 SELECT_LEX_UNIT *unit= derived->
derived;