diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index e7080a67d90..a73fd8a4948 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5929,5 +5929,55 @@ a b 2 30 DROP TABLE t1, t2; # +# MDEV-33549: Incorrect handling of UPDATE in PS mode in case a table's colum declared as NOT NULL +# +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1 SET b=?' USING DEFAULT; +SELECT * FROM t1; +a b +20 NULL +# Run twice the same update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1 SET b=?'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# The same test for multi-table update +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +CREATE TABLE t2 (a INT, c INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +INSERT INTO t2 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +a b +20 NULL +# Run twice the same multi-table update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; +# Clean up +DROP TABLE t1; +# This time checks that a default value for table's column +# represented by a function call is handled correctly on UPDATE in PS mode +CREATE TABLE t1 (a INT, b INT DEFAULT MOD(a, 3)); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +a b +20 2 +# Run twice the same multi-table update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; +# # End of 10.4 tests # diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index e710050cb48..61d1513fa0b 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -5362,6 +5362,60 @@ SELECT * FROM t2; # Cleanup DROP TABLE t1, t2; +--echo # +--echo # MDEV-33549: Incorrect handling of UPDATE in PS mode in case a table's colum declared as NOT NULL +--echo # + +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1 SET b=?' USING DEFAULT; +SELECT * FROM t1; + +--echo # Run twice the same update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1 SET b=?'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; + +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + +--echo # The same test for multi-table update +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +CREATE TABLE t2 (a INT, c INT DEFAULT NULL); + +INSERT INTO t1 VALUES (20, 30); +INSERT INTO t2 VALUES (20, 30); + +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +--echo # Run twice the same multi-table update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; +--echo # Clean up +DROP TABLE t1; + +--echo # This time checks that a default value for table's column +--echo # represented by a function call is handled correctly on UPDATE in PS mode +CREATE TABLE t1 (a INT, b INT DEFAULT MOD(a, 3)); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; + +--echo # Run twice the same multi-table update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; + +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 7c8c9acca35..0e5ed30cb91 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5131,9 +5131,19 @@ bool Item_param::assign_default(Field *field) } if (m_default_field->default_value) - m_default_field->set_default(); - - return field_conv(field, m_default_field); + { + return m_default_field->default_value->expr->save_in_field(field, 0); + } + else if (m_default_field->is_null()) + { + field->set_null(); + return false; + } + else + { + field->set_notnull(); + return field_conv(field, m_default_field); + } } diff --git a/sql/item.h b/sql/item.h index f5c9ed2a7ab..1b696db66e9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3995,6 +3995,12 @@ public: Item_param(THD *thd, const LEX_CSTRING *name_arg, uint pos_in_query_arg, uint len_in_query_arg); + void cleanup() override + { + m_default_field= NULL; + Item::cleanup(); + } + Type type() const override { // Don't pretend to be a constant unless value for this item is set. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c136df0edc6..5d23a972cdc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2955,7 +2955,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) sigset_t set; int sig; my_thread_init(); // Init new thread - DBUG_ENTER("signal_hand"); signal_thread_in_use= 1; /* @@ -3009,7 +3008,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) { DBUG_PRINT("quit",("signal_handler: calling my_thread_end()")); my_thread_end(); - DBUG_LEAVE; // Must match DBUG_ENTER() signal_thread_in_use= 0; pthread_exit(0); // Safety return 0; // Avoid compiler warnings