Merge 10.2 into 10.3

This commit is contained in:
Marko Mäkelä 2019-06-19 08:56:10 +03:00
commit 192aa295b4
41 changed files with 668 additions and 399 deletions

View file

@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2018, Oracle and/or its affiliates.
Copyright (c) 2009, 2018, MariaDB Corporation
Copyright (c) 2009, 2019, 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
@ -40,6 +40,7 @@
#include "my_readline.h"
#include <signal.h>
#include <violite.h>
#include <my_sys.h>
#include <source_revision.h>
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
#include <locale.h>
@ -4697,7 +4698,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
select_limit,max_join_size);
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
}
if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME))
default_charset= (char *)my_default_csname();
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
if (!do_connect(&mysql, host, user, password, database,

View file

@ -26,6 +26,7 @@
#include <welcome_copyright_notice.h>
#include <my_rnd.h>
#include <password.h>
#include <my_sys.h>
#define ADMIN_VERSION "9.1"
#define MAX_MYSQL_VAR 512
@ -371,6 +372,8 @@ int main(int argc,char *argv[])
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME))
default_charset= (char *)my_default_csname();
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
error_flags= (myf)(opt_nobeep ? 0 : ME_BELL);

View file

@ -440,8 +440,10 @@ static int get_options(int *argc, char ***argv)
else
default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
}
if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) &&
!get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))
if (!strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME))
default_charset= (char *)my_default_csname();
if (!get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))
{
printf("Unsupported character set: %s\n", default_charset);
DBUG_RETURN(1);

View file

@ -30,6 +30,8 @@
#define IMPORT_VERSION "3.7"
#include "client_priv.h"
#include <my_sys.h>
#include "mysql_version.h"
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
@ -472,8 +474,9 @@ static MYSQL *db_connect(char *host, char *database,
if (opt_default_auth && *opt_default_auth)
mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME))
default_charset= (char *)my_default_csname();
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, my_default_csname());
mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
"program_name", "mysqlimport");

View file

@ -135,6 +135,8 @@ int main(int argc, char **argv)
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME))
default_charset= (char *)my_default_csname();
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
if (opt_plugin_dir && *opt_plugin_dir)

View file

@ -1049,6 +1049,7 @@ extern char *get_tty_password(const char *opt_message);
/* File system character set */
extern CHARSET_INFO *fs_character_set(void);
#endif
extern const char *my_default_csname(void);
extern size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
char *to, size_t to_length,
const char *from, size_t length);

View file

@ -0,0 +1,2 @@
@@character_set_client
cp1257

View file

@ -0,0 +1,2 @@
--source include/windows.inc
--exec chcp 1257 > NUL && $MYSQL --default-character-set=auto -e "select @@character_set_client"

View file

@ -47,3 +47,46 @@ t1 CREATE TABLE `t1` (
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t1, t2;
#
# MDEV-19055 Assertion `(_my_thread_var())->thr_errno != 0' failed in pagecache_read
#
CREATE OR REPLACE TABLE t1 (x INT) ENGINE=Aria;
CREATE TEMPORARY TABLE t2 (a TIME) ENGINE=Aria;
ALTER TABLE t2 ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t2 ADD CHECK (b = 4);
INSERT IGNORE INTO t2 () VALUES (),(),(),();
ALTER IGNORE TABLE t2 ADD c INT;
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
DELETE FROM t2 ORDER BY c LIMIT 1;
INSERT IGNORE INTO t2 SELECT * FROM t2;
OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 optimize status OK
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
INSERT IGNORE INTO t2 SELECT * FROM t2;
SET SQL_MODE= 'STRICT_ALL_TABLES';
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
ALTER TABLE t2 CHANGE IF EXISTS d c INT;
ERROR 22007: Incorrect datetime value: '4'
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
ALTER IGNORE TABLE t2 ADD IF NOT EXISTS e BIT;
ALTER TABLE t1 MODIFY IF EXISTS xx INT;
INSERT IGNORE INTO t2 () VALUES (),(),(),();
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
check table t2;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t1,t2;

View file

@ -42,3 +42,38 @@ ALTER TABLE t1 ORDER BY unknown_column;
SHOW CREATE TABLE t1;
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t1, t2;
--echo #
--echo # MDEV-19055 Assertion `(_my_thread_var())->thr_errno != 0' failed in pagecache_read
--echo #
--disable_warnings
CREATE OR REPLACE TABLE t1 (x INT) ENGINE=Aria;
CREATE TEMPORARY TABLE t2 (a TIME) ENGINE=Aria;
ALTER TABLE t2 ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t2 ADD CHECK (b = 4);
INSERT IGNORE INTO t2 () VALUES (),(),(),();
ALTER IGNORE TABLE t2 ADD c INT;
SELECT count(a),sum(a) FROM t2;
DELETE FROM t2 ORDER BY c LIMIT 1;
INSERT IGNORE INTO t2 SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT count(a),sum(a) FROM t2;
INSERT IGNORE INTO t2 SELECT * FROM t2;
SET SQL_MODE= 'STRICT_ALL_TABLES';
SELECT count(a),sum(a) FROM t2;
--error ER_TRUNCATED_WRONG_VALUE
ALTER TABLE t2 CHANGE IF EXISTS d c INT;
SELECT count(a),sum(a) FROM t2;
ALTER IGNORE TABLE t2 ADD IF NOT EXISTS e BIT;
ALTER TABLE t1 MODIFY IF EXISTS xx INT;
INSERT IGNORE INTO t2 () VALUES (),(),(),();
SELECT count(a),sum(a) FROM t2;
--enable_warnings
check table t1;
check table t2;
DROP TABLE t1,t2;
#
# End of 10.2 tests
#

View file

@ -0,0 +1,23 @@
CREATE TABLE t1 (b INT);
INSERT INTO t1 VALUES (5);
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=Aria ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES (1);
DELETE FROM t1 LIMIT 2;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
SELECT * FROM t1;
a
INSERT INTO t1 VALUES (1),(2);
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
ALTER TABLE t1 CHANGE COLUMN IF EXISTS x x INT;
Warnings:
Note 1054 Unknown column 'x' in 't1'
ALTER TABLE t1;
DROP TEMPORARY TABLE t1;
DROP TABLE t1;

View file

@ -0,0 +1,20 @@
#
# MDEV-19595
# ER_CRASHED_ON_USAGE and Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())'
# failed upon actions on temporary Aria table with ROW_FORMAT DYNAMIC
#
CREATE TABLE t1 (b INT);
INSERT INTO t1 VALUES (5);
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=Aria ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES (1);
DELETE FROM t1 LIMIT 2;
OPTIMIZE TABLE t1;
CHECK TABLE t1;
SELECT * FROM t1;
INSERT INTO t1 VALUES (1),(2);
CHECK TABLE t1;
ALTER TABLE t1 CHANGE COLUMN IF EXISTS x x INT;
ALTER TABLE t1;
DROP TEMPORARY TABLE t1;
DROP TABLE t1;

View file

@ -203,10 +203,10 @@ drop table t1;
create table t1 (a int, b int);
insert into t1 values (3, 30), (4, 20), (1, 20);
create table t2 (c int, d int, v int as (d+1), index idx(c));
insert into t2(c,d) values
insert into t2(c,d) values
(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
insert into t2(c,d) values
insert into t2(c,d) values
(120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
set join_cache_level=6;
@ -423,5 +423,43 @@ ERROR HY000: Incorrect information in file: './test/t1.frm'
ALTER TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
#
# MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
create or replace table t1 (pk int primary key, col_bit bit(15) default null,
vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
select pk, col_bit+0, vcol_bit+0 from t1;
pk col_bit+0 vcol_bit+0
99 1000 1000
replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
select pk, col_bit+0, vcol_bit+0 from t1;
pk col_bit+0 vcol_bit+0
99 10000 1023
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
Warnings:
Warning 1264 Out of range value for column 'vcol_bit' at row 1
drop table t1;
#
# MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
#
SET @old_sql_mode=@@sql_mode;
SET sql_mode= STRICT_ALL_TABLES;
CREATE TABLE t1 (
pk INT,
i TINYINT,
vi TINYINT AS (i+1) PERSISTENT,
PRIMARY KEY(pk)
);
INSERT INTO t1 (pk,i) VALUES (1,1);
TRUNCATE TABLE t1;
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
REPLACE INTO t1 (pk,i) VALUES (1,2);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
#
# End of 10.2 tests
#

View file

@ -215,12 +215,12 @@ drop table t1;
create table t1 (a int, b int);
insert into t1 values (3, 30), (4, 20), (1, 20);
create table t2 (c int, d int, v int as (d+1), index idx(c));
insert into t2(c,d) values
insert into t2(c,d) values
(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
insert into t2(c,d) values
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
insert into t2(c,d) values
(120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
set join_cache_level=6;
explain
@ -391,6 +391,40 @@ SHOW CREATE TABLE t1;
ALTER TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--echo #
--echo # MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
--echo
create or replace table t1 (pk int primary key, col_bit bit(15) default null,
vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
select pk, col_bit+0, vcol_bit+0 from t1;
replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
select pk, col_bit+0, vcol_bit+0 from t1;
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
drop table t1;
--echo #
--echo # MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
--echo #
SET @old_sql_mode=@@sql_mode;
SET sql_mode= STRICT_ALL_TABLES;
CREATE TABLE t1 (
pk INT,
i TINYINT,
vi TINYINT AS (i+1) PERSISTENT,
PRIMARY KEY(pk)
);
INSERT INTO t1 (pk,i) VALUES (1,1);
TRUNCATE TABLE t1;
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
REPLACE INTO t1 (pk,i) VALUES (1,2);
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
--echo #
--echo # End of 10.2 tests
--echo #

View file

@ -20,7 +20,12 @@
#include <m_string.h>
#include <my_dir.h>
#include <my_xml.h>
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
/*
The code below implements this functionality:
@ -1216,3 +1221,214 @@ size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
*to= 0;
return overflow ? (ulong)~0 : (ulong) (to - to_start);
}
typedef enum my_cs_match_type_enum
{
/* MySQL and OS charsets are fully compatible */
my_cs_exact,
/* MySQL charset is very close to OS charset */
my_cs_approx,
/*
MySQL knows this charset, but it is not supported as client character set.
*/
my_cs_unsupp
} my_cs_match_type;
typedef struct str2str_st
{
const char* os_name;
const char* my_name;
my_cs_match_type param;
} MY_CSET_OS_NAME;
static const MY_CSET_OS_NAME charsets[] =
{
#ifdef _WIN32
{"cp437", "cp850", my_cs_approx},
{"cp850", "cp850", my_cs_exact},
{"cp852", "cp852", my_cs_exact},
{"cp858", "cp850", my_cs_approx},
{"cp866", "cp866", my_cs_exact},
{"cp874", "tis620", my_cs_approx},
{"cp932", "cp932", my_cs_exact},
{"cp936", "gbk", my_cs_approx},
{"cp949", "euckr", my_cs_approx},
{"cp950", "big5", my_cs_exact},
{"cp1200", "utf16le", my_cs_unsupp},
{"cp1201", "utf16", my_cs_unsupp},
{"cp1250", "cp1250", my_cs_exact},
{"cp1251", "cp1251", my_cs_exact},
{"cp1252", "latin1", my_cs_exact},
{"cp1253", "greek", my_cs_exact},
{"cp1254", "latin5", my_cs_exact},
{"cp1255", "hebrew", my_cs_approx},
{"cp1256", "cp1256", my_cs_exact},
{"cp1257", "cp1257", my_cs_exact},
{"cp10000", "macroman", my_cs_exact},
{"cp10001", "sjis", my_cs_approx},
{"cp10002", "big5", my_cs_approx},
{"cp10008", "gb2312", my_cs_approx},
{"cp10021", "tis620", my_cs_approx},
{"cp10029", "macce", my_cs_exact},
{"cp12001", "utf32", my_cs_unsupp},
{"cp20107", "swe7", my_cs_exact},
{"cp20127", "latin1", my_cs_approx},
{"cp20866", "koi8r", my_cs_exact},
{"cp20932", "ujis", my_cs_exact},
{"cp20936", "gb2312", my_cs_approx},
{"cp20949", "euckr", my_cs_approx},
{"cp21866", "koi8u", my_cs_exact},
{"cp28591", "latin1", my_cs_approx},
{"cp28592", "latin2", my_cs_exact},
{"cp28597", "greek", my_cs_exact},
{"cp28598", "hebrew", my_cs_exact},
{"cp28599", "latin5", my_cs_exact},
{"cp28603", "latin7", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
{"cp28605", "latin9", my_cs_exact},
#endif
{"cp38598", "hebrew", my_cs_exact},
{"cp51932", "ujis", my_cs_exact},
{"cp51936", "gb2312", my_cs_exact},
{"cp51949", "euckr", my_cs_exact},
{"cp51950", "big5", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
{"cp54936", "gb18030", my_cs_exact},
#endif
{"cp65001", "utf8", my_cs_exact},
#else /* not Windows */
{"646", "latin1", my_cs_approx}, /* Default on Solaris */
{"ANSI_X3.4-1968", "latin1", my_cs_approx},
{"ansi1251", "cp1251", my_cs_exact},
{"armscii8", "armscii8", my_cs_exact},
{"armscii-8", "armscii8", my_cs_exact},
{"ASCII", "latin1", my_cs_approx},
{"Big5", "big5", my_cs_exact},
{"cp1251", "cp1251", my_cs_exact},
{"cp1255", "hebrew", my_cs_approx},
{"CP866", "cp866", my_cs_exact},
{"eucCN", "gb2312", my_cs_exact},
{"euc-CN", "gb2312", my_cs_exact},
{"eucJP", "ujis", my_cs_exact},
{"euc-JP", "ujis", my_cs_exact},
{"eucKR", "euckr", my_cs_exact},
{"euc-KR", "euckr", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
{"gb18030", "gb18030", my_cs_exact},
#endif
{"gb2312", "gb2312", my_cs_exact},
{"gbk", "gbk", my_cs_exact},
{"georgianps", "geostd8", my_cs_exact},
{"georgian-ps", "geostd8", my_cs_exact},
{"IBM-1252", "cp1252", my_cs_exact},
{"iso88591", "latin1", my_cs_approx},
{"ISO_8859-1", "latin1", my_cs_approx},
{"ISO8859-1", "latin1", my_cs_approx},
{"ISO-8859-1", "latin1", my_cs_approx},
{"iso885913", "latin7", my_cs_exact},
{"ISO_8859-13", "latin7", my_cs_exact},
{"ISO8859-13", "latin7", my_cs_exact},
{"ISO-8859-13", "latin7", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
{"iso885915", "latin9", my_cs_exact},
{"ISO_8859-15", "latin9", my_cs_exact},
{"ISO8859-15", "latin9", my_cs_exact},
{"ISO-8859-15", "latin9", my_cs_exact},
#endif
{"iso88592", "latin2", my_cs_exact},
{"ISO_8859-2", "latin2", my_cs_exact},
{"ISO8859-2", "latin2", my_cs_exact},
{"ISO-8859-2", "latin2", my_cs_exact},
{"iso88597", "greek", my_cs_exact},
{"ISO_8859-7", "greek", my_cs_exact},
{"ISO8859-7", "greek", my_cs_exact},
{"ISO-8859-7", "greek", my_cs_exact},
{"iso88598", "hebrew", my_cs_exact},
{"ISO_8859-8", "hebrew", my_cs_exact},
{"ISO8859-8", "hebrew", my_cs_exact},
{"ISO-8859-8", "hebrew", my_cs_exact},
{"iso88599", "latin5", my_cs_exact},
{"ISO_8859-9", "latin5", my_cs_exact},
{"ISO8859-9", "latin5", my_cs_exact},
{"ISO-8859-9", "latin5", my_cs_exact},
{"koi8r", "koi8r", my_cs_exact},
{"KOI8-R", "koi8r", my_cs_exact},
{"koi8u", "koi8u", my_cs_exact},
{"KOI8-U", "koi8u", my_cs_exact},
{"roman8", "hp8", my_cs_exact}, /* Default on HP UX */
{"Shift_JIS", "sjis", my_cs_exact},
{"SJIS", "sjis", my_cs_exact},
{"shiftjisx0213", "sjis", my_cs_exact},
{"tis620", "tis620", my_cs_exact},
{"tis-620", "tis620", my_cs_exact},
{"ujis", "ujis", my_cs_exact},
{"US-ASCII", "latin1", my_cs_approx},
{"utf8", "utf8", my_cs_exact},
{"utf-8", "utf8", my_cs_exact},
#endif
{NULL, NULL, 0}
};
static const char*
my_os_charset_to_mysql_charset(const char* csname)
{
const MY_CSET_OS_NAME* csp;
for (csp = charsets; csp->os_name; csp++)
{
if (!strcasecmp(csp->os_name, csname))
{
switch (csp->param)
{
case my_cs_exact:
return csp->my_name;
case my_cs_approx:
/*
Maybe we should print a warning eventually:
character set correspondence is not exact.
*/
return csp->my_name;
default:
return NULL;
}
}
}
return NULL;
}
const char* my_default_csname()
{
const char* csname = NULL;
#ifdef _WIN32
char cpbuf[64];
int cp = GetConsoleCP();
if (cp == 0)
cp = GetACP();
snprintf(cpbuf, sizeof(cpbuf), "cp%d", (int)cp);
csname = my_os_charset_to_mysql_charset(cpbuf);
#elif defined(HAVE_SETLOCALE) && defined(HAVE_NL_LANGINFO)
if (setlocale(LC_CTYPE, "") && (csname = nl_langinfo(CODESET)))
csname = my_os_charset_to_mysql_charset(csname);
#endif
return csname ? csname : MYSQL_DEFAULT_CHARSET_NAME;
}

View file

@ -68,6 +68,8 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
if (readbytes != Count)
{
/* We should never read with wrong file descriptor! */
DBUG_ASSERT(readbytes != (size_t)-1 || errno != EBADF);
my_errno= errno;
if (errno == 0 || (readbytes != (size_t) -1 &&
(MyFlags & (MY_NABP | MY_FNABP))))

View file

@ -1920,250 +1920,13 @@ static MYSQL_METHODS client_methods=
};
typedef enum my_cs_match_type_enum
{
/* MySQL and OS charsets are fully compatible */
my_cs_exact,
/* MySQL charset is very close to OS charset */
my_cs_approx,
/*
MySQL knows this charset, but it is not supported as client character set.
*/
my_cs_unsupp
} my_cs_match_type;
typedef struct str2str_st
{
const char *os_name;
const char *my_name;
my_cs_match_type param;
} MY_CSET_OS_NAME;
const MY_CSET_OS_NAME charsets[]=
{
#ifdef __WIN__
{"cp437", "cp850", my_cs_approx},
{"cp850", "cp850", my_cs_exact},
{"cp852", "cp852", my_cs_exact},
{"cp858", "cp850", my_cs_approx},
{"cp866", "cp866", my_cs_exact},
{"cp874", "tis620", my_cs_approx},
{"cp932", "cp932", my_cs_exact},
{"cp936", "gbk", my_cs_approx},
{"cp949", "euckr", my_cs_approx},
{"cp950", "big5", my_cs_exact},
{"cp1200", "utf16le", my_cs_unsupp},
{"cp1201", "utf16", my_cs_unsupp},
{"cp1250", "cp1250", my_cs_exact},
{"cp1251", "cp1251", my_cs_exact},
{"cp1252", "latin1", my_cs_exact},
{"cp1253", "greek", my_cs_exact},
{"cp1254", "latin5", my_cs_exact},
{"cp1255", "hebrew", my_cs_approx},
{"cp1256", "cp1256", my_cs_exact},
{"cp1257", "cp1257", my_cs_exact},
{"cp10000", "macroman", my_cs_exact},
{"cp10001", "sjis", my_cs_approx},
{"cp10002", "big5", my_cs_approx},
{"cp10008", "gb2312", my_cs_approx},
{"cp10021", "tis620", my_cs_approx},
{"cp10029", "macce", my_cs_exact},
{"cp12001", "utf32", my_cs_unsupp},
{"cp20107", "swe7", my_cs_exact},
{"cp20127", "latin1", my_cs_approx},
{"cp20866", "koi8r", my_cs_exact},
{"cp20932", "ujis", my_cs_exact},
{"cp20936", "gb2312", my_cs_approx},
{"cp20949", "euckr", my_cs_approx},
{"cp21866", "koi8u", my_cs_exact},
{"cp28591", "latin1", my_cs_approx},
{"cp28592", "latin2", my_cs_exact},
{"cp28597", "greek", my_cs_exact},
{"cp28598", "hebrew", my_cs_exact},
{"cp28599", "latin5", my_cs_exact},
{"cp28603", "latin7", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
{"cp28605", "latin9", my_cs_exact},
#endif
{"cp38598", "hebrew", my_cs_exact},
{"cp51932", "ujis", my_cs_exact},
{"cp51936", "gb2312", my_cs_exact},
{"cp51949", "euckr", my_cs_exact},
{"cp51950", "big5", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
{"cp54936", "gb18030", my_cs_exact},
#endif
{"cp65001", "utf8", my_cs_exact},
#else /* not Windows */
{"646", "latin1", my_cs_approx}, /* Default on Solaris */
{"ANSI_X3.4-1968", "latin1", my_cs_approx},
{"ansi1251", "cp1251", my_cs_exact},
{"armscii8", "armscii8", my_cs_exact},
{"armscii-8", "armscii8", my_cs_exact},
{"ASCII", "latin1", my_cs_approx},
{"Big5", "big5", my_cs_exact},
{"cp1251", "cp1251", my_cs_exact},
{"cp1255", "hebrew", my_cs_approx},
{"CP866", "cp866", my_cs_exact},
{"eucCN", "gb2312", my_cs_exact},
{"euc-CN", "gb2312", my_cs_exact},
{"eucJP", "ujis", my_cs_exact},
{"euc-JP", "ujis", my_cs_exact},
{"eucKR", "euckr", my_cs_exact},
{"euc-KR", "euckr", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
{"gb18030", "gb18030", my_cs_exact},
#endif
{"gb2312", "gb2312", my_cs_exact},
{"gbk", "gbk", my_cs_exact},
{"georgianps", "geostd8", my_cs_exact},
{"georgian-ps", "geostd8", my_cs_exact},
{"IBM-1252", "cp1252", my_cs_exact},
{"iso88591", "latin1", my_cs_approx},
{"ISO_8859-1", "latin1", my_cs_approx},
{"ISO8859-1", "latin1", my_cs_approx},
{"ISO-8859-1", "latin1", my_cs_approx},
{"iso885913", "latin7", my_cs_exact},
{"ISO_8859-13", "latin7", my_cs_exact},
{"ISO8859-13", "latin7", my_cs_exact},
{"ISO-8859-13", "latin7", my_cs_exact},
#ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
{"iso885915", "latin9", my_cs_exact},
{"ISO_8859-15", "latin9", my_cs_exact},
{"ISO8859-15", "latin9", my_cs_exact},
{"ISO-8859-15", "latin9", my_cs_exact},
#endif
{"iso88592", "latin2", my_cs_exact},
{"ISO_8859-2", "latin2", my_cs_exact},
{"ISO8859-2", "latin2", my_cs_exact},
{"ISO-8859-2", "latin2", my_cs_exact},
{"iso88597", "greek", my_cs_exact},
{"ISO_8859-7", "greek", my_cs_exact},
{"ISO8859-7", "greek", my_cs_exact},
{"ISO-8859-7", "greek", my_cs_exact},
{"iso88598", "hebrew", my_cs_exact},
{"ISO_8859-8", "hebrew", my_cs_exact},
{"ISO8859-8", "hebrew", my_cs_exact},
{"ISO-8859-8", "hebrew", my_cs_exact},
{"iso88599", "latin5", my_cs_exact},
{"ISO_8859-9", "latin5", my_cs_exact},
{"ISO8859-9", "latin5", my_cs_exact},
{"ISO-8859-9", "latin5", my_cs_exact},
{"koi8r", "koi8r", my_cs_exact},
{"KOI8-R", "koi8r", my_cs_exact},
{"koi8u", "koi8u", my_cs_exact},
{"KOI8-U", "koi8u", my_cs_exact},
{"roman8", "hp8", my_cs_exact}, /* Default on HP UX */
{"Shift_JIS", "sjis", my_cs_exact},
{"SJIS", "sjis", my_cs_exact},
{"shiftjisx0213", "sjis", my_cs_exact},
{"tis620", "tis620", my_cs_exact},
{"tis-620", "tis620", my_cs_exact},
{"ujis", "ujis", my_cs_exact},
{"US-ASCII", "latin1", my_cs_approx},
{"utf8", "utf8", my_cs_exact},
{"utf-8", "utf8", my_cs_exact},
#endif
{NULL, NULL, 0}
};
static const char *
my_os_charset_to_mysql_charset(const char *csname)
{
const MY_CSET_OS_NAME *csp;
for (csp= charsets; csp->os_name; csp++)
{
if (!my_strcasecmp(&my_charset_latin1, csp->os_name, csname))
{
switch (csp->param)
{
case my_cs_exact:
return csp->my_name;
case my_cs_approx:
/*
Maybe we should print a warning eventually:
character set correspondence is not exact.
*/
return csp->my_name;
default:
my_printf_error(ER_UNKNOWN_ERROR,
"OS character set '%s'"
" is not supported by MySQL client",
MYF(0), csp->my_name);
goto def;
}
}
}
my_printf_error(ER_UNKNOWN_ERROR,
"Unknown OS character set '%s'.",
MYF(0), csname);
def:
csname= MYSQL_DEFAULT_CHARSET_NAME;
my_printf_error(ER_UNKNOWN_ERROR,
"Switching to the default character set '%s'.",
MYF(0), csname);
return csname;
}
#ifndef __WIN__
#include <stdlib.h> /* for getenv() */
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#endif /* __WIN__ */
#include <my_sys.h>
static int
mysql_autodetect_character_set(MYSQL *mysql)
{
const char *csname= MYSQL_DEFAULT_CHARSET_NAME;
#ifdef __WIN__
char cpbuf[64];
{
UINT cp= GetConsoleCP();
if (cp == 0)
cp= GetACP();
my_snprintf(cpbuf, sizeof(cpbuf), "cp%d", (int)cp);
csname= my_os_charset_to_mysql_charset(cpbuf);
}
#elif defined(HAVE_SETLOCALE) && defined(HAVE_NL_LANGINFO)
{
if (setlocale(LC_CTYPE, "") && (csname= nl_langinfo(CODESET)))
csname= my_os_charset_to_mysql_charset(csname);
}
#endif
if (mysql->options.charset_name)
my_free(mysql->options.charset_name);
if (!(mysql->options.charset_name= my_strdup(csname, MYF(MY_WME))))
if (!(mysql->options.charset_name= my_strdup(my_default_csname(),MYF(MY_WME))))
return 1;
return 0;
}
@ -2204,16 +1967,13 @@ C_MODE_START
int mysql_init_character_set(MYSQL *mysql)
{
/* Set character set */
if (!mysql->options.charset_name)
if (!mysql->options.charset_name ||
!strcmp(mysql->options.charset_name,
MYSQL_AUTODETECT_CHARSET_NAME))
{
if (!(mysql->options.charset_name=
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
if (mysql_autodetect_character_set(mysql))
return 1;
}
else if (!strcmp(mysql->options.charset_name,
MYSQL_AUTODETECT_CHARSET_NAME) &&
mysql_autodetect_character_set(mysql))
return 1;
mysql_set_character_set_with_default_collation(mysql);

View file

@ -195,8 +195,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info->table=table;
info->addon_field= addon_field;
if ((table->s->tmp_table == INTERNAL_TMP_TABLE ||
table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) &&
if ((table->s->tmp_table == INTERNAL_TMP_TABLE) &&
!addon_field)
(void) table->file->extra(HA_EXTRA_MMAP);

View file

@ -700,19 +700,23 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
MDL_SHARED_NO_READ_WRITE lock (MDL_SHARED_WRITE cannot be upgraded)
by *not* having HA_CONCURRENT_OPTIMIZE table_flag.
*/
if (lock_type == TL_WRITE && !table->table->s->tmp_table &&
table->mdl_request.type > MDL_SHARED_WRITE)
if (lock_type == TL_WRITE && table->mdl_request.type > MDL_SHARED_WRITE)
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
query_cache_invalidate3(thd, table->table, 0);
/*
XXX: hack: switch off open_for_modify to skip the
flush that is made later in the execution flow.
*/
open_for_modify= 0;
if (table->table->s->tmp_table)
thd->close_unused_temporary_table_instances(tables);
else
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
query_cache_invalidate3(thd, table->table, 0);
/*
XXX: hack: switch off open_for_modify to skip the
flush that is made later in the execution flow.
*/
open_for_modify= 0;
}
}
if (table->table->s->crashed && operator_func == &handler::ha_check)

View file

@ -1786,12 +1786,15 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
}
if (table->vfield)
{
my_bool abort_on_warning= thd->abort_on_warning;
/*
We have not yet called update_virtual_fields(VOL_UPDATE_FOR_READ)
in handler methods for the just read row in record[1].
*/
table->move_fields(table->field, table->record[1], table->record[0]);
thd->abort_on_warning= 0;
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE);
thd->abort_on_warning= abort_on_warning;
table->move_fields(table->field, table->record[0], table->record[1]);
}
if (info->handle_duplicates == DUP_UPDATE)

View file

@ -791,8 +791,6 @@ void init_update_queries(void)
Note that SQLCOM_RENAME_TABLE should not be in this list!
*/
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DROP_SEQUENCE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_TRUNCATE]|= CF_PREOPEN_TMP_TABLES;
@ -4743,7 +4741,14 @@ mysql_execute_command(THD *thd)
case SQLCOM_DROP_SEQUENCE:
case SQLCOM_DROP_TABLE:
{
int result;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
thd->open_options|= HA_OPEN_FOR_REPAIR;
result= thd->open_temporary_tables(all_tables);
thd->open_options&= ~HA_OPEN_FOR_REPAIR;
if (result)
goto error;
if (!lex->tmp_table())
{
if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))

View file

@ -9845,6 +9845,8 @@ do_continue:;
DEBUG_SYNC(thd, "alter_table_copy_after_lock_upgrade");
}
else
thd->close_unused_temporary_table_instances(table_list);
// It's now safe to take the table level lock.
if (lock_tables(thd, table_list, alter_ctx.tables_opened,

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2016 MariaDB Corporation
Copyright (c) 2016, 2019, 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
@ -395,6 +395,9 @@ bool THD::open_temporary_table(TABLE_LIST *tl)
rgi_slave->is_parallel_exec &&
wait_for_prior_commit())
DBUG_RETURN(true);
if (!table && is_error())
DBUG_RETURN(true); // Error when opening table
}
if (!table)

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
Copyright (c) 2018, 2019, 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
@ -358,6 +358,24 @@ public:
return(true);
}
/**
Iterate over all the blocks in reverse and call the iterator
@return false if iteration was terminated. */
template <typename Functor>
bool for_each_block_in_reverse(const Functor& functor) const
{
for (block_t* block = UT_LIST_GET_LAST(m_list);
block != NULL;
block = UT_LIST_GET_PREV(m_node, block)) {
if (!functor(block)) {
return(false);
}
}
return(true);
}
/**
@return the first block */
block_t* front()

View file

@ -525,7 +525,7 @@ struct mtr_t {
/** Check if this mini-transaction is dirtying a clean page.
@param block block being x-fixed
@return true if the mtr is dirtying a clean page. */
static bool is_block_dirtied(const buf_block_t* block)
static inline bool is_block_dirtied(const buf_block_t* block)
MY_ATTRIBUTE((warn_unused_result));
private:

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
Copyright (c) 2017, 2019, 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
@ -26,6 +26,20 @@ Created 11/26/1995 Heikki Tuuri
#include "buf0buf.h"
/** Check if a mini-transaction is dirtying a clean page.
@return true if the mtr is dirtying a clean page. */
bool
mtr_t::is_block_dirtied(const buf_block_t* block)
{
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->page.buf_fix_count > 0);
/* It is OK to read oldest_modification because no
other thread can be performing a write of it and it
is only during write that the value is reset to 0. */
return(block->page.oldest_modification == 0);
}
/**
Pushes an object to an mtr memo stack. */
void

View file

@ -38,7 +38,9 @@ enum mtr_log_t {
/** Default mode: log all operations modifying disk-based data */
MTR_LOG_ALL = 21,
/** Log no operations and dirty pages are not added to the flush list */
/** Log no operations and dirty pages are not added to the flush list.
Set when applying log in crash recovery or when a modification of a
ROW_FORMAT=COMPRESSED page is attempted. */
MTR_LOG_NONE = 22,
/** Don't generate REDO log but add dirty pages to flush list */

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2019, 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
@ -37,16 +37,43 @@ Created 11/26/1995 Heikki Tuuri
/** Iterate over a memo block in reverse. */
template <typename Functor>
struct Iterate {
struct CIterate {
CIterate() : functor() {}
/** Release specific object */
explicit Iterate(Functor& functor)
:
m_functor(functor)
CIterate(const Functor& functor) : functor(functor) {}
/** @return false if the functor returns false. */
bool operator()(mtr_buf_t::block_t* block) const
{
/* Do nothing */
const mtr_memo_slot_t* start =
reinterpret_cast<const mtr_memo_slot_t*>(
block->begin());
mtr_memo_slot_t* slot =
reinterpret_cast<mtr_memo_slot_t*>(
block->end());
ut_ad(!(block->used() % sizeof(*slot)));
while (slot-- != start) {
if (!functor(slot)) {
return(false);
}
}
return(true);
}
Functor functor;
};
template <typename Functor>
struct Iterate {
Iterate() : functor() {}
Iterate(const Functor& functor) : functor(functor) {}
/** @return false if the functor returns false. */
bool operator()(mtr_buf_t::block_t* block)
{
@ -62,7 +89,7 @@ struct Iterate {
while (slot-- != start) {
if (!m_functor(slot)) {
if (!functor(slot)) {
return(false);
}
}
@ -70,7 +97,7 @@ struct Iterate {
return(true);
}
Functor& m_functor;
Functor functor;
};
/** Find specific object */
@ -430,20 +457,6 @@ private:
lsn_t m_end_lsn;
};
/** Check if a mini-transaction is dirtying a clean page.
@return true if the mtr is dirtying a clean page. */
bool
mtr_t::is_block_dirtied(const buf_block_t* block)
{
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->page.buf_fix_count > 0);
/* It is OK to read oldest_modification because no
other thread can be performing a write of it and it
is only during write that the value is reset to 0. */
return(block->page.oldest_modification == 0);
}
/** Write the block contents to the REDO log */
struct mtr_write_log_t {
/** Append a block to the redo log buffer.
@ -509,12 +522,7 @@ mtr_t::Command::release_resources()
/* Currently only used in commit */
ut_ad(m_impl->m_state == MTR_STATE_COMMITTING);
#ifdef UNIV_DEBUG
DebugCheck release;
Iterate<DebugCheck> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
#endif /* UNIV_DEBUG */
ut_d(m_impl->m_memo.for_each_block_in_reverse(CIterate<DebugCheck>()));
/* Reset the mtr buffers */
m_impl->m_log.erase();
@ -702,11 +710,10 @@ mtr_t::memo_release(const void* object, ulint type)
middle of a mini-transaction. */
ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX);
Find find(object, type);
Iterate<Find> iterator(find);
Iterate<Find> iteration(Find(object, type));
if (!m_impl.m_memo.for_each_block_in_reverse(iterator)) {
memo_slot_release(find.m_slot);
if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) {
memo_slot_release(iteration.functor.m_slot);
return(true);
}
@ -726,11 +733,10 @@ mtr_t::release_page(const void* ptr, mtr_memo_type_t type)
middle of a mini-transaction. */
ut_ad(!m_impl.m_modifications || type != MTR_MEMO_PAGE_X_FIX);
FindPage find(ptr, type);
Iterate<FindPage> iterator(find);
Iterate<FindPage> iteration(FindPage(ptr, type));
if (!m_impl.m_memo.for_each_block_in_reverse(iterator)) {
memo_slot_release(find.get_slot());
if (!m_impl.m_memo.for_each_block_in_reverse(iteration)) {
memo_slot_release(iteration.functor.get_slot());
return;
}
@ -854,10 +860,7 @@ mtr_t::Command::finish_write(
void
mtr_t::Command::release_all()
{
ReleaseAll release;
Iterate<ReleaseAll> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>());
/* Note that we have released the latches. */
m_locks_released = 1;
@ -867,10 +870,7 @@ mtr_t::Command::release_all()
void
mtr_t::Command::release_latches()
{
ReleaseLatches release;
Iterate<ReleaseLatches> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>());
/* Note that we have released the latches. */
m_locks_released = 1;
@ -880,10 +880,10 @@ mtr_t::Command::release_latches()
void
mtr_t::Command::release_blocks()
{
ReleaseBlocks release(m_start_lsn, m_end_lsn, m_impl->m_flush_observer);
Iterate<ReleaseBlocks> iterator(release);
m_impl->m_memo.for_each_block_in_reverse(iterator);
m_impl->m_memo.for_each_block_in_reverse(
CIterate<const ReleaseBlocks>(
ReleaseBlocks(m_start_lsn, m_end_lsn,
m_impl->m_flush_observer)));
}
/** Write the redo log record, add dirty pages to the flush list and release
@ -928,10 +928,8 @@ mtr_t::memo_contains(
const void* object,
ulint type)
{
Find find(object, type);
Iterate<Find> iterator(find);
if (memo->for_each_block_in_reverse(iterator)) {
Iterate<Find> iteration(Find(object, type));
if (memo->for_each_block_in_reverse(iteration)) {
return(false);
}
@ -1020,10 +1018,8 @@ mtr_t::memo_contains_flagged(const void* ptr, ulint flags) const
ut_ad(m_impl.m_magic_n == MTR_MAGIC_N);
ut_ad(is_committing() || is_active());
FlaggedCheck check(ptr, flags);
Iterate<FlaggedCheck> iterator(check);
return(!m_impl.m_memo.for_each_block_in_reverse(iterator));
return !m_impl.m_memo.for_each_block_in_reverse(
CIterate<FlaggedCheck>(FlaggedCheck(ptr, flags)));
}
/** Check if memo contains the given page.
@ -1037,11 +1033,9 @@ mtr_t::memo_contains_page_flagged(
const byte* ptr,
ulint flags) const
{
FindPage check(ptr, flags);
Iterate<FindPage> iterator(check);
return(m_impl.m_memo.for_each_block_in_reverse(iterator)
? NULL : check.get_block());
Iterate<FindPage> iteration(FindPage(ptr, flags));
return m_impl.m_memo.for_each_block_in_reverse(iteration)
? NULL : iteration.functor.get_block();
}
/** Mark the given latched page as modified.

View file

@ -1217,6 +1217,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
if (!file || !param) return HA_ADMIN_INTERNAL_ERROR;
unmap_file(file);
maria_chk_init(param);
param->thd= thd;
param->op_name= "check";
@ -1437,6 +1438,7 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
if (!file || !param)
return HA_ADMIN_INTERNAL_ERROR;
unmap_file(file);
old_trn= file->trn;
maria_chk_init(param);
param->thd= thd;
@ -1535,6 +1537,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
param->out_flag= 0;
share->state.dupp_key= MI_MAX_KEY;
strmov(fixed_name, share->open_file_name.str);
unmap_file(file);
/*
Don't lock tables if we have used LOCK TABLE or if we come from
@ -1714,7 +1717,6 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt)
TABLE_LIST *table_list= table->pos_in_table_list;
DBUG_ENTER("ha_maria::assign_to_keycache");
table->keys_in_use_for_query.clear_all();
if (table_list->process_index_hints(table))
@ -2669,7 +2671,8 @@ int ha_maria::external_lock(THD *thd, int lock_type)
}
else
{
TRN *trn= (file->trn != &dummy_transaction_object ? file->trn : 0);
/* We have to test for THD_TRN to protect against implicit commits */
TRN *trn= (file->trn != &dummy_transaction_object && THD_TRN ? file->trn : 0);
/* End of transaction */
/*

View file

@ -5244,6 +5244,8 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_scan_init_block_record");
DBUG_ASSERT(info->dfile.file == share->bitmap.file.file);
/*
bitmap_buff may already be allocated if this is the second call to
rnd_init() without a rnd_end() in between, see sql/handler.h

View file

@ -113,10 +113,7 @@ int maria_close(register MARIA_HA *info)
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
share->deleting ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))
error= my_errno;
#ifdef HAVE_MMAP
if (share->file_map)
_ma_unmap_file(info);
#endif
unmap_file(info);
if (((share->changed && share->base.born_transactional) ||
maria_is_crashed(info) || (share->temporary && !share->deleting)))
{

View file

@ -38,6 +38,9 @@ int maria_delete_all_rows(MARIA_HA *info)
MARIA_SHARE *share= info->s;
my_bool log_record;
LSN lsn;
#ifdef HAVE_MMAP
my_bool mmap_file= share->file_map != 0;
#endif
DBUG_ENTER("maria_delete_all_rows");
if (share->options & HA_OPTION_READ_ONLY_DATA)
@ -95,7 +98,7 @@ int maria_delete_all_rows(MARIA_HA *info)
*/
#ifdef HAVE_MMAP
if (share->file_map)
if (mmap_file)
_ma_unmap_file(info);
#endif
@ -141,7 +144,7 @@ int maria_delete_all_rows(MARIA_HA *info)
_ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
#ifdef HAVE_MMAP
/* Map again */
if (share->file_map)
if (mmap_file)
_ma_dynmap_file(info, (my_off_t) 0);
#endif
DBUG_RETURN(0);

View file

@ -1564,8 +1564,13 @@ my_bool _ma_memmap_file(MARIA_HA *info)
void _ma_unmap_file(MARIA_HA *info)
{
my_munmap((char*) info->s->file_map,
(size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN);
MARIA_SHARE *share= info->s;
my_munmap((char*) share->file_map,
(size_t) share->mmaped_length + MEMMAP_EXTRA_MARGIN);
share->file_map= 0;
share->file_read= _ma_nommap_pread;
share->file_write= _ma_nommap_pwrite;
info->opt_flag&= ~MEMMAP_USED;
}

View file

@ -3464,8 +3464,6 @@ restart:
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
#endif
}
if (status & PCBLOCK_ERROR)
my_errno= block->error;
}
remove_reader(block);
@ -3497,6 +3495,7 @@ restart:
if (status & PCBLOCK_ERROR)
{
my_errno= block->error;
DBUG_ASSERT(my_errno != 0);
DBUG_PRINT("error", ("Got error %d when doing page read", my_errno));
DBUG_RETURN((uchar *) 0);

View file

@ -1432,3 +1432,11 @@ extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx);
extern my_bool ma_killed_standalone(MARIA_HA *);
extern uint _ma_file_callback_to_id(void *callback_data);
static inline void unmap_file(MARIA_HA *info __attribute__((unused)))
{
#ifdef HAVE_MMAP
if (info->s->file_map)
_ma_unmap_file(info);
#endif
}

View file

@ -11029,6 +11029,41 @@ void ha_rocksdb::read_thd_vars(THD *const thd) {
m_checksums_pct = THDVAR(thd, checksums_pct);
}
ulonglong ha_rocksdb::table_flags() const
{
DBUG_ENTER_FUNC();
/*
HA_BINLOG_STMT_CAPABLE
Upstream: MyRocks advertises itself as it supports SBR, but has additional
checks in ha_rocksdb::external_lock()/ start_stmt() which will return an
error if one tries to run the statement.
Exceptions: @@rocksdb_unsafe_for_binlog or we are an SQL slave thread.
MariaDB: Inform the upper layer we don't support SBR, so it switches to RBR
if possible. The exceptions are the same as with the upstream.
HA_REC_NOT_IN_SEQ
If we don't set it, filesort crashes, because it assumes rowids are
1..8 byte numbers
HA_PRIMARY_KEY_IN_READ_INDEX
This flag is always set, even for tables that:
- have no PK
- have some (or all) of PK that can't be decoded from the secondary
index.
*/
THD *thd= ha_thd();
DBUG_RETURN(HA_BINLOG_ROW_CAPABLE |
((thd && (THDVAR(thd, unsafe_for_binlog) ||thd->rgi_slave))?
HA_BINLOG_STMT_CAPABLE : 0) |
HA_REC_NOT_IN_SEQ | HA_CAN_INDEX_BLOBS |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_NULL_IN_KEY |
HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX);
}
/**
@return
@ -11041,6 +11076,9 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
DBUG_ASSERT(thd != nullptr);
int res = HA_EXIT_SUCCESS;
#if 0
// MariaDB uses a different way to implement this, see ha_rocksdb::table_flags
int binlog_format = my_core::thd_binlog_format(thd);
bool unsafe_for_binlog = THDVAR(ha_thd(), unsafe_for_binlog);
@ -11069,6 +11107,7 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
my_error(ER_REQUIRE_ROW_BINLOG_FORMAT, MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}
#endif
if (lock_type == F_UNLCK) {
Rdb_transaction *const tx = get_tx_from_thd(thd);
@ -11171,20 +11210,6 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
int ha_rocksdb::start_stmt(THD *const thd, thr_lock_type lock_type) {
DBUG_ENTER_FUNC();
/*
MariaDB: the following is a copy of the check in ha_rocksdb::external_lock:
*/
int binlog_format = my_core::thd_binlog_format(thd);
bool unsafe_for_binlog = THDVAR(ha_thd(), unsafe_for_binlog);
if (lock_type >= TL_WRITE_ALLOW_WRITE &&
!thd->rgi_slave && !unsafe_for_binlog &&
binlog_format != BINLOG_FORMAT_ROW &&
binlog_format != BINLOG_FORMAT_UNSPEC &&
my_core::thd_binlog_filter_ok(thd)) {
my_error(ER_REQUIRE_ROW_BINLOG_FORMAT, MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}
DBUG_ASSERT(thd != nullptr);
Rdb_transaction *const tx = get_or_create_tx(thd);

View file

@ -863,31 +863,7 @@ public:
This is a list of flags that indicate what functionality the storage engine
implements. The current table flags are documented in handler.h
*/
ulonglong table_flags() const override {
DBUG_ENTER_FUNC();
/*
HA_BINLOG_STMT_CAPABLE
We are saying that this engine is just statement capable to have
an engine that can only handle statement-based logging. This is
used in testing.
HA_REC_NOT_IN_SEQ
If we don't set it, filesort crashes, because it assumes rowids are
1..8 byte numbers
HA_PRIMARY_KEY_IN_READ_INDEX
This flag is always set, even for tables that:
- have no PK
- have some (or all) of PK that can't be decoded from the secondary
index.
*/
DBUG_RETURN(HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_REC_NOT_IN_SEQ | HA_CAN_INDEX_BLOBS |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_NULL_IN_KEY |
HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX);
}
ulonglong table_flags() const override ;
private:
bool init_with_fields(); /* no 'override' in MariaDB */
public:

View file

@ -18,7 +18,16 @@ set @tmp_bf= @@binlog_format;
set binlog_format='STATEMENT';
lock tables t1 write;
insert into t1 values(1);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
unlock tables;
set @@binlog_format=@tmp_bf;
drop table t1;
#
# MDEV-17045: MyRocks tables cannot be updated when binlog_format=MIXED.
#
set @tmp_bf= @@binlog_format;
set binlog_format='MIXED';
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1);
drop table t1;
set @@binlog_format=@tmp_bf;

View file

@ -8,7 +8,7 @@ select @@binlog_format;
STATEMENT
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1),(2),(3);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
set session rocksdb_unsafe_for_binlog=on;
insert into t1 values (1),(2),(3);
select * from t1;
@ -19,7 +19,7 @@ pk
delete from t1;
set session rocksdb_unsafe_for_binlog=off;
insert into t1 values (1),(2),(3);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
set binlog_format=row;
insert into t1 values (1),(2),(3);
include/sync_slave_sql_with_master.inc

View file

@ -21,10 +21,20 @@ unlock tables;
set @tmp_bf= @@binlog_format;
set binlog_format='STATEMENT';
lock tables t1 write;
--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values(1);
unlock tables;
set @@binlog_format=@tmp_bf;
drop table t1;
--echo #
--echo # MDEV-17045: MyRocks tables cannot be updated when binlog_format=MIXED.
--echo #
set @tmp_bf= @@binlog_format;
set binlog_format='MIXED';
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1);
drop table t1;
set @@binlog_format=@tmp_bf;

View file

@ -12,7 +12,7 @@ connection master;
select @@binlog_format;
create table t1 (pk int primary key) engine=rocksdb;
--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values (1),(2),(3);
set session rocksdb_unsafe_for_binlog=on;
@ -21,7 +21,7 @@ select * from t1;
delete from t1;
set session rocksdb_unsafe_for_binlog=off;
--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values (1),(2),(3);
set binlog_format=row;