summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy58
1 files changed, 51 insertions, 7 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b3632c339c4..f073d4173ad 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1911,7 +1911,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
view_list_opt view_list view_select
trigger_tail sp_tail sf_tail event_tail
- udf_tail create_function_tail
+ udf_tail create_function_tail create_aggregate_function_tail
install uninstall partition_entry binlog_base64_event
normal_key_options normal_key_opts all_key_opt
spatial_key_options fulltext_key_options normal_key_opt
@@ -2638,8 +2638,16 @@ create:
event_tail
{ }
| create_or_replace definer FUNCTION_SYM
- { Lex->create_info.set($1); }
- sf_tail
+ {
+ Lex->create_info.set($1);
+ }
+ sf_tail_not_aggregate
+ { }
+ | create_or_replace definer AGGREGATE_SYM FUNCTION_SYM
+ {
+ Lex->create_info.set($1);
+ }
+ sf_tail_aggregate
{ }
| create_or_replace no_definer FUNCTION_SYM
{ Lex->create_info.set($1); }
@@ -2648,9 +2656,8 @@ create:
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM
{
Lex->create_info.set($1);
- Lex->udf.type= UDFTYPE_AGGREGATE;
}
- udf_tail
+ create_aggregate_function_tail
{ }
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
@@ -2677,11 +2684,36 @@ create:
{ }
;
+sf_tail_not_aggregate:
+ sf_tail
+ {
+ if (Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)
+ {
+ my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0), ""));
+ }
+ Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE);
+ }
+
+sf_tail_aggregate:
+ sf_tail
+ {
+ if (!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))
+ {
+ my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0), ""));
+ }
+ Lex->sphead->set_chistics_agg_type(GROUP_AGGREGATE);
+ }
+
create_function_tail:
- sf_tail { }
+ sf_tail_not_aggregate { }
| udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; }
;
+create_aggregate_function_tail:
+ sf_tail_aggregate
+ { }
+ | udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
+ ;
opt_sequence:
/* empty */ { }
| sequence_defs
@@ -4011,7 +4043,19 @@ sp_proc_stmt_fetch_head:
;
sp_proc_stmt_fetch:
- sp_proc_stmt_fetch_head sp_fetch_list { }
+ sp_proc_stmt_fetch_head sp_fetch_list { }
+ | FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
+ {
+ LEX *lex= Lex;
+ sp_head *sp= lex->sphead;
+ lex->sphead->m_flags|= sp_head::HAS_AGGREGATE_INSTR;
+ sp_instr_agg_cfetch *i=
+ new (thd->mem_root) sp_instr_agg_cfetch(sp->instructions(),
+ lex->spcont);
+ if (i == NULL ||
+ sp->add_instr(i))
+ MYSQL_YYABORT;
+ }
;
sp_proc_stmt_close: