mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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 sql/item_strfunc.h: Auto merged sql/table.h: Auto merged
This commit is contained in:
@ -395,9 +395,9 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2);
|
||||
SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2)
|
||||
abcdabc
|
||||
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);
|
||||
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';
|
||||
_latin1'B' between _latin1'a' and _latin1'c'
|
||||
1
|
||||
@ -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
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
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, "#");
|
||||
lpad(12345, 5, "#")
|
||||
12345
|
||||
|
@ -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;
|
||||
show create view v1;
|
||||
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;
|
||||
show create view v1;
|
||||
View Create View
|
||||
@ -1517,3 +1517,114 @@ s1
|
||||
deallocate prepare stmt1;
|
||||
drop view v2;
|
||||
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;
|
||||
deallocate prepare stmt1;
|
||||
drop view v2;
|
||||
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:
|
||||
Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
|
||||
String *val_str(String *);
|
||||
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,
|
||||
thd->net.pkt_nr = net->pkt_nr;
|
||||
}
|
||||
if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0,
|
||||
TL_WRITE))
|
||||
TL_WRITE, 0))
|
||||
thd->query_error = 1;
|
||||
if (thd->cuted_fields)
|
||||
{
|
||||
|
@ -840,7 +840,8 @@ bool eval_const_cond(COND *cond);
|
||||
/* sql_load.cc */
|
||||
int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
|
||||
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);
|
||||
|
||||
/* sql_manager.cc */
|
||||
|
@ -2697,7 +2697,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds)
|
||||
table->keys_in_use_for_query.subtract(map);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (tablenr > MAX_TABLES)
|
||||
|
@ -319,14 +319,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
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
|
||||
@ -336,6 +328,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
|
||||
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
|
||||
if (lock_type == TL_WRITE_DELAYED)
|
||||
{
|
||||
|
@ -1616,6 +1616,7 @@ bool st_lex::can_use_merged()
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
case SQLCOM_REPLACE:
|
||||
case SQLCOM_REPLACE_SELECT:
|
||||
case SQLCOM_LOAD:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
|
@ -71,16 +71,19 @@ public:
|
||||
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,
|
||||
ulong skip_lines);
|
||||
static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
|
||||
ulong skip_lines,
|
||||
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,
|
||||
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,
|
||||
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];
|
||||
File file;
|
||||
@ -88,6 +91,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
int error;
|
||||
String *field_term=ex->field_term,*escaped=ex->escaped;
|
||||
String *enclosed=ex->enclosed;
|
||||
Item *unused_conds;
|
||||
bool is_fifo=0;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
LOAD_FILE_INFO lf_info;
|
||||
@ -117,8 +121,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
table_list->lock_type= lock_type;
|
||||
if ((res= open_and_lock_tables(thd, table_list)))
|
||||
DBUG_RETURN(res);
|
||||
/* TODO: add key check when we will support VIEWs in LOAD */
|
||||
if (!table_list->updatable)
|
||||
if (setup_tables(thd, table_list, &unused_conds))
|
||||
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");
|
||||
DBUG_RETURN(-1);
|
||||
@ -294,11 +299,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
MODE_STRICT_ALL_TABLES)));
|
||||
|
||||
if (!field_term->length() && !enclosed->length())
|
||||
error=read_fixed_length(thd,info,table,fields,read_info,
|
||||
skip_lines);
|
||||
error= read_fixed_length(thd, info, table_list, fields,read_info,
|
||||
skip_lines, ignore_check_option_errors);
|
||||
else
|
||||
error=read_sep_field(thd,info,table,fields,read_info,*enclosed,
|
||||
skip_lines);
|
||||
error= read_sep_field(thd, info, table_list, fields, read_info,
|
||||
*enclosed, skip_lines,
|
||||
ignore_check_option_errors);
|
||||
if (table->file->end_bulk_insert())
|
||||
error=1; /* purecov: inspected */
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
@ -401,11 +407,13 @@ err:
|
||||
****************************************************************************/
|
||||
|
||||
static int
|
||||
read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
|
||||
READ_INFO &read_info, ulong skip_lines)
|
||||
read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
||||
List<Item> &fields, READ_INFO &read_info, ulong skip_lines,
|
||||
bool ignore_check_option_errors)
|
||||
{
|
||||
List_iterator_fast<Item> it(fields);
|
||||
Item_field *sql_field;
|
||||
TABLE *table= table_list->table;
|
||||
ulonglong id;
|
||||
bool no_trans_update;
|
||||
DBUG_ENTER("read_fixed_length");
|
||||
@ -472,6 +480,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
|
||||
ER_WARN_TOO_MANY_RECORDS,
|
||||
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))
|
||||
DBUG_RETURN(1);
|
||||
thd->no_trans_update= no_trans_update;
|
||||
@ -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);
|
||||
}
|
||||
thd->row_count++;
|
||||
continue_loop:;
|
||||
}
|
||||
if (id && !read_info.error)
|
||||
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,
|
||||
|
||||
|
||||
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,
|
||||
String &enclosed, ulong skip_lines)
|
||||
String &enclosed, ulong skip_lines,
|
||||
bool ignore_check_option_errors)
|
||||
{
|
||||
List_iterator_fast<Item> it(fields);
|
||||
Item_field *sql_field;
|
||||
TABLE *table= table_list->table;
|
||||
uint enclosed_length;
|
||||
ulonglong id;
|
||||
bool no_trans_update;
|
||||
@ -580,6 +602,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
|
||||
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))
|
||||
DBUG_RETURN(1);
|
||||
/*
|
||||
@ -605,6 +639,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->row_count++;
|
||||
continue_loop:;
|
||||
}
|
||||
if (id && !read_info.error)
|
||||
thd->insert_id(id); // For binary/update log
|
||||
|
@ -3135,7 +3135,8 @@ unsent_create_error:
|
||||
goto error;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -7921,7 +7921,7 @@ check_option:
|
||||
/* empty */
|
||||
{ Lex->create_view_check= VIEW_CHECK_NONE; }
|
||||
| WITH CHECK_SYM OPTION
|
||||
{ Lex->create_view_check= VIEW_CHECK_LOCAL; }
|
||||
{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
|
||||
| WITH CASCADED CHECK_SYM OPTION
|
||||
{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
|
||||
| WITH LOCAL_SYM CHECK_SYM OPTION
|
||||
|
23
sql/table.cc
23
sql/table.cc
@ -1499,6 +1499,8 @@ void st_table_list::set_ancestor()
|
||||
st_table_list::setup_ancestor()
|
||||
thd - thread handler
|
||||
conds - condition of this JOIN
|
||||
check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
|
||||
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
|
||||
|
||||
DESCRIPTION
|
||||
It is:
|
||||
@ -1513,7 +1515,8 @@ void st_table_list::set_ancestor()
|
||||
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;
|
||||
SELECT_LEX *select= &view->select_lex;
|
||||
@ -1527,7 +1530,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
|
||||
DBUG_ENTER("st_table_list::setup_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);
|
||||
|
||||
if (field_translation)
|
||||
@ -1586,23 +1592,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
|
||||
field_translation= transl;
|
||||
/* 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;
|
||||
TABLE_LIST *tbl= this;
|
||||
if (arena->is_conventional())
|
||||
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;
|
||||
|
||||
if (arena)
|
||||
thd->set_n_backup_item_arena(arena, &backup);
|
||||
|
||||
if (effective_with_check)
|
||||
if (check_opt_type)
|
||||
{
|
||||
if (where)
|
||||
check_option= where->copy_andor_structure(thd);
|
||||
if (effective_with_check == VIEW_CHECK_CASCADED)
|
||||
if (check_opt_type == VIEW_CHECK_CASCADED)
|
||||
{
|
||||
check_option= and_conds(check_option, ancestor->check_option);
|
||||
}
|
||||
@ -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
|
||||
(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 */
|
||||
for (; tbl; tbl= tbl->embedding)
|
||||
|
@ -283,7 +283,7 @@ typedef struct st_table_list
|
||||
void calc_md5(char *buffer);
|
||||
void set_ancestor();
|
||||
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; }
|
||||
void print(THD *thd, String *str);
|
||||
inline st_table_list *next_independent()
|
||||
|
Reference in New Issue
Block a user