From bd2c119176e7dded04b2251d20a31d1e63512744 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Fri, 3 Sep 2004 15:18:40 +0300 Subject: [PATCH 1/4] CHECK OPTIONs added (WL#1983) --- include/mysqld_error.h | 4 +- mysql-test/r/view.result | 77 ++++++++++++++++++++++++++++++- mysql-test/t/view.test | 70 +++++++++++++++++++++++++++- sql/share/czech/errmsg.txt | 2 + sql/share/danish/errmsg.txt | 2 + sql/share/dutch/errmsg.txt | 2 + sql/share/english/errmsg.txt | 2 + sql/share/estonian/errmsg.txt | 2 + sql/share/french/errmsg.txt | 2 + sql/share/german/errmsg.txt | 2 + sql/share/greek/errmsg.txt | 2 + sql/share/hungarian/errmsg.txt | 2 + sql/share/italian/errmsg.txt | 2 + sql/share/japanese/errmsg.txt | 2 + sql/share/korean/errmsg.txt | 2 + sql/share/norwegian-ny/errmsg.txt | 2 + sql/share/norwegian/errmsg.txt | 2 + sql/share/polish/errmsg.txt | 2 + sql/share/portuguese/errmsg.txt | 2 + sql/share/romanian/errmsg.txt | 2 + sql/share/russian/errmsg.txt | 2 + sql/share/serbian/errmsg.txt | 2 + sql/share/slovak/errmsg.txt | 2 + sql/share/spanish/errmsg.txt | 2 + sql/share/swedish/errmsg.txt | 2 + sql/share/ukrainian/errmsg.txt | 2 + sql/sql_insert.cc | 37 +++++++++++++++ sql/sql_lex.h | 1 + sql/sql_update.cc | 34 ++++++++++++++ sql/sql_view.cc | 33 +++++++++---- sql/sql_yacc.yy | 12 +++-- sql/table.cc | 48 +++++++++++++------ sql/table.h | 7 +++ 33 files changed, 336 insertions(+), 33 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 3ee12fa9580..c25d93ce487 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -374,4 +374,6 @@ #define ER_VIEW_INVALID 1355 #define ER_SP_NO_DROP_SP 1356 #define ER_SP_GOTO_IN_HNDLR 1357 -#define ER_ERROR_MESSAGES 357 +#define ER_VIEW_NONUPD_CHECK 1358 +#define ER_VIEW_CHECK_FAILED 1359 +#define ER_ERROR_MESSAGES 360 diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 18da4882894..232d5472ab9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -477,8 +477,10 @@ drop view v1; drop table t1; create table t1 (a int); create view v1 as select distinct a from t1 WITH CHECK OPTION; -create view v2 as select distinct a from t1 WITH CASCADED CHECK OPTION; -create view v3 as select distinct a from t1 WITH LOCAL CHECK OPTION; +ERROR HY000: CHECK OPTION on non-updatable view +create view v1 as select a from t1 WITH CHECK OPTION; +create view v2 as select a from t1 WITH CASCADED CHECK OPTION; +create view v3 as select a from t1 WITH LOCAL CHECK OPTION; drop view v3 RESTRICT; drop view v2 CASCADE; drop view v1; @@ -1166,3 +1168,74 @@ Table Create Table v3 CREATE VIEW `test`.`v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from `test`.`v1` join `test`.`v2` where (`v1`.`col1` = `v2`.`col1`) drop view v3, v2, v1; drop table t2, t1; +create table t1 (a int); +create view v1 as select * from t1 where a < 2 with check option; +insert into v1 values(1); +insert into v1 values(3); +ERROR HY000: CHECK OPTION failed +insert ignore into v1 values (2),(3),(0); +Warnings: +Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed +select * from t1; +a +1 +0 +delete from t1; +insert into v1 SELECT 1; +insert into v1 SELECT 3; +ERROR HY000: CHECK OPTION failed +create table t2 (a int); +insert into t2 values (2),(3),(0); +insert ignore into v1 SELECT a from t2; +Warnings: +Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed +select * from t1; +a +1 +0 +update v1 set a=-1 where a=0; +update v1 set a=2 where a=1; +ERROR HY000: CHECK OPTION failed +select * from t1; +a +1 +-1 +update v1 set a=0 where a=0; +insert into t2 values (1); +update v1,t2 set v1.a=v1.a-1 where v1.a=t2.a; +select * from t1; +a +0 +-1 +update v1 set a=a+1; +update ignore v1,t2 set v1.a=v1.a+1 where v1.a=t2.a; +Warnings: +Error 1359 CHECK OPTION failed +select * from t1; +a +1 +1 +drop view v1; +drop table t1, t2; +create table t1 (a int); +create view v1 as select * from t1 where a < 2 with check option; +create view v2 as select * from v1 where a > 0 with local check option; +create view v3 as select * from v1 where a > 0 with cascaded check option; +insert into v2 values (1); +insert into v3 values (1); +insert into v2 values (0); +ERROR HY000: CHECK OPTION failed +insert into v3 values (0); +ERROR HY000: CHECK OPTION failed +insert into v2 values (2); +insert into v3 values (2); +ERROR HY000: CHECK OPTION failed +select * from t1; +a +1 +1 +2 +drop view v3,v2,v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index e73133afa67..7628dd59750 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -392,9 +392,11 @@ drop table t1; # syntax compatibility # create table t1 (a int); +-- error 1358 create view v1 as select distinct a from t1 WITH CHECK OPTION; -create view v2 as select distinct a from t1 WITH CASCADED CHECK OPTION; -create view v3 as select distinct a from t1 WITH LOCAL CHECK OPTION; +create view v1 as select a from t1 WITH CHECK OPTION; +create view v2 as select a from t1 WITH CASCADED CHECK OPTION; +create view v3 as select a from t1 WITH LOCAL CHECK OPTION; drop view v3 RESTRICT; drop view v2 CASCADE; drop view v1; @@ -1106,3 +1108,67 @@ select * from v3; show create view v3; drop view v3, v2, v1; drop table t2, t1; + +# +# WITH CHECK OPTION insert/update test +# +create table t1 (a int); +create view v1 as select * from t1 where a < 2 with check option; +# simple insert +insert into v1 values(1); +-- error 1359 +insert into v1 values(3); +# simple insert with ignore +insert ignore into v1 values (2),(3),(0); +select * from t1; +# prepare data for next check +delete from t1; +# INSERT SELECT test +insert into v1 SELECT 1; +-- error 1359 +insert into v1 SELECT 3; +# prepare data for next check +create table t2 (a int); +insert into t2 values (2),(3),(0); +# INSERT SELECT with ignore test +insert ignore into v1 SELECT a from t2; +select * from t1; +#simple UPDATE test +update v1 set a=-1 where a=0; +-- error 1359 +update v1 set a=2 where a=1; +select * from t1; +# prepare data for next check +update v1 set a=0 where a=0; +insert into t2 values (1); +# multiupdate test +update v1,t2 set v1.a=v1.a-1 where v1.a=t2.a; +select * from t1; +# prepare data for next check +update v1 set a=a+1; +# multiupdate with ignore test +update ignore v1,t2 set v1.a=v1.a+1 where v1.a=t2.a; +select * from t1; + +drop view v1; +drop table t1, t2; + +# +# CASCADED/LOCAL CHECK OPTION test +# +create table t1 (a int); +create view v1 as select * from t1 where a < 2 with check option; +create view v2 as select * from v1 where a > 0 with local check option; +create view v3 as select * from v1 where a > 0 with cascaded check option; +insert into v2 values (1); +insert into v3 values (1); +-- error 1359 +insert into v2 values (0); +-- error 1359 +insert into v3 values (0); +insert into v2 values (2); +-- error 1359 +insert into v3 values (2); +select * from t1; +drop view v3,v2,v1; +drop table t1; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 9d1c429d5b6..67b27fbaab5 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -370,3 +370,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index b2d2fdf4d77..b114ca95bec 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -364,3 +364,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 85c0443869f..b1d5688bede 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -372,3 +372,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 641f267d67e..561d08c57c8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -361,3 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index e64c0c17e74..66f6d93d301 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -366,3 +366,5 @@ character-set=latin7 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index f3443457346..41c7a0a1b44 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -361,3 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 498a230faed..a0467836f72 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -373,3 +373,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 2827517ba9a..5746be6c955 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -361,3 +361,5 @@ character-set=greek "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index fab0b156322..c411bcc5dc9 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -363,3 +363,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 24634514a23..c01b37132a0 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -361,3 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 68f2857aeca..ee2b1ed4d9f 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -363,3 +363,5 @@ character-set=ujis "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 70267c82364..2a44095a5c9 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -361,3 +361,5 @@ character-set=euckr "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 1d84a3a5e5a..3b5de96ddd7 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -363,3 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index be881d54473..d2a8b505cd6 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -363,3 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 8a576b5bf82..89cb546c668 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -365,3 +365,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 6794db726cc..f308d7eac1d 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -362,3 +362,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 9eaa4860b64..ef56babaca0 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -365,3 +365,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index eec85d611fc..fbb41c886c4 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -363,3 +363,5 @@ character-set=koi8r "View '%-.64s.%-.64s' ссылается на несуществующие таблицы или слолбцы" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION для необновляемого VIEW" +"проверка CHECK OPTION провалилась" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 4039268f446..265c77f576f 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -367,3 +367,5 @@ character-set=cp1250 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 9be5ce01d6a..4575fa5b7c6 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -369,3 +369,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index dc15f8b8d5e..d2df49488ff 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -363,3 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index ee5436c3b80..efd5640ddfd 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -361,3 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION on non-updatable view" +"CHECK OPTION failed" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index cb1d99e2fec..503124d7a55 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -366,3 +366,5 @@ character-set=koi8u "View '%-.64s.%-.64s' посила╓тся на не╕снуюч╕ таблиц╕ або стовбц╕" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" +"CHECK OPTION для VIEW що не може бути оновленним" +"перев╕рка CHECK OPTION не пройшла" diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b43c4d31b34..5656cfaba1d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -128,6 +128,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, */ bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL)); bool transactional_table, log_delayed; + bool check; uint value_count; ulong counter = 1; ulonglong id; @@ -268,6 +269,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, if (lock_type != TL_WRITE_DELAYED) table->file->start_bulk_insert(values_list.elements); + check= (table_list->check_option != 0); + while ((values= its++)) { if (fields.elements || !value_count) @@ -302,6 +305,21 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, break; } } + if (check && table_list->check_option->val_int() == 0) + { + if (thd->lex->duplicates == DUP_IGNORE) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); + continue; + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0)); + error=1; + break; + } + } #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) { @@ -1562,6 +1580,11 @@ int mysql_insert_select_prepare(THD *thd) bool insert_into_view= (table_list->view != 0); DBUG_ENTER("mysql_insert_select_prepare"); + /* + SELECT_LEX do not belong to INSERT statement, so we can't add WHERE + clasue if table is VIEW + */ + table_list->no_where_clause= 1; if (setup_tables(thd, table_list, &lex->select_lex.where)) DBUG_RETURN(-1); @@ -1627,6 +1650,20 @@ bool select_insert::send_data(List &values) fill_record(*fields, values, 1); else fill_record(table->field, values, 1); + if (table_list->check_option && table_list->check_option->val_int() == 0) + { + if (thd->lex->duplicates == DUP_IGNORE) + { + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); + DBUG_RETURN(0); + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0)); + DBUG_RETURN(1); + } + } if (thd->net.report_error || write_record(table,&info)) DBUG_RETURN(1); if (table->next_number_field) // Clear for next record diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 84b5cf3454b..a3986d7d6ff 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -682,6 +682,7 @@ typedef struct st_lex uint8 describe; uint8 derived_tables; uint8 create_view_algorithm; + uint8 create_view_check; bool drop_if_exists, drop_temporary, local_file, one_shot_set; bool in_comment, ignore_space, verbose, no_write_to_binlog; /* special JOIN::prepare mode: changing of query is prohibited */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 61fb4b97200..b43afa8ea79 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -97,6 +97,7 @@ int mysql_update(THD *thd, bool using_limit=limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table, log_delayed; + bool check; int error=0; uint used_index; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -344,6 +345,7 @@ int mysql_update(THD *thd, thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ thd->cuted_fields=0L; thd->proc_info="Updating"; + check= (table_list->check_option != 0); query_id=thd->query_id; while (!(error=info.read_record(&info)) && !thd->killed) @@ -353,6 +355,22 @@ int mysql_update(THD *thd, store_record(table,record[1]); if (fill_record(fields,values, 0) || thd->net.report_error) break; /* purecov: inspected */ + if (check && table_list->check_option->val_int() == 0) + { + if (thd->lex->duplicates == DUP_IGNORE) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); + continue; + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0)); + error=1; + break; + } + } + found++; if (compare_record(table, query_id)) { @@ -984,6 +1002,22 @@ bool multi_update::send_data(List ¬_used_values) store_record(table,record[1]); if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) DBUG_RETURN(1); + + if (cur_table->check_option && cur_table->check_option->val_int() == 0) + { + if (thd->lex->duplicates == DUP_IGNORE) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); + continue; + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0)); + DBUG_RETURN(1); + } + } + found++; if (compare_record(table, thd->query_id)) { diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3f0e0db1724..31e5796d946 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -327,6 +327,7 @@ static char *view_field_names[]= (char*)"md5", (char*)"updatable", (char*)"algorithm", + (char*)"with_check_option", (char*)"revision", (char*)"timestamp", (char*)"create-version", @@ -343,13 +344,15 @@ static File_option view_parameters[]= FILE_OPTIONS_ULONGLONG}, {{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm), FILE_OPTIONS_ULONGLONG}, - {{view_field_names[4], 8}, offsetof(TABLE_LIST, revision), + {{view_field_names[4], 17}, offsetof(TABLE_LIST, with_check), + FILE_OPTIONS_ULONGLONG}, + {{view_field_names[5], 8}, offsetof(TABLE_LIST, revision), FILE_OPTIONS_REV}, - {{view_field_names[5], 9}, offsetof(TABLE_LIST, timestamp), + {{view_field_names[6], 9}, offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, - {{view_field_names[6], 14}, offsetof(TABLE_LIST, file_version), + {{view_field_names[7], 14}, offsetof(TABLE_LIST, file_version), FILE_OPTIONS_ULONGLONG}, - {{view_field_names[7], 6}, offsetof(TABLE_LIST, source), + {{view_field_names[8], 6}, offsetof(TABLE_LIST, source), FILE_OPTIONS_ESTRING}, {{NULL, 0}, 0, FILE_OPTIONS_STRING} @@ -421,7 +424,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (mode == VIEW_CREATE_NEW) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias); - DBUG_RETURN(1); + DBUG_RETURN(-1); } File_parser *parser= sql_parse_prepare(&path, &thd->mem_root, 0); @@ -439,14 +442,14 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (parser->parse((gptr)view, &thd->mem_root, view_parameters + revision_number_position, 1)) { - DBUG_RETURN(1); + DBUG_RETURN(thd->net.report_error? -1 : 1); } } else { my_error(ER_WRONG_OBJECT, MYF(0), (view->db?view->db:thd->db), view->real_name, "VIEW"); - DBUG_RETURN(1); + DBUG_RETURN(-1); } } else @@ -459,7 +462,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (mode == VIEW_ALTER) { my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias); - DBUG_RETURN(1); + DBUG_RETURN(-1); } } } @@ -481,6 +484,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, thd->lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } view->algorithm= thd->lex->create_view_algorithm; + view->with_check= thd->lex->create_view_check; if ((view->updatable_view= (can_be_merged && view->algorithm != VIEW_ALGORITHM_TMEPTABLE))) { @@ -496,10 +500,18 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, } } } + + if (view->with_check != VIEW_CHECK_NONE && + !view->updatable_view) + { + my_error(ER_VIEW_NONUPD_CHECK, MYF(0)); + DBUG_RETURN(-1); + } + if (sql_create_definition_file(&dir, &file, view_file_type, (gptr)view, view_parameters, 3)) { - DBUG_RETURN(1); + DBUG_RETURN(thd->net.report_error? -1 : 1); } DBUG_RETURN(0); } @@ -551,7 +563,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) TODO: when VIEWs will be stored in cache, table mem_root should be used here */ - if (parser->parse((gptr)table, &thd->mem_root, view_parameters, 6)) + if (parser->parse((gptr)table, &thd->mem_root, view_parameters, 7)) goto err; /* @@ -706,6 +718,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE")); lex->select_lex.linkage= DERIVED_TABLE_TYPE; table->updatable= 0; + table->with_check= VIEW_CHECK_NONE; /* SELECT tree link */ lex->unit.include_down(table->select_lex); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 172ec48fb18..491c03f00bd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7556,9 +7556,13 @@ algorithm: { Lex->create_view_algorithm= VIEW_ALGORITHM_TMEPTABLE; } ; check_option: - /* empty */ {} - | WITH CHECK_SYM OPTION {} - | WITH CASCADED CHECK_SYM OPTION {} - | WITH LOCAL_SYM CHECK_SYM OPTION {} + /* empty */ + { Lex->create_view_check= VIEW_CHECK_NONE; } + | WITH CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_LOCAL; } + | WITH CASCADED CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_CASCADED; } + | WITH LOCAL_SYM CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_LOCAL; } ; diff --git a/sql/table.cc b/sql/table.cc index 3e481443801..4797aa1edd0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1581,27 +1581,47 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) if (arena) thd->set_n_backup_item_arena(arena, &backup); - if (outer_join) + + if (with_check) { - /* - Store WHERE condition to ON expression for outer join, because we - can't use WHERE to correctly execute jeft joins on VIEWs and this - expression will not be moved to WHERE condition (i.e. will be clean - correctly for PS/SP) - */ - on_expr= and_conds(on_expr, where); + check_option= where->copy_andor_structure(thd); + if (with_check == VIEW_CHECK_CASCADED) + { + check_option= and_conds(check_option, ancestor->check_option); + } } - else + + if (!no_where_clause) { - /* - It is conds of JOIN, but it will be stored in st_select_lex::prep_where - for next reexecution - */ - *conds= and_conds(*conds, where); + if (outer_join) + { + /* + Store WHERE condition to ON expression for outer join, because we + can't use WHERE to correctly execute jeft joins on VIEWs and this + expression will not be moved to WHERE condition (i.e. will be + clean correctly for PS/SP) + */ + on_expr= and_conds(on_expr, where); + } + else + { + /* + It is conds of JOIN, but it will be stored in + st_select_lex::prep_where for next reexecution + */ + *conds= and_conds(*conds, where); + } } if (arena) thd->restore_backup_item_arena(arena, &backup); } + /* + fix_fields do not need tables, because new are only AND operation and we + just need recollect statistics + */ + if (check_option && !check_option->fixed && + check_option->fix_fields(thd, 0, &check_option)) + goto err; /* full text function moving to current select */ if (view->select_lex.ftfunc_list->elements) diff --git a/sql/table.h b/sql/table.h index dd41ab79b7b..89d1b717185 100644 --- a/sql/table.h +++ b/sql/table.h @@ -182,6 +182,10 @@ struct st_table { #define VIEW_ALGORITHM_TMEPTABLE 1 #define VIEW_ALGORITHM_MERGE 2 +#define VIEW_CHECK_NONE 0 +#define VIEW_CHECK_LOCAL 1 +#define VIEW_CHECK_CASCADED 2 + struct st_lex; typedef struct st_table_list @@ -215,6 +219,7 @@ typedef struct st_table_list /* most upper view this table belongs to */ st_table_list *belong_to_view; Item *where; /* VIEW WHERE clause condition */ + Item *check_option; /* WITH CHECK OPTION condition */ LEX_STRING query; /* text of (CRETE/SELECT) statement */ LEX_STRING md5; /* md5 of query tesxt */ LEX_STRING source; /* source of CREATE VIEW */ @@ -225,6 +230,7 @@ typedef struct st_table_list ulonglong updatable_view; /* VIEW can be updated */ ulonglong revision; /* revision control number */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ + ulonglong with_check; /* WITH CHECK OPTION */ uint effective_algorithm; /* which algorithm was really used */ GRANT_INFO grant; thr_lock_type lock_type; @@ -236,6 +242,7 @@ typedef struct st_table_list bool updating; /* for replicate-do/ignore table */ bool force_index; /* prefer index over table scan */ bool ignore_leaves; /* preload only non-leaf nodes */ + bool no_where_clause; /* do not attach WHERE to SELECT */ table_map dep_tables; /* tables the table depends on */ table_map on_expr_dep_tables; /* tables on expression depends on */ struct st_nested_join *nested_join; /* if the element is a nested join */ From fa8d44b63b89bda91e641d3d6fdf08de9f68c3ce Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Mon, 6 Sep 2004 08:27:18 +0300 Subject: [PATCH 2/4] postmerge fix --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6f5ff4775ac..2ce4a7e8e39 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1620,7 +1620,7 @@ int mysql_insert_select_prepare(THD *thd) SELECT_LEX do not belong to INSERT statement, so we can't add WHERE clasue if table is VIEW */ - table_list->no_where_clause= 1; + lex->query_tables->no_where_clause= 1; if (mysql_prepare_insert_check_table(thd, lex->query_tables, lex->field_list, &lex->select_lex.where)) From f7e92479e973b221398826edf004b77e9f169699 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Mon, 6 Sep 2004 23:55:36 +0300 Subject: [PATCH 3/4] added CHECK option test for INSERT ... ON DUPLICATE KEY UPDATE (WL#1983) --- mysql-test/r/view.result | 13 +++++++++++++ mysql-test/t/view.test | 13 +++++++++++++ sql/sql_class.h | 15 ++++++--------- sql/sql_insert.cc | 35 +++++++++++++++++++++++++++++++++++ sql/sql_parse.cc | 3 ++- 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 1560a4be208..47c73dfb23f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1343,3 +1343,16 @@ a 2 drop view v3,v2,v1; drop table t1; +create table t1 (a int, primary key (a)); +create view v1 as select * from t1 where a < 2 with check option; +insert into v1 values (1) on duplicate key update a=2; +insert into v1 values (1) on duplicate key update a=2; +ERROR HY000: CHECK OPTION failed +insert ignore into v1 values (1) on duplicate key update a=2; +Warnings: +Error 1359 CHECK OPTION failed +select * from t1; +a +1 +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 87637fab826..b1aa198d1c8 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1296,3 +1296,16 @@ insert into v3 values (2); select * from t1; drop view v3,v2,v1; drop table t1; + +# +# CHECK OPTION with INSERT ... ON DUPLICATE KEY UPDATE +# +create table t1 (a int, primary key (a)); +create view v1 as select * from t1 where a < 2 with check option; +insert into v1 values (1) on duplicate key update a=2; +-- error 1359 +insert into v1 values (1) on duplicate key update a=2; +insert ignore into v1 values (1) on duplicate key update a=2; +select * from t1; +drop view v1; +drop table t1; diff --git a/sql/sql_class.h b/sql/sql_class.h index eccaf072008..fd05dd8d73b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -227,6 +227,9 @@ typedef struct st_copy_info { /* for INSERT ... UPDATE */ List *update_fields; List *update_values; +/* for VIEW ... WITH CHECK OPTION */ + Item *check_option; + bool ignore; } COPY_INFO; @@ -1180,14 +1183,8 @@ class select_insert :public select_result { bool insert_into_view; select_insert(TABLE_LIST *table_list_par, TABLE *table_par, - List *fields_par, enum_duplicates duplic) - :table_list(table_list_par), table(table_par), fields(fields_par), - last_insert_id(0), - insert_into_view(table_list_par && table_list_par->view != 0) - { - bzero((char*) &info,sizeof(info)); - info.handle_duplicates=duplic; - } + List *fields_par, enum_duplicates duplic, + bool ignore_check_option_errors); ~select_insert(); int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flags) { return 0; } @@ -1211,7 +1208,7 @@ public: List &fields_par, List &keys_par, List &select_fields,enum_duplicates duplic) - :select_insert (NULL, NULL, &select_fields, duplic), create_table(table), + :select_insert (NULL, NULL, &select_fields, duplic, 0), create_table(table), extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), lock(0) {} diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9ab75a725a6..9afef1b7cb0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -242,6 +242,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, info.handle_duplicates=duplic; info.update_fields=&update_fields; info.update_values=&update_values; + info.check_option= table_list->check_option; + info.ignore= thd->lex->duplicates == DUP_IGNORE; /* Count warnings for all inserts. For single line insert, generate an error if try to set a NOT NULL field @@ -714,6 +716,24 @@ int write_record(TABLE *table,COPY_INFO *info) restore_record(table,record[1]); if (fill_record(*info->update_fields, *info->update_values, 0)) goto err; + + /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ + if (info->check_option && + info->check_option->val_int() == 0) + { + if (info->ignore) + { + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); + break; + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0)); + goto err; + } + } + if ((error=table->file->update_row(table->record[1],table->record[0]))) goto err; info->updated++; @@ -1633,6 +1653,21 @@ int mysql_insert_select_prepare(THD *thd) } +select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, + List *fields_par, enum_duplicates duplic, + bool ignore_check_option_errors) + :table_list(table_list_par), table(table_par), fields(fields_par), + last_insert_id(0), + insert_into_view(table_list_par && table_list_par->view != 0) +{ + bzero((char*) &info,sizeof(info)); + info.handle_duplicates=duplic; + if (table_list_par) + info.check_option= table_list_par->check_option; + info.ignore= ignore_check_option_errors; +} + + int select_insert::prepare(List &values, SELECT_LEX_UNIT *u) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 546183563c9..e3390594cd2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2769,7 +2769,8 @@ unsent_create_error: if ((res= mysql_insert_select_prepare(thd))) break; if ((result= new select_insert(first_table, first_table->table, - &lex->field_list, lex->duplicates))) + &lex->field_list, lex->duplicates, + lex->duplicates == DUP_IGNORE))) /* Skip first table, which is the table we are inserting in */ lex->select_lex.table_list.first= (byte*) first_table->next_local; /* From 392292a46b99b6403436a30578f40c4dd515f03d Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 29 Sep 2004 16:35:01 +0300 Subject: [PATCH 4/4] post review changes: CHECK OPTION moved to one function view name added to error messages --- mysql-test/r/view.result | 28 ++++++------- sql/share/czech/errmsg.txt | 4 +- sql/share/danish/errmsg.txt | 4 +- sql/share/dutch/errmsg.txt | 4 +- sql/share/english/errmsg.txt | 4 +- sql/share/estonian/errmsg.txt | 4 +- sql/share/french/errmsg.txt | 4 +- sql/share/german/errmsg.txt | 4 +- sql/share/greek/errmsg.txt | 4 +- sql/share/hungarian/errmsg.txt | 4 +- sql/share/italian/errmsg.txt | 4 +- sql/share/japanese/errmsg.txt | 4 +- sql/share/korean/errmsg.txt | 4 +- sql/share/norwegian-ny/errmsg.txt | 4 +- sql/share/norwegian/errmsg.txt | 4 +- sql/share/polish/errmsg.txt | 4 +- sql/share/portuguese/errmsg.txt | 4 +- sql/share/romanian/errmsg.txt | 4 +- sql/share/russian/errmsg.txt | 4 +- sql/share/serbian/errmsg.txt | 4 +- sql/share/slovak/errmsg.txt | 4 +- sql/share/spanish/errmsg.txt | 4 +- sql/share/swedish/errmsg.txt | 4 +- sql/share/ukrainian/errmsg.txt | 4 +- sql/sql_class.h | 2 +- sql/sql_insert.cc | 69 +++++++++++-------------------- sql/sql_update.cc | 62 ++++++++++++--------------- sql/sql_view.cc | 6 +-- sql/table.cc | 34 +++++++++++++++ sql/table.h | 7 ++++ 30 files changed, 154 insertions(+), 146 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 47c73dfb23f..9e9b81a1393 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -477,7 +477,7 @@ drop view v1; drop table t1; create table t1 (a int); create view v1 as select distinct a from t1 WITH CHECK OPTION; -ERROR HY000: CHECK OPTION on non-updatable view +ERROR HY000: CHECK OPTION on non-updatable view 'test.v1' create view v1 as select a from t1 WITH CHECK OPTION; create view v2 as select a from t1 WITH CASCADED CHECK OPTION; create view v3 as select a from t1 WITH LOCAL CHECK OPTION; @@ -1276,11 +1276,11 @@ create table t1 (a int); create view v1 as select * from t1 where a < 2 with check option; insert into v1 values(1); insert into v1 values(3); -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v1' insert ignore into v1 values (2),(3),(0); Warnings: -Error 1359 CHECK OPTION failed -Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed 'test.v1' +Error 1359 CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1288,20 +1288,20 @@ a delete from t1; insert into v1 SELECT 1; insert into v1 SELECT 3; -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v1' create table t2 (a int); insert into t2 values (2),(3),(0); insert ignore into v1 SELECT a from t2; Warnings: -Error 1359 CHECK OPTION failed -Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed 'test.v1' +Error 1359 CHECK OPTION failed 'test.v1' select * from t1; a 1 0 update v1 set a=-1 where a=0; update v1 set a=2 where a=1; -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1316,7 +1316,7 @@ a update v1 set a=a+1; update ignore v1,t2 set v1.a=v1.a+1 where v1.a=t2.a; Warnings: -Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1330,12 +1330,12 @@ create view v3 as select * from v1 where a > 0 with cascaded check option; insert into v2 values (1); insert into v3 values (1); insert into v2 values (0); -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v2' insert into v3 values (0); -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v3' insert into v2 values (2); insert into v3 values (2); -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v3' select * from t1; a 1 @@ -1347,10 +1347,10 @@ create table t1 (a int, primary key (a)); create view v1 as select * from t1 where a < 2 with check option; insert into v1 values (1) on duplicate key update a=2; insert into v1 values (1) on duplicate key update a=2; -ERROR HY000: CHECK OPTION failed +ERROR HY000: CHECK OPTION failed 'test.v1' insert ignore into v1 values (1) on duplicate key update a=2; Warnings: -Error 1359 CHECK OPTION failed +Error 1359 CHECK OPTION failed 'test.v1' select * from t1; a 1 diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 7bc8350c2eb..d5be03e85a6 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -370,5 +370,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 25f43038072..228db75e126 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -364,5 +364,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index d324135b1a0..2a31a3a23cc 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -372,5 +372,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index b89cc530130..0b9bbd08250 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -361,5 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 39861a6534d..cebf27d8461 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -366,5 +366,5 @@ character-set=latin7 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index e173cd4bd23..f356ad6a002 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -361,5 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index a843a183487..fd6307ae7cd 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -373,5 +373,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 6d90dade6c4..a634df3a13b 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -361,5 +361,5 @@ character-set=greek "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 6e5f71888f2..b6e15d58bb2 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -363,5 +363,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 944770ea1f7..01de7becbf2 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -361,5 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 592dcb906f0..a273134b5a4 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -363,5 +363,5 @@ character-set=ujis "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 303cac6a415..45b23c3fb0f 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -361,5 +361,5 @@ character-set=euckr "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 2204c8233c7..a9aca0af144 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -363,5 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index d0cdef14b6b..73a8eb0a0dc 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -363,5 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index bfbff949ef6..bf2e8d289e5 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -365,5 +365,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 16320887933..255a8c6c974 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -362,5 +362,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8ed25a2bc12..e5b5152260d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -365,5 +365,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 857c1399a72..fb58bafb196 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -363,5 +363,5 @@ character-set=koi8r "View '%-.64s.%-.64s' ссылается на несуществующие таблицы или слолбцы" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION для необновляемого VIEW" -"проверка CHECK OPTION провалилась" +"CHECK OPTION для необновляемого VIEW '%-.64s.%-.64s'" +"проверка CHECK OPTION для VIEW '%-.64s.%-.64s' провалилась" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index f0ddbebd9d1..eb00c450898 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -367,5 +367,5 @@ character-set=cp1250 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 41e03dee4a2..83105c709c4 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -369,5 +369,5 @@ character-set=latin2 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index da155dfe2c9..331e96a9435 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -363,5 +363,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 1874bb289d3..e3553914e6c 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -361,5 +361,5 @@ character-set=latin1 "View '%-.64s.%-.64s' references invalid table(s) or column(s)" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION on non-updatable view" -"CHECK OPTION failed" +"CHECK OPTION on non-updatable view '%-.64s.%-.64s'" +"CHECK OPTION failed '%-.64s.%-.64s'" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 8bebd615eef..fa4fc8e12c6 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -366,5 +366,5 @@ character-set=koi8u "View '%-.64s.%-.64s' посила╓тся на не╕снуюч╕ таблиц╕ або стовбц╕" "Can't drop a %s from within another stored routine" "GOTO is not allowed in a stored procedure handler" -"CHECK OPTION для VIEW що не може бути оновленним" -"перев╕рка CHECK OPTION не пройшла" +"CHECK OPTION для VIEW '%-.64s.%-.64s' що не може бути оновленним" +"перев╕рка CHECK OPTION для VIEW '%-.64s.%-.64s' не пройшла" diff --git a/sql/sql_class.h b/sql/sql_class.h index fd05dd8d73b..5681724e451 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -228,7 +228,7 @@ typedef struct st_copy_info { List *update_fields; List *update_values; /* for VIEW ... WITH CHECK OPTION */ - Item *check_option; + TABLE_LIST *view; bool ignore; } COPY_INFO; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9afef1b7cb0..03afc665941 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -128,7 +128,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, */ bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL)); bool transactional_table, log_delayed; - bool check; + bool ignore_err= (thd->lex->duplicates == DUP_IGNORE); uint value_count; ulong counter = 1; ulonglong id; @@ -242,8 +242,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, info.handle_duplicates=duplic; info.update_fields=&update_fields; info.update_values=&update_values; - info.check_option= table_list->check_option; - info.ignore= thd->lex->duplicates == DUP_IGNORE; + info.view= (table_list->view ? table_list : 0); + info.ignore= ignore_err; /* Count warnings for all inserts. For single line insert, generate an error if try to set a NOT NULL field @@ -271,8 +271,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, if (lock_type != TL_WRITE_DELAYED) table->file->start_bulk_insert(values_list.elements); - check= (table_list->check_option != 0); - while ((values= its++)) { if (fields.elements || !value_count) @@ -307,20 +305,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, break; } } - if (check && table_list->check_option->val_int() == 0) + if ((res= table_list->view_check_option(thd, ignore_err)) == + VIEW_CHECK_SKIP) + continue; + else if (res == VIEW_CHECK_ERROR) { - if (thd->lex->duplicates == DUP_IGNORE) - { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); - continue; - } - else - { - my_error(ER_VIEW_CHECK_FAILED, MYF(0)); - error=1; - break; - } + error= 1; + break; } #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) @@ -708,6 +699,7 @@ int write_record(TABLE *table,COPY_INFO *info) } if (info->handle_duplicates == DUP_UPDATE) { + int res= 0; /* we don't check for other UNIQUE keys - the first row that matches, is updated. If update causes a conflict again, an error is returned @@ -718,21 +710,12 @@ int write_record(TABLE *table,COPY_INFO *info) goto err; /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ - if (info->check_option && - info->check_option->val_int() == 0) - { - if (info->ignore) - { - push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); - break; - } - else - { - my_error(ER_VIEW_CHECK_FAILED, MYF(0)); - goto err; - } - } + if (info->view && + (res= info->view->view_check_option(current_thd, info->ignore)) == + VIEW_CHECK_SKIP) + break; + else if (res == VIEW_CHECK_ERROR) + goto err; if ((error=table->file->update_row(table->record[1],table->record[0]))) goto err; @@ -1663,7 +1646,7 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, bzero((char*) &info,sizeof(info)); info.handle_duplicates=duplic; if (table_list_par) - info.check_option= table_list_par->check_option; + info.view= (table_list_par->view ? table_list_par : 0); info.ignore= ignore_check_option_errors; } @@ -1712,19 +1695,13 @@ bool select_insert::send_data(List &values) fill_record(*fields, values, 1); else fill_record(table->field, values, 1); - if (table_list->check_option && table_list->check_option->val_int() == 0) + switch (table_list->view_check_option(thd, + thd->lex->duplicates == DUP_IGNORE)) { - if (thd->lex->duplicates == DUP_IGNORE) - { - push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); - DBUG_RETURN(0); - } - else - { - my_error(ER_VIEW_CHECK_FAILED, MYF(0)); - DBUG_RETURN(1); - } + case VIEW_CHECK_SKIP: + DBUG_RETURN(0); + case VIEW_CHECK_ERROR: + DBUG_RETURN(1); } if (thd->net.report_error || write_record(table,&info)) DBUG_RETURN(1); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 06b0a5c08ed..62694e32ba7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -94,11 +94,12 @@ int mysql_update(THD *thd, ha_rows limit, enum enum_duplicates handle_duplicates) { - bool using_limit=limit != HA_POS_ERROR; + bool using_limit= limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table, log_delayed; - bool check; + bool ignore_err= (thd->lex->duplicates == DUP_IGNORE); int error=0; + int res; uint used_index; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint want_privilege; @@ -150,7 +151,7 @@ int mysql_update(THD *thd, #endif { thd->lex->select_lex.no_wrap_view_item= 1; - int res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); + res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); thd->lex->select_lex.no_wrap_view_item= 0; if (res) DBUG_RETURN(-1); /* purecov: inspected */ @@ -345,7 +346,6 @@ int mysql_update(THD *thd, thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ thd->cuted_fields=0L; thd->proc_info="Updating"; - check= (table_list->check_option != 0); query_id=thd->query_id; while (!(error=info.read_record(&info)) && !thd->killed) @@ -355,25 +355,21 @@ int mysql_update(THD *thd, store_record(table,record[1]); if (fill_record(fields,values, 0) || thd->net.report_error) break; /* purecov: inspected */ - if (check && table_list->check_option->val_int() == 0) - { - if (thd->lex->duplicates == DUP_IGNORE) - { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); - continue; - } - else - { - my_error(ER_VIEW_CHECK_FAILED, MYF(0)); - error=1; - break; - } - } - found++; if (compare_record(table, query_id)) { + if ((res= table_list->view_check_option(thd, ignore_err)) != + VIEW_CHECK_OK) + { + found--; + if (res == VIEW_CHECK_SKIP) + continue; + else if (res == VIEW_CHECK_ERROR) + { + error= 1; + break; + } + } if (!(error=table->file->update_row((byte*) table->record[1], (byte*) table->record[0]))) { @@ -974,6 +970,7 @@ multi_update::~multi_update() bool multi_update::send_data(List ¬_used_values) { TABLE_LIST *cur_table; + bool ignore_err= (thd->lex->duplicates == DUP_IGNORE); DBUG_ENTER("multi_update::send_data"); for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) @@ -1002,26 +999,19 @@ bool multi_update::send_data(List ¬_used_values) store_record(table,record[1]); if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) DBUG_RETURN(1); - - if (cur_table->check_option && cur_table->check_option->val_int() == 0) - { - if (thd->lex->duplicates == DUP_IGNORE) - { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED)); - continue; - } - else - { - my_error(ER_VIEW_CHECK_FAILED, MYF(0)); - DBUG_RETURN(1); - } - } - found++; if (compare_record(table, thd->query_id)) { int error; + if ((error= cur_table->view_check_option(thd, ignore_err)) != + VIEW_CHECK_OK) + { + found--; + if (error == VIEW_CHECK_SKIP) + continue; + else if (error == VIEW_CHECK_ERROR) + DBUG_RETURN(1); + } if (!updated++) { /* diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 2877d6177ea..c94cc9acb44 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -398,7 +398,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, char path_buff[FN_REFLEN]; LEX_STRING path; File_parser *parser; - + path.str= path_buff; fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME); path.length= strlen(path_buff); @@ -424,7 +424,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, /* read revision number - + TODO: read dependense list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ @@ -481,7 +481,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (view->with_check != VIEW_CHECK_NONE && !view->updatable_view) { - my_error(ER_VIEW_NONUPD_CHECK, MYF(0)); + my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->real_name); DBUG_RETURN(-1); } diff --git a/sql/table.cc b/sql/table.cc index 28ba4287348..cc6210b1455 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1653,6 +1653,40 @@ err: } +/* + check CHECK OPTION condition + + SYNOPSIS + check_option() + ignore_failure ignore check option fail + + RETURN + VIEW_CHECK_OK OK + VIEW_CHECK_ERROR FAILED + VIEW_CHECK_SKIP FAILED, but continue +*/ + +int st_table_list::view_check_option(THD *thd, bool ignore_failure) +{ + if (check_option && check_option->val_int() == 0) + { + if (ignore_failure) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), + view_db.str, view_name.str); + return(VIEW_CHECK_SKIP); + } + else + { + my_error(ER_VIEW_CHECK_FAILED, MYF(0), view_db.str, view_name.str); + return(VIEW_CHECK_ERROR); + } + } + return(VIEW_CHECK_OK); +} + + void Field_iterator_view::set(TABLE_LIST *table) { ptr= table->field_translation; diff --git a/sql/table.h b/sql/table.h index 4c397ded0cf..8f846ee157b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -185,10 +185,16 @@ struct st_table { #define VIEW_ALGORITHM_TMPTABLE 1 #define VIEW_ALGORITHM_MERGE 2 +/* view WITH CHECK OPTION parameter options */ #define VIEW_CHECK_NONE 0 #define VIEW_CHECK_LOCAL 1 #define VIEW_CHECK_CASCADED 2 +/* result of view WITH CHECK OPTION parameter check */ +#define VIEW_CHECK_OK 0 +#define VIEW_CHECK_ERROR 1 +#define VIEW_CHECK_SKIP 2 + struct st_lex; typedef struct st_table_list @@ -264,6 +270,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 placeholder() {return derived || view; } void print(THD *thd, String *str);