From 2c411a5dc3b7bb6a3b8c4c9017814c8fbadd8770 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 27 Dec 2016 01:53:22 +0530 Subject: MDEV-11297 Add support for LIMIT clause in GROUP_CONCAT Comments added, parser rules updated --- sql/item_sum.cc | 14 +++++-------- sql/item_sum.h | 4 ++++ sql/sql_yacc.yy | 64 ++++++++------------------------------------------------- 3 files changed, 17 insertions(+), 65 deletions(-) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 6b3e5252b44..126ab9d84f6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3218,7 +3218,7 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, bool distinct_arg, List *select_list, const SQL_I_List &order_list, String *separator_arg, bool limit_clause, - Item *rowLimit, Item *offsetLimit) + Item *row_limit_arg, Item *offset_limit_arg) :Item_sum(thd), tmp_table_param(0), separator(separator_arg), tree(0), unique_filter(NULL), table(0), order(0), context(context_arg), @@ -3227,8 +3227,8 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, row_count(0), distinct(distinct_arg), warning_for_row(FALSE), - force_copy_fields(0),row_limit(0), - offset_limit(0),limit_clause(limit_clause), + force_copy_fields(0),row_limit(NULL), + offset_limit(NULL),limit_clause(limit_clause), copy_offset_limit(0), copy_row_limit(0),original(0) { Item *item_select; @@ -3274,12 +3274,8 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, if (limit_clause) { - if (!(row_limit=(Item*) thd->alloc(sizeof(Item)))) - return; - row_limit= rowLimit; - if (!(offset_limit= (Item*)thd->alloc(sizeof(Item)))) - return; - offset_limit= offsetLimit; + row_limit= row_limit_arg; + offset_limit= offset_limit_arg; } } diff --git a/sql/item_sum.h b/sql/item_sum.h index 49cb9ee72da..d7822a03719 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1583,10 +1583,14 @@ class Item_func_group_concat : public Item_sum bool always_null; bool force_copy_fields; bool no_appended; + /** Limits the rows in the result */ Item *row_limit; + /** Skips a particular number of rows in from the result*/ Item *offset_limit; bool limit_clause; + /* copy of the offset limit */ ulonglong copy_offset_limit; + /*copy of the row limit */ ulonglong copy_row_limit; /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 445058dcc43..f4f64e57ff3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1844,7 +1844,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_escape sp_opt_default simple_ident_nospvar simple_ident_q - field_or_var limit_option glimit_option + field_or_var limit_option part_func_expr window_func_expr window_func @@ -10708,25 +10708,28 @@ glimit_clause_init: ; glimit_clause: - glimit_clause_init glimit_options{} + glimit_clause_init glimit_options + { + Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); + } ; glimit_options: - glimit_option + limit_option { SELECT_LEX *sel= Select; sel->select_limit= $1; sel->offset_limit= 0; sel->explicit_limit= 1; } - | glimit_option ',' glimit_option + | limit_option ',' limit_option { SELECT_LEX *sel= Select; sel->select_limit= $3; sel->offset_limit= $1; sel->explicit_limit= 1; } - | glimit_option OFFSET_SYM glimit_option + | limit_option OFFSET_SYM limit_option { SELECT_LEX *sel= Select; sel->select_limit= $1; @@ -10735,57 +10738,6 @@ glimit_options: } ; -glimit_option: - ident - { - Item_splocal *splocal; - LEX *lex= thd->lex; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - sp_variable *spv; - sp_pcontext *spc = lex->spcont; - if (spc && (spv = spc->find_variable($1, false))) - { - splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->sql_type(), - lip->get_tok_start() - lex->sphead->m_tmp_query, - lip->get_ptr() - lip->get_tok_start()); - if (splocal == NULL) - MYSQL_YYABORT; -#ifndef DBUG_OFF - splocal->m_sp= lex->sphead; -#endif - lex->safe_to_cache_query=0; - } - else - my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); - if (splocal->type() != Item::INT_ITEM) - my_yyabort_error((ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0))); - splocal->limit_clause_param= TRUE; - $$= splocal; - } - | param_marker - { - $1->limit_clause_param= TRUE; - } - | ULONGLONG_NUM - { - $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) - MYSQL_YYABORT; - } - | LONG_NUM - { - $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) - MYSQL_YYABORT; - } - | NUM - { - $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) - MYSQL_YYABORT; - } - ; in_sum_expr: opt_all -- cgit v1.2.1