summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc116
1 files changed, 108 insertions, 8 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d0f9b5cd58d..3283a8372df 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1684,6 +1684,31 @@ void st_select_lex_node::include_down(st_select_lex_node *upper)
slave= 0;
}
+
+void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
+{
+ for (; slave; slave= slave->next)
+ if (slave == slave_arg)
+ return;
+
+ if (slave)
+ {
+ st_select_lex_node *slave_arg_slave= slave_arg->slave;
+ /* Insert in the front of list of slaves if any. */
+ slave_arg->include_neighbour(slave);
+ /* include_neighbour() sets slave_arg->slave=0, restore it. */
+ slave_arg->slave= slave_arg_slave;
+ /* Count on include_neighbour() setting the master. */
+ DBUG_ASSERT(slave_arg->master == this);
+ }
+ else
+ {
+ slave= slave_arg;
+ slave_arg->master= this;
+ }
+}
+
+
/*
include on level down (but do not link)
@@ -1735,17 +1760,29 @@ void st_select_lex_node::fast_exclude()
}
+
+/*
+ Exclude a node from the tree lex structure, but leave it in the global
+ list of nodes.
+*/
+
+void st_select_lex_node::exclude_from_tree()
+{
+ if ((*prev= next))
+ next->prev= prev;
+}
+
+
/*
- excluding select_lex structure (except first (first select can't be
+ Exclude select_lex structure (except first (first select can't be
deleted, because it is most upper select))
*/
void st_select_lex_node::exclude()
{
- //exclude from global list
+ /* exclude from global list */
fast_exclude();
- //exclude from other structures
- if ((*prev= next))
- next->prev= prev;
+ /* exclude from other structures */
+ exclude_from_tree();
/*
We do not need following statements, because prev pointer of first
list element point to master->slave
@@ -2145,8 +2182,8 @@ void st_select_lex::print_limit(THD *thd,
select_limit == 1, and there should be no offset_limit.
*/
(((subs_type == Item_subselect::IN_SUBS) &&
- ((Item_in_subselect*)item)->exec_method ==
- Item_in_subselect::MATERIALIZATION) ?
+ ((Item_in_subselect*)item)->in_strategy &
+ SUBS_MATERIALIZATION) ?
TRUE :
(select_limit->val_int() == 1LL) &&
offset_limit == 0));
@@ -3076,6 +3113,70 @@ bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
str, length));
}
+
+bool st_select_lex::optimize_unflattened_subqueries()
+{
+ for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
+ {
+ Item_subselect *subquery_predicate= un->item;
+ if (subquery_predicate)
+ {
+ for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
+ {
+ JOIN *inner_join= sl->join;
+ SELECT_LEX *save_select= un->thd->lex->current_select;
+ ulonglong save_options;
+ int res;
+ /* We need only 1 row to determine existence */
+ un->set_limit(un->global_parameters);
+ un->thd->lex->current_select= sl;
+ save_options= inner_join->select_options;
+ if (un->outer_select()->options & SELECT_DESCRIBE)
+ {
+ /* Optimize the subquery in the context of EXPLAIN. */
+ set_explain_type();
+ inner_join->select_options= options;
+ }
+ res= inner_join->optimize();
+ inner_join->select_options= save_options;
+ un->thd->lex->current_select= save_select;
+ if (res)
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/**
+ Set the EXPLAIN type for this subquery.
+*/
+
+void st_select_lex::set_explain_type()
+{
+ SELECT_LEX *first= master_unit()->first_select();
+ /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
+ uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
+
+ type= ((&master_unit()->thd->lex->select_lex == this) ?
+ (first_inner_unit() || next_select() ?
+ "PRIMARY" : "SIMPLE") :
+ ((this == first) ?
+ ((linkage == DERIVED_TABLE_TYPE) ?
+ "DERIVED" :
+ ((is_uncacheable & UNCACHEABLE_DEPENDENT) ?
+ "DEPENDENT SUBQUERY" :
+ (is_uncacheable ? "UNCACHEABLE SUBQUERY" :
+ "SUBQUERY"))) :
+ ((is_uncacheable & UNCACHEABLE_DEPENDENT) ?
+ "DEPENDENT UNION":
+ is_uncacheable ? "UNCACHEABLE UNION":
+ "UNION")));
+ options|= SELECT_DESCRIBE;
+}
+
+
/**
A routine used by the parser to decide whether we are specifying a full
partitioning or if only partitions to add or to split.
@@ -3093,4 +3194,3 @@ bool st_lex::is_partition_management() const
(alter_info.flags == ALTER_ADD_PARTITION ||
alter_info.flags == ALTER_REORGANIZE_PARTITION));
}
-