summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/SETUP.sh2
-rw-r--r--CREDITS2
-rw-r--r--client/mysqlbinlog.cc1
-rw-r--r--mysql-test/main/contributors.result2
-rw-r--r--mysql-test/main/ctype_utf32.result25
-rw-r--r--mysql-test/main/ctype_utf32.test19
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result7
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test45
-rw-r--r--mysql-test/suite/rpl/r/mdev_24667.result30
-rw-r--r--mysql-test/suite/rpl/t/mdev_24667.cnf8
-rw-r--r--mysql-test/suite/rpl/t/mdev_24667.test56
-rw-r--r--plugin/server_audit/server_audit.c6
-rw-r--r--scripts/mysql_install_db.sh2
-rw-r--r--sql/contributors.h2
-rw-r--r--sql/handler.h4
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_table.cc43
-rw-r--r--sql/table.cc20
-rw-r--r--sql/temporary_tables.cc2
-rw-r--r--sql/unireg.cc11
-rw-r--r--storage/innobase/buf/buf0buf.cc96
-rw-r--r--storage/innobase/fil/fil0fil.cc7
-rw-r--r--storage/innobase/fts/fts0fts.cc4
-rw-r--r--storage/perfschema/unittest/stub_pfs_global.h14
-rw-r--r--strings/decimal.c32
25 files changed, 326 insertions, 118 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index bbf3aba1438..3d993f63805 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -211,7 +211,7 @@ fi
max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
-max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --without-plugin=plugin_file_key_management --with-plugin-rocksdb=dynamic --without-plugin-tokudb --with-plugin-test_sql_discovery=DYNAMIC"
+max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --with-plugin-rocksdb=dynamic --without-plugin-tokudb --with-plugin-test_sql_discovery=DYNAMIC --with-plugin-file_key_management=DYNAMIC"
all_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-innodb_plugin --with-libevent"
#
diff --git a/CREDITS b/CREDITS
index f5e87e18752..35092602ccf 100644
--- a/CREDITS
+++ b/CREDITS
@@ -4,9 +4,11 @@ organization registered in the USA.
The current main sponsors of the MariaDB Foundation are:
Alibaba Cloud https://www.alibabacloud.com/ (2017)
+Intel https://www.intel.com (2022)
MariaDB Corporation https://www.mariadb.com (2013)
Microsoft https://microsoft.com/ (2017)
ServiceNow https://servicenow.com (2019)
+SIT https://sit.org (2022)
Tencent Cloud https://cloud.tencent.com (2017)
Development Bank of Singapore https://dbs.com (2016)
IBM https://www.ibm.com (2017)
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 1fa16015f4a..7df83ae9fd9 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -2569,6 +2569,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info,
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
+ fflush(result_file);
DBUG_RETURN(OK_CONTINUE);
}
diff --git a/mysql-test/main/contributors.result b/mysql-test/main/contributors.result
index 0c7ca03a2c5..8d72373696c 100644
--- a/mysql-test/main/contributors.result
+++ b/mysql-test/main/contributors.result
@@ -5,6 +5,8 @@ Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundati
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation
ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation
+Intel https://www.intel.com Platinum Sponsor of the MariaDB Foundation
+SIT https://sit.org Platinum Sponsor of the MariaDB Foundation
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result
index 143fff9e419..22cea274182 100644
--- a/mysql-test/main/ctype_utf32.result
+++ b/mysql-test/main/ctype_utf32.result
@@ -2913,5 +2913,30 @@ t1 CREATE TABLE `t1` (
DROP TABLE t1;
SET NAMES utf8;
#
+# MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
+#
+CREATE TABLE t1 (
+c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
+c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` enum('a','b') CHARACTER SET utf32 DEFAULT 'a',
+ `c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
+c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` enum('00000061','00000062') CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '00000061',
+ `c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test
index 46ff333b5f7..739096ae9cb 100644
--- a/mysql-test/main/ctype_utf32.test
+++ b/mysql-test/main/ctype_utf32.test
@@ -1068,5 +1068,24 @@ SET NAMES utf8;
--echo #
+--echo # MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
+--echo #
+
+CREATE TABLE t1 (
+ c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
+ c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
+ c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
new file mode 100644
index 00000000000..9148f0e8c2b
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
@@ -0,0 +1,7 @@
+CREATE TABLE t1 (a int);
+FLUSH LOGS;
+INSERT INTO t1 VALUES (1);
+# timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
+# MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+FOUND 1 /GTID 0-1-2/ in local-bin.000002.out
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
new file mode 100644
index 00000000000..f95fc0137a2
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
@@ -0,0 +1,45 @@
+#
+# Purpose:
+# When using mariadb-binlog with options for --raw and --stop-never, events
+# from the master's currently active log file should be written to their
+# respective log file specified by --result-file, and shown on-disk. This test
+# ensures that the log files on disk, created by mariadb-binlog, have the most
+# up-to-date events from the master.
+#
+# Methodology:
+# On the master, rotate to a newly active binlog file and write an event to
+# it. Read the master's binlog using mariadb-binlog with --raw and --stop-never
+# and write the data to an intermediary binlog file (a timeout is used on this
+# command to ensure it exits). Read the local intermediary binlog file to ensure
+# that the master's most recent event exists in the local file.
+#
+# References:
+# MDEV-14608: mysqlbinlog lastest backupfile size is 0
+#
+
+--source include/linux.inc
+--source include/have_log_bin.inc
+
+# Create newly active log
+CREATE TABLE t1 (a int);
+FLUSH LOGS;
+INSERT INTO t1 VALUES (1);
+
+# Read binlog data from master to intermediary result file
+--let TIMEOUT=1
+--echo # timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
+--error 124 # Error 124 means timeout was reached
+--exec timeout $TIMEOUT $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --stop-never --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001
+
+# Ensure the binlog output has the most recent events from the master
+--echo # MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/tmp/master-bin.000002 > $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--let SEARCH_PATTERN= GTID 0-1-2
+--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--source include/search_pattern_in_file.inc
+
+# Cleanup
+DROP TABLE t1;
+--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000001
+--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000002
+--remove_file $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
diff --git a/mysql-test/suite/rpl/r/mdev_24667.result b/mysql-test/suite/rpl/r/mdev_24667.result
new file mode 100644
index 00000000000..7c7342d63d6
--- /dev/null
+++ b/mysql-test/suite/rpl/r/mdev_24667.result
@@ -0,0 +1,30 @@
+include/rpl_init.inc [topology=1->2->3]
+call mtr.add_suppression('Unsafe statement written to the binary log using ');
+connection server_1;
+set binlog_format=statement;
+#first bug
+create table t1 (a int);
+create temporary table tmp like t1;
+load data local infile 'MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
+insert into t1 select * from tmp;
+#second bug
+create table t2 (a int);
+create temporary table tmp2 like t2;
+insert into tmp2 values(10);
+update tmp2 set a = 20 limit 1;
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+insert into t2 select * from tmp2;
+connection server_2;
+connection server_3;
+#t1 should have 2 rows
+select count(*) = 2 from t1;
+count(*) = 2
+1
+#t2 should have 1 rows with a = 20
+select * from t2;
+a
+20
+connection server_1;
+drop table t1, t2, tmp, tmp2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/mdev_24667.cnf b/mysql-test/suite/rpl/t/mdev_24667.cnf
new file mode 100644
index 00000000000..58b605ad928
--- /dev/null
+++ b/mysql-test/suite/rpl/t/mdev_24667.cnf
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.3]
+log-slave-updates
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
diff --git a/mysql-test/suite/rpl/t/mdev_24667.test b/mysql-test/suite/rpl/t/mdev_24667.test
new file mode 100644
index 00000000000..d8490b335db
--- /dev/null
+++ b/mysql-test/suite/rpl/t/mdev_24667.test
@@ -0,0 +1,56 @@
+#
+# MDEV-24667 LOAD DATA INFILE/inserted rows not written to binlog
+#
+# In this test we will have a replication configuration like 1->2->3
+# 1 will have statement format
+# 2 and 3 will have mixed format
+# We will make some updates on temporary table which are unsafe , So 2 must
+# Log these queries in row format, Since it is on tmp table , It wont be logged
+# So the next query which copies the data from tmp table to normal must be logged
+# into the row format. Instead of checking for the binlog We will compare the
+# results on the 3, If no binlog is lost(ie it is logged into row format), There
+# should not be any data loss.
+--let $rpl_topology=1->2->3
+--source include/rpl_init.inc
+--source include/have_binlog_format_mixed.inc
+call mtr.add_suppression('Unsafe statement written to the binary log using ');
+--connection server_1
+
+set binlog_format=statement;
+--echo #first bug
+create table t1 (a int);
+create temporary table tmp like t1;
+--write_file $MYSQLTEST_VARDIR/load_data
+1
+2
+EOF
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval load data local infile '$MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
+insert into t1 select * from tmp;
+
+--echo #second bug
+create table t2 (a int);
+#insert into t2 values(10);
+create temporary table tmp2 like t2;
+insert into tmp2 values(10);
+update tmp2 set a = 20 limit 1;
+insert into t2 select * from tmp2;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+--save_master_pos
+
+--connection server_3
+--sync_with_master
+--echo #t1 should have 2 rows
+select count(*) = 2 from t1;
+--echo #t2 should have 1 rows with a = 20
+select * from t2;
+
+
+# cleanup
+--connection server_1
+drop table t1, t2, tmp, tmp2;
+--remove_file $MYSQLTEST_VARDIR/load_data
+--source include/rpl_end.inc
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index deada5699b4..12f43c3e330 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -2351,6 +2351,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
#ifdef __x86_64__
db_off= 608;
db_len_off= 616;
+#elif __aarch64__
+ db_off= 632;
+ db_len_off= 640;
#else
db_off= 0;
db_len_off= 0;
@@ -2361,6 +2364,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
#ifdef __x86_64__
db_off= 536;
db_len_off= 544;
+#elif __aarch64__
+ db_off= 552;
+ db_len_off= 560;
#else
db_off= 0;
db_len_off= 0;
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 8a0da9811b5..4c6376142cc 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -505,7 +505,7 @@ mysqld_install_cmd_line()
{
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
- "--plugin-dir=${plugindir}" --loose-disable-plugin-file-key-management \
+ "--plugin-dir=${plugindir}" \
$args --max_allowed_packet=8M \
--net_buffer_length=16K
}
diff --git a/sql/contributors.h b/sql/contributors.h
index e16448ee985..bc8ba4eabbb 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -42,6 +42,8 @@ struct show_table_contributors_st show_table_contributors[]= {
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"Intel", "https://www.intel.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"SIT", "https://sit.org", "Platinum Sponsor of the MariaDB Foundation"},
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
diff --git a/sql/handler.h b/sql/handler.h
index c65b7b6a8d5..de4fd513070 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 2022, MariaDB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -4765,7 +4765,7 @@ static inline const char *ha_resolve_storage_engine_name(const handlerton *db_ty
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
{
- return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
+ return db_type && (db_type->flags & flag);
}
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 637e16c991b..8268ebe0bcd 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4173,13 +4173,13 @@ public:
*/
DBUG_PRINT("debug",
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
- YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
+ YESNO(has_temporary_tables()), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if (in_sub_stmt == 0)
{
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
set_current_stmt_binlog_format_row();
- else if (!has_thd_temporary_tables())
+ else if (!has_temporary_tables())
set_current_stmt_binlog_format_stmt();
}
DBUG_VOID_RETURN;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 07adda33ad3..648b2f3cba5 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9614,22 +9614,24 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
}
+ handlerton * const old_db_type= table->s->db_type();
+ handlerton *new_db_type= create_info->db_type;
+
DBUG_PRINT("info", ("old type: %s new type: %s",
- ha_resolve_storage_engine_name(table->s->db_type()),
- ha_resolve_storage_engine_name(create_info->db_type)));
- if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED))
+ ha_resolve_storage_engine_name(old_db_type),
+ ha_resolve_storage_engine_name(new_db_type)));
+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(table->s->db_type())->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str,
alter_ctx.db.str, alter_ctx.table_name.str);
DBUG_RETURN(true);
}
- if (ha_check_storage_engine_flag(create_info->db_type,
- HTON_ALTER_NOT_SUPPORTED))
+ if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(create_info->db_type)->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str,
alter_ctx.new_db.str, alter_ctx.new_name.str);
DBUG_RETURN(true);
}
@@ -9772,6 +9774,17 @@ do_continue:;
DBUG_RETURN(true);
}
}
+ /*
+ If the old table had partitions and we are doing ALTER TABLE ...
+ engine= <new_engine>, the new table must preserve the original
+ partitioning. This means that the new engine is still the
+ partitioning engine, not the engine specified in the parser.
+ This is discovered in prep_alter_part_table, which in such case
+ updates create_info->db_type.
+ It's therefore important that the assignment below is done
+ after prep_alter_part_table.
+ */
+ new_db_type= create_info->db_type;
#endif
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
@@ -9853,7 +9866,7 @@ do_continue:;
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|| is_inplace_alter_impossible(table, create_info, alter_info)
|| IF_PARTITIONING((partition_changed &&
- !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
+ !(old_db_type->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
{
if (alter_info->algorithm(thd) ==
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
@@ -9871,22 +9884,10 @@ do_continue:;
request table rebuild. Set ALTER_RECREATE flag to force table
rebuild.
*/
- if (create_info->db_type == table->s->db_type() &&
+ if (new_db_type == old_db_type &&
create_info->used_fields & HA_CREATE_USED_ENGINE)
alter_info->flags|= ALTER_RECREATE;
- /*
- If the old table had partitions and we are doing ALTER TABLE ...
- engine= <new_engine>, the new table must preserve the original
- partitioning. This means that the new engine is still the
- partitioning engine, not the engine specified in the parser.
- This is discovered in prep_alter_part_table, which in such case
- updates create_info->db_type.
- It's therefore important that the assignment below is done
- after prep_alter_part_table.
- */
- handlerton *new_db_type= create_info->db_type;
- handlerton *old_db_type= table->s->db_type();
TABLE *new_table= NULL;
ha_rows copied=0,deleted=0;
diff --git a/sql/table.cc b/sql/table.cc
index 5e30732fc82..2ab947d69cd 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1245,6 +1245,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
+ bool *interval_unescaped= NULL;
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
keyinfo= &first_keyinfo;
@@ -1724,6 +1725,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err;
+ if (interval_count)
+ {
+ if (!(interval_unescaped= (bool*) my_alloca(interval_count * sizeof(bool))))
+ goto err;
+ bzero(interval_unescaped, interval_count * sizeof(bool));
+ }
+
field_ptr= share->field;
table_check_constraints= share->check_constraints;
read_length=(uint) (share->fields * field_pack_length +
@@ -2019,11 +2027,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->mysql_version < 100200)
pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
- if (interval_nr && charset->mbminlen > 1)
+ if (interval_nr && charset->mbminlen > 1 &&
+ !interval_unescaped[interval_nr - 1])
{
- /* Unescape UCS2 intervals from HEX notation */
+ /*
+ Unescape UCS2/UTF16/UTF32 intervals from HEX notation.
+ Note, ENUM/SET columns with equal value list share a single
+ copy of TYPELIB. Unescape every TYPELIB only once.
+ */
TYPELIB *interval= share->intervals + interval_nr - 1;
unhex_type2(interval);
+ interval_unescaped[interval_nr - 1]= true;
}
#ifndef TO_BE_DELETED_ON_PRODUCTION
@@ -2720,6 +2734,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++;
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(0);
err:
@@ -2734,6 +2749,7 @@ err:
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
}
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index 26036fba7e0..8cae54f6a54 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -876,7 +876,7 @@ void THD::restore_tmp_table_share(TMP_TABLE_SHARE *share)
@return false Temporary tables exist
true No temporary table exist
*/
-inline bool THD::has_temporary_tables()
+bool THD::has_temporary_tables()
{
DBUG_ENTER("THD::has_temporary_tables");
bool result= (rgi_slave
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 86a58db2f9d..efbb5e773b4 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -844,7 +844,16 @@ static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
while ((field=it++) != last_field)
{
- if (field->interval_id && field->interval->count == interval->count)
+ /*
+ ENUM/SET columns with equal value lists share a single
+ copy of the underlying TYPELIB.
+ Fields with different mbminlen can't reuse TYPELIBs, because:
+ - mbminlen==1 are written to FRM as is
+ - mbminlen>1 are written to FRM in hex-encoded format
+ */
+ if (field->interval_id &&
+ field->interval->count == interval->count &&
+ field->charset->mbminlen == last_field->charset->mbminlen)
{
const char **a,**b;
for (a=field->interval->type_names, b=interval->type_names ;
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 3cacf8daf79..aa6a6169db5 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -975,8 +975,6 @@ buf_page_is_corrupted(
#endif
size_t checksum_field1 = 0;
size_t checksum_field2 = 0;
- uint32_t crc32 = 0;
- bool crc32_inited = false;
ulint page_type = mach_read_from_2(read_buf + FIL_PAGE_TYPE);
@@ -1100,8 +1098,13 @@ buf_page_is_corrupted(
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
return !buf_page_is_checksum_valid_none(
read_buf, checksum_field1, checksum_field2);
+ case SRV_CHECKSUM_ALGORITHM_NONE:
+ /* should have returned false earlier */
+ break;
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_INNODB:
+ const uint32_t crc32 = buf_calc_page_crc32(read_buf);
+
if (buf_page_is_checksum_valid_none(read_buf,
checksum_field1, checksum_field2)) {
#ifdef UNIV_INNOCHECKSUM
@@ -1117,7 +1120,7 @@ buf_page_is_corrupted(
" crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
cur_page_num,
buf_calc_page_new_checksum(read_buf),
- buf_calc_page_crc32(read_buf),
+ crc32,
checksum_field1);
}
#endif /* UNIV_INNOCHECKSUM */
@@ -1134,85 +1137,34 @@ buf_page_is_corrupted(
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) {
- DBUG_EXECUTE_IF(
- "page_intermittent_checksum_mismatch", {
- static int page_counter;
- if (page_counter++ == 2) {
- checksum_field2++;
- }
- });
-
- crc32 = buf_page_check_crc32(read_buf,
- checksum_field2);
- crc32_inited = true;
-
- if (checksum_field2 != crc32
- && checksum_field2
- != buf_calc_page_old_checksum(read_buf)) {
- return true;
- }
- } else {
- ut_ad(curr_algo
- == SRV_CHECKSUM_ALGORITHM_INNODB);
-
- if (checksum_field2
- != buf_calc_page_old_checksum(read_buf)) {
- crc32 = buf_page_check_crc32(
- read_buf, checksum_field2);
- crc32_inited = true;
-
- if (checksum_field2 != crc32) {
- return true;
- }
- }
+ DBUG_EXECUTE_IF(
+ "page_intermittent_checksum_mismatch", {
+ static int page_counter;
+ if (page_counter++ == 2) return true;
+ });
+
+ if ((checksum_field1 != crc32
+ || checksum_field2 != crc32)
+ && checksum_field2
+ != buf_calc_page_old_checksum(read_buf)) {
+ return true;
}
}
- if (checksum_field1 == 0
- || checksum_field1 == BUF_NO_CHECKSUM_MAGIC) {
- } else if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) {
- if (!crc32_inited) {
- crc32 = buf_page_check_crc32(
- read_buf, checksum_field2);
- crc32_inited = true;
- }
-
- if (checksum_field1 != crc32
+ switch (checksum_field1) {
+ case 0:
+ case BUF_NO_CHECKSUM_MAGIC:
+ break;
+ default:
+ if ((checksum_field1 != crc32
+ || checksum_field2 != crc32)
&& checksum_field1
!= buf_calc_page_new_checksum(read_buf)) {
return true;
}
- } else {
- ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB);
-
- if (checksum_field1
- != buf_calc_page_new_checksum(read_buf)) {
-
- if (!crc32_inited) {
- crc32 = buf_page_check_crc32(
- read_buf, checksum_field2);
- crc32_inited = true;
- }
-
- if (checksum_field1 != crc32) {
- return true;
- }
- }
- }
-
- if (crc32_inited
- && ((checksum_field1 == crc32
- && checksum_field2 != crc32)
- || (checksum_field1 != crc32
- && checksum_field2 == crc32))) {
- return true;
}
break;
- case SRV_CHECKSUM_ALGORITHM_NONE:
- /* should have returned false earlier */
- break;
}
return false;
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 89f89d60454..45a4a280b10 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2021, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2021, MariaDB Corporation.
+Copyright (c) 2014, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2730,10 +2730,11 @@ fil_make_filepath(
if (path != NULL) {
memcpy(full_name, path, path_len);
len = path_len;
- full_name[len] = '\0';
- os_normalize_path(full_name);
}
+ full_name[len] = '\0';
+ os_normalize_path(full_name);
+
if (trim_name) {
/* Find the offset of the last DIR separator and set it to
null in order to strip off the old basename from this path. */
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index c9610d29a55..6ac41ac1f03 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -2285,9 +2285,7 @@ fts_trx_table_create(
fts_trx_table_t* ftt;
ftt = static_cast<fts_trx_table_t*>(
- mem_heap_alloc(fts_trx->heap, sizeof(*ftt)));
-
- memset(ftt, 0x0, sizeof(*ftt));
+ mem_heap_zalloc(fts_trx->heap, sizeof *ftt));
ftt->table = table;
ftt->fts_trx = fts_trx;
diff --git a/storage/perfschema/unittest/stub_pfs_global.h b/storage/perfschema/unittest/stub_pfs_global.h
index 8a1f9216ba2..b7adbe33504 100644
--- a/storage/perfschema/unittest/stub_pfs_global.h
+++ b/storage/perfschema/unittest/stub_pfs_global.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
@@ -24,6 +25,9 @@
#include <my_sys.h>
#include <pfs_global.h>
#include <string.h>
+#ifdef HAVE_MEMALIGN
+# include <malloc.h>
+#endif
bool pfs_initialized= false;
@@ -43,7 +47,17 @@ void *pfs_malloc(size_t size, myf)
if (--stub_alloc_fails_after_count <= 0)
return NULL;
+#ifndef PFS_ALIGNEMENT
void *ptr= malloc(size);
+#elif defined HAVE_MEMALIGN
+ void *ptr= memalign(PFS_ALIGNEMENT, size);
+#elif defined HAVE_ALIGNED_MALLOC
+ void *ptr= _aligned_malloc(size, PFS_ALIGNEMENT);
+#else
+ void *ptr;
+ if (posix_memalign(&ptr, PFS_ALIGNEMENT, size))
+ ptr= NULL;
+#endif
if (ptr != NULL)
memset(ptr, 0, size);
return ptr;
diff --git a/strings/decimal.c b/strings/decimal.c
index 16bc887814a..aa3a78fca24 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1128,13 +1128,21 @@ int decimal2ulonglong(const decimal_t *from, ulonglong *to)
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
{
- ulonglong y=x;
- x=x*DIG_BASE + *buf++;
- if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
+ /*
+ Check that the decimal is bigger than any possible integer.
+ Do it before we do the x*=DIB_BASE to avoid integer
+ overflow.
+ */
+ if (unlikely (
+ x >= ULONGLONG_MAX/DIG_BASE &&
+ (x > ULONGLONG_MAX/DIG_BASE ||
+ *buf > (dec1) (ULONGLONG_MAX%DIG_BASE))))
{
*to=ULONGLONG_MAX;
return E_DEC_OVERFLOW;
}
+
+ x=x*DIG_BASE + *buf++;
}
*to=x;
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
@@ -1151,23 +1159,29 @@ int decimal2longlong(const decimal_t *from, longlong *to)
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
{
- longlong y=x;
/*
+ Check that the decimal is less than any possible integer.
+ Do it before we do the x*=DIB_BASE to avoid integer
+ overflow.
Attention: trick!
we're calculating -|from| instead of |from| here
because |LONGLONG_MIN| > LONGLONG_MAX
- so we can convert -9223372036854775808 correctly
+ so we can convert -9223372036854775808 correctly.
*/
- x=x*DIG_BASE - *buf++;
- if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
+ if (unlikely (
+ x <= LONGLONG_MIN/DIG_BASE &&
+ (x < LONGLONG_MIN/DIG_BASE ||
+ *buf > (dec1) (-(LONGLONG_MIN%DIG_BASE)))))
{
/*
- the decimal is bigger than any possible integer
- return border integer depending on the sign
+ the decimal is bigger than any possible integer
+ return border integer depending on the sign
*/
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
return E_DEC_OVERFLOW;
}
+
+ x=x*DIG_BASE - *buf++;
}
/* boundary case: 9223372036854775808 */
if (unlikely(from->sign==0 && x == LONGLONG_MIN))