Commit cd01f7cd authored by unknown's avatar unknown

Fixed error handling to be able do not interrupt update (907) (SCRUM)

fixed bug of current select pointer in subselect execution
fixed layuot


mysql-test/r/subselect.result:
  test of update with IGNORE option and error in subselect
mysql-test/t/subselect.test:
  test of update with IGNORE option and error in subselect
sql/item_subselect.cc:
  fixed bug of current select pointer
sql/mysqld.cc:
  error converting to warnings if hd->lex.current_select->no_error id true
  layout fixed
sql/sql_lex.cc:
  initialization
sql/sql_lex.h:
  flag which force converting errors to warnings
sql/sql_select.cc:
  switch on error convering to warnings in select executing if IGNORE option present
parent 3eaf8865
......@@ -1151,3 +1151,16 @@ INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
REF_ID
DROP TABLE t1;
create table t1 (a int, b int);
create table t2 (a int, b int);
insert into t1 values (1,0), (2,0), (3,0);
insert into t2 values (1,1), (2,1), (3,1), (2,2);
update ignore t1 set b=(select b from t2 where t1.a=t2.a);
Warnings:
Error 1240 Subselect returns more than 1 record
select * from t1;
a b
1 1
2 NULL
3 1
drop table t1, t2;
......@@ -732,3 +732,17 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
DROP TABLE t1;
#
# uninterruptable update
#
create table t1 (a int, b int);
create table t2 (a int, b int);
insert into t1 values (1,0), (2,0), (3,0);
insert into t2 values (1,1), (2,1), (3,1), (2,2);
update ignore t1 set b=(select b from t2 where t1.a=t2.a);
select * from t1;
drop table t1, t2;
......@@ -824,6 +824,8 @@ int subselect_single_select_engine::exec()
{
DBUG_ENTER("subselect_single_select_engine::exec");
char const *save_where= join->thd->where;
SELECT_LEX_NODE *save_select= join->thd->lex.current_select;
join->thd->lex.current_select= select_lex;
if (!optimized)
{
optimized=1;
......@@ -831,6 +833,7 @@ int subselect_single_select_engine::exec()
{
join->thd->where= save_where;
executed= 1;
join->thd->lex.current_select= save_select;
DBUG_RETURN(join->error?join->error:1);
}
}
......@@ -839,6 +842,7 @@ int subselect_single_select_engine::exec()
if (join->reinit())
{
join->thd->where= save_where;
join->thd->lex.current_select= save_select;
DBUG_RETURN(1);
}
item->reset();
......@@ -846,15 +850,14 @@ int subselect_single_select_engine::exec()
}
if (!executed)
{
SELECT_LEX_NODE *save_select= join->thd->lex.current_select;
join->thd->lex.current_select= select_lex;
join->exec();
join->thd->lex.current_select= save_select;
executed= 1;
join->thd->where= save_where;
join->thd->lex.current_select= save_select;
DBUG_RETURN(join->error||thd->is_fatal_error);
}
join->thd->where= save_where;
join->thd->lex.current_select= save_select;
DBUG_RETURN(0);
}
......
......@@ -1818,15 +1818,23 @@ extern "C" int my_message_sql(uint error, const char *str,
{
THD *thd;
DBUG_ENTER("my_message_sql");
DBUG_PRINT("error",("Message: '%s'",str));
if ((thd=current_thd))
DBUG_PRINT("error", ("Message: '%s'", str));
if ((thd= current_thd))
{
NET *net= &thd->net;
net->report_error= 1;
if (!net->last_error[0]) // Return only first message
if (thd->lex.current_select->no_error && !thd->is_fatal_error)
{
strmake(net->last_error,str,sizeof(net->last_error)-1);
net->last_errno=error ? error : ER_UNKNOWN_ERROR;
DBUG_PRINT("error", ("above error converted to warning"));
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
}
else
{
NET *net= &thd->net;
net->report_error= 1;
if (!net->last_error[0]) // Return only first message
{
strmake(net->last_error, str, sizeof(net->last_error)-1);
net->last_errno= error ? error : ER_UNKNOWN_ERROR;
}
}
}
else
......
......@@ -122,6 +122,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
lex->sql_command=SQLCOM_END;
lex->duplicates= DUP_ERROR;
return lex;
}
......@@ -965,7 +966,7 @@ void st_select_lex_node::init_query()
{
options= 0;
linkage= UNSPECIFIED_TYPE;
no_table_names_allowed= uncacheable= dependent= 0;
no_error= no_table_names_allowed= uncacheable= dependent= 0;
ref_pointer_array= 0;
}
......
......@@ -212,6 +212,7 @@ class st_select_lex_node {
bool dependent; /* dependent from outer select subselect */
bool uncacheable; /* result of this query can't be cached */
bool no_table_names_allowed; /* used for global order by */
bool no_error; /* suppress error message (convert it to warnings) */
static void *operator new(size_t size)
{
......
......@@ -436,6 +436,9 @@ JOIN::optimize()
DBUG_RETURN(0);
optimized= 1;
// Ignore errors of execution if option IGNORE present
if (thd->lex.duplicates == DUP_IGNORE)
thd->lex.current_select->no_error= 1;
#ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */
if (having && !group_list && !sum_func_count)
......
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