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

CHECK OPTIONs added (WL#1983)

parent e04f4fb4
...@@ -374,4 +374,6 @@ ...@@ -374,4 +374,6 @@
#define ER_VIEW_INVALID 1355 #define ER_VIEW_INVALID 1355
#define ER_SP_NO_DROP_SP 1356 #define ER_SP_NO_DROP_SP 1356
#define ER_SP_GOTO_IN_HNDLR 1357 #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
...@@ -477,8 +477,10 @@ drop view v1; ...@@ -477,8 +477,10 @@ drop view v1;
drop table t1; drop table t1;
create table t1 (a int); create table t1 (a int);
create view v1 as select distinct a from t1 WITH CHECK OPTION; 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; ERROR HY000: CHECK OPTION on non-updatable view
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 v3 RESTRICT;
drop view v2 CASCADE; drop view v2 CASCADE;
drop view v1; drop view v1;
...@@ -1166,3 +1168,74 @@ Table Create Table ...@@ -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`) 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 view v3, v2, v1;
drop table t2, t1; 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;
...@@ -392,9 +392,11 @@ drop table t1; ...@@ -392,9 +392,11 @@ drop table t1;
# syntax compatibility # syntax compatibility
# #
create table t1 (a int); create table t1 (a int);
-- error 1358
create view v1 as select distinct a from t1 WITH CHECK OPTION; 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 v1 as select a from t1 WITH CHECK OPTION;
create view v3 as select distinct a from t1 WITH LOCAL 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 v3 RESTRICT;
drop view v2 CASCADE; drop view v2 CASCADE;
drop view v1; drop view v1;
...@@ -1106,3 +1108,67 @@ select * from v3; ...@@ -1106,3 +1108,67 @@ select * from v3;
show create view v3; show create view v3;
drop view v3, v2, v1; drop view v3, v2, v1;
drop table t2, t1; 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;
...@@ -370,3 +370,5 @@ character-set=latin2 ...@@ -370,3 +370,5 @@ character-set=latin2
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -364,3 +364,5 @@ character-set=latin1 ...@@ -364,3 +364,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -372,3 +372,5 @@ character-set=latin1 ...@@ -372,3 +372,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=latin1 ...@@ -361,3 +361,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -366,3 +366,5 @@ character-set=latin7 ...@@ -366,3 +366,5 @@ character-set=latin7
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=latin1 ...@@ -361,3 +361,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -373,3 +373,5 @@ character-set=latin1 ...@@ -373,3 +373,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=greek ...@@ -361,3 +361,5 @@ character-set=greek
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=latin2 ...@@ -363,3 +363,5 @@ character-set=latin2
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=latin1 ...@@ -361,3 +361,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=ujis ...@@ -363,3 +363,5 @@ character-set=ujis
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=euckr ...@@ -361,3 +361,5 @@ character-set=euckr
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=latin1 ...@@ -363,3 +363,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=latin1 ...@@ -363,3 +363,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -365,3 +365,5 @@ character-set=latin2 ...@@ -365,3 +365,5 @@ character-set=latin2
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -362,3 +362,5 @@ character-set=latin1 ...@@ -362,3 +362,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -365,3 +365,5 @@ character-set=latin2 ...@@ -365,3 +365,5 @@ character-set=latin2
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=koi8r ...@@ -363,3 +363,5 @@ character-set=koi8r
"View '%-.64s.%-.64s' " "View '%-.64s.%-.64s' "
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION VIEW"
" CHECK OPTION "
...@@ -367,3 +367,5 @@ character-set=cp1250 ...@@ -367,3 +367,5 @@ character-set=cp1250
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -369,3 +369,5 @@ character-set=latin2 ...@@ -369,3 +369,5 @@ character-set=latin2
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -363,3 +363,5 @@ character-set=latin1 ...@@ -363,3 +363,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -361,3 +361,5 @@ character-set=latin1 ...@@ -361,3 +361,5 @@ character-set=latin1
"View '%-.64s.%-.64s' references invalid table(s) or column(s)" "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION on non-updatable view"
"CHECK OPTION failed"
...@@ -366,3 +366,5 @@ character-set=koi8u ...@@ -366,3 +366,5 @@ character-set=koi8u
"View '%-.64s.%-.64s' Ŧަ æ æ" "View '%-.64s.%-.64s' Ŧަ æ æ"
"Can't drop a %s from within another stored routine" "Can't drop a %s from within another stored routine"
"GOTO is not allowed in a stored procedure handler" "GOTO is not allowed in a stored procedure handler"
"CHECK OPTION VIEW "
"צ CHECK OPTION "
...@@ -128,6 +128,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -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 log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL));
bool transactional_table, log_delayed; bool transactional_table, log_delayed;
bool check;
uint value_count; uint value_count;
ulong counter = 1; ulong counter = 1;
ulonglong id; ulonglong id;
...@@ -268,6 +269,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -268,6 +269,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
if (lock_type != TL_WRITE_DELAYED) if (lock_type != TL_WRITE_DELAYED)
table->file->start_bulk_insert(values_list.elements); table->file->start_bulk_insert(values_list.elements);
check= (table_list->check_option != 0);
while ((values= its++)) while ((values= its++))
{ {
if (fields.elements || !value_count) if (fields.elements || !value_count)
...@@ -302,6 +305,21 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -302,6 +305,21 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
break; 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 #ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED) if (lock_type == TL_WRITE_DELAYED)
{ {
...@@ -1562,6 +1580,11 @@ int mysql_insert_select_prepare(THD *thd) ...@@ -1562,6 +1580,11 @@ int mysql_insert_select_prepare(THD *thd)
bool insert_into_view= (table_list->view != 0); bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_insert_select_prepare"); 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)) if (setup_tables(thd, table_list, &lex->select_lex.where))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -1627,6 +1650,20 @@ bool select_insert::send_data(List<Item> &values) ...@@ -1627,6 +1650,20 @@ bool select_insert::send_data(List<Item> &values)
fill_record(*fields, values, 1); fill_record(*fields, values, 1);
else else
fill_record(table->field, values, 1); 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)) if (thd->net.report_error || write_record(table,&info))
DBUG_RETURN(1); DBUG_RETURN(1);
if (table->next_number_field) // Clear for next record if (table->next_number_field) // Clear for next record
......
...@@ -682,6 +682,7 @@ typedef struct st_lex ...@@ -682,6 +682,7 @@ typedef struct st_lex
uint8 describe; uint8 describe;
uint8 derived_tables; uint8 derived_tables;
uint8 create_view_algorithm; uint8 create_view_algorithm;
uint8 create_view_check;
bool drop_if_exists, drop_temporary, local_file, one_shot_set; bool drop_if_exists, drop_temporary, local_file, one_shot_set;
bool in_comment, ignore_space, verbose, no_write_to_binlog; bool in_comment, ignore_space, verbose, no_write_to_binlog;
/* special JOIN::prepare mode: changing of query is prohibited */ /* special JOIN::prepare mode: changing of query is prohibited */
......
...@@ -97,6 +97,7 @@ int mysql_update(THD *thd, ...@@ -97,6 +97,7 @@ int mysql_update(THD *thd,
bool using_limit=limit != HA_POS_ERROR; bool using_limit=limit != HA_POS_ERROR;
bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool safe_update= thd->options & OPTION_SAFE_UPDATES;
bool used_key_is_modified, transactional_table, log_delayed; bool used_key_is_modified, transactional_table, log_delayed;
bool check;
int error=0; int error=0;
uint used_index; uint used_index;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
...@@ -344,6 +345,7 @@ int mysql_update(THD *thd, ...@@ -344,6 +345,7 @@ int mysql_update(THD *thd,
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L; thd->cuted_fields=0L;
thd->proc_info="Updating"; thd->proc_info="Updating";
check= (table_list->check_option != 0);
query_id=thd->query_id; query_id=thd->query_id;
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
...@@ -353,6 +355,22 @@ int mysql_update(THD *thd, ...@@ -353,6 +355,22 @@ int mysql_update(THD *thd,
store_record(table,record[1]); store_record(table,record[1]);
if (fill_record(fields,values, 0) || thd->net.report_error) if (fill_record(fields,values, 0) || thd->net.report_error)
break; /* purecov: inspected */ 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++; found++;
if (compare_record(table, query_id)) if (compare_record(table, query_id))
{ {
...@@ -984,6 +1002,22 @@ bool multi_update::send_data(List<Item> &not_used_values) ...@@ -984,6 +1002,22 @@ bool multi_update::send_data(List<Item> &not_used_values)
store_record(table,record[1]); store_record(table,record[1]);
if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0))
DBUG_RETURN(1); 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++; found++;
if (compare_record(table, thd->query_id)) if (compare_record(table, thd->query_id))
{ {
......
...@@ -327,6 +327,7 @@ static char *view_field_names[]= ...@@ -327,6 +327,7 @@ static char *view_field_names[]=
(char*)"md5", (char*)"md5",
(char*)"updatable", (char*)"updatable",
(char*)"algorithm", (char*)"algorithm",
(char*)"with_check_option",
(char*)"revision", (char*)"revision",
(char*)"timestamp", (char*)"timestamp",
(char*)"create-version", (char*)"create-version",
...@@ -343,13 +344,15 @@ static File_option view_parameters[]= ...@@ -343,13 +344,15 @@ static File_option view_parameters[]=
FILE_OPTIONS_ULONGLONG}, FILE_OPTIONS_ULONGLONG},
{{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm), {{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm),
FILE_OPTIONS_ULONGLONG}, 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}, FILE_OPTIONS_REV},
{{view_field_names[5], 9}, offsetof(TABLE_LIST, timestamp), {{view_field_names[6], 9}, offsetof(TABLE_LIST, timestamp),
FILE_OPTIONS_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}, FILE_OPTIONS_ULONGLONG},
{{view_field_names[7], 6}, offsetof(TABLE_LIST, source), {{view_field_names[8], 6}, offsetof(TABLE_LIST, source),
FILE_OPTIONS_ESTRING}, FILE_OPTIONS_ESTRING},
{{NULL, 0}, 0, {{NULL, 0}, 0,
FILE_OPTIONS_STRING} FILE_OPTIONS_STRING}
...@@ -421,7 +424,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -421,7 +424,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
if (mode == VIEW_CREATE_NEW) if (mode == VIEW_CREATE_NEW)
{ {
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias); 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); 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, ...@@ -439,14 +442,14 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
if (parser->parse((gptr)view, &thd->mem_root, if (parser->parse((gptr)view, &thd->mem_root,
view_parameters + revision_number_position, 1)) view_parameters + revision_number_position, 1))
{ {
DBUG_RETURN(1); DBUG_RETURN(thd->net.report_error? -1 : 1);
} }
} }
else else
{ {
my_error(ER_WRONG_OBJECT, MYF(0), (view->db?view->db:thd->db), my_error(ER_WRONG_OBJECT, MYF(0), (view->db?view->db:thd->db),
view->real_name, "VIEW"); view->real_name, "VIEW");
DBUG_RETURN(1); DBUG_RETURN(-1);
} }
} }
else else
...@@ -459,7 +462,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -459,7 +462,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
if (mode == VIEW_ALTER) if (mode == VIEW_ALTER)
{ {
my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias); 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, ...@@ -481,6 +484,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
thd->lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; thd->lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
} }
view->algorithm= thd->lex->create_view_algorithm; view->algorithm= thd->lex->create_view_algorithm;
view->with_check= thd->lex->create_view_check;
if ((view->updatable_view= (can_be_merged && if ((view->updatable_view= (can_be_merged &&
view->algorithm != VIEW_ALGORITHM_TMEPTABLE))) view->algorithm != VIEW_ALGORITHM_TMEPTABLE)))
{ {
...@@ -496,10 +500,18 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -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, if (sql_create_definition_file(&dir, &file, view_file_type,
(gptr)view, view_parameters, 3)) (gptr)view, view_parameters, 3))
{ {
DBUG_RETURN(1); DBUG_RETURN(thd->net.report_error? -1 : 1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -551,7 +563,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) ...@@ -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 TODO: when VIEWs will be stored in cache, table mem_root should
be used here 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; goto err;
/* /*
...@@ -706,6 +718,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) ...@@ -706,6 +718,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE")); DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
lex->select_lex.linkage= DERIVED_TABLE_TYPE; lex->select_lex.linkage= DERIVED_TABLE_TYPE;
table->updatable= 0; table->updatable= 0;
table->with_check= VIEW_CHECK_NONE;
/* SELECT tree link */ /* SELECT tree link */
lex->unit.include_down(table->select_lex); lex->unit.include_down(table->select_lex);
......
...@@ -7556,9 +7556,13 @@ algorithm: ...@@ -7556,9 +7556,13 @@ algorithm:
{ Lex->create_view_algorithm= VIEW_ALGORITHM_TMEPTABLE; } { Lex->create_view_algorithm= VIEW_ALGORITHM_TMEPTABLE; }
; ;
check_option: check_option:
/* empty */ {} /* empty */
| WITH CHECK_SYM OPTION {} { Lex->create_view_check= VIEW_CHECK_NONE; }
| WITH CASCADED CHECK_SYM OPTION {} | WITH CHECK_SYM OPTION
| WITH LOCAL_SYM 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; }
; ;
...@@ -1581,27 +1581,47 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1581,27 +1581,47 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
if (arena) if (arena)
thd->set_n_backup_item_arena(arena, &backup); thd->set_n_backup_item_arena(arena, &backup);
if (outer_join)
if (with_check)
{ {
/* check_option= where->copy_andor_structure(thd);
Store WHERE condition to ON expression for outer join, because we if (with_check == VIEW_CHECK_CASCADED)
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 check_option= and_conds(check_option, ancestor->check_option);
correctly for PS/SP) }
*/
on_expr= and_conds(on_expr, where);
} }
else
if (!no_where_clause)
{ {
/* if (outer_join)
It is conds of JOIN, but it will be stored in st_select_lex::prep_where {
for next reexecution /*
*/ Store WHERE condition to ON expression for outer join, because we
*conds= and_conds(*conds, where); 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) if (arena)
thd->restore_backup_item_arena(arena, &backup); 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 */ /* full text function moving to current select */
if (view->select_lex.ftfunc_list->elements) if (view->select_lex.ftfunc_list->elements)
......
...@@ -182,6 +182,10 @@ struct st_table { ...@@ -182,6 +182,10 @@ struct st_table {
#define VIEW_ALGORITHM_TMEPTABLE 1 #define VIEW_ALGORITHM_TMEPTABLE 1
#define VIEW_ALGORITHM_MERGE 2 #define VIEW_ALGORITHM_MERGE 2
#define VIEW_CHECK_NONE 0
#define VIEW_CHECK_LOCAL 1
#define VIEW_CHECK_CASCADED 2
struct st_lex; struct st_lex;
typedef struct st_table_list typedef struct st_table_list
...@@ -215,6 +219,7 @@ typedef struct st_table_list ...@@ -215,6 +219,7 @@ typedef struct st_table_list
/* most upper view this table belongs to */ /* most upper view this table belongs to */
st_table_list *belong_to_view; st_table_list *belong_to_view;
Item *where; /* VIEW WHERE clause condition */ Item *where; /* VIEW WHERE clause condition */
Item *check_option; /* WITH CHECK OPTION condition */
LEX_STRING query; /* text of (CRETE/SELECT) statement */ LEX_STRING query; /* text of (CRETE/SELECT) statement */
LEX_STRING md5; /* md5 of query tesxt */ LEX_STRING md5; /* md5 of query tesxt */
LEX_STRING source; /* source of CREATE VIEW */ LEX_STRING source; /* source of CREATE VIEW */
...@@ -225,6 +230,7 @@ typedef struct st_table_list ...@@ -225,6 +230,7 @@ typedef struct st_table_list
ulonglong updatable_view; /* VIEW can be updated */ ulonglong updatable_view; /* VIEW can be updated */
ulonglong revision; /* revision control number */ ulonglong revision; /* revision control number */
ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */
ulonglong with_check; /* WITH CHECK OPTION */
uint effective_algorithm; /* which algorithm was really used */ uint effective_algorithm; /* which algorithm was really used */
GRANT_INFO grant; GRANT_INFO grant;
thr_lock_type lock_type; thr_lock_type lock_type;
...@@ -236,6 +242,7 @@ typedef struct st_table_list ...@@ -236,6 +242,7 @@ typedef struct st_table_list
bool updating; /* for replicate-do/ignore table */ bool updating; /* for replicate-do/ignore table */
bool force_index; /* prefer index over table scan */ bool force_index; /* prefer index over table scan */
bool ignore_leaves; /* preload only non-leaf nodes */ 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 dep_tables; /* tables the table depends on */
table_map on_expr_dep_tables; /* tables on expression 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 */ struct st_nested_join *nested_join; /* if the element is a nested join */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment