From dabef66e66a48f2d5f4ca5fdfd1f9d927e935471 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Mon, 29 Apr 2019 20:32:36 +1000 Subject: [PATCH 1/4] MDEV-19188 Server Crash When Using a Trigger With A Number of Virtual Columns on INSERT/UPDATE use s->fields instead of s->stored_fields. extra_null_bitmap is allocated in Table_triggers_list::prepare_record_accessors with respect to virtual fields, so it will not overflow Closes #1292 --- mysql-test/r/trigger.result | 30 +++++++++++++++++++++++++----- mysql-test/t/trigger.test | 33 ++++++++++++++++++++++++++++----- sql/sql_trigger.h | 2 +- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 901d132cd2c..00f16accb3e 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1962,7 +1962,7 @@ ERROR HY000: Can't update table 't2' in stored function/trigger because it is al DROP TABLE t1; DROP TRIGGER t_insert; DROP TABLE t2; -End of 5.0 tests +# End of 5.0 tests drop table if exists table_25411_a; drop table if exists table_25411_b; create table table_25411_a(a int); @@ -2131,7 +2131,7 @@ b # Work around Bug#45235 DROP DATABASE db1; USE test; -End of 5.1 tests. +# End of 5.1 tests. create table t1 (i int); create table t2 (i int); flush tables; @@ -2150,7 +2150,7 @@ select * from t2; i 2 drop table t1,t2; -End of 5.2 tests. +# End of 5.2 tests. # # Bug#34453 Can't change size of file (Errcode: 1224) # @@ -2253,7 +2253,7 @@ c aaa DROP TABLE t1; -End of 5.5 tests. +# End of 5.5 tests. # # BUG #910083: materialized subquery in a trigger # @@ -2300,7 +2300,7 @@ b SET optimizer_switch=@save_optimizer_switch; DROP TRIGGER tr; DROP TABLE t1, t2; -End of 5.3 tests. +# End of 5.3 tests. set time_zone="+00:00"; SET TIMESTAMP=UNIX_TIMESTAMP('2001-01-01 10:20:30'); SET @@session.sql_mode = 'STRICT_ALL_TABLES,STRICT_TRANS_TABLES'; @@ -2407,3 +2407,23 @@ CREATE TRIGGER tr AFTER UPDATE ON t1 FOR EACH ROW SELECT (SELECT b FROM t2) INTO @x; # Running 20000 queries DROP TABLE t1,t2; +# +# MDEV-19188 Server Crash When Using a Trigger With A Number of Virtual Columns on INSERT/UPDATE +# +CREATE TABLE t1 ( +virt1 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt2 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt3 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt4 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt5 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt6 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt7 INT GENERATED ALWAYS AS (0) VIRTUAL, +virt8 INT GENERATED ALWAYS AS (0) VIRTUAL +); +INSERT INTO t1 () VALUES (); +CREATE TRIGGER t1_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN END; +INSERT INTO t1 () VALUES (); +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index b9e908e9944..a4beeaf9161 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2184,7 +2184,7 @@ DROP TABLE t1; DROP TRIGGER t_insert; DROP TABLE t2; ---echo End of 5.0 tests +--echo # End of 5.0 tests # # Bug#25411 (trigger code truncated) @@ -2406,7 +2406,7 @@ let $MYSQLD_DATADIR = `select @@datadir`; DROP DATABASE db1; USE test; ---echo End of 5.1 tests. +--echo # End of 5.1 tests. # # Test that using a trigger will not open mysql.proc @@ -2430,7 +2430,7 @@ select * from t1; select * from t2; drop table t1,t2; ---echo End of 5.2 tests. +--echo # End of 5.2 tests. --echo # --echo # Bug#34453 Can't change size of file (Errcode: 1224) @@ -2574,7 +2574,7 @@ SELECT c FROM t1; DROP TABLE t1; --echo ---echo End of 5.5 tests. +--echo # End of 5.5 tests. --echo # --echo # BUG #910083: materialized subquery in a trigger @@ -2613,7 +2613,7 @@ SET optimizer_switch=@save_optimizer_switch; DROP TRIGGER tr; DROP TABLE t1, t2; ---echo End of 5.3 tests. +--echo # End of 5.3 tests. # # MDEV-4829 BEFORE INSERT triggers dont issue 1406 error @@ -2737,3 +2737,26 @@ while ($n) --enable_query_log DROP TABLE t1,t2; + +--echo # +--echo # MDEV-19188 Server Crash When Using a Trigger With A Number of Virtual Columns on INSERT/UPDATE +--echo # + +CREATE TABLE t1 ( + virt1 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt2 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt3 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt4 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt5 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt6 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt7 INT GENERATED ALWAYS AS (0) VIRTUAL, + virt8 INT GENERATED ALWAYS AS (0) VIRTUAL +); +INSERT INTO t1 () VALUES (); +CREATE TRIGGER t1_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN END; +INSERT INTO t1 () VALUES (); +DROP TABLE t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 9d1c79cc7cf..6e94f348447 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -274,7 +274,7 @@ public: Field **nullable_fields() { return record0_field; } void reset_extra_null_bitmap() { - size_t null_bytes= (trigger_table->s->stored_fields - + size_t null_bytes= (trigger_table->s->fields - trigger_table->s->null_fields + 7)/8; bzero(extra_null_bitmap, null_bytes); } From b953bf7eb2cbebf74b1f8861f4c45a789d365f28 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 1 May 2019 13:14:50 +0200 Subject: [PATCH 2/4] compilation fixes for VS 2019 --- sql/sql_analyze_stmt.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc index 8e67267f6a0..9aed432c2b6 100644 --- a/sql/sql_analyze_stmt.cc +++ b/sql/sql_analyze_stmt.cc @@ -45,7 +45,7 @@ void Filesort_tracker::print_json_members(Json_writer *writer) else if (r_limit == 0) writer->add_str(varied_str); else - writer->add_ll((longlong) rint(r_limit)); + writer->add_ll(r_limit); } writer->add_member("r_used_priority_queue"); @@ -61,13 +61,13 @@ void Filesort_tracker::print_json_members(Json_writer *writer) if (!get_r_loops()) writer->add_member("r_output_rows").add_null(); else - writer->add_member("r_output_rows").add_ll((longlong) rint(r_output_rows / - get_r_loops())); + writer->add_member("r_output_rows").add_ll( + (longlong) rint((double)r_output_rows / get_r_loops())); if (sort_passes) { - writer->add_member("r_sort_passes").add_ll((longlong) rint(sort_passes / - get_r_loops())); + writer->add_member("r_sort_passes").add_ll( + (longlong) rint((double)sort_passes / get_r_loops())); } if (sort_buffer_size != 0) From dc8e15db7e170964699dec7b5214d20200b4b182 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 2 Jan 2018 12:00:55 +1100 Subject: [PATCH 3/4] MDEV-15051: signal handler - output information about the core generation The working directory, resource limits and core pattern will aid the user finding a core file in the case of failure. While the core file size is most relevant however other resource limits may give a clue as the the cause of the fatal signal so include them also. As signal handler functions are limited, proc filesystem reads/ readlink calls are used instead of the more obvious getcwd/getrlimits functions which aren't listed as signal safe. Results in output of the form: Writing a core file: working directory at /tmp/datadir Resource Limits: Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size unlimited unlimited bytes Max resident set unlimited unlimited bytes Max processes 47194 47194 processes Max open files 1024 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 47194 47194 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us Core pattern: |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t %P %I Segmentation fault (core dumped) Closes #537 --- sql/signal_handler.cc | 46 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 68e801d5885..6c0220b1254 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -30,6 +30,10 @@ #define SIGNAL_FMT "signal %d" #endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + /* We are handling signals/exceptions in this file. Any global variables we read should be 'volatile sig_atomic_t' @@ -44,6 +48,43 @@ extern volatile sig_atomic_t ld_assume_kernel_is_set; extern const char *optimizer_switch_names[]; +static inline void output_core_info() +{ + /* proc is optional on some BSDs so it can't hurt to look */ +#ifdef HAVE_READLINK + char buff[PATH_MAX]; + ssize_t len; + int fd; + if ((len= readlink("/proc/self/cwd", buff, sizeof(buff))) >= 0) + { + my_safe_printf_stderr("Writing a core file...\nWorking directory at %.*s\n", + (int) len, buff); + } + if ((fd= my_open("/proc/self/limits", O_RDONLY, MYF(0))) >= 0) + { + my_safe_printf_stderr("Resource Limits:\n"); + while ((len= my_read(fd, (uchar*)buff, sizeof(buff), MYF(0))) > 0) + { + my_write_stderr(buff, len); + } + my_close(fd, MYF(0)); + } +#ifdef __linux__ + if ((fd= my_open("/proc/sys/kernel/core_pattern", O_RDONLY, MYF(0))) >= 0) + { + len= my_read(fd, (uchar*)buff, sizeof(buff), MYF(0)); + my_safe_printf_stderr("Core pattern: %.*s\n", (int) len, buff); + my_close(fd, MYF(0)); + } +#endif +#else + char buff[80]; + my_getwd(buff, sizeof(buff), 0); + my_safe_printf_stderr("Writing a core file at %s\n", buff); + fflush(stderr); +#endif +} + /** * Handler for fatal signals on POSIX, exception handler on Windows. * @@ -295,13 +336,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) } #endif + output_core_info(); #ifdef HAVE_WRITE_CORE if (test_flags & TEST_CORE_ON_SIGNAL) { - char buff[80]; - my_getwd(buff, sizeof(buff), 0); - my_safe_printf_stderr("Writing a core file at %s\n", buff); - fflush(stderr); my_write_core(sig); } #endif From 2370eeb028b269243633b18f7661dca999089a41 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Fri, 9 Nov 2018 06:12:43 -0800 Subject: [PATCH 4/4] MDEV-17654 Incorrect syntax returned for column with CHECK constraint in the "SHOW CREATE TABLE ..." result Prepend COMMENT before CHECK constraint in SHOW CREATE Closes #924 --- mysql-test/r/constraints.result | 19 +++++++++++++++++++ mysql-test/t/constraints.test | 17 +++++++++++++++++ sql/sql_show.cc | 17 ++++++++++------- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result index 3c061989fd3..df93b69cb9e 100644 --- a/mysql-test/r/constraints.result +++ b/mysql-test/r/constraints.result @@ -111,3 +111,22 @@ long_enough_name CREATE TABLE `long_enough_name` ( CONSTRAINT `constr` CHECK (`f6` >= 0) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE long_enough_name; +CREATE TABLE test.t(t int COMMENT 't_comment' CHECK(t>0)); +SHOW CREATE TABLE test.t; +Table Create Table +t CREATE TABLE `t` ( + `t` int(11) DEFAULT NULL COMMENT 't_comment' CHECK (`t` > 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP table test.t; +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; +CREATE TABLE test.t (f int foo=bar check(f>0)); +Warnings: +Warning 1911 Unknown option 'foo' +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `f` int(11) DEFAULT NULL `foo`=bar CHECK (`f` > 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP table test.t; +SET @@SQL_MODE=@OLD_SQL_MODE; diff --git a/mysql-test/t/constraints.test b/mysql-test/t/constraints.test index fe51e5060dc..39b2eb52a9f 100644 --- a/mysql-test/t/constraints.test +++ b/mysql-test/t/constraints.test @@ -102,3 +102,20 @@ SELECT * FROM long_enough_name AS tbl; SHOW CREATE TABLE long_enough_name; DROP TABLE long_enough_name; + +# +# MDEV-17654 Incorrect syntax returned for column with CHECK constraint +# in the "SHOW CREATE TABLE ..." result +# + +CREATE TABLE test.t(t int COMMENT 't_comment' CHECK(t>0)); +SHOW CREATE TABLE test.t; +DROP table test.t; + +SET @OLD_SQL_MODE=@@SQL_MODE; +SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; + +CREATE TABLE test.t (f int foo=bar check(f>0)); +SHOW CREATE TABLE t; +DROP table test.t; +SET @@SQL_MODE=@OLD_SQL_MODE; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a29a6871b78..c84ac5f4977 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2065,6 +2065,16 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, !(sql_mode & MODE_NO_FIELD_OPTIONS)) packet->append(STRING_WITH_LEN(" AUTO_INCREMENT")); } + + if (field->comment.length) + { + packet->append(STRING_WITH_LEN(" COMMENT ")); + append_unescaped(packet, field->comment.str, field->comment.length); + } + + append_create_options(thd, packet, field->option_list, check_options, + hton->field_options); + if (field->check_constraint) { StringBuffer str(&my_charset_utf8mb4_general_ci); @@ -2074,13 +2084,6 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(")")); } - if (field->comment.length) - { - packet->append(STRING_WITH_LEN(" COMMENT ")); - append_unescaped(packet, field->comment.str, field->comment.length); - } - append_create_options(thd, packet, field->option_list, check_options, - hton->field_options); } key_info= table->key_info;