diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 9bea0fe0d4c..642f1aedd78 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -460,4 +460,17 @@ end| call bug3294()| ERROR 42S02: Unknown table 't5' drop procedure bug3294| +drop procedure if exists bug6807| +create procedure bug6807() +begin +declare id int; +set id = connection_id(); +kill query id; +select 'Not reached'; +end| +call bug6807()| +ERROR 70100: Query execution was interrupted +call bug6807()| +ERROR 70100: Query execution was interrupted +drop procedure bug6807| drop table t1| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index c04f8e6f9e9..c24f9df16be 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -632,6 +632,28 @@ end| call bug3294()| drop procedure bug3294| +# +# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY +# +--disable_warnings +drop procedure if exists bug6807| +--enable_warnings +create procedure bug6807() +begin + declare id int; + + set id = connection_id(); + kill query id; + select 'Not reached'; +end| + +--error 1317 +call bug6807()| +--error 1317 +call bug6807()| + +drop procedure bug6807| + drop table t1| diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 605204fe35d..ce39a846fda 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -650,7 +650,6 @@ typedef struct st_lex char *help_arg; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ - time_t purge_time; /* For PURGE MASTER LOGS BEFORE */ char* x509_subject,*x509_issuer,*ssl_cipher; char* found_colon; /* For multi queries - next query */ String *wild; @@ -694,7 +693,7 @@ typedef struct st_lex HA_CREATE_INFO create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; - ulong thread_id,type; + ulong type; enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option, multi_lock_option; enum SSL_type ssl_type; /* defined in violite.h */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fce8d294456..50d413ade38 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2327,10 +2327,24 @@ mysql_execute_command(THD *thd) } case SQLCOM_PURGE_BEFORE: { + Item *it; + if (check_global_access(thd, SUPER_ACL)) goto error; /* PURGE MASTER LOGS BEFORE 'data' */ - res = purge_master_logs_before_date(thd, lex->purge_time); + it= (Item *)lex->value_list.head(); + if (it->check_cols(1) || it->fix_fields(lex->thd, 0, &it)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); + goto error; + } + it= new Item_func_unix_timestamp(it); + /* + it is OK only emulate fix_fieds, because we need only + value of constant + */ + it->quick_fix_field(); + res = purge_master_logs_before_date(thd, (ulong)it->val_int()); break; } #endif @@ -3505,8 +3519,18 @@ create_error: break; } case SQLCOM_KILL: - kill_one_thread(thd,lex->thread_id, lex->type & ONLY_KILL_QUERY); + { + Item *it= (Item *)lex->value_list.head(); + + if (it->fix_fields(lex->thd, 0, &it) || it->check_cols(1)) + { + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), + MYF(0)); + goto error; + } + kill_one_thread(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY); break; + } #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: if ((thd->priv_user && diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dd9cd4af0f3..2316145ac65 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6280,19 +6280,10 @@ purge_option: } | BEFORE_SYM expr { - if ($2->check_cols(1) || $2->fix_fields(Lex->thd, 0, &$2)) - { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); - YYABORT; - } - Item *tmp= new Item_func_unix_timestamp($2); - /* - it is OK only emulate fix_fieds, because we need only - value of constant - */ - tmp->quick_fix_field(); - Lex->sql_command = SQLCOM_PURGE_BEFORE; - Lex->purge_time= (ulong) tmp->val_int(); + LEX *lex= Lex; + lex->value_list.empty(); + lex->value_list.push_front($2); + lex->sql_command= SQLCOM_PURGE_BEFORE; } ; @@ -6302,14 +6293,9 @@ kill: KILL_SYM kill_option expr { LEX *lex=Lex; - if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) - { - my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), - MYF(0)); - YYABORT; - } - lex->sql_command=SQLCOM_KILL; - lex->thread_id= (ulong) $3->val_int(); + lex->value_list.empty(); + lex->value_list.push_front($3); + lex->sql_command= SQLCOM_KILL; }; kill_option: