diff options
author | unknown <bell@sanja.is.com.ua> | 2004-09-06 15:56:38 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-09-06 15:56:38 +0300 |
commit | c05fbd4c0be5be8a5bf9900a11cdc95d90bc0813 (patch) | |
tree | 7cc298f1b88a43a4da02556927f340c392cebfb5 | |
parent | 0a04f6b165035ec77e602b66482510d54c28e0bd (diff) | |
parent | c751fdd9aa9ce8fc30b6a18abc11d4db1a41fc2c (diff) | |
download | mariadb-git-c05fbd4c0be5be8a5bf9900a11cdc95d90bc0813.tar.gz |
merge
sql/sql_insert.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_update.cc:
Auto merged
sql/share/czech/errmsg.txt:
Auto merged
sql/share/danish/errmsg.txt:
Auto merged
sql/share/dutch/errmsg.txt:
Auto merged
sql/share/english/errmsg.txt:
Auto merged
sql/share/estonian/errmsg.txt:
Auto merged
sql/share/french/errmsg.txt:
Auto merged
sql/share/german/errmsg.txt:
Auto merged
sql/share/greek/errmsg.txt:
Auto merged
sql/share/hungarian/errmsg.txt:
Auto merged
sql/share/italian/errmsg.txt:
Auto merged
sql/share/japanese/errmsg.txt:
Auto merged
sql/share/korean/errmsg.txt:
Auto merged
sql/share/norwegian-ny/errmsg.txt:
Auto merged
sql/share/norwegian/errmsg.txt:
Auto merged
sql/share/polish/errmsg.txt:
Auto merged
sql/share/portuguese/errmsg.txt:
Auto merged
sql/share/romanian/errmsg.txt:
Auto merged
sql/share/russian/errmsg.txt:
Auto merged
sql/share/serbian/errmsg.txt:
Auto merged
sql/share/slovak/errmsg.txt:
Auto merged
sql/share/spanish/errmsg.txt:
Auto merged
sql/share/swedish/errmsg.txt:
Auto merged
sql/share/ukrainian/errmsg.txt:
Auto merged
sql/table.h:
Auto merged
33 files changed, 330 insertions, 29 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 432919db04b..5b666139d66 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 358 +#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 35b76a8ab4b..1560a4be208 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; @@ -1270,3 +1272,74 @@ s1 7 drop view v1; drop table 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 9464e291e05..87637fab826 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; @@ -1230,3 +1232,67 @@ insert into v1 values (1) on duplicate key update s1 = 7; select * from t1; drop view v1; drop table 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 35310f5210f..7bc8350c2eb 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 d6a0a9d81e8..25f43038072 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 8fd5277d4ec..d324135b1a0 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 a60881b5df6..b89cc530130 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 2e8a9270cd3..39861a6534d 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 b8ec7866a68..e173cd4bd23 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 c28792cc8c6..a843a183487 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 8ceb24bd376..6d90dade6c4 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 f47684f9225..6e5f71888f2 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 eb241ef08a0..944770ea1f7 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 166d6e8e1c1..592dcb906f0 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 66486fd8a0f..303cac6a415 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 739d40178df..2204c8233c7 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 227e16e1590..d0cdef14b6b 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 62e10e778f2..bfbff949ef6 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 08c03fcaf2a..16320887933 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 0f6df4f919b..8ed25a2bc12 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 71c983ff55e..857c1399a72 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 bff4fad6108..f0ddbebd9d1 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 363ba86afc7..41e03dee4a2 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 7ab9b416c2e..da155dfe2c9 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 b7add017e44..1874bb289d3 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 364a2a03c16..8bebd615eef 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 857c500f200..9ab75a725a6 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) { @@ -1602,6 +1620,11 @@ int mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; 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 + */ + lex->query_tables->no_where_clause= 1; if (mysql_prepare_insert_check_table(thd, lex->query_tables, lex->field_list, &lex->select_lex.where)) @@ -1654,6 +1677,20 @@ bool select_insert::send_data(List<Item> &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 1c479444485..7028da4507d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -683,6 +683,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 9d7134aee84..06b0a5c08ed 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<Item> ¬_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 2b1971907b3..2877d6177ea 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -317,7 +317,6 @@ static const int required_view_parameters= 7; Note that one should NOT change the order for this, as it's used by parse() */ - static File_option view_parameters[]= {{{(char*) "query", 5}, offsetof(TABLE_LIST, query), FILE_OPTIONS_STRING}, @@ -327,6 +326,8 @@ static File_option view_parameters[]= FILE_OPTIONS_ULONGLONG}, {{(char*) "algorithm", 9}, offsetof(TABLE_LIST, algorithm), FILE_OPTIONS_ULONGLONG}, + {{"with_check_option", 17}, offsetof(TABLE_LIST, with_check), + FILE_OPTIONS_ULONGLONG}, {{(char*) "revision", 8}, offsetof(TABLE_LIST, revision), FILE_OPTIONS_REV}, {{(char*) "timestamp", 9}, offsetof(TABLE_LIST, timestamp), @@ -407,7 +408,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); } if (!(parser= sql_parse_prepare(&path, &thd->mem_root, 0))) @@ -418,7 +419,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { my_error(ER_WRONG_OBJECT, MYF(0), (view->db ? view->db : thd->db), view->real_name, "VIEW"); - DBUG_RETURN(1); + DBUG_RETURN(-1); } /* @@ -430,7 +431,7 @@ 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 : 0); } } else @@ -438,7 +439,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); } } } @@ -460,6 +461,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_TMPTABLE))) { @@ -475,10 +477,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); } @@ -707,6 +717,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 ba3a36f2c34..1aa302b7f19 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7556,9 +7556,13 @@ algorithm: { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } ; 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 1764df75a7e..28ba4287348 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1579,27 +1579,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 b7cabe21638..4c397ded0cf 100644 --- a/sql/table.h +++ b/sql/table.h @@ -185,6 +185,10 @@ struct st_table { #define VIEW_ALGORITHM_TMPTABLE 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 @@ -218,6 +222,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 */ @@ -228,6 +233,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; @@ -239,6 +245,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 */ |