Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä 2020-05-20 17:46:05 +03:00
commit 5ece2155cb
37 changed files with 466 additions and 312 deletions

View file

@ -5535,7 +5535,7 @@ static bool xtrabackup_prepare_func(char** argv)
error_cleanup:
xb_filters_free();
return ok;
return ok && !ib::error::was_logged();
}
/**************************************************************************

View file

@ -483,7 +483,7 @@ sub mtr_report_stats ($$$$) {
$comment =~ s/[\"]//g;
# if a test case has to be retried it should have the result MTR_RES_FAILED in jUnit XML
if ($test->{'result'} eq "MTR_RES_FAILED" || $test->{'retries'}) {
if ($test->{'result'} eq "MTR_RES_FAILED" || $test->{'retries'} > 0) {
my $logcontents = $test->{'logfile-failed'} || $test->{'logfile'};
$xml_report .= qq(>\n\t\t\t<failure message="" type="MTR_RES_FAILED">\n<![CDATA[$logcontents]]>\n\t\t\t</failure>\n\t\t</testcase>\n);
@ -649,6 +649,8 @@ sub mtr_error (@) {
}
else
{
use Carp qw(cluck);
cluck "Error happened" if $verbose > 0;
exit(1);
}
}

View file

@ -2815,6 +2815,31 @@ SET DEFAULT_STORAGE_ENGINE=Default;
# End of 10.2 tests
#
#
# Start of 10.3 tests
#
#
# MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
#
SET NAMES utf8;
CREATE TABLE t1 (a TEXT CHARACTER SET utf16);
SELECT * FROM (VALUES (1) UNION SELECT * FROM t1) AS t;
1
1
DROP TABLE t1;
VALUES (1) UNION SELECT _utf16 0x0020;
1
1
VALUES ('') UNION SELECT _utf16 0x0020 COLLATE utf16_bin;
VALUES ('') UNION VALUES ( _utf16 0x0020 COLLATE utf16_bin);
#
# End of 10.3 tests
#
#
# Start of 10.5 tests
#
#

View file

@ -935,6 +935,27 @@ let $coll_pad='utf16_bin';
--echo # End of 10.2 tests
--echo #
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
--echo #
SET NAMES utf8;
CREATE TABLE t1 (a TEXT CHARACTER SET utf16);
SELECT * FROM (VALUES (1) UNION SELECT * FROM t1) AS t;
DROP TABLE t1;
VALUES (1) UNION SELECT _utf16 0x0020;
VALUES ('') UNION SELECT _utf16 0x0020 COLLATE utf16_bin;
VALUES ('') UNION VALUES ( _utf16 0x0020 COLLATE utf16_bin);
--echo #
--echo # End of 10.3 tests
--echo #
--echo #
--echo # Start of 10.5 tests

View file

@ -11324,6 +11324,18 @@ SELECT x AS 5天内最近一次登录时间 FROM t1;
1
DROP TABLE t1;
#
# MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
#
SET NAMES utf8;
VALUES (_latin1 0xDF) UNION SELECT _utf8'a' COLLATE utf8_bin;
_latin1 0xDF
ß
a
VALUES (_latin1 0xDF) UNION VALUES(_utf8'a' COLLATE utf8_bin);
_latin1 0xDF
ß
a
#
# End of 10.3 tests
#
#

View file

@ -2257,6 +2257,13 @@ INSERT INTO t1 VALUES (1);
SELECT x AS 5天内最近一次登录时间 FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
--echo #
SET NAMES utf8;
VALUES (_latin1 0xDF) UNION SELECT _utf8'a' COLLATE utf8_bin;
VALUES (_latin1 0xDF) UNION VALUES(_utf8'a' COLLATE utf8_bin);
--echo #
--echo # End of 10.3 tests

View file

@ -5472,6 +5472,23 @@ drop procedure p;
drop view v1;
drop table t1;
#
# MDEV-22591 Debug build crashes on EXECUTE IMMEDIATE '... WHERE ?' USING IGNORE
#
CREATE TABLE t1 (a INT);
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING IGNORE;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING IGNORE;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING 0;
a
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING 0;
a
DROP TABLE t1;
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING 0;
Database
#
# End of 10.2 tests
#
#

View file

@ -4914,6 +4914,23 @@ drop procedure p;
drop view v1;
drop table t1;
--echo #
--echo # MDEV-22591 Debug build crashes on EXECUTE IMMEDIATE '... WHERE ?' USING IGNORE
--echo #
CREATE TABLE t1 (a INT);
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING IGNORE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING IGNORE;
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING 0;
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING 0;
DROP TABLE t1;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING DEFAULT;
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING 0;
--echo #
--echo # End of 10.2 tests
--echo #

View file

@ -0,0 +1,20 @@
CREATE DATABASE test1;
CREATE PROCEDURE test1.sp3() BEGIN END;
SHOW PROCEDURE STATUS;
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
mtr add_suppression PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mtr check_testcase PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mtr check_warnings PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mysql AddGeometryColumn PROCEDURE mariadb.sys@localhost # # INVOKER latin1 latin1_swedish_ci latin1_swedish_ci
mysql DropGeometryColumn PROCEDURE mariadb.sys@localhost # # INVOKER latin1 latin1_swedish_ci latin1_swedish_ci
test sp2 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
test1 sp1 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
test1 sp3 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
DROP PROCEDURE sp2;
DROP DATABASE test1;
select count(*) from mysql.event;
count(*)
416
flush tables;
show events;
truncate table mysql.event;

37
mysql-test/main/sp2.test Normal file

File diff suppressed because one or more lines are too long

View file

@ -785,8 +785,14 @@ sub run_test_server ($$$) {
if ( $result->is_failed() ) {
my $worker_logdir= $result->{savedir};
my $log_file_name=dirname($worker_logdir)."/".$result->{shortname}.".log";
$result->{'logfile-failed'} = mtr_lastlinesfromfile($log_file_name, 20);
rename $log_file_name,$log_file_name.".failed";
if (-e $log_file_name) {
$result->{'logfile-failed'} = mtr_lastlinesfromfile($log_file_name, 20);
} else {
$result->{'logfile-failed'} = "";
}
rename $log_file_name, $log_file_name.".failed";
}
delete($result->{result});
$result->{retries}= $retries+1;

View file

@ -20,5 +20,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SET @binlog_fragment_0='012345';
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
ERROR 42000: Incorrect argument type to variable 'binlog_fragment_not_exist'
SET @a= '42';
BINLOG @a, @a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
# Cleanup
DROP TABLE t;

View file

@ -41,6 +41,11 @@ SET @binlog_fragment_0='012345';
--error ER_WRONG_TYPE_FOR_VAR
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
# MDEV-22520
SET @a= '42';
--error ER_SYNTAX_ERROR
BINLOG @a, @a;
--echo # Cleanup
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
DROP TABLE t;

View file

@ -1,26 +1,24 @@
connection node_2;
connection node_1;
connection node_1;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
connection node_2;
SET SESSION wsrep_retry_autocommit = 0;
INSERT INTO t1(f1) SELECT 1 FROM ten as a1, ten AS a2;
set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;;
INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6, ten AS a7, ten AS a8;
connection node_1;
TRUNCATE TABLE t1;;
connection node_1;
connection node_2;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
connection node_1;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
connection node_2;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
EXPECT_0
0
connection node_1;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
EXPECT_0
0
DROP TABLE t1;
DROP TABLE ten;

View file

@ -4,50 +4,42 @@
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/not_embedded.inc
--source include/have_debug.inc
#
# INSERT and TRUNCATE on different nodes
#
--connection node_1
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
# Insert 1m rows
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 10 FROM ten;
--source include/wait_condition.inc
# Prevent autocommit retring from masking the deadlock error we expect to get
SET SESSION wsrep_retry_autocommit = 0;
INSERT INTO t1(f1) SELECT 1 FROM ten as a1, ten AS a2;
set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;
--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6, ten AS a7, ten AS a8
--connection node_1
# Wait for a above insert to start
--let $wait_condition = SELECT COUNT(*) >= 100 from t1;
--source include/wait_condition.inc
--send TRUNCATE TABLE t1;
--connection node_1
--reap
--connection node_2
--error ER_LOCK_DEADLOCK
--reap
--connection node_1
--reap
--connection node_2
SELECT COUNT(*) = 0 FROM t1;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
--connection node_1
SELECT COUNT(*) = 0 FROM t1;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
DROP TABLE t1;
DROP TABLE ten;

View file

@ -17,13 +17,12 @@ set global debug_dbug=@old_dbug;
connection master;
### Dump thread is hanging despite slave has gracefully exited.
let $id=`SELECT id from information_schema.processlist where command='Binlog Dump'`;
if ($id) {
replace_result $id DUMP_THREAD;
eval kill $id;
let $wait_condition= SELECT count(*)=0 from information_schema.processlist where command='Binlog Dump';
let $wait_condition= SELECT count(*)=0 from information_schema.processlist where command='Killed';
source include/wait_condition.inc;
}

View file

@ -700,7 +700,7 @@ VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Number of threads performing background key rotation
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
NUMERIC_MAX_VALUE 255
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO

View file

@ -7197,6 +7197,23 @@ public:
enum Type type() const { return TYPE_HOLDER; }
const TYPELIB *get_typelib() const { return enum_set_typelib; }
/*
When handling a query like this:
VALUES ('') UNION VALUES( _utf16 0x0020 COLLATE utf16_bin);
Item_type_holder can be passed to
Type_handler_xxx::Item_hybrid_func_fix_attributes()
We don't want the latter to perform character set conversion of a
Item_type_holder by calling its val_str(), which calls DBUG_ASSERT(0).
Let's override const_item() and is_expensive() to avoid this.
Note, Item_hybrid_func_fix_attributes() could probably
have a new argument to distinguish what we need:
- (a) aggregate data type attributes only
- (b) install converters after attribute aggregation
So st_select_lex_unit::join_union_type_attributes() could
ask it to do (a) only, without (b).
*/
bool const_item() const { return false; }
bool is_expensive() { return true; }
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);

View file

@ -158,8 +158,9 @@ int binlog_defragment(THD *thd)
memcpy(const_cast<char*>(thd->lex->comment.str) + gathered_length, entry[k]->value,
entry[k]->length);
gathered_length += entry[k]->length;
update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
}
for (uint k=0; k < 2; k++)
update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
DBUG_ASSERT(gathered_length == thd->lex->comment.length);

View file

@ -2161,7 +2161,9 @@ dict_index_remove_from_cache_low(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(table->id);
#ifdef BTR_CUR_HASH_ADAPT
ut_ad(!index->freed());
#endif /* BTR_CUR_HASH_ADAPT */
/* No need to acquire the dict_index_t::lock here because
there can't be any active operations on this index (or table). */

View file

@ -2681,10 +2681,7 @@ fseg_free_extent(
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_d(space->modify_check(*mtr));
#if defined BTR_CUR_HASH_ADAPT || defined UNIV_DEBUG
const ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
#endif /* BTR_CUR_HASH_ADAPT || UNIV_DEBUG */
ut_d(ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE));
const uint16_t xoffset= uint16_t(descr - xdes->frame + XDES_FLST_NODE);
const uint16_t ioffset= uint16_t(seg_inode - iblock->frame);

View file

@ -583,7 +583,7 @@ fts_cache_init(
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = ib_vector_create(
cache->sync_heap, sizeof(fts_update_t), 4);
cache->sync_heap, sizeof(doc_id_t), 4);
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
/* Reset the cache data for all the FTS indexes. */
@ -2592,11 +2592,11 @@ dberr_t
fts_cmp_set_sync_doc_id(
/*====================*/
const dict_table_t* table, /*!< in: table */
doc_id_t doc_id_cmp, /*!< in: Doc ID to compare */
doc_id_t cmp_doc_id, /*!< in: Doc ID to compare */
ibool read_only, /*!< in: TRUE if read the
synced_doc_id only */
doc_id_t* doc_id) /*!< out: larger document id
after comparing "doc_id_cmp"
after comparing "cmp_doc_id"
to the one stored in CONFIG
table */
{
@ -2667,10 +2667,10 @@ retry:
goto func_exit;
}
if (doc_id_cmp == 0 && *doc_id) {
if (cmp_doc_id == 0 && *doc_id) {
cache->synced_doc_id = *doc_id - 1;
} else {
cache->synced_doc_id = ut_max(doc_id_cmp, *doc_id);
cache->synced_doc_id = ut_max(cmp_doc_id, *doc_id);
}
mutex_enter(&cache->doc_id_lock);
@ -2681,7 +2681,7 @@ retry:
}
mutex_exit(&cache->doc_id_lock);
if (doc_id_cmp > *doc_id) {
if (cmp_doc_id > *doc_id) {
error = fts_update_sync_doc_id(
table, cache->synced_doc_id, trx);
}
@ -2803,7 +2803,7 @@ fts_doc_ids_create(void)
fts_doc_ids->self_heap = ib_heap_allocator_create(heap);
fts_doc_ids->doc_ids = static_cast<ib_vector_t*>(ib_vector_create(
fts_doc_ids->self_heap, sizeof(fts_update_t), 32));
fts_doc_ids->self_heap, sizeof(doc_id_t), 32));
return(fts_doc_ids);
}
@ -3878,7 +3878,7 @@ fts_sync_add_deleted_cache(
ut_a(ib_vector_size(doc_ids) > 0);
ib_vector_sort(doc_ids, fts_update_doc_id_cmp);
ib_vector_sort(doc_ids, fts_doc_id_cmp);
info = pars_info_create();
@ -3896,13 +3896,13 @@ fts_sync_add_deleted_cache(
"BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
fts_update_t* update;
doc_id_t* update;
doc_id_t write_doc_id;
update = static_cast<fts_update_t*>(ib_vector_get(doc_ids, i));
update = static_cast<doc_id_t*>(ib_vector_get(doc_ids, i));
/* Convert to "storage" byte order. */
fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id", &write_doc_id);
error = fts_eval_sql(sync->trx, graph);
@ -5193,12 +5193,12 @@ fts_cache_append_deleted_doc_ids(
for (ulint i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
fts_update_t* update;
doc_id_t* update;
update = static_cast<fts_update_t*>(
update = static_cast<doc_id_t*>(
ib_vector_get(cache->deleted_doc_ids, i));
ib_vector_push(vector, &update->doc_id);
ib_vector_push(vector, &update);
}
mutex_exit((ib_mutex_t*) &cache->deleted_lock);

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2019, MariaDB Corporation.
Copyright (c) 2016, 2020, 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
@ -925,7 +925,7 @@ fts_fetch_doc_ids(
int i = 0;
sel_node_t* sel_node = static_cast<sel_node_t*>(row);
fts_doc_ids_t* fts_doc_ids = static_cast<fts_doc_ids_t*>(user_arg);
fts_update_t* update = static_cast<fts_update_t*>(
doc_id_t* update = static_cast<doc_id_t*>(
ib_vector_push(fts_doc_ids->doc_ids, NULL));
for (exp = sel_node->select_list;
@ -941,8 +941,7 @@ fts_fetch_doc_ids(
/* Note: The column numbers below must match the SELECT. */
switch (i) {
case 0: /* DOC_ID */
update->fts_indexes = NULL;
update->doc_id = fts_read_doc_id(
*update = fts_read_doc_id(
static_cast<byte*>(data));
break;
@ -1010,7 +1009,7 @@ fts_table_fetch_doc_ids(
mutex_exit(&dict_sys.mutex);
if (error == DB_SUCCESS) {
ib_vector_sort(doc_ids->doc_ids, fts_update_doc_id_cmp);
ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp);
}
if (alloc_bk_trx) {
@ -1027,7 +1026,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
fts_update_t* array, /*!< in: array to sort */
doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: the array lower bound */
int upper, /*!< in: the array upper bound */
doc_id_t doc_id) /*!< in: the doc id to search for */
@ -1041,9 +1040,9 @@ fts_bsearch(
while (lower < upper) {
int i = (lower + upper) >> 1;
if (doc_id > array[i].doc_id) {
if (doc_id > array[i]) {
lower = i + 1;
} else if (doc_id < array[i].doc_id) {
} else if (doc_id < array[i]) {
upper = i - 1;
} else {
return(i); /* Found. */
@ -1052,7 +1051,7 @@ fts_bsearch(
}
if (lower == upper && lower < orig_size) {
if (doc_id == array[lower].doc_id) {
if (doc_id == array[lower]) {
return(lower);
} else if (lower == 0) {
return(-1);
@ -1079,7 +1078,7 @@ fts_optimize_lookup(
{
int pos;
int upper = static_cast<int>(ib_vector_size(doc_ids));
fts_update_t* array = (fts_update_t*) doc_ids->data;
doc_id_t* array = (doc_id_t*) doc_ids->data;
pos = fts_bsearch(array, static_cast<int>(lower), upper, first_doc_id);
@ -1092,10 +1091,10 @@ fts_optimize_lookup(
/* If i is 1, it could be first_doc_id is less than
either the first or second array item, do a
double check */
if (i == 1 && array[0].doc_id <= last_doc_id
&& first_doc_id < array[0].doc_id) {
if (i == 1 && array[0] <= last_doc_id
&& first_doc_id < array[0]) {
pos = 0;
} else if (i < upper && array[i].doc_id <= last_doc_id) {
} else if (i < upper && array[i] <= last_doc_id) {
/* Check if the "next" doc id is within the
first & last doc id of the node. */
@ -1234,12 +1233,12 @@ test_again:
delta for decoding the entries following this document's
entries. */
if (*del_pos >= 0 && *del_pos < (int) ib_vector_size(del_vec)) {
fts_update_t* update;
doc_id_t* update;
update = (fts_update_t*) ib_vector_get(
update = (doc_id_t*) ib_vector_get(
del_vec, ulint(*del_pos));
del_doc_id = update->doc_id;
del_doc_id = *update;
}
if (enc->src_ilist_ptr == src_node->ilist && doc_id == 0) {
@ -2025,7 +2024,7 @@ fts_optimize_purge_deleted_doc_ids(
ulint i;
pars_info_t* info;
que_t* graph;
fts_update_t* update;
doc_id_t* update;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
char deleted[MAX_FULL_NAME_LEN];
@ -2035,11 +2034,11 @@ fts_optimize_purge_deleted_doc_ids(
ut_a(ib_vector_size(optim->to_delete->doc_ids) > 0);
update = static_cast<fts_update_t*>(
update = static_cast<doc_id_t*>(
ib_vector_get(optim->to_delete->doc_ids, 0));
/* Convert to "storage" byte order. */
fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
fts_write_doc_id((byte*) &write_doc_id, *update);
/* This is required for the SQL parser to work. It must be able
to find the following variables. So we do it twice. */
@ -2061,11 +2060,11 @@ fts_optimize_purge_deleted_doc_ids(
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
update = static_cast<fts_update_t*>(ib_vector_get(
update = static_cast<doc_id_t*>(ib_vector_get(
optim->to_delete->doc_ids, i));
/* Convert to "storage" byte order. */
fts_write_doc_id((byte*) &write_doc_id, update->doc_id);
fts_write_doc_id((byte*) &write_doc_id, *update);
fts_bind_doc_id(info, "doc_id1", &write_doc_id);

View file

@ -731,10 +731,10 @@ fts_query_union_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's not already in our set. */
if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
fts_ranking_t ranking;
@ -762,10 +762,10 @@ fts_query_remove_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
ut_free(rbt_remove_node(query->doc_ids, parent.last));
@ -792,10 +792,10 @@ fts_query_change_ranking(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
/* Check if the doc id is deleted and it's in our set. */
if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0
if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0
&& rbt_search(query->doc_ids, &parent, &doc_id) == 0) {
fts_ranking_t* ranking;
@ -829,7 +829,7 @@ fts_query_intersect_doc_id(
{
ib_rbt_bound_t parent;
ulint size = ib_vector_size(query->deleted->doc_ids);
fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data;
doc_id_t* updates = (doc_id_t*) query->deleted->doc_ids->data;
fts_ranking_t* ranking= NULL;
/* There are three types of intersect:
@ -841,7 +841,7 @@ fts_query_intersect_doc_id(
if it matches 'b' and it's in doc_ids.(multi_exist = true). */
/* Check if the doc id is deleted and it's in our set */
if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0) {
if (fts_bsearch(updates, 0, static_cast<int>(size), doc_id) < 0) {
fts_ranking_t new_ranking;
if (rbt_search(query->doc_ids, &parent, &doc_id) != 0) {
@ -3651,8 +3651,8 @@ fts_query_prepare_result(
if (query->flags == FTS_OPT_RANKING) {
fts_word_freq_t* word_freq;
ulint size = ib_vector_size(query->deleted->doc_ids);
fts_update_t* array =
(fts_update_t*) query->deleted->doc_ids->data;
doc_id_t* updates =
(doc_id_t*) query->deleted->doc_ids->data;
node = rbt_first(query->word_freqs);
ut_ad(node);
@ -3667,7 +3667,7 @@ fts_query_prepare_result(
doc_freq = rbt_value(fts_doc_freq_t, node);
/* Don't put deleted docs into result */
if (fts_bsearch(array, 0, static_cast<int>(size),
if (fts_bsearch(updates, 0, static_cast<int>(size),
doc_freq->doc_id) >= 0) {
/* one less matching doc count */
--word_freq->doc_count;
@ -4018,7 +4018,7 @@ fts_query(
DEBUG_SYNC_C("fts_deleted_doc_ids_append");
/* Sort the vector so that we can do a binary search over the ids. */
ib_vector_sort(query.deleted->doc_ids, fts_update_doc_id_cmp);
ib_vector_sort(query.deleted->doc_ids, fts_doc_id_cmp);
/* Convert the query string to lower case before parsing. We own
the ut_malloc'ed result and so remember to free it before return. */

View file

@ -20141,7 +20141,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"Number of threads performing background key rotation ",
NULL,
innodb_encryption_threads_update,
srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,

View file

@ -1018,16 +1018,12 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
@return whether the table will be rebuilt */
bool need_rebuild () const { return(old_table != new_table); }
/** Clear uncommmitted added indexes after a failed operation. */
void clear_added_indexes()
{
for (ulint i = 0; i < num_to_add_index; i++) {
if (!add_index[i]->is_committed()) {
add_index[i]->detach_columns();
add_index[i]->n_fields = 0;
}
}
}
/** Clear uncommmitted added indexes after a failed operation. */
void clear_added_indexes()
{
for (ulint i= 0; i < num_to_add_index; i++)
add_index[i]->detach_columns(true);
}
/** Convert table-rebuilding ALTER to instant ALTER. */
void prepare_instant()
@ -6190,6 +6186,7 @@ prepare_inplace_alter_table_dict(
create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table,
ha_alter_info->create_info, NULL, NULL,
srv_file_per_table);
ut_d(bool stats_wait = false);
/* The primary index would be rebuilt if a FTS Doc ID
column is to be added, and the primary index definition
@ -6241,6 +6238,7 @@ prepare_inplace_alter_table_dict(
XXX what may happen if bg stats opens the table after we
have unlocked data dictionary below? */
dict_stats_wait_bg_to_stop_using_table(user_table, ctx->trx);
ut_d(stats_wait = true);
online_retry_drop_indexes_low(ctx->new_table, ctx->trx);
@ -7123,7 +7121,8 @@ error_handled:
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
holding dict_sys.latch X-latch. */
DBUG_ASSERT(user_table->get_ref_count() == 1 || ctx->online);
ut_ad(!stats_wait || ctx->online
|| user_table->get_ref_count() == 1);
online_retry_drop_indexes_with_trx(user_table, ctx->trx);
} else {

View file

@ -579,101 +579,103 @@ private:
static const unsigned DROPPED = 1023;
public:
/** Detach the column from an index.
@param[in] index index to be detached from */
inline void detach(const dict_index_t& index);
/** Detach a virtual column from an index.
@param index being-freed index */
inline void detach(const dict_index_t &index);
/** Data for instantly added columns */
struct def_t {
/** original default value of instantly added column */
const void* data;
/** len of data, or UNIV_SQL_DEFAULT if unavailable */
ulint len;
} def_val;
/** Data for instantly added columns */
struct def_t
{
/** original default value of instantly added column */
const void *data;
/** len of data, or UNIV_SQL_DEFAULT if unavailable */
ulint len;
} def_val;
/** Retrieve the column name.
@param[in] table the table of this column */
const char* name(const dict_table_t& table) const;
/** Retrieve the column name.
@param table the table of this column */
const char *name(const dict_table_t &table) const;
/** @return whether this is a virtual column */
bool is_virtual() const { return prtype & DATA_VIRTUAL; }
/** @return whether NULL is an allowed value for this column */
bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
/** @return whether this is a virtual column */
bool is_virtual() const { return prtype & DATA_VIRTUAL; }
/** @return whether NULL is an allowed value for this column */
bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
/** @return whether table of this system field is TRX_ID-based */
bool vers_native() const
{
ut_ad(vers_sys_start() || vers_sys_end());
ut_ad(mtype == DATA_INT || mtype == DATA_FIXBINARY);
return mtype == DATA_INT;
}
/** @return whether this user column (not row_start, row_end)
has System Versioning property */
bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
/** @return whether this is the system version start */
bool vers_sys_start() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_START;
}
/** @return whether this is the system version end */
bool vers_sys_end() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_END;
}
/** @return whether table of this system field is TRX_ID-based */
bool vers_native() const
{
ut_ad(vers_sys_start() || vers_sys_end());
ut_ad(mtype == DATA_INT || mtype == DATA_FIXBINARY);
return mtype == DATA_INT;
}
/** @return whether this user column (not row_start, row_end)
has System Versioning property */
bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
/** @return whether this is the system version start */
bool vers_sys_start() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_START;
}
/** @return whether this is the system version end */
bool vers_sys_end() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_END;
}
/** @return whether this is an instantly-added column */
bool is_added() const
{
DBUG_ASSERT(def_val.len != UNIV_SQL_DEFAULT || !def_val.data);
return def_val.len != UNIV_SQL_DEFAULT;
}
/** Flag the column instantly dropped */
void set_dropped() { ind = DROPPED; }
/** Flag the column instantly dropped.
@param[in] not_null whether the column was NOT NULL
@param[in] len2 whether the length exceeds 255 bytes
@param[in] fixed_len the fixed length in bytes, or 0 */
void set_dropped(bool not_null, bool len2, unsigned fixed)
{
DBUG_ASSERT(!len2 || !fixed);
prtype = not_null
? DATA_NOT_NULL | DATA_BINARY_TYPE
: DATA_BINARY_TYPE;
if (fixed) {
mtype = DATA_FIXBINARY;
len = static_cast<uint16_t>(fixed);
} else {
mtype = DATA_BINARY;
len = len2 ? 65535 : 255;
}
mbminlen = mbmaxlen = 0;
ind = DROPPED;
ord_part = 0;
max_prefix = 0;
}
/** @return whether the column was instantly dropped */
bool is_dropped() const { return ind == DROPPED; }
/** @return whether the column was instantly dropped
@param[in] index the clustered index */
inline bool is_dropped(const dict_index_t& index) const;
/** @return whether this is an instantly-added column */
bool is_added() const
{
DBUG_ASSERT(def_val.len != UNIV_SQL_DEFAULT || !def_val.data);
return def_val.len != UNIV_SQL_DEFAULT;
}
/** Flag the column instantly dropped */
void set_dropped() { ind = DROPPED; }
/** Flag the column instantly dropped.
@param not_null whether the column was NOT NULL
@param len2 whether the length exceeds 255 bytes
@param fixed_len the fixed length in bytes, or 0 */
void set_dropped(bool not_null, bool len2, unsigned fixed)
{
DBUG_ASSERT(!len2 || !fixed);
prtype= not_null ? DATA_NOT_NULL | DATA_BINARY_TYPE : DATA_BINARY_TYPE;
if (fixed)
{
mtype= DATA_FIXBINARY;
len= static_cast<uint16_t>(fixed);
}
else
{
mtype= DATA_BINARY;
len= len2 ? 65535 : 255;
}
mbminlen= mbmaxlen= 0;
ind= DROPPED;
ord_part= 0;
max_prefix= 0;
}
/** @return whether the column was instantly dropped */
bool is_dropped() const { return ind == DROPPED; }
/** @return whether the column was instantly dropped
@param index the clustered index */
inline bool is_dropped(const dict_index_t &index) const;
/** Get the default value of an instantly-added column.
@param[out] len value length (in bytes), or UNIV_SQL_NULL
@return default value
@retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
const byte* instant_value(ulint* len) const
{
DBUG_ASSERT(is_added());
*len = def_val.len;
return static_cast<const byte*>(def_val.data);
}
/** Get the default value of an instantly-added column.
@param[out] len value length (in bytes), or UNIV_SQL_NULL
@return default value
@retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
const byte *instant_value(ulint *len) const
{
DBUG_ASSERT(is_added());
*len= def_val.len;
return static_cast<const byte*>(def_val.data);
}
/** Remove the 'instant ADD' status of the column */
void clear_instant()
{
def_val.len = UNIV_SQL_DEFAULT;
def_val.data = NULL;
}
/** Remove the 'instant ADD' status of the column */
void clear_instant()
{
def_val.len= UNIV_SQL_DEFAULT;
def_val.data= NULL;
}
/** @return whether two columns have compatible data type encoding */
bool same_type(const dict_col_t &other) const
@ -719,24 +721,21 @@ public:
/** @return whether two collations codes have the same character encoding */
static bool same_encoding(uint16_t a, uint16_t b);
/** Determine if the columns have the same format
except for is_nullable() and is_versioned().
@param[in] other column to compare to
@return whether the columns have the same format */
bool same_format(const dict_col_t& other) const
{
return same_type(other)
&& len >= other.len
&& mbminlen == other.mbminlen
&& mbmaxlen == other.mbmaxlen
&& !((prtype ^ other.prtype)
& ~(DATA_NOT_NULL | DATA_VERSIONED
| CHAR_COLL_MASK << 16
| DATA_LONG_TRUE_VARCHAR));
}
/** Determine if the columns have the same format
except for is_nullable() and is_versioned().
@param other column to compare to
@return whether the columns have the same format */
bool same_format(const dict_col_t &other) const
{
return same_type(other) && len >= other.len &&
mbminlen == other.mbminlen && mbmaxlen == other.mbmaxlen &&
!((prtype ^ other.prtype) & ~(DATA_NOT_NULL | DATA_VERSIONED |
CHAR_COLL_MASK << 16 |
DATA_LONG_TRUE_VARCHAR));
}
/** @return whether the column values are comparable by memcmp() */
inline bool is_binary() const { return prtype & DATA_BINARY_TYPE; }
bool is_binary() const { return prtype & DATA_BINARY_TYPE; }
};
/** Index information put in a list of virtual column structure. Index
@ -774,27 +773,30 @@ struct dict_v_col_t{
std::forward_list<dict_v_idx_t, ut_allocator<dict_v_idx_t> >
v_indexes;
/** Detach the column from an index.
@param[in] index index to be detached from */
void detach(const dict_index_t& index)
{
if (!n_v_indexes) return;
auto i = v_indexes.before_begin();
ut_d(unsigned n = 0);
do {
auto prev = i++;
if (i == v_indexes.end()) {
ut_ad(n == n_v_indexes);
return;
}
ut_ad(++n <= n_v_indexes);
if (i->index == &index) {
v_indexes.erase_after(prev);
n_v_indexes--;
return;
}
} while (i != v_indexes.end());
}
/** Detach the column from an index.
@param index index to be detached from */
void detach(const dict_index_t &index)
{
if (!n_v_indexes) return;
auto i= v_indexes.before_begin();
ut_d(unsigned n= 0);
do {
auto prev = i++;
if (i == v_indexes.end())
{
ut_ad(n == n_v_indexes);
return;
}
ut_ad(++n <= n_v_indexes);
if (i->index == &index)
{
v_indexes.erase_after(prev);
n_v_indexes--;
return;
}
}
while (i != v_indexes.end());
}
};
/** Data structure for newly added virtual column in a table */
@ -1204,15 +1206,22 @@ public:
/** @return whether the index is corrupted */
inline bool is_corrupted() const;
/** Detach the columns from the index that is to be freed. */
void detach_columns()
{
if (has_virtual()) {
for (unsigned i = 0; i < n_fields; i++) {
fields[i].col->detach(*this);
}
}
}
/** Detach the virtual columns from the index that is to be removed.
@param whether to reset fields[].col */
void detach_columns(bool clear= false)
{
if (!has_virtual())
return;
for (unsigned i= 0; i < n_fields; i++)
{
dict_col_t* col= fields[i].col;
if (!col || !col->is_virtual())
continue;
col->detach(*this);
if (clear)
fields[i].col= nullptr;
}
}
/** Determine how many fields of a given prefix can be set NULL.
@param[in] n_prefix number of fields in the prefix
@ -1358,13 +1367,12 @@ public:
inline record_size_info_t record_size_info() const;
};
/** Detach a column from an index.
@param[in] index index to be detached from */
inline void dict_col_t::detach(const dict_index_t& index)
/** Detach a virtual column from an index.
@param index being-freed index */
inline void dict_col_t::detach(const dict_index_t &index)
{
if (is_virtual()) {
reinterpret_cast<dict_v_col_t*>(this)->detach(index);
}
if (is_virtual())
reinterpret_cast<dict_v_col_t*>(this)->detach(index);
}
/** The status of online index creation */

View file

@ -239,7 +239,7 @@ Do a binary search for a doc id in the array
int
fts_bsearch(
/*========*/
fts_update_t* array, /*!< in: array to sort */
doc_id_t* array, /*!< in: array to sort */
int lower, /*!< in: lower bound of array*/
int upper, /*!< in: upper bound of array*/
doc_id_t doc_id) /*!< in: doc id to lookup */

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
Copyright (c) 2017, 2020, 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
@ -80,20 +80,6 @@ struct fts_index_cache_t {
CHARSET_INFO* charset; /*!< charset */
};
/** For supporting the tracking of updates on multiple FTS indexes we need
to track which FTS indexes need to be updated. For INSERT and DELETE we
update all fts indexes. */
struct fts_update_t {
doc_id_t doc_id; /*!< The doc id affected */
ib_vector_t* fts_indexes; /*!< The FTS indexes that need to be
updated. A NULL value means all
indexes need to be updated. This
vector is not allocated on the heap
and so must be freed explicitly,
when we are done with it */
};
/** Stop word control infotmation. */
struct fts_stopword_t {
ulint status; /*!< Status of the stopword tree */
@ -319,10 +305,9 @@ fts_ranking_doc_id_cmp(
const void* p2); /*!< in: id2 */
/******************************************************************//**
Compare two fts_update_t instances doc_ids. */
Compare two doc_ids. */
UNIV_INLINE
int
fts_update_doc_id_cmp(
int fts_doc_id_cmp(
/*==================*/
/*!< out:
< 0 if n1 < n2,

View file

@ -79,19 +79,18 @@ fts_ranking_doc_id_cmp(
}
/******************************************************************//**
Compare two fts_update_t doc_ids.
Compare two doc_ids.
@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */
UNIV_INLINE
int
fts_update_doc_id_cmp(
int fts_doc_id_cmp(
/*==================*/
const void* p1, /*!< in: id1 */
const void* p2) /*!< in: id2 */
{
const fts_update_t* up1 = (const fts_update_t*) p1;
const fts_update_t* up2 = (const fts_update_t*) p2;
const doc_id_t* up1 = static_cast<const doc_id_t*>(p1);
const doc_id_t* up2 = static_cast<const doc_id_t*>(p2);
return((int)(up1->doc_id - up2->doc_id));
return static_cast<int>(*up1 - *up2);
}
/******************************************************************//**

View file

@ -411,6 +411,14 @@ class error : public logger {
public:
ATTRIBUTE_COLD
~error();
/** Indicates that error::~error() was invoked. Can be used to
determine if error messages were logged during innodb code execution.
@return true if there were error messages, false otherwise. */
static bool was_logged() { return logged; }
private:
/** true if error::~error() was invoked, false otherwise */
static bool logged;
};
/** The class fatal is used to emit an error message and stop the server

View file

@ -6207,7 +6207,7 @@ static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
ut_ad(lock->trx == element->trx);
if (lock_get_type_low(lock) == LOCK_REC)
{
ut_ad(!dict_index_is_online_ddl(lock->index) ||
ut_ad(lock->index->online_status != ONLINE_INDEX_CREATION ||
lock->index->is_primary());
ut_ad(lock->index->table != table);
}

View file

@ -4005,7 +4005,7 @@ static bool is_linux_native_aio_supported()
case -EINVAL:
case -ENOSYS:
ib::error()
ib::warn()
<< "Linux Native AIO not supported. You can either"
" move "
<< (srv_read_only_mode ? log_file_path : "tmpdir")
@ -4015,7 +4015,7 @@ static bool is_linux_native_aio_supported()
/* fall through. */
default:
ib::error()
ib::warn()
<< "Linux Native AIO check on "
<< (srv_read_only_mode ? log_file_path : "tmpdir")
<< "returned error[" << -err << "]";

View file

@ -58,35 +58,22 @@ check.
If you make a change in this module make sure that no codepath is
introduced where a call to log_free_check() is bypassed. */
/***********************************************************//**
Creates an entry template for each index of a table. */
static
void
ins_node_create_entry_list(
/*=======================*/
ins_node_t* node) /*!< in: row insert node */
/** Create an row template for each index of a table. */
static void ins_node_create_entry_list(ins_node_t *node)
{
dict_index_t* index;
dtuple_t* entry;
node->entry_list.reserve(UT_LIST_GET_LEN(node->table->indexes));
ut_ad(node->entry_sys_heap);
/* We will include all indexes (include those corrupted
secondary indexes) in the entry list. Filtration of
these corrupted index will be done in row_ins() */
node->entry_list.reserve(UT_LIST_GET_LEN(node->table->indexes));
for (index = dict_table_get_first_index(node->table);
index != 0;
index = dict_table_get_next_index(index)) {
entry = row_build_index_entry_low(
node->row, NULL, index, node->entry_sys_heap,
ROW_BUILD_FOR_INSERT);
node->entry_list.push_back(entry);
}
for (dict_index_t *index= dict_table_get_first_index(node->table); index;
index= dict_table_get_next_index(index))
{
/* Corrupted or incomplete secondary indexes will be filtered out in
row_ins(). */
dtuple_t *entry= index->online_status >= ONLINE_INDEX_ABORTED
? dtuple_create(node->entry_sys_heap, 0)
: row_build_index_entry_low(node->row, NULL, index, node->entry_sys_heap,
ROW_BUILD_FOR_INSERT);
node->entry_list.push_back(entry);
}
}
/*****************************************************************//**

View file

@ -1280,10 +1280,6 @@ void
row_sel_open_pcur(
/*==============*/
plan_t* plan, /*!< in: table plan */
#ifdef BTR_CUR_HASH_ADAPT
rw_lock_t* ahi_latch,
/*!< in: the adaptive hash index latch */
#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
@ -1327,7 +1323,7 @@ row_sel_open_pcur(
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
BTR_SEARCH_LEAF, &plan->pcur,
ahi_latch, mtr);
NULL, mtr);
} else {
/* Open the cursor to the start or the end of the index
(FALSE: no init) */
@ -1472,16 +1468,12 @@ row_sel_try_search_shortcut(
ut_ad(plan->unique_search);
ut_ad(!plan->must_get_clust);
rw_lock_t* ahi_latch = btr_get_search_latch(index);
rw_lock_s_lock(ahi_latch);
row_sel_open_pcur(plan, ahi_latch, mtr);
row_sel_open_pcur(plan, mtr);
const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, *index)) {
retry:
rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY);
}
@ -1493,7 +1485,6 @@ retry:
if (btr_pcur_get_up_match(&(plan->pcur)) < plan->n_exact_match) {
exhausted:
rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED);
}
@ -1539,7 +1530,6 @@ exhausted:
ut_ad(plan->pcur.latch_mode == BTR_SEARCH_LEAF);
plan->n_rows_fetched++;
rw_lock_s_unlock(ahi_latch);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@ -1661,11 +1651,7 @@ table_loop:
if (!plan->pcur_is_open) {
/* Evaluate the expressions to build the search tuple and
open the cursor */
row_sel_open_pcur(plan,
#ifdef BTR_CUR_HASH_ADAPT
NULL,
#endif /* BTR_CUR_HASH_ADAPT */
&mtr);
row_sel_open_pcur(plan, &mtr);
cursor_just_opened = TRUE;

View file

@ -576,9 +576,13 @@ warn::~warn()
sql_print_warning("InnoDB: %s", m_oss.str().c_str());
}
/** true if error::~error() was invoked, false otherwise */
bool error::logged;
error::~error()
{
sql_print_error("InnoDB: %s", m_oss.str().c_str());
logged = true;
}
#ifdef _MSC_VER

View file

@ -1288,6 +1288,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16;
data= bitmap->map+byte;
first_found= 0; /* Don't update full_head_size */
DBUG_ASSERT(data <= end);
}
else