diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-07-17 21:24:29 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-07-17 21:24:29 +0200 |
commit | 97e640b9ae83e07b444fceede6b0524256c7a3cc (patch) | |
tree | 8f48fbfaf88ea7895ce59fd3ac2fbe6184334387 /sql/sql_lex.cc | |
parent | 2f6a2494a5eb2cf3ab06fbedd2584eca85d90230 (diff) | |
parent | c7973615e723b13c6457b494b72be2fac35bfd18 (diff) | |
download | mariadb-git-97e640b9ae83e07b444fceede6b0524256c7a3cc.tar.gz |
5.5 merge
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1114723079d..fd18d2f6c52 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify @@ -1876,9 +1876,11 @@ void st_select_lex::init_query() cond_count= between_count= with_wild= 0; max_equal_elems= 0; ref_pointer_array= 0; + ref_pointer_array_size= 0; select_n_where_fields= 0; select_n_reserved= 0; select_n_having_items= 0; + n_sum_items= 0; n_child_sum_items= 0; subquery_in_having= explicit_limit= 0; is_item_list_lookup= 0; @@ -2239,6 +2241,11 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc) } +bool st_select_lex::add_gorder_to_list(THD *thd, Item *item, bool asc) +{ + return add_to_list(thd, gorder_list, item, asc); +} + bool st_select_lex::add_item_to_list(THD *thd, Item *item) { DBUG_ENTER("st_select_lex::add_item_to_list"); @@ -2309,11 +2316,6 @@ ulong st_select_lex::get_table_join_options() bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) { - DBUG_ENTER("st_select_lex::setup_ref_array"); - - if (ref_pointer_array) - DBUG_RETURN(0); - // find_order_in_list() may need some extra space, so multiply by two. order_group_num*= 2; @@ -2321,14 +2323,31 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) We have to create array in prepared statement memory if it is a prepared statement */ - ref_pointer_array= - (Item **)thd->stmt_arena->alloc(sizeof(Item*) * (n_child_sum_items + - item_list.elements + - select_n_reserved + - select_n_having_items + - select_n_where_fields + - order_group_num)*5); - DBUG_RETURN(ref_pointer_array == 0); + Query_arena *arena= thd->stmt_arena; + const uint n_elems= (n_sum_items + + n_child_sum_items + + item_list.elements + + select_n_reserved + + select_n_having_items + + select_n_where_fields + + order_group_num) * 5; + if (ref_pointer_array != NULL) + { + /* + We need to take 'n_sum_items' into account when allocating the array, + and this may actually increase during the optimization phase due to + MIN/MAX rewrite in Item_in_subselect::single_value_transformer. + In the usual case we can reuse the array from the prepare phase. + If we need a bigger array, we must allocate a new one. + */ + if (ref_pointer_array_size >= n_elems) + return false; + } + ref_pointer_array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems)); + if (ref_pointer_array != NULL) + ref_pointer_array_size= n_elems; + + return ref_pointer_array == NULL; } |