Commit 4db726c0 authored by Chaithra Gopalareddy's avatar Chaithra Gopalareddy

Bug#16347426:ASSERTION FAILED: (SELECT_INSERT &&

             !TABLES->NEXT_NAME_RESOLUTION_TABLE) || !TAB
      
Problem:
The context info of select query gets corrupted when a query
with group_concat having order by is present in an order by
clause of the select query. As a result, server crashes with
an assert.
      
Analysis:
While parsing order by for group_concat, it is presumed that
it is always present before the actual order by for the
select query.
As a result, parser uses select->order_list to populate the
order by items of group_concat and creates a select->gorder_list
to which select->order_list is copied onto. Once this is done,
it empties the select->order_list.
In the case presented in the bugpage, as order by is already
parsed when group_concat's order by is encountered, parser
presumes that it is the second order by in the select query
and creates fake_lex_unit which results in the change of
context info.
      
Solution:
Make group_concat's order by parsing independent of the select
parent 84b942d1
...@@ -2960,11 +2960,12 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), ...@@ -2960,11 +2960,12 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
Item_func_group_concat:: Item_func_group_concat::
Item_func_group_concat(Name_resolution_context *context_arg, Item_func_group_concat(Name_resolution_context *context_arg,
bool distinct_arg, List<Item> *select_list, bool distinct_arg, List<Item> *select_list,
SQL_I_List<ORDER> *order_list, String *separator_arg) const SQL_I_List<ORDER> &order_list,
String *separator_arg)
:tmp_table_param(0), warning(0), :tmp_table_param(0), warning(0),
separator(separator_arg), tree(0), unique_filter(NULL), table(0), separator(separator_arg), tree(0), unique_filter(NULL), table(0),
order(0), context(context_arg), order(0), context(context_arg),
arg_count_order(order_list ? order_list->elements : 0), arg_count_order(order_list.elements),
arg_count_field(select_list->elements), arg_count_field(select_list->elements),
count_cut_values(0), count_cut_values(0),
distinct(distinct_arg), distinct(distinct_arg),
...@@ -3004,7 +3005,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, ...@@ -3004,7 +3005,7 @@ Item_func_group_concat(Name_resolution_context *context_arg,
if (arg_count_order) if (arg_count_order)
{ {
ORDER **order_ptr= order; ORDER **order_ptr= order;
for (ORDER *order_item= order_list->first; for (ORDER *order_item= order_list.first;
order_item != NULL; order_item != NULL;
order_item= order_item->next) order_item= order_item->next)
{ {
......
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights
* reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -1222,7 +1223,7 @@ class Item_func_group_concat : public Item_sum ...@@ -1222,7 +1223,7 @@ class Item_func_group_concat : public Item_sum
public: public:
Item_func_group_concat(Name_resolution_context *context_arg, Item_func_group_concat(Name_resolution_context *context_arg,
bool is_distinct, List<Item> *is_select, bool is_distinct, List<Item> *is_select,
SQL_I_List<ORDER> *is_order, String *is_separator); const SQL_I_List<ORDER> &is_order, String *is_separator);
Item_func_group_concat(THD *thd, Item_func_group_concat *item); Item_func_group_concat(THD *thd, Item_func_group_concat *item);
~Item_func_group_concat(); ~Item_func_group_concat();
......
/* /*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -2427,6 +2427,11 @@ inline bool add_order_to_list(THD *thd, Item *item, bool asc) ...@@ -2427,6 +2427,11 @@ inline bool add_order_to_list(THD *thd, Item *item, bool asc)
return thd->lex->current_select->add_order_to_list(thd, item, asc); return thd->lex->current_select->add_order_to_list(thd, item, asc);
} }
inline bool add_gorder_to_list(THD *thd, Item *item, bool asc)
{
return thd->lex->current_select->add_gorder_to_list(thd, item, asc);
}
inline bool add_group_to_list(THD *thd, Item *item, bool asc) inline bool add_group_to_list(THD *thd, Item *item, bool asc)
{ {
return thd->lex->current_select->add_group_to_list(thd, item, asc); return thd->lex->current_select->add_group_to_list(thd, item, asc);
......
/* /*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2013 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -1920,6 +1920,11 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc) ...@@ -1920,6 +1920,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) bool st_select_lex::add_item_to_list(THD *thd, Item *item)
{ {
DBUG_ENTER("st_select_lex::add_item_to_list"); DBUG_ENTER("st_select_lex::add_item_to_list");
......
/* /*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -628,7 +628,7 @@ public: ...@@ -628,7 +628,7 @@ public:
const char *type; /* type of select for EXPLAIN */ const char *type; /* type of select for EXPLAIN */
SQL_I_List<ORDER> order_list; /* ORDER clause */ SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> *gorder_list; SQL_I_List<ORDER> gorder_list;
Item *select_limit, *offset_limit; /* LIMIT clause parameters */ Item *select_limit, *offset_limit; /* LIMIT clause parameters */
// Arrays of pointers to top elements of all_fields list // Arrays of pointers to top elements of all_fields list
Item **ref_pointer_array; Item **ref_pointer_array;
...@@ -763,6 +763,7 @@ public: ...@@ -763,6 +763,7 @@ public:
bool add_group_to_list(THD *thd, Item *item, bool asc); bool add_group_to_list(THD *thd, Item *item, bool asc);
bool add_ftfunc_to_list(Item_func_match *func); bool add_ftfunc_to_list(Item_func_match *func);
bool add_order_to_list(THD *thd, Item *item, bool asc); bool add_order_to_list(THD *thd, Item *item, bool asc);
bool add_gorder_to_list(THD *thd, Item *item, bool asc);
TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table, TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table,
LEX_STRING *alias, LEX_STRING *alias,
ulong table_options, ulong table_options,
......
/* /*
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -8334,6 +8334,7 @@ sum_expr: ...@@ -8334,6 +8334,7 @@ sum_expr:
if ($$ == NULL) if ($$ == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
$5->empty(); $5->empty();
sel->gorder_list.empty();
} }
; ;
...@@ -8403,18 +8404,27 @@ opt_gconcat_separator: ...@@ -8403,18 +8404,27 @@ opt_gconcat_separator:
opt_gorder_clause: opt_gorder_clause:
/* empty */ /* empty */
| ORDER_SYM BY
{ {
Select->gorder_list = NULL; LEX *lex= Lex;
} SELECT_LEX *sel= lex->current_select;
| order_clause if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
sel->olap != UNSPECIFIED_OLAP_TYPE &&
(sel->linkage != UNION_TYPE || sel->braces))
{ {
SELECT_LEX *select= Select; my_error(ER_WRONG_USAGE, MYF(0),
select->gorder_list= new (YYTHD->mem_root) "CUBE/ROLLUP", "ORDER BY");
SQL_I_List<ORDER>(select->order_list);
if (select->gorder_list == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
select->order_list.empty();
} }
}
gorder_list;
;
gorder_list:
gorder_list ',' order_ident order_dir
{ if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
| order_ident order_dir
{ if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
; ;
in_sum_expr: in_sum_expr:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment