Commit 7f896917 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0

into sanja.is.com.ua:/home/bell/mysql/bk/work-view-5.0
parents 4c605cec ed7b229a
...@@ -395,9 +395,9 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); ...@@ -395,9 +395,9 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2);
SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2) SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2)
abcdabc abcdabc
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2);
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index' ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substring_index'
select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2);
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index' ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substring_index'
select _latin1'B' between _latin1'a' and _latin1'c'; select _latin1'B' between _latin1'a' and _latin1'c';
_latin1'B' between _latin1'a' and _latin1'c' _latin1'B' between _latin1'a' and _latin1'c'
1 1
...@@ -638,7 +638,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo ...@@ -638,7 +638,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substring_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")`
SELECT lpad(12345, 5, "#"); SELECT lpad(12345, 5, "#");
lpad(12345, 5, "#") lpad(12345, 5, "#")
12345 12345
......
...@@ -1467,7 +1467,7 @@ v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` ...@@ -1467,7 +1467,7 @@ v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a`
alter algorithm=undefined view v1 as select * from t1 with check option; alter algorithm=undefined view v1 as select * from t1 with check option;
show create view v1; show create view v1;
View Create View View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH LOCAL CHECK OPTION v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH CASCADED CHECK OPTION
alter algorithm=merge view v1 as select * from t1 with cascaded check option; alter algorithm=merge view v1 as select * from t1 with cascaded check option;
show create view v1; show create view v1;
View Create View View Create View
...@@ -1517,3 +1517,114 @@ s1 ...@@ -1517,3 +1517,114 @@ s1
deallocate prepare stmt1; deallocate prepare stmt1;
drop view v2; drop view v2;
drop table t1, t2; drop table t1, t2;
create table t1 (t time);
create view v1 as select substring_index(t,':',2) as t from t1;
insert into t1 (t) values ('12:24:10');
select substring_index(t,':',2) from t1;
substring_index(t,':',2)
12:24
select substring_index(t,':',2) from v1;
substring_index(t,':',2)
12:24
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0 with local check option;
create view v2 as select * from v1 with cascaded check option;
insert into v2 values (0);
ERROR HY000: CHECK OPTION failed 'test.v2'
drop view v2, v1;
drop table t1;
create table t1 (s1 int);
create view v1 as select * from t1 where s1 < 5 with check option;
insert ignore into v1 values (6);
ERROR HY000: CHECK OPTION failed 'test.v1'
insert ignore into v1 values (6),(3);
Warnings:
Error 1369 CHECK OPTION failed 'test.v1'
select * from t1;
s1
3
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create trigger t1_bi before insert on t1 for each row set new.s1 = 500;
create view v1 as select * from t1 where s1 <> 127 with check option;
insert into v1 values (0);
ERROR HY000: CHECK OPTION failed 'test.v1'
select * from v1;
s1
select * from t1;
s1
drop trigger t1.t1_bi;
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0;
create view v2 as select * from v1 where s1 <> 1 with cascaded check option;
insert into v2 values (0);
ERROR HY000: CHECK OPTION failed 'test.v2'
select * from v2;
s1
select * from t1;
s1
drop view v2, v1;
drop table t1;
create table t1 (a int, b char(10));
create view v1 as select * from t1 where a != 0 with check option;
load data infile '../../std_data/loaddata3.dat' into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
ERROR HY000: CHECK OPTION failed 'test.v1'
select * from t1;
a b
1 row 1
2 row 2
select * from v1;
a b
1 row 1
2 row 2
delete from t1;
load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 3
Error 1369 CHECK OPTION failed 'test.v1'
Warning 1264 Out of range value adjusted for column 'a' at row 4
Error 1369 CHECK OPTION failed 'test.v1'
select * from t1;
a b
1 row 1
2 row 2
3 row 3
select * from v1;
a b
1 row 1
2 row 2
3 row 3
drop view v1;
drop table t1;
create table t1 (a text, b text);
create view v1 as select * from t1 where a <> 'Field A' with check option;
load data infile '../../std_data/loaddata2.dat' into table v1 fields terminated by ',' enclosed by '''';
ERROR HY000: CHECK OPTION failed 'test.v1'
select concat('|',a,'|'), concat('|',b,'|') from t1;
concat('|',a,'|') concat('|',b,'|')
select concat('|',a,'|'), concat('|',b,'|') from v1;
concat('|',a,'|') concat('|',b,'|')
delete from t1;
load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by '''';
Warnings:
Error 1369 CHECK OPTION failed 'test.v1'
Warning 1261 Row 2 doesn't contain data for all columns
select concat('|',a,'|'), concat('|',b,'|') from t1;
concat('|',a,'|') concat('|',b,'|')
|Field 1| |Field 2'
Field 3,'Field 4|
|Field 5' ,'Field 6| NULL
|Field 6| | 'Field 7'|
select concat('|',a,'|'), concat('|',b,'|') from v1;
concat('|',a,'|') concat('|',b,'|')
|Field 1| |Field 2'
Field 3,'Field 4|
|Field 5' ,'Field 6| NULL
|Field 6| | 'Field 7'|
drop view v1;
drop table t1;
...@@ -1460,3 +1460,97 @@ execute stmt1; ...@@ -1460,3 +1460,97 @@ execute stmt1;
deallocate prepare stmt1; deallocate prepare stmt1;
drop view v2; drop view v2;
drop table t1, t2; drop table t1, t2;
#
# test of substring_index with view
#
create table t1 (t time);
create view v1 as select substring_index(t,':',2) as t from t1;
insert into t1 (t) values ('12:24:10');
select substring_index(t,':',2) from t1;
select substring_index(t,':',2) from v1;
drop view v1;
drop table t1;
#
# test of cascaded check option for whiew without WHERE clause
#
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0 with local check option;
create view v2 as select * from v1 with cascaded check option;
-- error 1369
insert into v2 values (0);
drop view v2, v1;
drop table t1;
#
# inserting single value with check option failed always get error
#
create table t1 (s1 int);
create view v1 as select * from t1 where s1 < 5 with check option;
#single value
-- error 1369
insert ignore into v1 values (6);
#several values
insert ignore into v1 values (6),(3);
select * from t1;
drop view v1;
drop table t1;
#
# changing value by trigger and CHECK OPTION
#
create table t1 (s1 tinyint);
create trigger t1_bi before insert on t1 for each row set new.s1 = 500;
create view v1 as select * from t1 where s1 <> 127 with check option;
-- error 1369
insert into v1 values (0);
select * from v1;
select * from t1;
drop trigger t1.t1_bi;
drop view v1;
drop table t1;
#
# CASCADED should be used for all underlaying VIEWs
#
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0;
create view v2 as select * from v1 where s1 <> 1 with cascaded check option;
-- error 1369
insert into v2 values (0);
select * from v2;
select * from t1;
drop view v2, v1;
drop table t1;
#
# LOAD DATA with view and CHECK OPTION
#
# fixed length fields
create table t1 (a int, b char(10));
create view v1 as select * from t1 where a != 0 with check option;
-- error 1369
load data infile '../../std_data/loaddata3.dat' into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
select * from t1;
select * from v1;
delete from t1;
load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
select * from t1;
select * from v1;
drop view v1;
drop table t1;
# variable length fields
create table t1 (a text, b text);
create view v1 as select * from t1 where a <> 'Field A' with check option;
-- error 1369
load data infile '../../std_data/loaddata2.dat' into table v1 fields terminated by ',' enclosed by '''';
select concat('|',a,'|'), concat('|',b,'|') from t1;
select concat('|',a,'|'), concat('|',b,'|') from v1;
delete from t1;
load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by '''';
select concat('|',a,'|'), concat('|',b,'|') from t1;
select concat('|',a,'|'), concat('|',b,'|') from v1;
drop view v1;
drop table t1;
...@@ -218,7 +218,7 @@ public: ...@@ -218,7 +218,7 @@ public:
Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
const char *func_name() const { return "substr_index"; } const char *func_name() const { return "substring_index"; }
}; };
......
...@@ -2548,7 +2548,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -2548,7 +2548,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
thd->net.pkt_nr = net->pkt_nr; thd->net.pkt_nr = net->pkt_nr;
} }
if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0,
TL_WRITE)) TL_WRITE, 0))
thd->query_error = 1; thd->query_error = 1;
if (thd->cuted_fields) if (thd->cuted_fields)
{ {
......
...@@ -838,9 +838,10 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table, ...@@ -838,9 +838,10 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
bool eval_const_cond(COND *cond); bool eval_const_cond(COND *cond);
/* sql_load.cc */ /* sql_load.cc */
int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool local_file,thr_lock_type lock_type); bool local_file, thr_lock_type lock_type,
bool ignore_check_option_errors);
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 */
......
...@@ -2697,7 +2697,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds) ...@@ -2697,7 +2697,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds)
table->keys_in_use_for_query.subtract(map); table->keys_in_use_for_query.subtract(map);
} }
table->used_keys.intersect(table->keys_in_use_for_query); table->used_keys.intersect(table->keys_in_use_for_query);
if (table_list->ancestor && table_list->setup_ancestor(thd, conds)) if (table_list->ancestor &&
table_list->setup_ancestor(thd, conds,
table_list->effective_with_check))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (tablenr > MAX_TABLES) if (tablenr > MAX_TABLES)
......
...@@ -319,14 +319,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -319,14 +319,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
break; break;
} }
} }
if ((res= table_list->view_check_option(thd, ignore_err)) ==
VIEW_CHECK_SKIP)
continue;
else if (res == VIEW_CHECK_ERROR)
{
error= 1;
break;
}
/* /*
FIXME: Actually we should do this before FIXME: Actually we should do this before
...@@ -336,6 +328,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -336,6 +328,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
table->triggers->process_triggers(thd, TRG_EVENT_INSERT, table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_BEFORE); TRG_ACTION_BEFORE);
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
0 :
ignore_err))) ==
VIEW_CHECK_SKIP)
continue;
else if (res == VIEW_CHECK_ERROR)
{
error= 1;
break;
}
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED) if (lock_type == TL_WRITE_DELAYED)
{ {
......
...@@ -1616,6 +1616,7 @@ bool st_lex::can_use_merged() ...@@ -1616,6 +1616,7 @@ bool st_lex::can_use_merged()
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
case SQLCOM_REPLACE_SELECT: case SQLCOM_REPLACE_SELECT:
case SQLCOM_LOAD:
return TRUE; return TRUE;
default: default:
return FALSE; return FALSE;
......
...@@ -71,16 +71,19 @@ public: ...@@ -71,16 +71,19 @@ public:
void set_io_cache_arg(void* arg) { cache.arg = arg; } void set_io_cache_arg(void* arg) { cache.arg = arg; }
}; };
static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table, static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info, List<Item> &fields, READ_INFO &read_info,
ulong skip_lines); ulong skip_lines,
static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, bool ignore_check_option_errors);
static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info, List<Item> &fields, READ_INFO &read_info,
String &enclosed, ulong skip_lines); String &enclosed, ulong skip_lines,
bool ignore_check_option_errors);
int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool read_file_from_client,thr_lock_type lock_type) bool read_file_from_client,thr_lock_type lock_type,
bool ignore_check_option_errors)
{ {
char name[FN_REFLEN]; char name[FN_REFLEN];
File file; File file;
...@@ -88,6 +91,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -88,6 +91,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
int error; int error;
String *field_term=ex->field_term,*escaped=ex->escaped; String *field_term=ex->field_term,*escaped=ex->escaped;
String *enclosed=ex->enclosed; String *enclosed=ex->enclosed;
Item *unused_conds;
bool is_fifo=0; bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info; LOAD_FILE_INFO lf_info;
...@@ -117,8 +121,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -117,8 +121,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table_list->lock_type= lock_type; table_list->lock_type= lock_type;
if ((res= open_and_lock_tables(thd, table_list))) if ((res= open_and_lock_tables(thd, table_list)))
DBUG_RETURN(res); DBUG_RETURN(res);
/* TODO: add key check when we will support VIEWs in LOAD */ if (setup_tables(thd, table_list, &unused_conds))
if (!table_list->updatable) DBUG_RETURN(-1);
if (!table_list->updatable || check_key_in_view(thd, table_list))
{ {
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -294,11 +299,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -294,11 +299,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MODE_STRICT_ALL_TABLES))); MODE_STRICT_ALL_TABLES)));
if (!field_term->length() && !enclosed->length()) if (!field_term->length() && !enclosed->length())
error=read_fixed_length(thd,info,table,fields,read_info, error= read_fixed_length(thd, info, table_list, fields,read_info,
skip_lines); skip_lines, ignore_check_option_errors);
else else
error=read_sep_field(thd,info,table,fields,read_info,*enclosed, error= read_sep_field(thd, info, table_list, fields, read_info,
skip_lines); *enclosed, skip_lines,
ignore_check_option_errors);
if (table->file->end_bulk_insert()) if (table->file->end_bulk_insert())
error=1; /* purecov: inspected */ error=1; /* purecov: inspected */
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
...@@ -401,11 +407,13 @@ err: ...@@ -401,11 +407,13 @@ err:
****************************************************************************/ ****************************************************************************/
static int static int
read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields, read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
READ_INFO &read_info, ulong skip_lines) List<Item> &fields, READ_INFO &read_info, ulong skip_lines,
bool ignore_check_option_errors)
{ {
List_iterator_fast<Item> it(fields); List_iterator_fast<Item> it(fields);
Item_field *sql_field; Item_field *sql_field;
TABLE *table= table_list->table;
ulonglong id; ulonglong id;
bool no_trans_update; bool no_trans_update;
DBUG_ENTER("read_fixed_length"); DBUG_ENTER("read_fixed_length");
...@@ -472,6 +480,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields, ...@@ -472,6 +480,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER_WARN_TOO_MANY_RECORDS, ER_WARN_TOO_MANY_RECORDS,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
} }
switch(table_list->view_check_option(thd,
ignore_check_option_errors))
{
case VIEW_CHECK_SKIP:
read_info.next_line();
goto continue_loop;
case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
if (thd->killed || write_record(thd,table,&info)) if (thd->killed || write_record(thd,table,&info))
DBUG_RETURN(1); DBUG_RETURN(1);
thd->no_trans_update= no_trans_update; thd->no_trans_update= no_trans_update;
...@@ -496,6 +515,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields, ...@@ -496,6 +515,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
} }
thd->row_count++; thd->row_count++;
continue_loop:;
} }
if (id && !read_info.error) if (id && !read_info.error)
thd->insert_id(id); // For binary/update log thd->insert_id(id); // For binary/update log
...@@ -505,12 +525,14 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields, ...@@ -505,12 +525,14 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
static int static int
read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info, List<Item> &fields, READ_INFO &read_info,
String &enclosed, ulong skip_lines) String &enclosed, ulong skip_lines,
bool ignore_check_option_errors)
{ {
List_iterator_fast<Item> it(fields); List_iterator_fast<Item> it(fields);
Item_field *sql_field; Item_field *sql_field;
TABLE *table= table_list->table;
uint enclosed_length; uint enclosed_length;
ulonglong id; ulonglong id;
bool no_trans_update; bool no_trans_update;
...@@ -580,6 +602,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, ...@@ -580,6 +602,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
} }
} }
switch(table_list->view_check_option(thd,
ignore_check_option_errors))
{
case VIEW_CHECK_SKIP:
read_info.next_line();
goto continue_loop;
case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
if (thd->killed || write_record(thd, table, &info)) if (thd->killed || write_record(thd, table, &info))
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
...@@ -605,6 +639,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, ...@@ -605,6 +639,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
thd->row_count++; thd->row_count++;
continue_loop:;
} }
if (id && !read_info.error) if (id && !read_info.error)
thd->insert_id(id); // For binary/update log thd->insert_id(id); // For binary/update log
......
...@@ -3135,7 +3135,8 @@ unsent_create_error: ...@@ -3135,7 +3135,8 @@ unsent_create_error:
goto error; goto error;
} }
res= mysql_load(thd, lex->exchange, first_table, lex->field_list, res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
lex->duplicates, (bool) lex->local_file, lex->lock_option); lex->duplicates, (bool) lex->local_file,
lex->lock_option, lex->duplicates == DUP_IGNORE);
break; break;
} }
......
...@@ -7921,7 +7921,7 @@ check_option: ...@@ -7921,7 +7921,7 @@ check_option:
/* empty */ /* empty */
{ Lex->create_view_check= VIEW_CHECK_NONE; } { Lex->create_view_check= VIEW_CHECK_NONE; }
| WITH CHECK_SYM OPTION | WITH CHECK_SYM OPTION
{ Lex->create_view_check= VIEW_CHECK_LOCAL; } { Lex->create_view_check= VIEW_CHECK_CASCADED; }
| WITH CASCADED CHECK_SYM OPTION | WITH CASCADED CHECK_SYM OPTION
{ Lex->create_view_check= VIEW_CHECK_CASCADED; } { Lex->create_view_check= VIEW_CHECK_CASCADED; }
| WITH LOCAL_SYM CHECK_SYM OPTION | WITH LOCAL_SYM CHECK_SYM OPTION
......
...@@ -1497,8 +1497,10 @@ void st_table_list::set_ancestor() ...@@ -1497,8 +1497,10 @@ void st_table_list::set_ancestor()
SYNOPSIS SYNOPSIS
st_table_list::setup_ancestor() st_table_list::setup_ancestor()
thd - thread handler thd - thread handler
conds - condition of this JOIN conds - condition of this JOIN
check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
DESCRIPTION DESCRIPTION
It is: It is:
...@@ -1513,7 +1515,8 @@ void st_table_list::set_ancestor() ...@@ -1513,7 +1515,8 @@ void st_table_list::set_ancestor()
1 - error 1 - error
*/ */
bool st_table_list::setup_ancestor(THD *thd, Item **conds) bool st_table_list::setup_ancestor(THD *thd, Item **conds,
uint8 check_opt_type)
{ {
Item **transl; Item **transl;
SELECT_LEX *select= &view->select_lex; SELECT_LEX *select= &view->select_lex;
...@@ -1527,7 +1530,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1527,7 +1530,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
DBUG_ENTER("st_table_list::setup_ancestor"); DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor && if (ancestor->ancestor &&
ancestor->setup_ancestor(thd, conds)) ancestor->setup_ancestor(thd, conds,
(check_opt_type == VIEW_CHECK_CASCADED ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (field_translation) if (field_translation)
...@@ -1586,23 +1592,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1586,23 +1592,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
field_translation= transl; field_translation= transl;
/* TODO: sort this list? Use hash for big number of fields */ /* TODO: sort this list? Use hash for big number of fields */
if (where) if (where ||
(check_opt_type == VIEW_CHECK_CASCADED &&
ancestor->check_option))
{ {
Item_arena *arena= thd->current_arena, backup; Item_arena *arena= thd->current_arena, backup;
TABLE_LIST *tbl= this; TABLE_LIST *tbl= this;
if (arena->is_conventional()) if (arena->is_conventional())
arena= 0; // For easier test arena= 0; // For easier test
if (!where->fixed && where->fix_fields(thd, ancestor, &where)) if (where && !where->fixed && where->fix_fields(thd, ancestor, &where))
goto err; goto err;
if (arena) if (arena)
thd->set_n_backup_item_arena(arena, &backup); thd->set_n_backup_item_arena(arena, &backup);
if (effective_with_check) if (check_opt_type)
{ {
check_option= where->copy_andor_structure(thd); if (where)
if (effective_with_check == VIEW_CHECK_CASCADED) check_option= where->copy_andor_structure(thd);
if (check_opt_type == VIEW_CHECK_CASCADED)
{ {
check_option= and_conds(check_option, ancestor->check_option); check_option= and_conds(check_option, ancestor->check_option);
} }
...@@ -1612,7 +1621,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1612,7 +1621,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
check that it is not VIEW in which we insert with INSERT SELECT check that it is not VIEW in which we insert with INSERT SELECT
(in this case we can't add view WHERE condition to main SELECT_LEX) (in this case we can't add view WHERE condition to main SELECT_LEX)
*/ */
if (!no_where_clause) if (where && !no_where_clause)
{ {
/* Go up to join tree and try to find left join */ /* Go up to join tree and try to find left join */
for (; tbl; tbl= tbl->embedding) for (; tbl; tbl= tbl->embedding)
......
...@@ -283,7 +283,7 @@ typedef struct st_table_list ...@@ -283,7 +283,7 @@ typedef struct st_table_list
void calc_md5(char *buffer); void calc_md5(char *buffer);
void set_ancestor(); void set_ancestor();
int view_check_option(THD *thd, bool ignore_failure); int view_check_option(THD *thd, bool ignore_failure);
bool setup_ancestor(THD *thd, Item **conds); bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
bool placeholder() {return derived || view; } bool placeholder() {return derived || view; }
void print(THD *thd, String *str); void print(THD *thd, String *str);
inline st_table_list *next_independent() inline st_table_list *next_independent()
......
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