From c9f87b881315af80e73da3b0b74b4ca36f1cab18 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 26 Oct 2023 11:00:26 +0200 Subject: [PATCH] MDEV-32586 incorrect error about cyclic reference about JSON type virtual column remove the hack where NO_DEFAULT_VALUE_FLAG was temporarily removed from a field to initialize DEFAULT() functions in CHECK constraints while disabling self-reference field checks. Instead, initialize DEFAULT() functions in CHECK explicitly, don't call check_field_expression_processor() for CHECK at all. --- mysql-test/main/check_constraint.result | 10 ++++++++++ mysql-test/main/check_constraint.test | 13 +++++++++++++ sql/item.cc | 5 +++++ sql/item.h | 2 ++ sql/table.cc | 15 +++++---------- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 01a71bf36a5..e3986dcf75b 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -308,5 +308,15 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; # +# MDEV-32586 incorrect error about cyclic reference about JSON type virtual column +# +create table t1 (a int, b json as (a)); +drop table t1; +create table t1 (a int, b int as (a) check (b > 0)); +insert t1 (a) values (1); +insert t1 (a) values (-1); +ERROR 23000: CONSTRAINT `t1.b` failed for `test`.`t1` +drop table t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index cfdddcab3a1..e12468e9013 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -231,6 +231,19 @@ alter table t1 force; show create table t1; drop table t1; +--echo # +--echo # MDEV-32586 incorrect error about cyclic reference about JSON type virtual column +--echo # + +create table t1 (a int, b json as (a)); +drop table t1; + +create table t1 (a int, b int as (a) check (b > 0)); +insert t1 (a) values (1); +--error ER_CONSTRAINT_FAILED +insert t1 (a) values (-1); +drop table t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 34272156aad..723552e6b35 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9412,6 +9412,11 @@ bool Item_default_value::eq(const Item *item, bool binary_cmp) const bool Item_default_value::check_field_expression_processor(void *) +{ + return Item_default_value::update_func_default_processor(0); +} + +bool Item_default_value::update_func_default_processor(void *) { field->default_value= ((Item_field *)(arg->real_item()))->field->default_value; return 0; diff --git a/sql/item.h b/sql/item.h index d04d77da666..cefd23df0f1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2080,6 +2080,7 @@ public: } virtual bool check_field_expression_processor(void *arg) { return 0; } virtual bool check_func_default_processor(void *arg) { return 0; } + virtual bool update_func_default_processor(void *arg) { return 0; } /* Check if an expression value has allowed arguments, like DATE/DATETIME for date functions. Also used by partitioning code to reject @@ -6544,6 +6545,7 @@ public: bool update_vcol_processor(void *arg) { return 0; } bool check_field_expression_processor(void *arg); bool check_func_default_processor(void *arg) { return true; } + bool update_func_default_processor(void *arg); bool register_field_in_read_map(void *arg); bool walk(Item_processor processor, bool walk_subquery, void *args) diff --git a/sql/table.cc b/sql/table.cc index e6684cd1c72..eafeb6185a3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1074,19 +1074,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, return vcol && vcol->expr->walk(&Item::check_field_expression_processor, 0, field); } - static bool check_constraint(Field *field, Virtual_column_info *vcol) - { - uint32 flags= field->flags; - /* Check constraints can refer it itself */ - field->flags|= NO_DEFAULT_VALUE_FLAG; - const bool res= check(field, vcol); - field->flags= flags; - return res; - } static bool check(Field *field) { if (check(field, field->vcol_info) || - check_constraint(field, field->check_constraint) || check(field, field->default_value)) return true; return false; @@ -1300,11 +1290,16 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, /* Check that expressions aren't referring to not yet initialized fields */ for (field_ptr= table->field; *field_ptr; field_ptr++) + { if (check_vcol_forward_refs::check(*field_ptr)) { *error_reported= true; goto end; } + if ((*field_ptr)->check_constraint) + (*field_ptr)->check_constraint->expr-> + walk(&Item::update_func_default_processor, 0, *field_ptr); + } table->find_constraint_correlated_indexes();