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.cc181
1 files changed, 112 insertions, 69 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 84a4ec4ed5b..a3718731d8c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -948,27 +948,17 @@ void st_select_lex_node::init_query()
options= 0;
linkage= UNSPECIFIED_TYPE;
no_error= no_table_names_allowed= uncacheable= dependent= 0;
- ref_pointer_array= 0;
- cond_count= 0;
}
void st_select_lex_node::init_select()
{
- order_list.elements= 0;
- order_list.first= 0;
- order_list.next= (byte**) &order_list.first;
- select_limit= HA_POS_ERROR;
- offset_limit= 0;
- select_n_having_items= 0;
- with_sum_func= 0;
- parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
void st_select_lex_unit::init_query()
{
st_select_lex_node::init_query();
linkage= GLOBAL_OPTIONS_TYPE;
- global_parameters= this;
+ global_parameters= first_select();
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
union_option= 0;
@@ -976,6 +966,7 @@ void st_select_lex_unit::init_query()
item= 0;
union_result= 0;
table= 0;
+ fake_select_lex= 0;
}
void st_select_lex::init_query()
@@ -988,7 +979,9 @@ void st_select_lex::init_query()
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
resolve_mode= NOMATTER_MODE;
- with_wild= 0;
+ cond_count= with_wild= 0;
+ ref_pointer_array= 0;
+ select_n_having_items= 0;
}
void st_select_lex::init_select()
@@ -997,7 +990,6 @@ void st_select_lex::init_select()
group_list.empty();
type= db= db1= table1= db2= table2= 0;
having= 0;
- group_list.empty();
use_index_ptr= ignore_index_ptr= 0;
table_join_options= 0;
in_sum_expr= with_wild= 0;
@@ -1010,6 +1002,13 @@ void st_select_lex::init_select()
ftfunc_list_alloc.empty();
ftfunc_list= &ftfunc_list_alloc;
linkage= UNSPECIFIED_TYPE;
+ order_list.elements= 0;
+ order_list.first= 0;
+ order_list.next= (byte**) &order_list.first;
+ select_limit= HA_POS_ERROR;
+ offset_limit= 0;
+ with_sum_func= 0;
+ parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
/*
@@ -1027,6 +1026,23 @@ void st_select_lex_node::include_down(st_select_lex_node *upper)
slave= 0;
}
+/*
+ include on level down (but do not link)
+
+ SYNOPSYS
+ st_select_lex_node::include_standalone()
+ upper - reference on node underr which this node should be included
+ ref - references on reference on this node
+*/
+void st_select_lex_node::include_standalone(st_select_lex_node *upper,
+ st_select_lex_node **ref)
+{
+ next= 0;
+ prev= ref;
+ master= upper;
+ slave= 0;
+}
+
/* include neighbour (on same level) */
void st_select_lex_node::include_neighbour(st_select_lex_node *before)
{
@@ -1108,33 +1124,6 @@ void st_select_lex_unit::exclude_level()
(*prev)= next;
}
-st_select_lex* st_select_lex_node::select_lex()
-{
- DBUG_ENTER("st_select_lex_node::select_lex (never should be called)");
- DBUG_ASSERT(0);
- DBUG_RETURN(0);
-}
-
-bool st_select_lex_node::add_item_to_list(THD *thd, Item *item)
-{
- return 1;
-}
-
-bool st_select_lex_node::add_group_to_list(THD *thd, Item *item, bool asc)
-{
- return 1;
-}
-
-bool st_select_lex_node::add_order_to_list(THD *thd, Item *item, bool asc)
-{
- return add_to_list(thd, order_list, item, asc);
-}
-
-bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func)
-{
- return 1;
-}
-
/*
st_select_lex_node::mark_as_dependent mark all st_select_lex struct from
this to 'last' as dependent
@@ -1148,31 +1137,26 @@ bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func)
*/
-void st_select_lex_node::mark_as_dependent(SELECT_LEX *last)
+void st_select_lex::mark_as_dependent(SELECT_LEX *last)
{
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
- for (SELECT_LEX_NODE *s= this;
+ for (SELECT_LEX *s= this;
s &&s != last;
s= s->outer_select())
if ( !s->dependent )
{
// Select is dependent of outer select
s->dependent= 1;
- if (s->linkage != GLOBAL_OPTIONS_TYPE)
- {
- //s is st_select_lex*
-
- s->master_unit()->dependent= 1;
- //Tables will be reopened many times
- for (TABLE_LIST *tbl=
- s->get_table_list();
- tbl;
- tbl= tbl->next)
- tbl->shared= 1;
- }
+ s->master_unit()->dependent= 1;
+ //Tables will be reopened many times
+ for (TABLE_LIST *tbl=
+ s->get_table_list();
+ tbl;
+ tbl= tbl->next)
+ tbl->shared= 1;
}
}
@@ -1190,10 +1174,49 @@ TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
List<String> *use_index,
List<String> *ignore_index,
LEX_STRING *option)
+ulong st_select_lex_node::get_table_join_options()
{
return 0;
}
-ulong st_select_lex_node::get_table_join_options() { return 0; }
+
+/*
+ prohibit using LIMIT clause
+*/
+bool st_select_lex::test_limit()
+{
+ if (select_limit != HA_POS_ERROR)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "LIMIT & IN/ALL/ANY/SOME subquery");
+ return(1);
+ }
+ // We need only 1 row to determinate existence
+ select_limit= 1;
+ // no sense in ORDER BY without LIMIT
+ order_list.empty();
+ return(0);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
@@ -1256,22 +1279,39 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first;
TABLE_LIST **new_table_list= *result, *aux;
SELECT_LEX *sl= (SELECT_LEX*)slave;
- for (; sl; sl= sl->next_select())
+
+ /*
+ iterate all inner selects + fake_select (if exists),
+ fake_select->next_select() always is 0
+ */
+ for (;
+ sl;
+ sl= (sl->next_select() ?
+ sl->next_select() :
+ (sl == fake_select_lex ?
+ 0 :
+ fake_select_lex)))
{
// check usage of ORDER BY in union
- if (sl->order_list.first && sl->next_select() && !sl->braces)
+ if (sl->order_list.first && sl->next_select() && !sl->braces &&
+ sl->linkage != GLOBAL_OPTIONS_TYPE)
{
net_printf(thd,ER_WRONG_USAGE,"UNION","ORDER BY");
return 1;
}
+
if (sl->linkage == DERIVED_TABLE_TYPE && !check_derived)
- continue;
+ goto end;
+
for (SELECT_LEX_UNIT *inner= sl->first_inner_unit();
inner;
inner= inner->next_unit())
+ {
if (inner->create_total_list_n_last_return(thd, lex,
&slave_list_last, 0))
return 1;
+ }
+
if ((aux= (TABLE_LIST*) sl->table_list.first))
{
TABLE_LIST *next;
@@ -1294,15 +1334,18 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
return 1;
}
*new_table_list= cursor;
+ cursor->table_list= aux; //to be able mark this table as shared
new_table_list= &cursor->next;
*new_table_list= 0; // end result list
}
else
- aux->shared= 1; // Mark that it's used twice
+ // Mark that it's used twice
+ cursor->table_list->shared= aux->shared= 1;
aux->table_list= cursor;
}
}
}
+end:
if (slave_list_first)
{
*new_table_list= slave_list_first;
@@ -1322,9 +1365,9 @@ st_select_lex* st_select_lex_unit::outer_select()
return (st_select_lex*) master;
}
-st_select_lex* st_select_lex::select_lex()
+bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
{
- return this;
+ return add_to_list(thd, order_list, item, asc);
}
bool st_select_lex::add_item_to_list(THD *thd, Item *item)
@@ -1394,17 +1437,17 @@ ulong st_select_lex::get_table_join_options()
return table_join_options;
}
-st_select_lex::st_select_lex(struct st_lex *lex)
+bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{
- select_number= ++lex->thd->select_number;
- init_query();
- init_select();
- include_neighbour(lex->current_select);
- include_global((st_select_lex_node**)&lex->all_selects_list);
- lex->current_select= this;
+ if (ref_pointer_array)
+ return 0;
+ return (ref_pointer_array=
+ (Item **)thd->alloc(sizeof(Item*) *
+ (item_list.elements +
+ select_n_having_items +
+ order_group_num)* 5)) == 0;
}
-
/*
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables in sql_parse.cc