mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge 10.11 into 11.0
This commit is contained in:
commit
0fb897b081
33 changed files with 377 additions and 190 deletions
|
@ -20,8 +20,6 @@ a RIGHT(b,20)
|
|||
2 bbbbbbbbbbbbbbbbbbbb
|
||||
connection default;
|
||||
SET DEBUG='+d,row_ins_extern_checkpoint';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET DEBUG_SYNC='before_row_ins_extern_latch SIGNAL rec_not_blob WAIT_FOR crash';
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
|
@ -88,8 +86,6 @@ BEGIN;
|
|||
INSERT INTO t2 VALUES (347);
|
||||
connection default;
|
||||
SET DEBUG='+d,row_upd_extern_checkpoint';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
|
||||
UPDATE t3 SET c=REPEAT('i',3000) WHERE a=2;
|
||||
connection con2;
|
||||
|
@ -126,8 +122,6 @@ BEGIN;
|
|||
INSERT INTO t2 VALUES (33101);
|
||||
connection default;
|
||||
SET DEBUG='+d,row_upd_extern_checkpoint';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET DEBUG_SYNC='after_row_upd_extern SIGNAL have_latch WAIT_FOR crash';
|
||||
UPDATE t3 SET c=REPEAT('j',3000) WHERE a=2;
|
||||
connection con2;
|
||||
|
|
|
@ -92,8 +92,6 @@ ALTER TABLE t1 FORCE, ADD COLUMN k4 int;
|
|||
connection default;
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR opened';
|
||||
SET debug = '+d,row_log_tmpfile_fail';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
INSERT INTO t1 select NULL,'aaa','bbb' from t480;
|
||||
INSERT INTO t1 select NULL,'aaaa','bbbb' from t480;
|
||||
SET DEBUG_SYNC= 'now SIGNAL flushed';
|
||||
|
|
|
@ -36,16 +36,10 @@ SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter';
|
|||
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
|
||||
ERROR HY000: Out of memory.
|
||||
SET SESSION DEBUG = @saved_debug_dbug;
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET SESSION DEBUG = '+d,innodb_OOM_inplace_alter';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
|
||||
ERROR HY000: Out of memory.
|
||||
SET SESSION DEBUG = @saved_debug_dbug;
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
|
||||
connection default;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
|
|
@ -16,8 +16,6 @@ SET @save_dbug = @@debug_dbug;
|
|||
SET DEBUG_DBUG = '+d,do_page_reorganize,do_lock_reverse_page_reorganize';
|
||||
insert into t1(f2) values (repeat('+', 100));
|
||||
SET DEBUG = @save_dbug;
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
commit;
|
||||
connection con1;
|
||||
f1
|
||||
|
|
|
@ -20,8 +20,6 @@ END//
|
|||
CALL populate_t1;
|
||||
SET autocommit=1;
|
||||
SET SESSION debug="+d,fts_instrument_result_cache_limit";
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
ALTER TABLE t1 ADD FULLTEXT INDEX `text_content_idx` (`text_content`);
|
||||
SELECT FTS_DOC_ID, text_content
|
||||
FROM t1
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
create table t1 (i int, g geometry not null, spatial index (g))engine=innodb;
|
||||
SET SESSION debug="+d,rtree_test_check_count";
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
insert into t1 values (1, POINT(1,1));
|
||||
insert into t1 values (1, POINT(1.5,1.5));
|
||||
insert into t1 values (1, POINT(3,3));
|
||||
|
|
|
@ -408,8 +408,6 @@ update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3;
|
|||
ERROR 23000: Duplicate entry '5' for key 'c'
|
||||
rollback;
|
||||
set session debug="+d,row_mysql_crash_if_error";
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3;
|
||||
ERROR HY000: Lost connection to server during query
|
||||
insert into t1 values(5, point(5,5), point(5,5), 5);
|
||||
|
|
|
@ -44,8 +44,6 @@ count(*)
|
|||
0
|
||||
SET @saved_dbug = @@SESSION.debug_dbug;
|
||||
SET DEBUG='+d,page_copy_rec_list_start_compress_fail';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
delete from t1;
|
||||
select count(*) from t1 where MBRWithin(t1.c2, @g1);
|
||||
count(*)
|
||||
|
|
|
@ -31,7 +31,5 @@ COUNT(*)
|
|||
0
|
||||
ALTER TABLE t1 DROP INDEX idx, ADD SPATIAL INDEX idx3(c2);
|
||||
SET SESSION debug="+d,row_merge_instrument_log_check_flush";
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
ALTER TABLE t1 DROP INDEX idx3, ADD SPATIAL INDEX idx4(c2), ADD SPATIAL INDEX idx5(c3);
|
||||
DROP TABLE t1;
|
||||
|
|
22
mysql-test/suite/perfschema/r/sxlock_func,debug.rdiff
Normal file
22
mysql-test/suite/perfschema/r/sxlock_func,debug.rdiff
Normal file
|
@ -0,0 +1,22 @@
|
|||
@@ -7,7 +7,6 @@
|
||||
WHERE name LIKE 'wait/synch/rwlock/innodb/%'
|
||||
AND name!='wait/synch/rwlock/innodb/btr_search_latch' ORDER BY name;
|
||||
name
|
||||
-wait/synch/rwlock/innodb/dict_operation_lock
|
||||
wait/synch/rwlock/innodb/fil_space_latch
|
||||
wait/synch/rwlock/innodb/lock_latch
|
||||
wait/synch/rwlock/innodb/trx_i_s_cache_lock
|
||||
@@ -19,11 +18,13 @@
|
||||
select name from performance_schema.setup_instruments
|
||||
where name like "wait/synch/sxlock/%" order by name;
|
||||
name
|
||||
+wait/synch/sxlock/innodb/dict_operation_lock
|
||||
wait/synch/sxlock/innodb/index_tree_rw_lock
|
||||
SELECT DISTINCT name FROM performance_schema.rwlock_instances
|
||||
WHERE name LIKE 'wait/synch/sxlock/innodb/%'
|
||||
ORDER BY name;
|
||||
name
|
||||
+wait/synch/sxlock/innodb/dict_operation_lock
|
||||
wait/synch/sxlock/innodb/index_tree_rw_lock
|
||||
create table t1(a int) engine=innodb;
|
||||
begin;
|
|
@ -5,6 +5,7 @@
|
|||
--source include/not_embedded.inc
|
||||
--source include/have_perfschema.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/maybe_debug.inc
|
||||
|
||||
UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES';
|
||||
|
||||
|
|
|
@ -270,16 +270,12 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_clients 1
|
||||
# Test failure of select error .
|
||||
SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
INSERT INTO t1 VALUES(3);
|
||||
connection slave;
|
||||
connection con1;
|
||||
# Test failure of pthread_create
|
||||
SET GLOBAL rpl_semi_sync_master_enabled = 0;
|
||||
SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET GLOBAL rpl_semi_sync_master_enabled= ON;
|
||||
# Test failure of pthread_join
|
||||
SET GLOBAL rpl_semi_sync_master_enabled= OFF;
|
||||
|
@ -287,8 +283,6 @@ SET GLOBAL rpl_semi_sync_master_enabled= OFF;
|
|||
# Failure on registering semisync slave
|
||||
#
|
||||
SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
SET GLOBAL rpl_semi_sync_master_enabled= ON;
|
||||
connection slave;
|
||||
STOP SLAVE IO_THREAD;
|
||||
|
@ -297,8 +291,6 @@ START SLAVE IO_THREAD;
|
|||
include/wait_for_slave_io_to_start.inc
|
||||
connection con1;
|
||||
SET GLOBAL debug='';
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
connection slave;
|
||||
START SLAVE IO_THREAD;
|
||||
include/wait_for_slave_io_to_start.inc
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
set session debug="L";
|
||||
Warnings:
|
||||
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
|
||||
select @@global.debug="1";
|
||||
@@global.debug="1"
|
||||
0
|
||||
|
|
|
@ -38,7 +38,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
|||
DEFAULT_VALUE
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE VARCHAR
|
||||
VARIABLE_COMMENT Built-in DBUG debugger
|
||||
VARIABLE_COMMENT Built-in DBUG debugger. Alias for --debug
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
|
|
|
@ -2284,6 +2284,81 @@ Warnings:
|
|||
Warning 1292 Incorrect inet6 value: ''
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types
|
||||
#
|
||||
CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f;
|
||||
f GROUP_CONCAT(c)
|
||||
NULL 2000-01-01 00:00:00.000000,1900-01-01 00:00:00.000000
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f;
|
||||
f COUNT(c)
|
||||
NULL 2
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
DROP TABLE t1;
|
||||
CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f FROM t1 ORDER BY f;
|
||||
f
|
||||
NULL
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
DROP TABLE t1;
|
||||
CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::'),('','::');
|
||||
SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f;
|
||||
f
|
||||
NULL
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f;
|
||||
f
|
||||
NULL
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f;
|
||||
f
|
||||
NULL
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
Warning 1292 Incorrect inet6 value: ''
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string
|
||||
#
|
||||
SET sql_mode='';
|
||||
|
|
|
@ -1675,6 +1675,32 @@ INSERT INTO t1 VALUES ('::');
|
|||
SELECT * FROM t1 WHERE a IN ('','::1');
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01');
|
||||
SELECT c + (b = a) AS f FROM t1 ORDER BY f;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL);
|
||||
INSERT INTO t1 VALUES ('','::'),('','::');
|
||||
SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f;
|
||||
SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f;
|
||||
SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string
|
||||
--echo #
|
||||
|
|
|
@ -71,7 +71,7 @@ usage() if ($opt_help); # the help function
|
|||
|
||||
if ($opt_host =~ s/:(\d+)$//)
|
||||
{
|
||||
$opt_port = $1;
|
||||
$opt_port = $1;
|
||||
}
|
||||
|
||||
if ($opt_host eq '')
|
||||
|
@ -101,7 +101,7 @@ my $prefix= 'mysql';
|
|||
if (eval {DBI->install_driver("MariaDB")}) {
|
||||
$dsn ="DBI:MariaDB:;";
|
||||
$prefix= 'mariadb';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$dsn = "DBI:mysql:;";
|
||||
}
|
||||
|
@ -229,11 +229,11 @@ sub setpwd
|
|||
{
|
||||
$pass = "PASSWORD(". $dbh->quote($pass) . ")";
|
||||
}
|
||||
my $uh= "$user@$host";
|
||||
my $uh= $user."@".$host;
|
||||
my $sth = $dbh->prepare("set password for $uh =$pass") || die $dbh->errstr;
|
||||
$sth->execute || die $dbh->errstr;
|
||||
$sth->finish;
|
||||
print "The password is set for user $user.\n\n";
|
||||
print "The password is set for user $uh.\n\n";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -457,40 +457,6 @@ void Item_bool_func::raise_note_if_key_become_unused(THD *thd, const Item_args &
|
|||
}
|
||||
|
||||
|
||||
bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
|
||||
{
|
||||
DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3
|
||||
|
||||
if (args[0]->cmp_type() == STRING_RESULT &&
|
||||
args[1]->cmp_type() == STRING_RESULT)
|
||||
{
|
||||
CHARSET_INFO *tmp;
|
||||
/*
|
||||
Use charset narrowing only for equalities, as that would allow
|
||||
to construct ref access.
|
||||
Non-equality comparisons with constants work without charset narrowing,
|
||||
the constant gets converted.
|
||||
Non-equality comparisons with non-constants would need narrowing to
|
||||
enable range optimizer to handle e.g.
|
||||
t1.mb3key_col <= const_table.mb4_col
|
||||
But this doesn't look important.
|
||||
*/
|
||||
bool allow_narrowing= MY_TEST(functype()==Item_func::EQ_FUNC ||
|
||||
functype()==Item_func::EQUAL_FUNC);
|
||||
|
||||
if (agg_arg_charsets_for_comparison(&tmp, &args[0], &args[1],
|
||||
allow_narrowing))
|
||||
return true;
|
||||
cmp->m_compare_collation= tmp;
|
||||
}
|
||||
// Convert constants when compared to int/year field
|
||||
DBUG_ASSERT(functype() != LIKE_FUNC);
|
||||
convert_const_compared_to_int_field(thd);
|
||||
|
||||
return cmp->set_cmp_func(thd, this, &args[0], &args[1], true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Comparison operators remove arguments' dependency on PAD_CHAR_TO_FULL_LENGTH
|
||||
in case of PAD SPACE comparison collations: trailing spaces do not affect
|
||||
|
@ -519,8 +485,15 @@ bool Item_bool_rowready_func2::fix_length_and_dec(THD *thd)
|
|||
if (!args[0] || !args[1])
|
||||
return FALSE;
|
||||
Item_args old_args(args[0], args[1]);
|
||||
if (setup_args_and_comparator(thd, &cmp))
|
||||
convert_const_compared_to_int_field(thd);
|
||||
Type_handler_hybrid_field_type tmp;
|
||||
if (tmp.aggregate_for_comparison(func_name_cstring(), args, 2, false) ||
|
||||
tmp.type_handler()->Item_bool_rowready_func2_fix_length_and_dec(thd,
|
||||
this))
|
||||
{
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
return true;
|
||||
}
|
||||
raise_note_if_key_become_unused(thd, old_args);
|
||||
return false;
|
||||
}
|
||||
|
@ -540,21 +513,14 @@ bool Item_bool_rowready_func2::fix_length_and_dec(THD *thd)
|
|||
*/
|
||||
|
||||
int Arg_comparator::set_cmp_func(THD *thd, Item_func_or_sum *owner_arg,
|
||||
const Type_handler *compare_handler,
|
||||
Item **a1, Item **a2)
|
||||
{
|
||||
owner= owner_arg;
|
||||
set_null= set_null && owner_arg;
|
||||
a= a1;
|
||||
b= a2;
|
||||
Item *tmp_args[2]= {*a1, *a2};
|
||||
Type_handler_hybrid_field_type tmp;
|
||||
if (tmp.aggregate_for_comparison(owner_arg->func_name_cstring(), tmp_args, 2,
|
||||
false))
|
||||
{
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
return 1;
|
||||
}
|
||||
m_compare_handler= tmp.type_handler();
|
||||
m_compare_handler= compare_handler;
|
||||
return m_compare_handler->set_comparator_func(thd, this);
|
||||
}
|
||||
|
||||
|
@ -605,6 +571,14 @@ bool Arg_comparator::set_cmp_func_string(THD *thd)
|
|||
We must set cmp_collation here as we may be called from for an automatic
|
||||
generated item, like in natural join.
|
||||
Allow reinterpted superset as subset.
|
||||
Use charset narrowing only for equalities, as that would allow
|
||||
to construct ref access.
|
||||
Non-equality comparisons with constants work without charset narrowing,
|
||||
the constant gets converted.
|
||||
Non-equality comparisons with non-constants would need narrowing to
|
||||
enable range optimizer to handle e.g.
|
||||
t1.mb3key_col <= const_table.mb4_col
|
||||
But this doesn't look important.
|
||||
*/
|
||||
bool allow_narrowing= false;
|
||||
if (owner->type() == Item::FUNC_ITEM)
|
||||
|
@ -2812,8 +2786,9 @@ Item_func_nullif::fix_length_and_dec(THD *thd)
|
|||
fix_char_length(args[2]->max_char_length());
|
||||
set_maybe_null();
|
||||
m_arg0= args[0];
|
||||
if (setup_args_and_comparator(thd, &cmp))
|
||||
return TRUE;
|
||||
convert_const_compared_to_int_field(thd);
|
||||
if (cmp.set_cmp_func(thd, this, &args[0], &args[1], true/*set_null*/))
|
||||
return true;
|
||||
/*
|
||||
A special code for EXECUTE..PREPARE.
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class Arg_comparator: public Sql_alloc
|
|||
// when one of arguments is NULL.
|
||||
|
||||
int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg,
|
||||
const Type_handler *compare_handler,
|
||||
Item **a1, Item **a2);
|
||||
|
||||
int compare_not_null_values(longlong val1, longlong val2)
|
||||
|
@ -95,11 +96,24 @@ public:
|
|||
bool set_cmp_func_decimal(THD *thd);
|
||||
|
||||
inline int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg,
|
||||
Item **a1, Item **a2, bool set_null_arg)
|
||||
const Type_handler *compare_handler,
|
||||
Item **a1, Item **a2, bool set_null_arg)
|
||||
{
|
||||
set_null= set_null_arg;
|
||||
return set_cmp_func(thd, owner_arg, a1, a2);
|
||||
return set_cmp_func(thd, owner_arg, compare_handler, a1, a2);
|
||||
}
|
||||
int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg,
|
||||
Item **a1, Item **a2, bool set_null_arg)
|
||||
{
|
||||
Item *tmp_args[2]= { *a1, *a2 };
|
||||
Type_handler_hybrid_field_type tmp;
|
||||
if (tmp.aggregate_for_comparison(owner_arg->func_name_cstring(),
|
||||
tmp_args, 2, false))
|
||||
return 1;
|
||||
return set_cmp_func(thd, owner_arg, tmp.type_handler(),
|
||||
a1, a2, set_null_arg);
|
||||
}
|
||||
|
||||
inline int compare() { return (this->*func)(); }
|
||||
|
||||
int compare_string(); // compare args[0] & args[1]
|
||||
|
@ -561,9 +575,17 @@ public:
|
|||
return this;
|
||||
}
|
||||
bool fix_length_and_dec(THD *thd) override;
|
||||
bool fix_length_and_dec_generic(THD *thd,
|
||||
const Type_handler *compare_handler)
|
||||
{
|
||||
DBUG_ASSERT(args == tmp_arg);
|
||||
return cmp.set_cmp_func(thd, this, compare_handler,
|
||||
tmp_arg, tmp_arg + 1, true/*set_null*/);
|
||||
}
|
||||
int set_cmp_func(THD *thd)
|
||||
{
|
||||
return cmp.set_cmp_func(thd, this, tmp_arg, tmp_arg + 1, true);
|
||||
DBUG_ASSERT(args == tmp_arg);
|
||||
return cmp.set_cmp_func(thd, this, tmp_arg, tmp_arg + 1, true/*set_null*/);
|
||||
}
|
||||
CHARSET_INFO *compare_collation() const override
|
||||
{ return cmp.compare_collation(); }
|
||||
|
|
|
@ -388,15 +388,6 @@ public:
|
|||
}
|
||||
}
|
||||
void convert_const_compared_to_int_field(THD *thd);
|
||||
/**
|
||||
Prepare arguments and setup a comparator.
|
||||
Used in Item_func_xxx with two arguments and a comparator,
|
||||
e.g. Item_bool_func2 and Item_func_nullif.
|
||||
args[0] or args[1] can be modified:
|
||||
- converted to character set and collation of the operation
|
||||
- or replaced to an Item_int_with_ref
|
||||
*/
|
||||
bool setup_args_and_comparator(THD *thd, Arg_comparator *cmp);
|
||||
Item_func *get_item_func() override { return this; }
|
||||
bool is_simplified_cond_processor(void *arg) override
|
||||
{ return const_item() && !val_int(); }
|
||||
|
|
|
@ -1296,9 +1296,14 @@ void Item_sum_min_max::setup_hybrid(THD *thd, Item *item, Item *value_arg)
|
|||
/* Don't cache value, as it will change */
|
||||
if (!item->const_item())
|
||||
arg_cache->set_used_tables(RAND_TABLE_BIT);
|
||||
DBUG_ASSERT(item->type_handler_for_comparison() ==
|
||||
value->type_handler_for_comparison());
|
||||
DBUG_ASSERT(item->type_handler_for_comparison() ==
|
||||
arg_cache->type_handler_for_comparison());
|
||||
cmp= new (thd->mem_root) Arg_comparator();
|
||||
if (cmp)
|
||||
cmp->set_cmp_func(thd, this, (Item**)&arg_cache, (Item**)&value, FALSE);
|
||||
cmp->set_cmp_func(thd, this, item->type_handler_for_comparison(),
|
||||
(Item**)&arg_cache, (Item**)&value, FALSE);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -5668,6 +5668,14 @@ Type_handler_string_result::Item_func_hybrid_field_type_get_date(
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
bool Type_handler::Item_bool_rowready_func2_fix_length_and_dec(THD *thd,
|
||||
Item_bool_rowready_func2 *func) const
|
||||
{
|
||||
return func->fix_length_and_dec_generic(thd, this);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
bool Type_handler_numeric::
|
||||
Item_func_between_fix_length_and_dec(Item_func_between *func) const
|
||||
{
|
||||
|
|
|
@ -55,6 +55,7 @@ class Item_hybrid_func;
|
|||
class Item_func_min_max;
|
||||
class Item_func_hybrid_field_type;
|
||||
class Item_bool_func2;
|
||||
class Item_bool_rowready_func2;
|
||||
class Item_func_between;
|
||||
class Item_func_in;
|
||||
class Item_func_round;
|
||||
|
@ -4257,6 +4258,8 @@ public:
|
|||
}
|
||||
virtual bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const= 0;
|
||||
virtual bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd,
|
||||
Item_bool_rowready_func2 *func) const;
|
||||
virtual bool Item_hybrid_func_fix_attributes(THD *thd,
|
||||
const LEX_CSTRING &name,
|
||||
Type_handler_hybrid_field_type *,
|
||||
|
|
|
@ -136,6 +136,21 @@ public:
|
|||
return Fbt_null(item, false).is_null();
|
||||
}
|
||||
|
||||
/*
|
||||
Check at fix_fields() time if any of the items can return a nullable
|
||||
value on conversion to Fbt.
|
||||
*/
|
||||
static bool fix_fields_maybe_null_on_conversion_to_fbt(Item **items,
|
||||
uint count)
|
||||
{
|
||||
for (uint i= 0; i < count; i++)
|
||||
{
|
||||
if (Fbt::fix_fields_maybe_null_on_conversion_to_fbt(items[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Fbt(Item *item, bool *error, bool warn= true)
|
||||
|
@ -1534,6 +1549,16 @@ public:
|
|||
Fbt_null na(a), nb(b);
|
||||
return !na.is_null() && !nb.is_null() && !na.cmp(nb);
|
||||
}
|
||||
bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd,
|
||||
Item_bool_rowready_func2 *func) const override
|
||||
{
|
||||
if (Type_handler::Item_bool_rowready_func2_fix_length_and_dec(thd, func))
|
||||
return true;
|
||||
if (!func->maybe_null() &&
|
||||
Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(), 2))
|
||||
func->set_maybe_null();
|
||||
return false;
|
||||
}
|
||||
bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name,
|
||||
Type_handler_hybrid_field_type *h,
|
||||
Type_all_attributes *attr,
|
||||
|
@ -1715,6 +1740,9 @@ public:
|
|||
|
||||
bool Item_func_between_fix_length_and_dec(Item_func_between *func) const override
|
||||
{
|
||||
if (!func->maybe_null() &&
|
||||
Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(), 3))
|
||||
func->set_maybe_null();
|
||||
return false;
|
||||
}
|
||||
longlong Item_func_between_val_int(Item_func_between *func) const override
|
||||
|
@ -1737,6 +1765,10 @@ public:
|
|||
Item_func_in *func)
|
||||
const override
|
||||
{
|
||||
if (!func->maybe_null() &&
|
||||
Fbt::fix_fields_maybe_null_on_conversion_to_fbt(func->arguments(),
|
||||
func->argument_count()))
|
||||
func->set_maybe_null();
|
||||
if (func->compatible_types_scalar_bisection_possible())
|
||||
{
|
||||
return func->value_list_convert_const_to_int(thd) ||
|
||||
|
|
|
@ -1049,11 +1049,10 @@ static Sys_var_charptr_fscs Sys_datadir(
|
|||
static Sys_var_dbug Sys_dbug(
|
||||
"debug", "Built-in DBUG debugger", sys_var::SESSION,
|
||||
CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
|
||||
ON_CHECK(check_has_super), ON_UPDATE(0),
|
||||
DEPRECATED("'@@debug_dbug'")); // since 5.5.37
|
||||
ON_CHECK(check_has_super));
|
||||
|
||||
static Sys_var_dbug Sys_debug_dbug(
|
||||
"debug_dbug", "Built-in DBUG debugger", sys_var::SESSION,
|
||||
"debug_dbug", "Built-in DBUG debugger. Alias for --debug", sys_var::SESSION,
|
||||
CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
|
||||
ON_CHECK(check_has_super));
|
||||
#endif
|
||||
|
|
|
@ -788,7 +788,8 @@ static rec_offs *btr_page_get_parent(rec_offs *offsets, mem_heap_t *heap,
|
|||
/************************************************************//**
|
||||
Returns the upper level node pointer to a page. It is assumed that mtr holds
|
||||
an x-latch on the tree.
|
||||
@return rec_get_offsets() of the node pointer record */
|
||||
@return rec_get_offsets() of the node pointer record
|
||||
@retval nullptr on corruption */
|
||||
static
|
||||
rec_offs*
|
||||
btr_page_get_father_block(
|
||||
|
@ -2374,6 +2375,11 @@ btr_attach_half_pages(
|
|||
offsets = btr_page_get_father_block(nullptr, heap, mtr,
|
||||
&cursor);
|
||||
|
||||
if (UNIV_UNLIKELY(!offsets)) {
|
||||
mem_heap_free(heap);
|
||||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
/* Replace the address of the old child node (= page) with the
|
||||
address of the new lower half */
|
||||
|
||||
|
@ -3247,6 +3253,14 @@ btr_lift_page_up(
|
|||
offsets = btr_page_get_father_block(offsets, heap,
|
||||
mtr, &cursor);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!offsets)) {
|
||||
parent_corrupted:
|
||||
mem_heap_free(heap);
|
||||
*err = DB_CORRUPTION;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
father_block = btr_cur_get_block(&cursor);
|
||||
father_page_zip = buf_block_get_page_zip(father_block);
|
||||
|
||||
|
@ -3272,6 +3286,10 @@ btr_lift_page_up(
|
|||
&cursor);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!offsets)) {
|
||||
goto parent_corrupted;
|
||||
}
|
||||
|
||||
blocks[n_blocks++] = b = btr_cur_get_block(&cursor);
|
||||
}
|
||||
|
||||
|
@ -3484,6 +3502,10 @@ get_offsets:
|
|||
NULL, heap, mtr, &father_cursor);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!offsets)) {
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
if (adjust) {
|
||||
nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
|
||||
if (UNIV_UNLIKELY(!nth_rec || nth_rec == ULINT_UNDEFINED)) {
|
||||
|
|
|
@ -2414,14 +2414,21 @@ lookup:
|
|||
|
||||
if (discard_attempted || !bpage->frame)
|
||||
{
|
||||
/* Even when we are holding a hash_lock, it should be
|
||||
acceptable to wait for a page S-latch here, because
|
||||
buf_page_t::read_complete() will not wait for buf_pool.mutex,
|
||||
and because S-latch would not conflict with a U-latch
|
||||
that would be protecting buf_page_t::write_complete(). */
|
||||
bpage->lock.s_lock();
|
||||
const bool got_s_latch= bpage->lock.s_lock_try();
|
||||
hash_lock.unlock_shared();
|
||||
break;
|
||||
if (UNIV_LIKELY(got_s_latch))
|
||||
break;
|
||||
/* We may fail to acquire bpage->lock because
|
||||
buf_page_t::read_complete() may be invoking
|
||||
buf_pool_t::corrupted_evict() on this block, which it would
|
||||
hold an exclusive latch on.
|
||||
|
||||
Let us aqcuire and release buf_pool.mutex to ensure that any
|
||||
buf_pool_t::corrupted_evict() will proceed before we reacquire
|
||||
the hash_lock that it could be waiting for. */
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
goto lookup;
|
||||
}
|
||||
|
||||
hash_lock.unlock_shared();
|
||||
|
|
|
@ -958,11 +958,12 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
|
|||
if (latch_ex_wait_start.compare_exchange_strong
|
||||
(old, now, std::memory_order_relaxed, std::memory_order_relaxed))
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
latch.x_lock(SRW_LOCK_ARGS(file, line));
|
||||
#else
|
||||
latch.wr_lock(SRW_LOCK_ARGS(file, line));
|
||||
#endif
|
||||
latch_ex_wait_start.store(0, std::memory_order_relaxed);
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -977,33 +978,39 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
|
|||
if (waited > threshold / 4)
|
||||
ib::warn() << "A long wait (" << waited
|
||||
<< " seconds) was observed for dict_sys.latch";
|
||||
#ifdef UNIV_DEBUG
|
||||
latch.x_lock(SRW_LOCK_ARGS(file, line));
|
||||
#else
|
||||
latch.wr_lock(SRW_LOCK_ARGS(file, line));
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UNIV_PFS_RWLOCK
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::unlock()
|
||||
{
|
||||
ut_ad(latch_ex == pthread_self());
|
||||
ut_ad(!latch_readers);
|
||||
ut_d(latch_ex= 0);
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.x_unlock();
|
||||
# else
|
||||
latch.wr_unlock();
|
||||
# endif
|
||||
}
|
||||
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line)
|
||||
{
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.s_lock(file, line);
|
||||
# else
|
||||
latch.rd_lock(file, line);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_readers++);
|
||||
# endif
|
||||
}
|
||||
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze()
|
||||
{
|
||||
ut_ad(!latch_ex);
|
||||
ut_ad(latch_readers--);
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.s_unlock();
|
||||
# else
|
||||
latch.rd_unlock();
|
||||
# endif
|
||||
}
|
||||
#endif /* UNIV_PFS_RWLOCK */
|
||||
|
||||
|
@ -4511,7 +4518,11 @@ void dict_sys_t::close()
|
|||
temp_id_hash.free();
|
||||
|
||||
unlock();
|
||||
#ifdef UNIV_DEBUG
|
||||
latch.free();
|
||||
#else
|
||||
latch.destroy();
|
||||
#endif
|
||||
|
||||
mysql_mutex_destroy(&dict_foreign_err_mutex);
|
||||
|
||||
|
|
|
@ -580,7 +580,13 @@ static PSI_rwlock_info all_innodb_rwlocks[] =
|
|||
# ifdef BTR_CUR_HASH_ADAPT
|
||||
{ &btr_search_latch_key, "btr_search_latch", 0 },
|
||||
# endif
|
||||
{ &dict_operation_lock_key, "dict_operation_lock", 0 },
|
||||
{ &dict_operation_lock_key, "dict_operation_lock",
|
||||
# ifdef UNIV_DEBUG
|
||||
PSI_RWLOCK_FLAG_SX
|
||||
# else
|
||||
0
|
||||
# endif
|
||||
},
|
||||
{ &fil_space_latch_key, "fil_space_latch", 0 },
|
||||
{ &trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0 },
|
||||
{ &trx_purge_latch_key, "trx_purge_latch", 0 },
|
||||
|
@ -13456,14 +13462,7 @@ int ha_innobase::delete_table(const char *name)
|
|||
/* FOREIGN KEY constraints cannot exist on partitioned tables. */;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t* f : table->referenced_set)
|
||||
if (dict_table_t* child= f->foreign_table)
|
||||
if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
dict_sys.unfreeze();
|
||||
}
|
||||
err= lock_table_children(table, trx);
|
||||
}
|
||||
|
||||
dict_table_t *table_stats= nullptr, *index_stats= nullptr;
|
||||
|
@ -13861,14 +13860,7 @@ int ha_innobase::truncate()
|
|||
dict_table_t *table_stats = nullptr, *index_stats = nullptr;
|
||||
MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
|
||||
|
||||
dberr_t error= DB_SUCCESS;
|
||||
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t *f : ib_table->referenced_set)
|
||||
if (dict_table_t *child= f->foreign_table)
|
||||
if ((error= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
dict_sys.unfreeze();
|
||||
dberr_t error= lock_table_children(ib_table, trx);
|
||||
|
||||
if (error == DB_SUCCESS)
|
||||
error= lock_table_for_trx(ib_table, trx, LOCK_X);
|
||||
|
@ -14059,16 +14051,7 @@ ha_innobase::rename_table(
|
|||
/* There is no need to lock any FOREIGN KEY child tables. */
|
||||
} else if (dict_table_t *table = dict_table_open_on_name(
|
||||
norm_from, false, DICT_ERR_IGNORE_FK_NOKEY)) {
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t* f : table->referenced_set) {
|
||||
if (dict_table_t* child = f->foreign_table) {
|
||||
error = lock_table_for_trx(child, trx, LOCK_X);
|
||||
if (error != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
error = lock_table_children(table, trx);
|
||||
if (error == DB_SUCCESS) {
|
||||
error = lock_table_for_trx(table, trx, LOCK_X);
|
||||
}
|
||||
|
@ -15667,15 +15650,17 @@ ha_innobase::extra(
|
|||
{
|
||||
/* Warning: since it is not sure that MariaDB calls external_lock()
|
||||
before calling this function, m_prebuilt->trx can be obsolete! */
|
||||
trx_t* trx = check_trx_exists(ha_thd());
|
||||
trx_t* trx;
|
||||
|
||||
switch (operation) {
|
||||
case HA_EXTRA_FLUSH:
|
||||
(void)check_trx_exists(ha_thd());
|
||||
if (m_prebuilt->blob_heap) {
|
||||
row_mysql_prebuilt_free_blob_heap(m_prebuilt);
|
||||
}
|
||||
break;
|
||||
case HA_EXTRA_RESET_STATE:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
reset_template();
|
||||
trx->duplicates = 0;
|
||||
stmt_boundary:
|
||||
|
@ -15684,18 +15669,23 @@ ha_innobase::extra(
|
|||
trx->bulk_insert = false;
|
||||
break;
|
||||
case HA_EXTRA_NO_KEYREAD:
|
||||
(void)check_trx_exists(ha_thd());
|
||||
m_prebuilt->read_just_key = 0;
|
||||
break;
|
||||
case HA_EXTRA_KEYREAD:
|
||||
(void)check_trx_exists(ha_thd());
|
||||
m_prebuilt->read_just_key = 1;
|
||||
break;
|
||||
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
|
||||
(void)check_trx_exists(ha_thd());
|
||||
m_prebuilt->keep_other_fields_on_keyread = 1;
|
||||
break;
|
||||
case HA_EXTRA_INSERT_WITH_UPDATE:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
trx->duplicates |= TRX_DUP_IGNORE;
|
||||
goto stmt_boundary;
|
||||
case HA_EXTRA_NO_IGNORE_DUP_KEY:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
trx->duplicates &= ~TRX_DUP_IGNORE;
|
||||
if (trx->is_bulk_insert()) {
|
||||
/* Allow a subsequent INSERT into an empty table
|
||||
|
@ -15707,9 +15697,11 @@ ha_innobase::extra(
|
|||
}
|
||||
goto stmt_boundary;
|
||||
case HA_EXTRA_WRITE_CAN_REPLACE:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
trx->duplicates |= TRX_DUP_REPLACE;
|
||||
goto stmt_boundary;
|
||||
case HA_EXTRA_WRITE_CANNOT_REPLACE:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
trx->duplicates &= ~TRX_DUP_REPLACE;
|
||||
if (trx->is_bulk_insert()) {
|
||||
/* Allow a subsequent INSERT into an empty table
|
||||
|
@ -15718,6 +15710,7 @@ ha_innobase::extra(
|
|||
}
|
||||
goto stmt_boundary;
|
||||
case HA_EXTRA_BEGIN_ALTER_COPY:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
m_prebuilt->table->skip_alter_undo = 1;
|
||||
if (m_prebuilt->table->is_temporary()
|
||||
|| !m_prebuilt->table->versioned_by_id()) {
|
||||
|
@ -15730,6 +15723,7 @@ ha_innobase::extra(
|
|||
.first->second.set_versioned(0);
|
||||
break;
|
||||
case HA_EXTRA_END_ALTER_COPY:
|
||||
trx = check_trx_exists(ha_thd());
|
||||
m_prebuilt->table->skip_alter_undo = 0;
|
||||
if (!m_prebuilt->table->is_temporary()
|
||||
&& !high_level_read_only) {
|
||||
|
|
|
@ -11222,16 +11222,7 @@ ha_innobase::commit_inplace_alter_table(
|
|||
fts_optimize_remove_table(ctx->old_table);
|
||||
}
|
||||
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (auto f : ctx->old_table->referenced_set) {
|
||||
if (dict_table_t* child = f->foreign_table) {
|
||||
error = lock_table_for_trx(child, trx, LOCK_X);
|
||||
if (error != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
error = lock_table_children(ctx->old_table, trx);
|
||||
|
||||
if (ctx->new_table->fts) {
|
||||
ut_ad(!ctx->new_table->fts->add_wq);
|
||||
|
|
|
@ -1311,14 +1311,14 @@ class dict_sys_t
|
|||
/** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */
|
||||
std::atomic<ulonglong> latch_ex_wait_start;
|
||||
|
||||
/** the rw-latch protecting the data dictionary cache */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch;
|
||||
#ifdef UNIV_DEBUG
|
||||
/** whether latch is being held in exclusive mode (by any thread) */
|
||||
Atomic_relaxed<pthread_t> latch_ex;
|
||||
/** number of S-latch holders */
|
||||
Atomic_counter<uint32_t> latch_readers;
|
||||
typedef index_lock dict_lock;
|
||||
#else
|
||||
typedef srw_lock dict_lock;
|
||||
#endif
|
||||
|
||||
/** the rw-latch protecting the data dictionary cache */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) dict_lock latch;
|
||||
public:
|
||||
/** Indexes of SYS_TABLE[] */
|
||||
enum
|
||||
|
@ -1469,15 +1469,12 @@ public:
|
|||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/** @return whether any thread (not necessarily the current thread)
|
||||
is holding the latch; that is, this check may return false
|
||||
positives */
|
||||
bool frozen() const { return latch_readers || latch_ex; }
|
||||
/** @return whether any thread (not necessarily the current thread)
|
||||
is holding a shared latch */
|
||||
bool frozen_not_locked() const { return latch_readers; }
|
||||
/** @return whether the current thread is holding the latch */
|
||||
bool frozen() const { return latch.have_any(); }
|
||||
/** @return whether the current thread is holding a shared latch */
|
||||
bool frozen_not_locked() const { return latch.have_s(); }
|
||||
/** @return whether the current thread holds the exclusive latch */
|
||||
bool locked() const { return latch_ex == pthread_self(); }
|
||||
bool locked() const { return latch.have_x(); }
|
||||
#endif
|
||||
private:
|
||||
/** Acquire the exclusive latch */
|
||||
|
@ -1492,13 +1489,11 @@ public:
|
|||
/** Exclusively lock the dictionary cache. */
|
||||
void lock(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
{
|
||||
if (latch.wr_lock_try())
|
||||
{
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
}
|
||||
else
|
||||
#ifdef UNIV_DEBUG
|
||||
if (!latch.x_lock_try())
|
||||
#else
|
||||
if (!latch.wr_lock_try())
|
||||
#endif
|
||||
lock_wait(SRW_LOCK_ARGS(file, line));
|
||||
}
|
||||
|
||||
|
@ -1513,24 +1508,29 @@ public:
|
|||
/** Unlock the data dictionary cache. */
|
||||
void unlock()
|
||||
{
|
||||
ut_ad(latch_ex == pthread_self());
|
||||
ut_ad(!latch_readers);
|
||||
ut_d(latch_ex= 0);
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.x_unlock();
|
||||
# else
|
||||
latch.wr_unlock();
|
||||
# endif
|
||||
}
|
||||
/** Acquire a shared lock on the dictionary cache. */
|
||||
void freeze()
|
||||
{
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.s_lock();
|
||||
# else
|
||||
latch.rd_lock();
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_readers++);
|
||||
# endif
|
||||
}
|
||||
/** Release a shared lock on the dictionary cache. */
|
||||
void unfreeze()
|
||||
{
|
||||
ut_ad(!latch_ex);
|
||||
ut_ad(latch_readers--);
|
||||
# ifdef UNIV_DEBUG
|
||||
latch.s_unlock();
|
||||
# else
|
||||
latch.rd_unlock();
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -438,6 +438,13 @@ dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
|
|||
bool no_wait= false)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Lock the child tables of a table.
|
||||
@param table parent table
|
||||
@param trx transaction
|
||||
@return error code */
|
||||
dberr_t lock_table_children(dict_table_t *table, trx_t *trx)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Exclusively lock the data dictionary tables.
|
||||
@param trx dictionary transaction
|
||||
@return error code
|
||||
|
|
|
@ -3940,6 +3940,8 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex)
|
|||
dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
|
||||
bool no_wait)
|
||||
{
|
||||
ut_ad(!dict_sys.frozen());
|
||||
|
||||
mem_heap_t *heap= mem_heap_create(512);
|
||||
sel_node_t *node= sel_node_create(heap);
|
||||
que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr);
|
||||
|
@ -3976,6 +3978,36 @@ run_again:
|
|||
return err;
|
||||
}
|
||||
|
||||
/** Lock the child tables of a table.
|
||||
@param table parent table
|
||||
@param trx transaction
|
||||
@return error code */
|
||||
dberr_t lock_table_children(dict_table_t *table, trx_t *trx)
|
||||
{
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
std::vector<dict_table_t*> children;
|
||||
|
||||
for (auto f : table->referenced_set)
|
||||
if (dict_table_t *child= f->foreign_table)
|
||||
{
|
||||
child->acquire();
|
||||
children.emplace_back(child);
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
|
||||
dberr_t err= DB_SUCCESS;
|
||||
|
||||
for (auto child : children)
|
||||
if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
|
||||
for (auto child : children)
|
||||
child->release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/** Exclusively lock the data dictionary tables.
|
||||
@param trx dictionary transaction
|
||||
@return error code
|
||||
|
|
Loading…
Reference in a new issue