Fixed behavior of LOAD DATA with subqueries in SET clause.

The idea is to use TABLE_LIST::lock_type for passing type of lock for
target table to mysql_load() instead of using LEX::lock_option 
(which were rewritten by first subselect in SET clause).

This should also fix potential problem with LOAD DATA in SP
(it is important for them to have right lock_type in the table
 list by the end of statement parsing).
parent f1691140
drop table if exists t1; drop table if exists t1, t2;
create table t1 (a date, b date, c date not null, d date); create table t1 (a date, b date, c date not null, d date);
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ','; load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
Warnings: Warnings:
...@@ -111,4 +111,12 @@ a b c ...@@ -111,4 +111,12 @@ a b c
5 6 5+6+123+6+NIL 5 6 5+6+123+6+NIL
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (a, @b); load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (a, @b);
ERROR HY000: Can't load value from file with fixed size rows to variable ERROR HY000: Can't load value from file with fixed size rows to variable
drop table t1; create table t2 (num int primary key, str varchar(10));
insert into t2 values (10,'Ten'), (15,'Fifteen');
truncate table t1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (@dummy,@n) set a= @n, c= (select str from t2 where num=@n);
select * from t1;
a b c
10 NULL Ten
15 NULL Fifteen
drop table t1, t2;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1, t2;
--enable_warnings --enable_warnings
create table t1 (a date, b date, c date not null, d date); create table t1 (a date, b date, c date not null, d date);
...@@ -64,4 +64,13 @@ select * from t1; ...@@ -64,4 +64,13 @@ select * from t1;
# and this should bark # and this should bark
--error 1409 --error 1409
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (a, @b); load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (a, @b);
drop table t1;
# Now let us test LOAD DATA with subselect
create table t2 (num int primary key, str varchar(10));
insert into t2 values (10,'Ten'), (15,'Fifteen');
truncate table t1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (@dummy,@n) set a= @n, c= (select str from t2 where num=@n);
select * from t1;
# cleanup
drop table t1, t2;
...@@ -2713,7 +2713,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -2713,7 +2713,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
update it inside mysql_load(). update it inside mysql_load().
*/ */
if (mysql_load(thd, &ex, &tables, field_list, set_fields, set_fields, if (mysql_load(thd, &ex, &tables, field_list, set_fields, set_fields,
handle_dup, ignore, net != 0, TL_WRITE)) handle_dup, ignore, net != 0))
thd->query_error= 1; thd->query_error= 1;
if (thd->cuted_fields) if (thd->cuted_fields)
{ {
......
...@@ -945,7 +945,7 @@ bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, ...@@ -945,7 +945,7 @@ bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields, List<Item> &fields_vars, List<Item> &set_fields,
List<Item> &set_values_list, List<Item> &set_values_list,
enum enum_duplicates handle_duplicates, bool ignore, enum enum_duplicates handle_duplicates, bool ignore,
bool local_file, thr_lock_type lock_type); bool local_file);
int write_record(THD *thd, TABLE *table, COPY_INFO *info); int write_record(THD *thd, TABLE *table, COPY_INFO *info);
/* sql_manager.cc */ /* sql_manager.cc */
......
...@@ -99,7 +99,6 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ...@@ -99,7 +99,6 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
replace row if we will meet duplicates. replace row if we will meet duplicates.
ignore - - indicates whenever we should ignore duplicates ignore - - indicates whenever we should ignore duplicates
read_file_from_client - is this LOAD DATA LOCAL ? read_file_from_client - is this LOAD DATA LOCAL ?
lock_type - what type of concurrency do we allow then we are inserting data
RETURN VALUES RETURN VALUES
TRUE - error / FALSE - success TRUE - error / FALSE - success
...@@ -109,7 +108,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -109,7 +108,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields, List<Item> &fields_vars, List<Item> &set_fields,
List<Item> &set_values, List<Item> &set_values,
enum enum_duplicates handle_duplicates, bool ignore, enum enum_duplicates handle_duplicates, bool ignore,
bool read_file_from_client, thr_lock_type lock_type) bool read_file_from_client)
{ {
char name[FN_REFLEN]; char name[FN_REFLEN];
File file; File file;
...@@ -143,7 +142,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -143,7 +142,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MYF(0)); MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
table_list->lock_type= lock_type;
if (open_and_lock_tables(thd, table_list)) if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (setup_tables(thd, table_list, &unused_conds, if (setup_tables(thd, table_list, &unused_conds,
......
...@@ -3355,7 +3355,7 @@ mysql_execute_command(THD *thd) ...@@ -3355,7 +3355,7 @@ mysql_execute_command(THD *thd)
res= mysql_load(thd, lex->exchange, first_table, lex->field_list, res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
lex->update_list, lex->value_list, lex->duplicates, lex->update_list, lex->value_list, lex->duplicates,
lex->ignore, (bool) lex->local_file, lex->lock_option); lex->ignore, (bool) lex->local_file);
break; break;
} }
......
...@@ -6437,16 +6437,20 @@ load_data: ...@@ -6437,16 +6437,20 @@ load_data:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->fname_end= lex->ptr; lex->fname_end= lex->ptr;
lex->field_list.empty();
lex->update_list.empty();
lex->value_list.empty();
}
TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec
{
if (!Select->add_table_to_list(YYTHD, $10, NULL, TL_OPTION_UPDATING))
YYABORT;
} }
TABLE_SYM table_ident
{
LEX *lex=Lex;
if (!Select->add_table_to_list(YYTHD, $10, NULL, TL_OPTION_UPDATING,
lex->lock_option))
YYABORT;
lex->field_list.empty();
lex->update_list.empty();
lex->value_list.empty();
}
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
{}
| |
FROM MASTER_SYM FROM MASTER_SYM
{ {
......
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