Merge 10.2 into 10.3
This commit is contained in:
commit
020e7d89eb
@ -211,7 +211,7 @@ fi
|
|||||||
|
|
||||||
max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
|
max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
|
||||||
max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
|
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"
|
all_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-innodb_plugin --with-libevent"
|
||||||
|
|
||||||
#
|
#
|
||||||
|
2
CREDITS
2
CREDITS
@ -4,9 +4,11 @@ organization registered in the USA.
|
|||||||
The current main sponsors of the MariaDB Foundation are:
|
The current main sponsors of the MariaDB Foundation are:
|
||||||
|
|
||||||
Alibaba Cloud https://www.alibabacloud.com/ (2017)
|
Alibaba Cloud https://www.alibabacloud.com/ (2017)
|
||||||
|
Intel https://www.intel.com (2022)
|
||||||
MariaDB Corporation https://www.mariadb.com (2013)
|
MariaDB Corporation https://www.mariadb.com (2013)
|
||||||
Microsoft https://microsoft.com/ (2017)
|
Microsoft https://microsoft.com/ (2017)
|
||||||
ServiceNow https://servicenow.com (2019)
|
ServiceNow https://servicenow.com (2019)
|
||||||
|
SIT https://sit.org (2022)
|
||||||
Tencent Cloud https://cloud.tencent.com (2017)
|
Tencent Cloud https://cloud.tencent.com (2017)
|
||||||
Development Bank of Singapore https://dbs.com (2016)
|
Development Bank of Singapore https://dbs.com (2016)
|
||||||
IBM https://www.ibm.com (2017)
|
IBM https://www.ibm.com (2017)
|
||||||
|
@ -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);
|
error("Could not write into log file '%s'", out_file_name);
|
||||||
DBUG_RETURN(ERROR_STOP);
|
DBUG_RETURN(ERROR_STOP);
|
||||||
}
|
}
|
||||||
|
fflush(result_file);
|
||||||
|
|
||||||
DBUG_RETURN(OK_CONTINUE);
|
DBUG_RETURN(OK_CONTINUE);
|
||||||
}
|
}
|
||||||
|
@ -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
|
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
|
||||||
MariaDB Corporation https://mariadb.com Founding member, 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
|
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
|
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
|
||||||
DBS https://dbs.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
|
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
|
||||||
|
@ -2913,5 +2913,30 @@ t1 CREATE TABLE `t1` (
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET NAMES utf8;
|
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
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
|
@ -1067,6 +1067,25 @@ DROP TABLE t1;
|
|||||||
SET NAMES utf8;
|
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 #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -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;
|
45
mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
Normal file
45
mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
Normal file
@ -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
|
30
mysql-test/suite/rpl/r/mdev_24667.result
Normal file
30
mysql-test/suite/rpl/r/mdev_24667.result
Normal file
@ -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
|
8
mysql-test/suite/rpl/t/mdev_24667.cnf
Normal file
8
mysql-test/suite/rpl/t/mdev_24667.cnf
Normal file
@ -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
|
56
mysql-test/suite/rpl/t/mdev_24667.test
Normal file
56
mysql-test/suite/rpl/t/mdev_24667.test
Normal file
@ -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
|
@ -2351,6 +2351,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
|
|||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
db_off= 608;
|
db_off= 608;
|
||||||
db_len_off= 616;
|
db_len_off= 616;
|
||||||
|
#elif __aarch64__
|
||||||
|
db_off= 632;
|
||||||
|
db_len_off= 640;
|
||||||
#else
|
#else
|
||||||
db_off= 0;
|
db_off= 0;
|
||||||
db_len_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__
|
#ifdef __x86_64__
|
||||||
db_off= 536;
|
db_off= 536;
|
||||||
db_len_off= 544;
|
db_len_off= 544;
|
||||||
|
#elif __aarch64__
|
||||||
|
db_off= 552;
|
||||||
|
db_len_off= 560;
|
||||||
#else
|
#else
|
||||||
db_off= 0;
|
db_off= 0;
|
||||||
db_len_off= 0;
|
db_len_off= 0;
|
||||||
|
@ -505,7 +505,7 @@ mysqld_install_cmd_line()
|
|||||||
{
|
{
|
||||||
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
|
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
|
||||||
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
|
"--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 \
|
$args --max_allowed_packet=8M \
|
||||||
--net_buffer_length=16K
|
--net_buffer_length=16K
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ struct show_table_contributors_st show_table_contributors[]= {
|
|||||||
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
|
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
|
||||||
{"MariaDB Corporation", "https://mariadb.com", "Founding member, 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"},
|
{"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"},
|
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||||
{"DBS", "https://dbs.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"},
|
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define HANDLER_INCLUDED
|
#define HANDLER_INCLUDED
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
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
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
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)
|
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)
|
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
|
||||||
|
@ -4173,13 +4173,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
DBUG_PRINT("debug",
|
DBUG_PRINT("debug",
|
||||||
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
|
("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)));
|
show_system_thread(system_thread)));
|
||||||
if (in_sub_stmt == 0)
|
if (in_sub_stmt == 0)
|
||||||
{
|
{
|
||||||
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
||||||
set_current_stmt_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();
|
set_current_stmt_binlog_format_stmt();
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -9614,22 +9614,24 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
|||||||
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
|
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",
|
DBUG_PRINT("info", ("old type: %s new type: %s",
|
||||||
ha_resolve_storage_engine_name(table->s->db_type()),
|
ha_resolve_storage_engine_name(old_db_type),
|
||||||
ha_resolve_storage_engine_name(create_info->db_type)));
|
ha_resolve_storage_engine_name(new_db_type)));
|
||||||
if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED))
|
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("doesn't support alter"));
|
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);
|
alter_ctx.db.str, alter_ctx.table_name.str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ha_check_storage_engine_flag(create_info->db_type,
|
if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
|
||||||
HTON_ALTER_NOT_SUPPORTED))
|
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("doesn't support alter"));
|
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);
|
alter_ctx.new_db.str, alter_ctx.new_name.str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
@ -9772,6 +9774,17 @@ do_continue:;
|
|||||||
DBUG_RETURN(true);
|
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
|
#endif
|
||||||
|
|
||||||
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
|
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
|
||||||
@ -9853,7 +9866,7 @@ do_continue:;
|
|||||||
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
||||||
|| is_inplace_alter_impossible(table, create_info, alter_info)
|
|| is_inplace_alter_impossible(table, create_info, alter_info)
|
||||||
|| IF_PARTITIONING((partition_changed &&
|
|| 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) ==
|
if (alter_info->algorithm(thd) ==
|
||||||
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|
||||||
@ -9871,22 +9884,10 @@ do_continue:;
|
|||||||
request table rebuild. Set ALTER_RECREATE flag to force table
|
request table rebuild. Set ALTER_RECREATE flag to force table
|
||||||
rebuild.
|
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)
|
create_info->used_fields & HA_CREATE_USED_ENGINE)
|
||||||
alter_info->flags|= ALTER_RECREATE;
|
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;
|
TABLE *new_table= NULL;
|
||||||
ha_rows copied=0,deleted=0;
|
ha_rows copied=0,deleted=0;
|
||||||
|
|
||||||
|
20
sql/table.cc
20
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;
|
MEM_ROOT *old_root= thd->mem_root;
|
||||||
Virtual_column_info **table_check_constraints;
|
Virtual_column_info **table_check_constraints;
|
||||||
|
bool *interval_unescaped= NULL;
|
||||||
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
|
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
|
||||||
|
|
||||||
keyinfo= &first_keyinfo;
|
keyinfo= &first_keyinfo;
|
||||||
@ -1724,6 +1725,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
|
|
||||||
goto err;
|
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;
|
field_ptr= share->field;
|
||||||
table_check_constraints= share->check_constraints;
|
table_check_constraints= share->check_constraints;
|
||||||
read_length=(uint) (share->fields * field_pack_length +
|
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)
|
if (share->mysql_version < 100200)
|
||||||
pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
|
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;
|
TYPELIB *interval= share->intervals + interval_nr - 1;
|
||||||
unhex_type2(interval);
|
unhex_type2(interval);
|
||||||
|
interval_unescaped[interval_nr - 1]= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TO_BE_DELETED_ON_PRODUCTION
|
#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;
|
share->error= OPEN_FRM_OK;
|
||||||
thd->status_var.opened_shares++;
|
thd->status_var.opened_shares++;
|
||||||
thd->mem_root= old_root;
|
thd->mem_root= old_root;
|
||||||
|
my_afree(interval_unescaped);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -2734,6 +2749,7 @@ err:
|
|||||||
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
|
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
|
||||||
|
|
||||||
thd->mem_root= old_root;
|
thd->mem_root= old_root;
|
||||||
|
my_afree(interval_unescaped);
|
||||||
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
|
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,7 +876,7 @@ void THD::restore_tmp_table_share(TMP_TABLE_SHARE *share)
|
|||||||
@return false Temporary tables exist
|
@return false Temporary tables exist
|
||||||
true No temporary table exist
|
true No temporary table exist
|
||||||
*/
|
*/
|
||||||
inline bool THD::has_temporary_tables()
|
bool THD::has_temporary_tables()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("THD::has_temporary_tables");
|
DBUG_ENTER("THD::has_temporary_tables");
|
||||||
bool result= (rgi_slave
|
bool result= (rgi_slave
|
||||||
|
@ -844,7 +844,16 @@ static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
|
|||||||
|
|
||||||
while ((field=it++) != last_field)
|
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;
|
const char **a,**b;
|
||||||
for (a=field->interval->type_names, b=interval->type_names ;
|
for (a=field->interval->type_names, b=interval->type_names ;
|
||||||
|
@ -975,8 +975,6 @@ buf_page_is_corrupted(
|
|||||||
#endif
|
#endif
|
||||||
size_t checksum_field1 = 0;
|
size_t checksum_field1 = 0;
|
||||||
size_t checksum_field2 = 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);
|
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:
|
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||||
return !buf_page_is_checksum_valid_none(
|
return !buf_page_is_checksum_valid_none(
|
||||||
read_buf, checksum_field1, checksum_field2);
|
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_CRC32:
|
||||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||||
|
const uint32_t crc32 = buf_calc_page_crc32(read_buf);
|
||||||
|
|
||||||
if (buf_page_is_checksum_valid_none(read_buf,
|
if (buf_page_is_checksum_valid_none(read_buf,
|
||||||
checksum_field1, checksum_field2)) {
|
checksum_field1, checksum_field2)) {
|
||||||
#ifdef UNIV_INNOCHECKSUM
|
#ifdef UNIV_INNOCHECKSUM
|
||||||
@ -1117,7 +1120,7 @@ buf_page_is_corrupted(
|
|||||||
" crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
|
" crc32 = " UINT32PF "; recorded = " ULINTPF ";\n",
|
||||||
cur_page_num,
|
cur_page_num,
|
||||||
buf_calc_page_new_checksum(read_buf),
|
buf_calc_page_new_checksum(read_buf),
|
||||||
buf_calc_page_crc32(read_buf),
|
crc32,
|
||||||
checksum_field1);
|
checksum_field1);
|
||||||
}
|
}
|
||||||
#endif /* UNIV_INNOCHECKSUM */
|
#endif /* UNIV_INNOCHECKSUM */
|
||||||
@ -1134,84 +1137,33 @@ buf_page_is_corrupted(
|
|||||||
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
|
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
|
||||||
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
|
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
|
||||||
|
|
||||||
if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) {
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
"page_intermittent_checksum_mismatch", {
|
"page_intermittent_checksum_mismatch", {
|
||||||
static int page_counter;
|
static int page_counter;
|
||||||
if (page_counter++ == 2) {
|
if (page_counter++ == 2) return true;
|
||||||
checksum_field2++;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
crc32 = buf_page_check_crc32(read_buf,
|
if ((checksum_field1 != crc32
|
||||||
checksum_field2);
|
|| checksum_field2 != crc32)
|
||||||
crc32_inited = true;
|
|
||||||
|
|
||||||
if (checksum_field2 != crc32
|
|
||||||
&& checksum_field2
|
&& checksum_field2
|
||||||
!= buf_calc_page_old_checksum(read_buf)) {
|
!= buf_calc_page_old_checksum(read_buf)) {
|
||||||
return true;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checksum_field1 == 0
|
switch (checksum_field1) {
|
||||||
|| checksum_field1 == BUF_NO_CHECKSUM_MAGIC) {
|
case 0:
|
||||||
} else if (curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32) {
|
case BUF_NO_CHECKSUM_MAGIC:
|
||||||
if (!crc32_inited) {
|
break;
|
||||||
crc32 = buf_page_check_crc32(
|
default:
|
||||||
read_buf, checksum_field2);
|
if ((checksum_field1 != crc32
|
||||||
crc32_inited = true;
|
|| checksum_field2 != crc32)
|
||||||
}
|
|
||||||
|
|
||||||
if (checksum_field1 != crc32
|
|
||||||
&& checksum_field1
|
&& checksum_field1
|
||||||
!= buf_calc_page_new_checksum(read_buf)) {
|
!= buf_calc_page_new_checksum(read_buf)) {
|
||||||
return true;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2021, Oracle and/or its affiliates. All Rights Reserved.
|
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
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -2730,9 +2730,10 @@ fil_make_filepath(
|
|||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
memcpy(full_name, path, path_len);
|
memcpy(full_name, path, path_len);
|
||||||
len = path_len;
|
len = path_len;
|
||||||
|
}
|
||||||
|
|
||||||
full_name[len] = '\0';
|
full_name[len] = '\0';
|
||||||
os_normalize_path(full_name);
|
os_normalize_path(full_name);
|
||||||
}
|
|
||||||
|
|
||||||
if (trim_name) {
|
if (trim_name) {
|
||||||
/* Find the offset of the last DIR separator and set it to
|
/* Find the offset of the last DIR separator and set it to
|
||||||
|
@ -2285,9 +2285,7 @@ fts_trx_table_create(
|
|||||||
fts_trx_table_t* ftt;
|
fts_trx_table_t* ftt;
|
||||||
|
|
||||||
ftt = static_cast<fts_trx_table_t*>(
|
ftt = static_cast<fts_trx_table_t*>(
|
||||||
mem_heap_alloc(fts_trx->heap, sizeof(*ftt)));
|
mem_heap_zalloc(fts_trx->heap, sizeof *ftt));
|
||||||
|
|
||||||
memset(ftt, 0x0, sizeof(*ftt));
|
|
||||||
|
|
||||||
ftt->table = table;
|
ftt->table = table;
|
||||||
ftt->fts_trx = fts_trx;
|
ftt->fts_trx = fts_trx;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
/* 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
|
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,
|
it under the terms of the GNU General Public License, version 2.0,
|
||||||
@ -24,6 +25,9 @@
|
|||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <pfs_global.h>
|
#include <pfs_global.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_MEMALIGN
|
||||||
|
# include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
bool pfs_initialized= false;
|
bool pfs_initialized= false;
|
||||||
|
|
||||||
@ -43,7 +47,17 @@ void *pfs_malloc(size_t size, myf)
|
|||||||
if (--stub_alloc_fails_after_count <= 0)
|
if (--stub_alloc_fails_after_count <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifndef PFS_ALIGNEMENT
|
||||||
void *ptr= malloc(size);
|
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)
|
if (ptr != NULL)
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -1128,13 +1128,21 @@ int decimal2ulonglong(const decimal_t *from, ulonglong *to)
|
|||||||
|
|
||||||
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
||||||
{
|
{
|
||||||
ulonglong y=x;
|
/*
|
||||||
x=x*DIG_BASE + *buf++;
|
Check that the decimal is bigger than any possible integer.
|
||||||
if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
|
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;
|
*to=ULONGLONG_MAX;
|
||||||
return E_DEC_OVERFLOW;
|
return E_DEC_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x=x*DIG_BASE + *buf++;
|
||||||
}
|
}
|
||||||
*to=x;
|
*to=x;
|
||||||
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
|
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
|
||||||
@ -1151,15 +1159,19 @@ int decimal2longlong(const decimal_t *from, longlong *to)
|
|||||||
|
|
||||||
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
|
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!
|
Attention: trick!
|
||||||
we're calculating -|from| instead of |from| here
|
we're calculating -|from| instead of |from| here
|
||||||
because |LONGLONG_MIN| > LONGLONG_MAX
|
because |LONGLONG_MIN| > LONGLONG_MAX
|
||||||
so we can convert -9223372036854775808 correctly
|
so we can convert -9223372036854775808 correctly.
|
||||||
*/
|
*/
|
||||||
x=x*DIG_BASE - *buf++;
|
if (unlikely (
|
||||||
if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
|
x <= LONGLONG_MIN/DIG_BASE &&
|
||||||
|
(x < LONGLONG_MIN/DIG_BASE ||
|
||||||
|
*buf > (dec1) (-(LONGLONG_MIN%DIG_BASE)))))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
the decimal is bigger than any possible integer
|
the decimal is bigger than any possible integer
|
||||||
@ -1168,6 +1180,8 @@ int decimal2longlong(const decimal_t *from, longlong *to)
|
|||||||
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
|
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
|
||||||
return E_DEC_OVERFLOW;
|
return E_DEC_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x=x*DIG_BASE - *buf++;
|
||||||
}
|
}
|
||||||
/* boundary case: 9223372036854775808 */
|
/* boundary case: 9223372036854775808 */
|
||||||
if (unlikely(from->sign==0 && x == LONGLONG_MIN))
|
if (unlikely(from->sign==0 && x == LONGLONG_MIN))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user