1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

Merge 11.4 into 11.8

This commit is contained in:
Marko Mäkelä
2026-10-16 09:25:49 +03:00
315 changed files with 9338 additions and 2635 deletions

View File

@@ -808,6 +808,16 @@ struct Expression_value
void set_int(long long value)
{
type= EXPR_INT;
is_numeric= true;
is_unsigned= false;
int_val= (unsigned long long) value;
}
/* Preserve the bit pattern after a defined unsigned operation. */
void set_int_from_uint(unsigned long long value)
{
type= EXPR_INT;
is_numeric= true;
@@ -1000,6 +1010,17 @@ struct Expression_value
};
static void check_mixed_unsigned_arithmetic(const Expression_value &left,
const Expression_value &right,
const char *op)
{
if ((left.is_unsigned || right.is_unsigned) &&
((!left.is_unsigned && left.to_int() < 0) ||
(!right.is_unsigned && right.to_int() < 0)))
die("Evaluation error: Signed integer overflow in operator '%s'", op);
}
/* Core expression parsing functions */
static void expr(Expression_value *result, const char **s);
static void logical_or(Expression_value *result, const char **s);
@@ -5711,7 +5732,15 @@ static void unary(Expression_value *result, const char **s)
unary(result, s);
if (!result->is_numeric)
die("Type error: unary minus requires an integer operand");
result->set_int(-result->to_int());
if (result->is_unsigned)
result->set_int_from_uint(0ULL - result->to_uint());
else
{
long long value= result->to_int();
if (value == LLONG_MIN)
die("Evaluation error: Signed integer overflow in unary '-'");
result->set_int(-value);
}
return;
}
if (match(s, "~"))
@@ -5760,10 +5789,26 @@ static void factor(Expression_value *result, const char **s)
bitwise_xor(&rhs, s);
if (!result->is_numeric || !rhs.is_numeric)
die("Type error: operator '*' requires integer operands");
check_mixed_unsigned_arithmetic(*result, rhs, "*");
if (result->is_unsigned || rhs.is_unsigned)
result->set_uint(result->to_uint() * rhs.to_uint());
{
unsigned long long left= result->to_uint();
unsigned long long right= rhs.to_uint();
if (right != 0 && left > ULLONG_MAX / right)
die("Evaluation error: Unsigned integer overflow in operator '*'");
result->set_uint(left * right);
}
else
result->set_int(result->to_int() * rhs.to_int());
{
long long left= result->to_int();
long long right= rhs.to_int();
if ((left > 0 && right > 0 && left > LLONG_MAX / right) ||
(left > 0 && right < 0 && right < LLONG_MIN / left) ||
(left < 0 && right > 0 && left < LLONG_MIN / right) ||
(left < 0 && right < 0 && left < LLONG_MAX / right))
die("Evaluation error: Signed integer overflow in operator '*'");
result->set_int(left * right);
}
}
else if (match(s, "/"))
{
@@ -5773,17 +5818,17 @@ static void factor(Expression_value *result, const char **s)
die("Type error: operator '/' requires integer operands");
if (rhs.to_int() == 0)
die("Evaluation error: Division by zero");
check_mixed_unsigned_arithmetic(*result, rhs, "/");
if (result->is_unsigned || rhs.is_unsigned)
result->set_uint(result->to_uint() / rhs.to_uint());
else
{
long long nominator= result->to_int();
long long denominator= rhs.to_int();
// Prevent fatal integer overflow from LLONG_MIN / -1, which causes a crash
// Prevent signed overflow from LLONG_MIN / -1.
if (nominator == LLONG_MIN && denominator == -1)
result->set_int(nominator);
else
result->set_int(nominator / denominator);
die("Evaluation error: Signed integer overflow in operator '/'");
result->set_int(nominator / denominator);
}
}
else if (match(s, "%"))
@@ -5794,13 +5839,14 @@ static void factor(Expression_value *result, const char **s)
die("Type error: operator '%%' requires integer operands");
if (rhs.to_int() == 0)
die("Evaluation error: Modulo by zero");
check_mixed_unsigned_arithmetic(*result, rhs, "%");
if (result->is_unsigned || rhs.is_unsigned)
result->set_uint(result->to_uint() % rhs.to_uint());
else
{
long long nominator= result->to_int();
long long denominator= rhs.to_int();
// Prevent fatal integer overflow from LLONG_MIN % -1, which causes a crash
// LLONG_MIN % -1 is zero, but the CPU division can still trap.
if (nominator == LLONG_MIN && denominator == -1)
result->set_int(0);
else
@@ -5826,10 +5872,24 @@ static void term(Expression_value *result, const char **s)
factor(&rhs, s);
if (!result->is_numeric || !rhs.is_numeric)
die("Type error: operator '+' requires integer operands");
check_mixed_unsigned_arithmetic(*result, rhs, "+");
if (result->is_unsigned || rhs.is_unsigned)
result->set_uint(result->to_uint() + rhs.to_uint());
{
unsigned long long left= result->to_uint();
unsigned long long right= rhs.to_uint();
if (left > ULLONG_MAX - right)
die("Evaluation error: Unsigned integer overflow in operator '+'");
result->set_uint(left + right);
}
else
result->set_int(result->to_int() + rhs.to_int());
{
long long left= result->to_int();
long long right= rhs.to_int();
if ((right > 0 && left > LLONG_MAX - right) ||
(right < 0 && left < LLONG_MIN - right))
die("Evaluation error: Signed integer overflow in operator '+'");
result->set_int(left + right);
}
}
else if (match(s, "-"))
{
@@ -5837,10 +5897,27 @@ static void term(Expression_value *result, const char **s)
factor(&rhs, s);
if (!result->is_numeric || !rhs.is_numeric)
die("Type error: operator '-' requires integer operands");
check_mixed_unsigned_arithmetic(*result, rhs, "-");
if (result->is_unsigned || rhs.is_unsigned)
result->set_uint(result->to_uint() - rhs.to_uint());
{
unsigned long long left= result->to_uint();
unsigned long long right= rhs.to_uint();
if (left >= right)
result->set_uint(left - right);
else if (right - left <= (unsigned long long) LLONG_MAX + 1)
result->set_int_from_uint(left - right); /* negative result */
else
die("Evaluation error: Integer overflow in operator '-'");
}
else
result->set_int(result->to_int() - rhs.to_int());
{
long long left= result->to_int();
long long right= rhs.to_int();
if ((right > 0 && left < LLONG_MIN + right) ||
(right < 0 && left > LLONG_MAX + right))
die("Evaluation error: Signed integer overflow in operator '-'");
result->set_int(left - right);
}
}
else
break;
@@ -6306,7 +6383,19 @@ void func_abs(Expression_value args[], int count, Expression_value *result)
if (!args[0].is_numeric)
die("abs() requires numeric argument");
result->set_int(llabs(args[0].to_int()));
if (args[0].is_unsigned)
{
if (args[0].to_uint() > (unsigned long long) LLONG_MAX)
die("Evaluation error: Signed integer overflow in abs()");
result->set_int((long long) args[0].to_uint());
}
else
{
long long value= args[0].to_int();
if (value == LLONG_MIN)
die("Evaluation error: Signed integer overflow in abs()");
result->set_int(value < 0 ? -value : value);
}
}
@@ -12747,7 +12836,7 @@ void init_re(void)
*/
const char *ps2_re_str =
"^("
"[[:space:]]*SELECT[[:space:]])";
"[[:space:]]*(\\([[:space:]]*)*SELECT[[:space:]])";
/*
Filter for queries that can be run as views

View File

@@ -1,5 +1,5 @@
# Used to check if running in Bash
bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/wsrep_notify:86]
bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/wsrep_notify:94]
bash-term-in-posix-shell '[ "$url" ==' [usr/bin/mariadbd-safe:216]
# In comment so false-positive
bash-term-in-posix-shell 'let' [usr/bin/mariadbd-safe:41]

View File

@@ -5,9 +5,6 @@ incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mar
incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_1/lib/DataGen_modify.pl]
incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_2/lib/gen_charset_utf8.pl]
incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/rpl/extension/checksum.pl]
# This is used to check if we are running under Bash
bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/mariadb-test/std_data/wsrep_notify.sh:87]
bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/mariadb-test/std_data/wsrep_notify_ssl.sh:87]
# These files are result files and they are supposed to be
# Natial encoded (ISO/IEC 8859-1) not UTF-8
national-encoding [usr/share/mysql/mariadb-test/include/ctype_E05C.inc]

View File

@@ -23,6 +23,8 @@ usr/lib/mysql/plugin/ha_example.so
usr/lib/mysql/plugin/ha_test_sql_discovery.so
usr/lib/mysql/plugin/libdaemon_example.so
usr/lib/mysql/plugin/mypluglib.so
usr/lib/mysql/plugin/plugin_name_ascii.so
usr/lib/mysql/plugin/plugin_name_non_ascii.so
usr/lib/mysql/plugin/qa_auth_interface.so
usr/lib/mysql/plugin/qa_auth_server.so
usr/lib/mysql/plugin/test_sql_service.so

View File

@@ -5614,13 +5614,14 @@ static bool xtrabackup_backup_func()
msg("cd to %s", mysql_real_data_home);
encryption_plugin_backup_init(mysql_connection);
if (innodb_log_checkpoint_now) {
msg("Initiating checkpoint");
if (mysql_send_query(mysql_connection,
C_STRING_WITH_LEN("SET GLOBAL "
"innodb_log_checkpoint_now=ON;"))) {
msg("initiating checkpoint failed");
return(false);
}
/* This had better finish before recv_sys.find_checkpoint()
starts executing below. The command may not be recognised
by an old server; we can ignore a failure to execute this
performance tweak. */
xb_mysql_query(
mysql_connection,
"SET GLOBAL innodb_log_checkpoint_now=ON;",
false, false);
}
msg("open files limit requested %lu, set to %lu",
@@ -5732,13 +5733,6 @@ fail:
goto fail;
}
/* try to wait for a log checkpoint, but do not fail if the
server does not support this */
if (innodb_log_checkpoint_now != false) {
mysql_read_query_result(mysql_connection);
msg("Finished waiting for checkpoint");
}
if (!select_history()) {
goto fail;
}

View File

@@ -573,7 +573,8 @@ enum ha_base_keytype {
#define HA_NAMELEN 64 /* Max length of saved filename */
#define NO_SUCH_KEY (~(uint)0) /* used as a key no. */
typedef ulong key_part_map;
typedef uint32 key_part_map;
#define MAX_REF_PARTS sizeof(key_part_map)*8 /* Max parts used as ref */
#define HA_WHOLE_KEY (~(key_part_map)0)
/* Intern constants in databases */

View File

@@ -95,8 +95,9 @@ C_MODE_START
#define MY_ROOT_USE_VMEM 0x20000U /* init_alloc_root: use my_virtual_mem_commit */
/* Tree that should delete things automatically */
#define MY_TREE_WITH_DELETE 0x40000U
#define MY_TRACK 0x80000U /* Track tmp usage */
#define MY_TRACK_WITH_LIMIT 0x100000U /* Give error if over tmp_file_usage */
#define MY_TRY_LARGE_PAGES 0x80000U /* try to allocate large pages */
#define MY_TRACK 0x100000U /* Track tmp usage */
#define MY_TRACK_WITH_LIMIT 0x200000U /* Give error if over tmp_file_usage */
#define MY_CHECK_ERROR 1U /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2U /* Give time info about process*/
@@ -179,14 +180,19 @@ extern void my_free(void *ptr);
extern void *my_memdup(PSI_memory_key key, const void *from,size_t length,myf MyFlags);
extern char *my_strdup(PSI_memory_key key, const char *from,myf MyFlags);
extern char *my_strndup(PSI_memory_key key, const char *from, size_t length, myf MyFlags);
extern my_bool my_use_large_pages;
/**
0, or MY_TRY_LARGE_PAGES to request large pages from my_large_malloc(),
my_large_virtual_alloc(), or the my_virtual_mem_*() functions. Set once
by my_init_large_pages(), does not change thereafter.
*/
extern myf my_large_pages_flag;
int my_init_large_pages(void);
uchar *my_large_malloc(size_t *size, myf my_flags);
#ifdef _WIN32
/* On Windows, use my_virtual_mem_reserve() and my_virtual_mem_commit(). */
#else
char *my_large_virtual_alloc(size_t *size);
char *my_large_virtual_alloc(size_t *size, myf my_flags);
#endif
void my_large_free(void *ptr, size_t size);
void my_large_page_truncate(size_t *size);

View File

@@ -19,6 +19,7 @@
(reserve, commit, decommit, release)
*/
#include <stddef.h> /*size_t*/
#include <my_global.h> /*myf*/
#ifdef __cplusplus
extern "C" {
@@ -26,9 +27,9 @@ extern "C" {
enum my_vmem_prot { MY_VMEM_READONLY= 0, MY_VMEM_READWRITE };
char *my_virtual_mem_reserve(size_t *size);
char *my_virtual_mem_commit(char *ptr, size_t size);
void my_virtual_mem_decommit(char *ptr, size_t size);
char *my_virtual_mem_reserve(size_t *size, myf my_flags);
char *my_virtual_mem_commit(char *ptr, size_t size, myf my_flags);
void my_virtual_mem_decommit(char *ptr, size_t size, myf my_flags);
void my_virtual_mem_release(char *ptr, size_t size);
void my_virtual_mem_protect(void *ptr, size_t size, enum my_vmem_prot prot);

View File

@@ -471,10 +471,19 @@ typedef struct st_net {
my_bool thread_specific_malloc;
unsigned char compress;
my_bool pkt_nr_can_be_reset;
/* Bits: NET_PROXY_PROTOCOL, NET_PROXY_PROTOCOL_CONNECT_ERRORS */
my_bool using_proxy_protocol;
/* Bits: NET_PROXY_PROTOCOL, NET_PROXY_PROTOCOL_CONNECT_ERRORS,
NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED, NET_PROXY_PROTOCOL_HOST_BLOCKED */
unsigned char using_proxy_protocol;
#define NET_PROXY_PROTOCOL 1
#define NET_PROXY_PROTOCOL_CONNECT_ERRORS 2
/*
A PROXY-header-derived peer address failed the "host privileged"/"host
blocked" check; rejection is deferred until the client's handshake
response is parsed, after SSL if requested, instead of being sent in
clear text right away.
*/
#define NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED 4
#define NET_PROXY_PROTOCOL_HOST_BLOCKED 8
/*
Pointer to query object in query cache, do not equal NULL (0) for
queries in cache that have not stored its results yet

View File

@@ -1,5 +1,34 @@
# Kill the server the current connection is on, and wait until its process
# is really gone.
#
# USAGE
#
# [--let $kill_signal = TERM] # defaults to KILL
# --source include/kill_galera.inc
#
# $kill_signal applies to this call only and is reset afterwards. Give the
# signal by name and never by number: signal numbers are not portable, and
# "kill -9" fails as an unknown signal on FreeBSD.
#
# On return the process no longer exists, so its pid file, ports and data
# directory are free: the node can be restarted, or its grastate.dat read,
# straight away. Waiting only for the connection to drop is not enough for
# that. The connection dies as soon as the server stops serving it, which for
# a signal that lets mysqld shut down gracefully is long before the process
# actually exits, and tests used to paper over the difference with a --sleep.
#
# What this does NOT wait for is the rest of the cluster noticing. A test that
# needs the surviving nodes to have processed the loss of this one has to wait
# for that itself, on a surviving node, e.g. for wsrep_cluster_size to drop or
# for wsrep_cluster_status to become non-Primary.
--echo Killing server ...
if (!$kill_signal)
{
--let $kill_signal = KILL
}
# Write file to make mysql-test-run.pl expect the crash, but don't start it
--let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')`
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect
@@ -7,14 +36,31 @@
# Kill the connected server
--disable_reconnect
--let KILL_SIGNAL_VALUE = $kill_signal
--let KILL_NODE_PIDFILE = `SELECT @@pid_file`
--perl
my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'};
my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
my $mysqld_pid = `cat $pid_filename`;
chomp($mysqld_pid);
system("kill -9 $mysqld_pid");
die "No pid found in $pid_filename\n"
unless $mysqld_pid =~ /^\d+$/;
system("kill -s $kill_sig $mysqld_pid");
# Wait for the process to be gone, and not merely for it to stop
# serving connections. my_safe_process is its parent and is sitting
# in waitpid() on it, so it is reaped as soon as it exits and kill(0)
# stops finding it.
my $waited = 0;
while (kill(0, $mysqld_pid)) {
die "Server pid $mysqld_pid did not exit\n" if $waited >= 60;
select(undef, undef, undef, 0.1);
$waited += 0.1;
}
exit(0);
EOF
--let $kill_signal =
--source include/wait_until_disconnected.inc

View File

@@ -1,34 +0,0 @@
#############################################
# checks if mysqlbinlog is debug compiled
# this "cannot" be done simply by using
# have_debug.inc
#############################################
--disable_query_log
--let $temp_out_help_file=$MYSQL_TMP_DIR/mysqlbinlog_help.tmp
--exec $MYSQL_BINLOG --help>$temp_out_help_file
let log_tmp=$temp_out_help_file;
--let $temp_inc=$MYSQL_TMP_DIR/temp.inc
let inc_tmp=$temp_inc;
--perl
use strict;
my $tmp_file= $ENV{'log_tmp'} or die "log_tmp not set";
open(FILE, "$tmp_file") or die("Unable to open $tmp_file: $!\n");
my $count = () = grep(/Output debug log/g,<FILE>);
close FILE;
my $temp_inc= $ENV{'inc_tmp'} or die "temp_inc not set";
open(FILE_INC,">", "$temp_inc") or die("can't open file \"$temp_inc\": $!");
print FILE_INC '--let $is_debug= '.$count;
close FILE_INC;
EOF
--source $temp_inc
if (!$is_debug)
{
--skip mysqlbinlog needs to be debug compiled
}
--remove_file $temp_out_help_file
--remove_file $temp_inc
--enable_query_log

View File

@@ -0,0 +1,6 @@
# Truncate the ddl log by cycling BACKUP STAGE END/START on con1, so a
# subsequent print_ddl_log.inc only shows entries logged after this point.
connection con1;
BACKUP STAGE END;
BACKUP STAGE START;
connection default;

View File

@@ -49,6 +49,13 @@ openssl req -newkey rsa:4096 -keyout client-key.pem -out demoCA/client-req.pem -
openssl rsa -in client-key.pem -out client-key.pem
openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out client-cert.pem -in demoCA/client-req.pem
# client cert with a single RDN whose value is the literal string "a/b+c"
# ('/' and '+' are separator characters some SSL libraries escape and
# some don't -- see https://github.com/wolfSSL/wolfssl/issues/11392)
openssl req -newkey rsa:4096 -keyout client-slash-cn-key.pem -out demoCA/client-slash-cn-req.pem -days 7300 -nodes -subj '/CN=a\/b\+c'
openssl rsa -in client-slash-cn-key.pem -out client-slash-cn-key.pem
openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out client-slash-cn-cert.pem -in demoCA/client-slash-cn-req.pem
# generate combined client cert and key file
cat client-cert.pem client-key.pem > client-certkey.pem
@@ -75,10 +82,12 @@ openssl genrsa -out gcadir/root.key 4096
openssl req -new -x509 '-sha256' -key gcadir/root.key -out galera-chain-ca.pem -days 7300 -subj "/O=MariaDB/OU=MariaDB/CN=Galera Chain Root CA" -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"
openssl genrsa -out gcadir/int.key 4096
openssl req -new '-sha256' -key gcadir/int.key -out gcadir/int.csr -subj "/O=MariaDB/OU=MariaDB/CN=Galera Chain Intermediate CA"
openssl x509 -req -in gcadir/int.csr -CA galera-chain-ca.pem -CAkey gcadir/root.key -CAcreateserial -days 7200 -sha256 -extfile <(printf "basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign") -out gcadir/int.crt
printf "basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign\n" > gcadir/int.ext
openssl x509 -req -in gcadir/int.csr -CA galera-chain-ca.pem -CAkey gcadir/root.key -CAcreateserial -days 7200 -sha256 -extfile gcadir/int.ext -out gcadir/int.crt
openssl genrsa -out galera-chain-key.pem 4096
openssl req -new '-sha256' -key galera-chain-key.pem -out gcadir/leaf.csr -subj "/CN=localhost"
openssl x509 -req -in gcadir/leaf.csr -CA gcadir/int.crt -CAkey gcadir/int.key -CAcreateserial -days 7100 -sha256 -extfile <(printf "basicConstraints=CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth,clientAuth\nsubjectAltName=DNS:localhost,IP:127.0.0.1") -out gcadir/leaf.crt
printf "basicConstraints=CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth,clientAuth\nsubjectAltName=DNS:localhost,IP:127.0.0.1\n" > gcadir/leaf.ext
openssl x509 -req -in gcadir/leaf.csr -CA gcadir/int.crt -CAkey gcadir/int.key -CAcreateserial -days 7100 -sha256 -extfile gcadir/leaf.ext -out gcadir/leaf.crt
cat gcadir/leaf.crt gcadir/int.crt > galera-chain-cert.pem
rm -rf gcadir

View File

@@ -23,7 +23,7 @@
# Tool used for executing a suite of .test file
#
# See the "MySQL Test framework manual" for more information
# https://mariadb.com/kb/en/library/mysqltest/
# https://mariadb.com/docs/server/clients-and-utilities/testing-tools/mariadb-test
#
# Please keep the test framework tools identical in all versions!
#

View File

@@ -234,9 +234,27 @@ ALTER,DATABASE,0,mysqltest,,,,0,,,
DROP,MyISAM,0,mysqltest,t90,id: 27,,0,,,
DROP,InnoDB,0,mysqltest,t91,id: 28,,0,,,
DROP,DATABASE,0,mysqltest,,,,0,,,
connection con1;
BACKUP STAGE END;
BACKUP STAGE START;
connection default;
#
# MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer
#
CREATE TABLE t1 (id INT) ENGINE=MyISAM;
RENAME TABLE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`#mysql50#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%` TO `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.t2;
DROP DATABASE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
#
# Reading backup ddl log file
#
CREATE,MyISAM,0,test,t1,id: 1,,0,,,
RENAME,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,#sql1,id: 1,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,t2,id: 1
DROP,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,t2,id: 1,,0,,,
DROP,DATABASE,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,,
#
# Cleanup
#
DROP TABLE t_exists;
DROP TABLE t_exists_template;
disconnect con1;
# End of 10.11 tests

View File

@@ -31,9 +31,31 @@ CREATE TABLE IF NOT EXISTS t_exists LIKE t_exists_template;
--source include/print_ddl_log.inc
--source include/truncate_ddl_log.inc
--echo #
--echo # MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer
--echo #
# A #mysql50# name is stored on disk as is, but is filename-encoded
# (up to 5 bytes per character) in the ddl log, so the record gets long
# without hitting MAX_PATH on Windows. Such names can't be created with
# SQL, so create the 5.0-style files directly.
let $MYSQLD_DATADIR= `select @@datadir`;
--mkdir $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
CREATE TABLE t1 (id INT) ENGINE=MyISAM;
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.frm
--move_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.MYI
--move_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.MYD
RENAME TABLE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`#mysql50#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%` TO `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.t2;
DROP DATABASE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
--source include/print_ddl_log.inc
--echo #
--echo # Cleanup
--echo #
DROP TABLE t_exists;
DROP TABLE t_exists_template;
disconnect con1;
--echo # End of 10.11 tests

View File

@@ -0,0 +1,24 @@
connect con1,localhost,root,,;
BACKUP STAGE START;
connection default;
#
# MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer
#
CREATE DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
CREATE TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` (id INT) ENGINE=MyISAM;
RENAME TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` TO `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`;
DROP TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`;
DROP DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
#
# Reading backup ddl log file
#
CREATE,DATABASE,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,,
CREATE,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040,id: 1,,0,,,
RENAME,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040,id: 1,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025,id: 1
DROP,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025,id: 1,,0,,,
DROP,DATABASE,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,,
connection con1;
BACKUP STAGE END;
disconnect con1;
connection default;
# End of 10.11 tests

View File

@@ -0,0 +1,27 @@
# Logging of ddl's with long special-character identifiers under backup
# stages. Not on Windows: the file paths of these identifiers exceed MAX_PATH.
--source include/not_embedded.inc
--source include/not_windows.inc
connect (con1,localhost,root,,);
BACKUP STAGE START;
connection default;
--echo #
--echo # MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer
--echo #
CREATE DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
CREATE TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` (id INT) ENGINE=MyISAM;
RENAME TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` TO `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`;
DROP TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`;
DROP DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`;
--source include/print_ddl_log.inc
connection con1;
BACKUP STAGE END;
disconnect con1;
connection default;
--echo # End of 10.11 tests

View File

@@ -1,3 +1,4 @@
call mtr.add_suppression("Host 'localhost' is not allowed to connect to this MariaDB server");
#
# MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty
#

View File

@@ -1,5 +1,7 @@
source include/not_embedded.inc;
call mtr.add_suppression("Host 'localhost' is not allowed to connect to this MariaDB server");
--echo #
--echo # MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty
--echo #

View File

@@ -4569,3 +4569,293 @@ a
drop view v1;
drop table t1,t2;
# End of 10.4 tests
#
# MDEV-41225: window functions and subqueries in the ORDER BY of a
# parenthesized query expression that must be wrapped into a derived table
#
CREATE TABLE t1 (c1 INT);
(SELECT 1 FROM t1 LIMIT 1)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER();
1
INSERT INTO t1 VALUES (1),(2),(3);
CREATE TABLE t2 (a INT);
INSERT INTO t2 VALUES (1),(2),(3);
# window functions must be computed over the rows left after LIMIT 2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY LEAD(c1) OVER (ORDER BY c1) IS NULL DESC, c1 LIMIT 1;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1;
c1
2
1
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) UNION (SELECT 3) ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1;
c1
2
SELECT * FROM ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) dt;
c1
2
SELECT ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) AS c;
c
2
# inner ORDER BY without LIMIT also forces the wrapping
(SELECT c1 FROM t1 ORDER BY c1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
c1
3
# no wrapping: the tail belongs to the parenthesized select itself
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
c1
3
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1;
c1
3
# subqueries must be attached to the wrapping select
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1;
c1
2
(SELECT c1 FROM t1 ORDER BY c1)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1;
c1
2
EXPLAIN EXTENDED (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using filesort
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
Note 1276 Field or reference '__2.c1' of SELECT #3 was resolved in SELECT #1
Note 1003 /* select#1 */ select `__2`.`c1` AS `c1` from ((/* select#2 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` order by `test`.`t1`.`c1` limit 2)) `__2` order by <expr_cache><`__2`.`c1`>((/* select#3 */ select count(0) from `test`.`t2` where `test`.`t2`.`a` > `__2`.`c1`)) limit 1
# t1.c1 is not visible outside of the derived table
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > t1.c1) LIMIT 1;
ERROR 42S22: Unknown column 't1.c1' in 'WHERE'
CREATE VIEW v1 AS (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a > c1), c1
LIMIT 1;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `__3`.`c1` AS `c1` from (select `t1`.`c1` AS `c1` from `t1` order by `t1`.`c1` limit 2) `__3` order by `__3`.`c1` = count(0) over () desc,(select max(`t2`.`a`) from `t2` where `t2`.`a` > `__3`.`c1`),`__3`.`c1` limit 1 latin1 latin1_swedish_ci
SELECT * FROM v1;
c1
2
DROP VIEW v1;
PREPARE stmt FROM "(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC,
(SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1";
EXECUTE stmt;
c1
2
EXECUTE stmt;
c1
2
DEALLOCATE PREPARE stmt;
# original query on a non-empty table
(SELECT 1 FROM t1 LIMIT 1)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER();
1
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY c1) OVER () = c1 DESC, c1
LIMIT 1;
c1
2
# locking clauses after a tail with ORDER BY
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 FOR UPDATE WAIT 1;
c1
2
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 FOR UPDATE NOWAIT;
c1
2
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE SKIP LOCKED;
c1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LOCK IN SHARE MODE WAIT 1;
c1
2
1
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
c1
3
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE;
c1
3
# locking clauses after a tail without ORDER BY
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 FOR UPDATE;
c1
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 LOCK IN SHARE MODE;
c1
1
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 FOR UPDATE NOWAIT;
c1
3
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 LOCK IN SHARE MODE;
c1
3
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE;
c1
1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE;
c1
1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE SKIP LOCKED;
c1
1
2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE NOWAIT;
c1
1
2
# tail referring to a table of the enclosing query
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY ABS(c1 - t2.a), c1 LIMIT 1) AS nearest
FROM t2 ORDER BY a;
a nearest
1 1
2 2
3 2
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 AS x WHERE x.a >= t2.a) = c1 DESC,
c1 LIMIT 1) AS c
FROM t2 ORDER BY a;
a c
1 1
2 2
3 1
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () + t2.a - 1 DESC, c1 LIMIT 1) AS c
FROM t2 ORDER BY a;
a c
1 2
2 1
3 1
SELECT a FROM t2
WHERE a = ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = t2.a DESC, c1 DESC LIMIT 1)
ORDER BY a;
a
1
2
# aggregate function in the tail belongs to the wrapping select
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY MAX(c1);
c1
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY COUNT(*), c1;
c1
1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT MAX(a) FROM t2 WHERE a >= MAX(c1));
c1
1
(SELECT c1 FROM t1) ORDER BY MAX(c1);
c1
1
# named window of the wrapped select is not visible in the tail
(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1) ORDER BY c1 LIMIT 2)
ORDER BY ROW_NUMBER() OVER w;
ERROR HY000: Window specification with name 'w' is not defined
(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1))
ORDER BY ROW_NUMBER() OVER w DESC LIMIT 1;
c1
3
# MATCH in the tail
CREATE TABLE t3 (b VARCHAR(20), FULLTEXT (b)) ENGINE=MyISAM;
INSERT INTO t3 VALUES ('apple'),('banana'),('cherry'),('apple pie');
(SELECT b FROM t3 ORDER BY b LIMIT 3) ORDER BY MATCH(b) AGAINST ('apple');
ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes
(SELECT b FROM t3 ORDER BY b LIMIT 3)
ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b;
ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes
SELECT b FROM (SELECT b FROM t3 ORDER BY b LIMIT 3) dt
ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b;
ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes
(SELECT b FROM t3) ORDER BY MATCH(b) AGAINST ('cherry') DESC, b LIMIT 1;
b
cherry
DROP TABLE t3;
# wrapped query inside a wrapped query
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1
LIMIT 1;
c1
1
EXPLAIN EXTENDED ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1
LIMIT 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DERIVED <derived2> ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort
Warnings:
Note 1276 Field or reference '__3.c1' of SELECT #4 was resolved in SELECT #1
Note 1003 /* select#1 */ select `__3`.`c1` AS `c1` from ((/* select#3 */ select `__2`.`c1` AS `c1` from ((/* select#2 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` order by `test`.`t1`.`c1` limit 3)) `__2` order by ntile(2) over ( order by `__2`.`c1`) desc,`__2`.`c1` limit 2)) `__3` order by `__3`.`c1` = count(0) over () desc,<expr_cache><`__3`.`c1`>((/* select#4 */ select max(`test`.`t2`.`a`) from `test`.`t2` where `test`.`t2`.`a` < `__3`.`c1`)),`__3`.`c1` limit 1
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY ((SELECT a FROM t2 ORDER BY a LIMIT 2)
ORDER BY a = COUNT(*) OVER () DESC, a LIMIT 1) = c1 DESC, c1
LIMIT 1;
c1
2
# stored procedure
CREATE PROCEDURE p1()
BEGIN
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC,
(SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1;
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
END|
CALL p1();
c1
2
c1
3
CALL p1();
c1
2
c1
3
DROP PROCEDURE p1;
DROP TABLE t1, t2;
# End of 10.11 tests

View File

@@ -2504,3 +2504,178 @@ drop table t1,t2;
--echo # End of 10.4 tests
--echo #
--echo # MDEV-41225: window functions and subqueries in the ORDER BY of a
--echo # parenthesized query expression that must be wrapped into a derived table
--echo #
CREATE TABLE t1 (c1 INT);
(SELECT 1 FROM t1 LIMIT 1)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER();
INSERT INTO t1 VALUES (1),(2),(3);
CREATE TABLE t2 (a INT);
INSERT INTO t2 VALUES (1),(2),(3);
--echo # window functions must be computed over the rows left after LIMIT 2
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY LEAD(c1) OVER (ORDER BY c1) IS NULL DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1;
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) UNION (SELECT 3) ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1;
SELECT * FROM ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) dt;
SELECT ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) AS c;
--echo # inner ORDER BY without LIMIT also forces the wrapping
(SELECT c1 FROM t1 ORDER BY c1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
--echo # no wrapping: the tail belongs to the parenthesized select itself
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1;
--echo # subqueries must be attached to the wrapping select
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1;
EXPLAIN EXTENDED (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1;
--echo # t1.c1 is not visible outside of the derived table
--error ER_BAD_FIELD_ERROR
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > t1.c1) LIMIT 1;
CREATE VIEW v1 AS (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a > c1), c1
LIMIT 1;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
PREPARE stmt FROM "(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC,
(SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
--echo # original query on a non-empty table
(SELECT 1 FROM t1 LIMIT 1)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER();
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY c1) OVER () = c1 DESC, c1
LIMIT 1;
--echo # locking clauses after a tail with ORDER BY
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 FOR UPDATE WAIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 FOR UPDATE NOWAIT;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE SKIP LOCKED;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, c1 LOCK IN SHARE MODE WAIT 1;
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
(SELECT c1 FROM t1)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE;
--echo # locking clauses after a tail without ORDER BY
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 FOR UPDATE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 LOCK IN SHARE MODE;
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 FOR UPDATE NOWAIT;
(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 LOCK IN SHARE MODE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE SKIP LOCKED;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE NOWAIT;
--echo # tail referring to a table of the enclosing query
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY ABS(c1 - t2.a), c1 LIMIT 1) AS nearest
FROM t2 ORDER BY a;
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT COUNT(*) FROM t2 AS x WHERE x.a >= t2.a) = c1 DESC,
c1 LIMIT 1) AS c
FROM t2 ORDER BY a;
SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () + t2.a - 1 DESC, c1 LIMIT 1) AS c
FROM t2 ORDER BY a;
SELECT a FROM t2
WHERE a = ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = t2.a DESC, c1 DESC LIMIT 1)
ORDER BY a;
--echo # aggregate function in the tail belongs to the wrapping select
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY MAX(c1);
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY COUNT(*), c1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY (SELECT MAX(a) FROM t2 WHERE a >= MAX(c1));
(SELECT c1 FROM t1) ORDER BY MAX(c1);
--echo # named window of the wrapped select is not visible in the tail
--error ER_WRONG_WINDOW_SPEC_NAME
(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1) ORDER BY c1 LIMIT 2)
ORDER BY ROW_NUMBER() OVER w;
(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1))
ORDER BY ROW_NUMBER() OVER w DESC LIMIT 1;
--echo # MATCH in the tail
CREATE TABLE t3 (b VARCHAR(20), FULLTEXT (b)) ENGINE=MyISAM;
INSERT INTO t3 VALUES ('apple'),('banana'),('cherry'),('apple pie');
--error ER_TABLE_CANT_HANDLE_FT
(SELECT b FROM t3 ORDER BY b LIMIT 3) ORDER BY MATCH(b) AGAINST ('apple');
--error ER_TABLE_CANT_HANDLE_FT
(SELECT b FROM t3 ORDER BY b LIMIT 3)
ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b;
--error ER_TABLE_CANT_HANDLE_FT
SELECT b FROM (SELECT b FROM t3 ORDER BY b LIMIT 3) dt
ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b;
(SELECT b FROM t3) ORDER BY MATCH(b) AGAINST ('cherry') DESC, b LIMIT 1;
DROP TABLE t3;
--echo # wrapped query inside a wrapped query
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1
LIMIT 1;
EXPLAIN EXTENDED ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1
LIMIT 1;
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY ((SELECT a FROM t2 ORDER BY a LIMIT 2)
ORDER BY a = COUNT(*) OVER () DESC, a LIMIT 1) = c1 DESC, c1
LIMIT 1;
--echo # stored procedure
DELIMITER |;
CREATE PROCEDURE p1()
BEGIN
(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2)
ORDER BY c1 = COUNT(*) OVER () DESC,
(SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1;
((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3)
ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2)
ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE;
END|
DELIMITER ;|
CALL p1();
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1, t2;
--echo # End of 10.11 tests

View File

@@ -1538,7 +1538,7 @@ LENGTH(a)
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` blob /*M!100301 COMPRESSED*/ NOT NULL DEFAULT ''
`a` blob /*M!100301 COMPRESSED*/ NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
DROP TABLE t1;
@@ -3091,3 +3091,55 @@ REPLACE INTO t VALUES ('abcdefghijklm');
UPDATE t SET c=MID(c,2,4);
DROP TABLE t;
# End of 10.6 tests
#
# MDEV-40417 A column with compression enabled automatically adds DEFAULT ''
#
CREATE TABLE t (
c1 LONGTEXT COMPRESSED NOT NULL,
nc1 LONGTEXT NOT NULL,
c2 LONGTEXT COMPRESSED NOT NULL DEFAULT '',
nc2 LONGTEXT NOT NULL DEFAULT '',
c3 VARCHAR(100) COMPRESSED NOT NULL,
nc3 VARCHAR(100) NOT NULL
) ENGINE=InnoDB;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`c1` longtext /*M!100301 COMPRESSED*/ NOT NULL,
`nc1` longtext NOT NULL,
`c2` longtext /*M!100301 COMPRESSED*/ NOT NULL DEFAULT '',
`nc2` longtext NOT NULL DEFAULT '',
`c3` varchar(100) /*M!100301 COMPRESSED*/ NOT NULL,
`nc3` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t' ORDER BY ORDINAL_POSITION;
COLUMN_NAME COLUMN_DEFAULT
c1 NULL
nc1 NULL
c2 ''
nc2 ''
c3 NULL
nc3 NULL
# A compressed column must be as mandatory as an uncompressed one
INSERT INTO t (nc1) VALUES ('x');
ERROR HY000: Field 'c1' doesn't have a default value
INSERT INTO t (c1, nc1, nc3) VALUES ('x', 'x', 'x');
ERROR HY000: Field 'c3' doesn't have a default value
INSERT INTO t (c1, nc1, c3, nc3) VALUES ('x', 'x', 'x', 'x');
SELECT * FROM t;
c1 nc1 c2 nc2 c3 nc3
x x x x
DROP TABLE t;
# ALTER TABLE must not add an implicit default either
CREATE TABLE t (c LONGTEXT COMPRESSED NOT NULL DEFAULT 'x') ENGINE=InnoDB;
ALTER TABLE t MODIFY c LONGTEXT COMPRESSED NOT NULL;
ALTER TABLE t ADD c2 VARCHAR(100) COMPRESSED NOT NULL;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`c` longtext /*M!100301 COMPRESSED*/ NOT NULL,
`c2` varchar(100) /*M!100301 COMPRESSED*/ NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t;
# End of 10.11 tests

View File

@@ -599,3 +599,37 @@ UPDATE t SET c=MID(c,2,4);
DROP TABLE t;
--echo # End of 10.6 tests
--echo #
--echo # MDEV-40417 A column with compression enabled automatically adds DEFAULT ''
--echo #
CREATE TABLE t (
c1 LONGTEXT COMPRESSED NOT NULL,
nc1 LONGTEXT NOT NULL,
c2 LONGTEXT COMPRESSED NOT NULL DEFAULT '',
nc2 LONGTEXT NOT NULL DEFAULT '',
c3 VARCHAR(100) COMPRESSED NOT NULL,
nc3 VARCHAR(100) NOT NULL
) ENGINE=InnoDB;
SHOW CREATE TABLE t;
SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t' ORDER BY ORDINAL_POSITION;
--echo # A compressed column must be as mandatory as an uncompressed one
--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t (nc1) VALUES ('x');
--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t (c1, nc1, nc3) VALUES ('x', 'x', 'x');
INSERT INTO t (c1, nc1, c3, nc3) VALUES ('x', 'x', 'x', 'x');
SELECT * FROM t;
DROP TABLE t;
--echo # ALTER TABLE must not add an implicit default either
CREATE TABLE t (c LONGTEXT COMPRESSED NOT NULL DEFAULT 'x') ENGINE=InnoDB;
ALTER TABLE t MODIFY c LONGTEXT COMPRESSED NOT NULL;
ALTER TABLE t ADD c2 VARCHAR(100) COMPRESSED NOT NULL;
SHOW CREATE TABLE t;
DROP TABLE t;
--echo # End of 10.11 tests

View File

@@ -89,3 +89,65 @@ db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4
Warnings:
Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed
DROP DATABASE db1;
#
# MDEV-41157 CREATE DATABASE COMMENT overflows db.opt comment buffer
#
set session sql_mode='';
create database db comment '$long_comment';
Warnings:
Warning 4160 Comment for database 'db' is too long (max = 1024)
# Bug 1: put_dbopt() must not overflow when storing a truncated comment
show create database db;
Database Create Database
db CREATE DATABASE `db` COMMENT '<A x1024>'
flush tables;
# Bug 2: write_db_opt() must persist a properly terminated truncated comment
show create database db;
Database Create Database
db CREATE DATABASE `db` COMMENT '<A x1024>'
# Bug 3: load_db_opt() must clamp an overlong comment loaded from a legacy db.opt file
flush tables;
show create database db;
Database Create Database
db CREATE DATABASE `db` COMMENT '<A x1024>'
Warnings:
Warning 4160 Comment in database options file './db/db.opt' is too long (max = 1024), truncated
# Bug 3: ALTER DATABASE without COMMENT must clamp a legacy overlong comment too
flush tables;
alter database db character set 'latin1';
Warnings:
Warning 4160 Comment in database options file './db/db.opt' is too long (max = 1024), truncated
show create database db;
Database Create Database
db CREATE DATABASE `db` COMMENT '<A x1024>'
drop database db;
# Bug 4: multi-byte comment must be truncated at a character boundary
set names utf8mb3;
create database dbmb comment '$mb_comment';
Warnings:
Warning 4160 Comment for database 'dbmb' is too long (max = 1024)
select char_length(schema_comment), octet_length(schema_comment)
from information_schema.schemata where schema_name='dbmb';
char_length(schema_comment) octet_length(schema_comment)
341 1023
flush tables;
select char_length(schema_comment), octet_length(schema_comment)
from information_schema.schemata where schema_name='dbmb';
char_length(schema_comment) octet_length(schema_comment)
341 1023
drop database dbmb;
# Bug 4: strict sql_mode must reject an overlong multi-byte comment
set session sql_mode='TRADITIONAL';
create database dbmb comment '$mb_comment';
ERROR HY000: Comment for database 'dbmb' is too long (max = 1024)
set session sql_mode='';
# a 1024-character multi-byte table comment must not be byte-clamped
create table test.t1 (a int) comment '$mb_table_comment';
select char_length(table_comment), octet_length(table_comment)
from information_schema.tables where table_name='t1';
char_length(table_comment) octet_length(table_comment)
1024 3072
drop table test.t1;
set names default;
set session sql_mode=default;
# End of 10.11 tests

View File

@@ -71,3 +71,70 @@ CREATE DATABASE db1;
SHOW CREATE DATABASE db1;
SHOW CREATE DATABASE db1;
DROP DATABASE db1;
--echo #
--echo # MDEV-41157 CREATE DATABASE COMMENT overflows db.opt comment buffer
--echo #
set session sql_mode='';
--let $long_comment= `select repeat('A', 4000)`
evalp create database db comment '$long_comment';
--echo # Bug 1: put_dbopt() must not overflow when storing a truncated comment
--replace_regex /A{1024}/<A x1024>/ # /\*!40100[^*]*\*/##
show create database db;
flush tables;
--echo # Bug 2: write_db_opt() must persist a properly terminated truncated comment
--replace_regex /A{1024}/<A x1024>/ # /\*!40100[^*]*\*/##
show create database db;
--echo # Bug 3: load_db_opt() must clamp an overlong comment loaded from a legacy db.opt file
--let $def_charset= `select @@character_set_server`
--let $def_collation= `select @@collation_server`
--remove_file $MARIADB_DATADIR/db/db.opt
--write_file $MARIADB_DATADIR/db/db.opt EOF eval
default-character-set=$def_charset
default-collation=$def_collation
comment=$long_comment
EOF
flush tables;
--replace_regex /A{1024}/<A x1024>/ /[\\]/\// # /\*!40100[^*]*\*/##
show create database db;
--echo # Bug 3: ALTER DATABASE without COMMENT must clamp a legacy overlong comment too
flush tables;
--replace_regex /[\\]/\//
alter database db character set 'latin1';
--replace_regex /A{1024}/<A x1024>/ # /\*!40100[^*]*\*/##
show create database db;
drop database db;
--echo # Bug 4: multi-byte comment must be truncated at a character boundary
set names utf8mb3;
--let $mb_comment= `select repeat(convert(0xE4B8AD using utf8mb3), 4000)`
evalp create database dbmb comment '$mb_comment';
select char_length(schema_comment), octet_length(schema_comment)
from information_schema.schemata where schema_name='dbmb';
flush tables;
select char_length(schema_comment), octet_length(schema_comment)
from information_schema.schemata where schema_name='dbmb';
drop database dbmb;
--echo # Bug 4: strict sql_mode must reject an overlong multi-byte comment
set session sql_mode='TRADITIONAL';
--error ER_TOO_LONG_DATABASE_COMMENT
evalp create database dbmb comment '$mb_comment';
set session sql_mode='';
--echo # a 1024-character multi-byte table comment must not be byte-clamped
--let $mb_table_comment= `select repeat(convert(0xE4B8AD using utf8mb3), 1024)`
evalp create table test.t1 (a int) comment '$mb_table_comment';
select char_length(table_comment), octet_length(table_comment)
from information_schema.tables where table_name='t1';
drop table test.t1;
set names default;
set session sql_mode=default;
--echo # End of 10.11 tests

View File

@@ -1,2 +1,8 @@
create table `...................................................`(i int);
ERROR HY000: Can't create table `test`.`...................................................` (errno: 38 "Filename too long")
#
# MDEV-28746 continued: a *relative* path can overflow MAX_PATH too
#
CREATE TABLE `NAME` (id INT);
ERROR HY000: Can't create table `test`.`NAME` (errno: 38 "Filename too long")
# End of 10.11 tests

View File

@@ -8,3 +8,17 @@
let $t = `SELECT(REPEAT('.',51))`;
--error ER_CANT_CREATE_TABLE
eval create table `$t`(i int);
--echo #
--echo # MDEV-28746 continued: a *relative* path can overflow MAX_PATH too
--echo #
# mariadbd opens table files via relative (to datadir) paths, so a short
# identifier can still overflow MAX_PATH (260) once resolved against a long
# enough datadir. '!' encodes to 5 bytes; pick the fewest of them that push
# datadir + "test\<name>.frm" (9 fixed bytes) to 260.
--let $t2= `SELECT REPEAT('!', GREATEST(1, CEIL((260 - LENGTH(@@datadir) - 9) / 5)))`
--replace_regex /!+/NAME/
--error ER_CANT_CREATE_TABLE
eval CREATE TABLE `$t2` (id INT);
--echo # End of 10.11 tests

View File

@@ -236,11 +236,8 @@ SELECT DATE_FORMAT('2004-02-02','%W');
SELECT HEX(DATE_FORMAT('2004-02-02','%W'));
#Enable after fix MDEV-33936
--disable_view_protocol
#enable after fix MDEV-34215
--disable_cursor_protocol
SELECT DATE_FORMAT(TIME'-01:01:01','%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01','%h'));
--enable_cursor_protocol
--enable_view_protocol
--echo # latin1 format, binary result
@@ -248,11 +245,8 @@ SELECT DATE_FORMAT('2004-02-02',_latin1'%W');
SELECT HEX(DATE_FORMAT('2004-02-02',_latin1'%W'));
#Enable after fix MDEV-33936
--disable_view_protocol
#enable after fix MDEV-34215
--disable_cursor_protocol
SELECT DATE_FORMAT(TIME'-01:01:01',_latin1'%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_latin1'%h'));
--enable_cursor_protocol
--enable_view_protocol
--echo # Binary format, latin1 result
@@ -261,11 +255,8 @@ SELECT DATE_FORMAT('2004-02-02',_binary'%W');
SELECT HEX(DATE_FORMAT('2004-02-02',_binary'%W'));
#Enable after fix MDEV-33936
--disable_view_protocol
#enable after fix MDEV-34215
--disable_cursor_protocol
SELECT DATE_FORMAT(TIME'-01:01:01',_binary'%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_binary'%h'));
--enable_cursor_protocol
--enable_view_protocol
--echo #
--echo # End of 10.4 tests

View File

@@ -1136,11 +1136,8 @@ SELECT HEX(DATE_FORMAT(TIME'-01:01:01','%h'));
--echo # utf8 format, utf32 result
SELECT DATE_FORMAT('2004-02-02',_utf8'%W');
SELECT HEX(DATE_FORMAT('2004-02-02',_utf8'%W'));
#enable after fix MDEV-34215
--disable_cursor_protocol
SELECT DATE_FORMAT(TIME'-01:01:01',_utf8'%h');
SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_utf8'%h'));
--enable_cursor_protocol
--echo # utf32 format, utf8 result
SET NAMES utf8;

View File

@@ -1222,3 +1222,71 @@ ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
DO FETCH GROUP NEXT ROW;
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
# End of 10.4 tests
#
# MDEV-38004 Double free on repeated execution of prepared aggregate
# function against empty table in Query_arena::free_items()
#
create aggregate function agg_cnt() returns int
begin
declare z int default 0;
declare continue handler for not found return z;
loop
fetch group next row;
set z= z+1;
end loop;
end|
create table t1 (id int);
prepare stmt from "select agg_cnt() from t1";
execute stmt;
agg_cnt()
NULL
execute stmt;
agg_cnt()
NULL
insert into t1 values (1),(2),(2);
execute stmt;
agg_cnt()
3
execute stmt;
agg_cnt()
3
deallocate prepare stmt;
#
# Compare with
select agg_cnt() from t1;
agg_cnt()
3
prepare stmt from "select id, agg_cnt() from t1 group by id with rollup";
execute stmt;
id agg_cnt()
1 1
2 2
NULL 3
execute stmt;
id agg_cnt()
1 1
2 2
NULL 3
deallocate prepare stmt;
#
# The same item is reused between two CALLs of a stored procedure
#
delete from t1;
create procedure p() select agg_cnt() from t1;
call p();
agg_cnt()
NULL
call p();
agg_cnt()
NULL
insert into t1 values (1),(2),(2);
call p();
agg_cnt()
3
call p();
agg_cnt()
3
drop procedure p;
drop function agg_cnt;
drop table t1;
# End of 10.11 tests

View File

@@ -1062,3 +1062,55 @@ CREATE EVENT ev1
DO FETCH GROUP NEXT ROW;
--echo # End of 10.4 tests
--echo #
--echo # MDEV-38004 Double free on repeated execution of prepared aggregate
--echo # function against empty table in Query_arena::free_items()
--echo #
--delimiter |
create aggregate function agg_cnt() returns int
begin
declare z int default 0;
declare continue handler for not found return z;
loop
fetch group next row;
set z= z+1;
end loop;
end|
--delimiter ;
create table t1 (id int);
prepare stmt from "select agg_cnt() from t1";
execute stmt;
execute stmt;
insert into t1 values (1),(2),(2);
execute stmt;
execute stmt;
deallocate prepare stmt;
--echo #
--echo # Compare with
select agg_cnt() from t1;
prepare stmt from "select id, agg_cnt() from t1 group by id with rollup";
execute stmt;
execute stmt;
deallocate prepare stmt;
--echo #
--echo # The same item is reused between two CALLs of a stored procedure
--echo #
delete from t1;
create procedure p() select agg_cnt() from t1;
call p();
call p();
insert into t1 values (1),(2),(2);
call p();
call p();
# Cleanup
drop procedure p;
drop function agg_cnt;
drop table t1;
--echo # End of 10.11 tests

View File

@@ -1987,3 +1987,23 @@ ERROR HY000: Encountered illegal format of dynamic column string
SELECT COLUMN_JSON(CONCAT(0x040200020001000000000000004241, REPEAT('D', 512)));
ERROR HY000: Encountered illegal format of dynamic column string
# End of 10.6 tests
#
# MDEV-41144 Assertion `scale <= precision' failed in decimal_bin_size
#
SELECT COLUMN_JSON(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex;
ERROR HY000: Encountered illegal format of dynamic column string
SELECT COLUMN_CHECK(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex;
ex
0
#
# Round trip check: a decimal scale beyond the SQL-layer
# DECIMAL_MAX_SCALE (38) must still be readable, since the dyncol
# format itself allows up to DECIMAL_MAX_POSSIBLE_PRECISION (81).
#
SELECT COLUMN_JSON(COLUMN_CREATE(1, '0.123456789012345678901234567890123456789' AS decimal)) AS ex;
ex
{"1":0.1234567890123456789012345678901234567}
SELECT COLUMN_CHECK(COLUMN_CREATE(1, 0.1234567890123456789012345678901234567890123456789 AS decimal)) AS ex;
ex
1
# End of 10.11 tests

View File

@@ -1044,3 +1044,20 @@ SELECT COLUMN_LIST(0x040100FFFF00000300666F6F21626172);
SELECT COLUMN_JSON(CONCAT(0x040200020001000000000000004241, REPEAT('D', 512)));
--echo # End of 10.6 tests
--echo #
--echo # MDEV-41144 Assertion `scale <= precision' failed in decimal_bin_size
--echo #
--error ER_DYN_COL_WRONG_FORMAT
SELECT COLUMN_JSON(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex;
SELECT COLUMN_CHECK(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex;
--echo #
--echo # Round trip check: a decimal scale beyond the SQL-layer
--echo # DECIMAL_MAX_SCALE (38) must still be readable, since the dyncol
--echo # format itself allows up to DECIMAL_MAX_POSSIBLE_PRECISION (81).
--echo #
SELECT COLUMN_JSON(COLUMN_CREATE(1, '0.123456789012345678901234567890123456789' AS decimal)) AS ex;
SELECT COLUMN_CHECK(COLUMN_CREATE(1, 0.1234567890123456789012345678901234567890123456789 AS decimal)) AS ex;
--echo # End of 10.11 tests

View File

@@ -791,3 +791,34 @@ CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria;
ALTER TABLE tmp ADD FULLTEXT (a);
INSERT INTO tmp VALUES ('foo');
DROP TABLE tmp;
#
# MDEV-32383 Server crashes in Item_func_match::init_search on 2nd execution of PS
#
CREATE TABLE t (a VARCHAR(255), FULLTEXT(a));
INSERT INTO t VALUES ('MariaDB'),('MariaDB server'),
('foo'),('bar'),('baz'),('qux'),('quux'),('corge');
CREATE VIEW v AS
SELECT MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) AS f
FROM t
WHERE MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) > 0
ORDER BY f;
# all three must return the same rows in the same order
SELECT ROUND(f,6) FROM v ORDER BY f;
ROUND(f,6)
1.073912
1.086122
PREPARE stmt FROM "SELECT ROUND(f,6) FROM v ORDER BY f";
EXECUTE stmt;
ROUND(f,6)
1.073912
1.086122
EXECUTE stmt;
ROUND(f,6)
1.073912
1.086122
DEALLOCATE PREPARE stmt;
DROP VIEW v;
DROP TABLE t;
#
# End of 10.11 tests
#

View File

@@ -738,3 +738,31 @@ CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria;
ALTER TABLE tmp ADD FULLTEXT (a);
INSERT INTO tmp VALUES ('foo');
DROP TABLE tmp;
--echo #
--echo # MDEV-32383 Server crashes in Item_func_match::init_search on 2nd execution of PS
--echo #
CREATE TABLE t (a VARCHAR(255), FULLTEXT(a));
INSERT INTO t VALUES ('MariaDB'),('MariaDB server'),
('foo'),('bar'),('baz'),('qux'),('quux'),('corge');
CREATE VIEW v AS
SELECT MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) AS f
FROM t
WHERE MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) > 0
ORDER BY f;
--echo # all three must return the same rows in the same order
SELECT ROUND(f,6) FROM v ORDER BY f;
PREPARE stmt FROM "SELECT ROUND(f,6) FROM v ORDER BY f";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP VIEW v;
DROP TABLE t;
--echo #
--echo # End of 10.11 tests
--echo #

View File

@@ -304,3 +304,12 @@ f
NULL
DROP TABLE t1;
# End of 10.5 tests
# Start of 10.11 tests
#
# MDEV-40673: Preserve the results of JSON_TYPE and GET_FORMAT in CONCAT
#
SELECT CONCAT(JSON_TYPE('{"a":1}'),'X') AS json_type,
CONCAT(GET_FORMAT(DATE, 'USA'), 'X') AS get_format;
json_type get_format
OBJECTX %m.%d.%YX
# End of 10.11 tests

View File

@@ -281,3 +281,11 @@ SELECT CONCAT_WS(' ', a, b, PASSWORD(c)) AS f FROM t1 GROUP BY f WITH ROLLUP;
DROP TABLE t1;
--echo # End of 10.5 tests
--echo # Start of 10.11 tests
--echo #
--echo # MDEV-40673: Preserve the results of JSON_TYPE and GET_FORMAT in CONCAT
--echo #
SELECT CONCAT(JSON_TYPE('{"a":1}'),'X') AS json_type,
CONCAT(GET_FORMAT(DATE, 'USA'), 'X') AS get_format;
--echo # End of 10.11 tests

View File

@@ -2730,6 +2730,47 @@ SELECT JSON_OVERLAPS(@json1, @json2);
JSON_OVERLAPS(@json1, @json2)
0
#
# MDEV-41067: Empty and nonempty nested JSON arrays
#
SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS forward,
JSON_OVERLAPS('[[]]', '[[1]]') AS reverse;
forward reverse
0 0
SELECT JSON_OVERLAPS('[[1],[2]]', '[[],[2]]') AS forward,
JSON_OVERLAPS('[[],[2]]', '[[1],[2]]') AS reverse;
forward reverse
1 1
SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS forward,
JSON_OVERLAPS('[[1,2]]', '[[1]]') AS reverse;
forward reverse
0 0
SELECT JSON_OVERLAPS('[[]]', '[[]]') AS r;
r
1
SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],2]]') AS r;
r
1
SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],3]]') AS forward,
JSON_OVERLAPS('[[[1],3]]', '[[[1],2]]') AS reverse;
forward reverse
0 0
SELECT JSON_OVERLAPS('[[[],1],[4]]', '[[{},1],[4]]') AS forward,
JSON_OVERLAPS('[[{},1],[4]]', '[[[],1],[4]]') AS reverse;
forward reverse
1 1
SELECT JSON_OVERLAPS('[[true]]', '[[1]]') AS forward,
JSON_OVERLAPS('[[1]]', '[[true]]') AS reverse;
forward reverse
0 0
SELECT JSON_OVERLAPS('[[1,2]]', '[[2,1]]') AS forward,
JSON_OVERLAPS('[[2,1]]', '[[1,2]]') AS reverse;
forward reverse
0 0
SELECT JSON_OVERLAPS('{"a":[1],"b":2}', '{"a":[],"b":2}') AS forward,
JSON_OVERLAPS('{"a":[],"b":2}', '{"a":[1],"b":2}') AS reverse;
forward reverse
1 1
#
# MDEV-30304: Json Range only affects first row of the result set
#
CREATE TABLE t1 ( j JSON );
@@ -3101,6 +3142,20 @@ NULL ["a", "b"] NULL
{"r": 1} NULL NULL
[{"a": 3}, {"d": [1, 2, 3]}] [{"d": [1E0, 2E0, 3E0]}, {"a":3E0}] 1
DROP TABLE t;
#
# MDEV-39049: Memory corruption & crash in check_key_in_list upon
# using JSON_KEYS after modifying character set name/collation
#
SET SESSION character_set_database=utf32;
SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}');
JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}')
NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 25
SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }');
JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }')
["", "k2"]
SET SESSION character_set_database= default;
# End of 10.11 Test
#
# MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-)

View File

@@ -1917,6 +1917,28 @@ SET @json2 = '{"kk":{"k1":"v1","k2":"v2","k3":"v3"}}';
SELECT JSON_OVERLAPS(@json2, @json1);
SELECT JSON_OVERLAPS(@json1, @json2);
--echo #
--echo # MDEV-41067: Empty and nonempty nested JSON arrays
--echo #
SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS forward,
JSON_OVERLAPS('[[]]', '[[1]]') AS reverse;
SELECT JSON_OVERLAPS('[[1],[2]]', '[[],[2]]') AS forward,
JSON_OVERLAPS('[[],[2]]', '[[1],[2]]') AS reverse;
SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS forward,
JSON_OVERLAPS('[[1,2]]', '[[1]]') AS reverse;
SELECT JSON_OVERLAPS('[[]]', '[[]]') AS r;
SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],2]]') AS r;
SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],3]]') AS forward,
JSON_OVERLAPS('[[[1],3]]', '[[[1],2]]') AS reverse;
SELECT JSON_OVERLAPS('[[[],1],[4]]', '[[{},1],[4]]') AS forward,
JSON_OVERLAPS('[[{},1],[4]]', '[[[],1],[4]]') AS reverse;
SELECT JSON_OVERLAPS('[[true]]', '[[1]]') AS forward,
JSON_OVERLAPS('[[1]]', '[[true]]') AS reverse;
SELECT JSON_OVERLAPS('[[1,2]]', '[[2,1]]') AS forward,
JSON_OVERLAPS('[[2,1]]', '[[1,2]]') AS reverse;
SELECT JSON_OVERLAPS('{"a":[1],"b":2}', '{"a":[],"b":2}') AS forward,
JSON_OVERLAPS('{"a":[],"b":2}', '{"a":[1],"b":2}') AS reverse;
--echo #
--echo # MDEV-30304: Json Range only affects first row of the result set
--echo #
@@ -2169,6 +2191,14 @@ SELECT c1, JSON_OVERLAPS(c1, '{"r": 1E0}') AS jo_c1_const FROM t;
SELECT c1, c2, JSON_OVERLAPS(c1, c2) AS jo_c1_c2 FROM t;
DROP TABLE t;
--echo #
--echo # MDEV-39049: Memory corruption & crash in check_key_in_list upon
--echo # using JSON_KEYS after modifying character set name/collation
--echo #
SET SESSION character_set_database=utf32;
SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}');
SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }');
SET SESSION character_set_database= default;
--echo # End of 10.11 Test
--echo #

View File

@@ -969,4 +969,188 @@ disconnect con1;
connection default;
drop procedure mysql.p1;
drop user u@localhost;
#
# MDEV-41099 HANDLER READ missing column privilege check
#
create database db;
create table db.t (id int primary key, a varchar(64), b int);
insert into db.t values (1,'tok1',100), (2,'tok2',200);
create user u@localhost;
grant select (id) on db.t to u@localhost;
connect con1, localhost, u, , db;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
handler t read first;
ERROR 42S02: Unknown table 't' in HANDLER
connection default;
grant select (a, b) on db.t to u@localhost;
connection con1;
handler t open;
handler t read first;
id a b
1 tok1 100
connect con2, localhost, root;
flush tables db.t;
connection default;
connection con1;
select 1 from information_schema.character_sets limit 1;
1
1
connection con2;
disconnect con2;
connection con1;
handler t read next;
id a b
1 tok1 100
# reopen after a column without privilege was added
connect con2, localhost, root;
alter table db.t add column c int default 42;
connection default;
connection con1;
select 1 from information_schema.character_sets limit 1;
1
1
connection con2;
disconnect con2;
connection con1;
handler t read first;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
handler t close;
# reopen after privileges changed
connection default;
grant select (c) on db.t to u@localhost;
connection con1;
handler t open;
handler t read first;
id a b c
1 tok1 100 42
connection default;
revoke select (id, a, b, c) on db.t from u@localhost;
grant select on db.t to u@localhost;
connection con1;
connect con2, localhost, root;
flush tables db.t;
connection default;
connection con1;
select 1 from information_schema.character_sets limit 1;
1
1
connection con2;
disconnect con2;
connection con1;
handler t read next;
id a b c
1 tok1 100 42
connection default;
revoke select on db.t from u@localhost;
connection con1;
connect con2, localhost, root;
flush tables db.t;
connection default;
connection con1;
select 1 from information_schema.character_sets limit 1;
1
1
connection con2;
disconnect con2;
connection con1;
handler t read next;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
connection default;
grant select (id, a, b, c) on db.t to u@localhost;
connection con1;
handler t read next;
id a b c
1 tok1 100 42
handler t close;
connection default;
revoke select (id, a, b, c) on db.t from u@localhost;
connection con1;
# column grants through a role
connection default;
create role r;
grant select (id) on db.t to r;
grant r to u@localhost;
connection con1;
set role r;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
connection default;
grant select (a, b, c) on db.t to r;
connection con1;
handler t open;
handler t read first;
id a b c
1 tok1 100 42
handler t close;
set role none;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
# column grants to PUBLIC
connection default;
grant select (id) on db.t to public;
connection con1;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
connection default;
grant select (a, b, c) on db.t to public;
connection con1;
handler t open;
handler t read first;
id a b c
1 tok1 100 42
handler t close;
# column grants split between PUBLIC and a role
connection default;
revoke select (a, b, c) on db.t from public;
revoke select (id) on db.t from r;
connection con1;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
set role r;
handler t open;
handler t read first;
id a b c
1 tok1 100 42
handler t close;
disconnect con1;
connection default;
revoke select (id) on db.t from public;
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
drop role r;
drop user u@localhost;
drop database db;
# Invisible columns: INVISIBLE_USER (a) needs a grant,
# INVISIBLE_SYSTEM (row_start, row_end) and INVISIBLE_FULL
# (DB_ROW_HASH_1) need none, as for SELECT
create database db;
create table db.t (id int primary key, a int invisible, b blob, unique(b))
with system versioning;
set time_zone= '+00:00';
set timestamp= unix_timestamp('2001-01-01 00:00:00');
insert into db.t (id, a, b) values (1, 10, 'x');
set timestamp= default;
set time_zone= default;
create user u@localhost;
grant select (id, b) on db.t to u@localhost;
connect con1, localhost, u, , db;
handler t open;
ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t`
connection default;
grant select (a) on db.t to u@localhost;
connection con1;
set time_zone= '+00:00';
select row_start, row_end from t;
row_start row_end
2001-01-01 00:00:00.000000 2106-02-07 06:28:15.999999
handler t open;
handler t read first;
id a b row_start row_end DB_ROW_HASH_1
1 10 x 2001-01-01 00:00:00.000000 2106-02-07 06:28:15.999999 #
handler t close;
disconnect con1;
connection default;
drop user u@localhost;
drop database db;
# End of 10.11 tests

View File

@@ -1049,5 +1049,145 @@ connection default;
drop procedure mysql.p1;
drop user u@localhost;
--echo #
--echo # MDEV-41099 HANDLER READ missing column privilege check
--echo #
create database db;
create table db.t (id int primary key, a varchar(64), b int);
insert into db.t values (1,'tok1',100), (2,'tok2',200);
create user u@localhost;
grant select (id) on db.t to u@localhost;
connect con1, localhost, u, , db;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
--error ER_UNKNOWN_TABLE
handler t read first;
connection default;
grant select (a, b) on db.t to u@localhost;
connection con1;
handler t open;
handler t read first;
let $ddl= flush tables db.t;
--source grant2_handler_reopen.inc
handler t read next;
--echo # reopen after a column without privilege was added
let $ddl= alter table db.t add column c int default 42;
--source grant2_handler_reopen.inc
--error ER_TABLEACCESS_DENIED_ERROR
handler t read first;
handler t close;
--echo # reopen after privileges changed
connection default;
grant select (c) on db.t to u@localhost;
connection con1;
handler t open;
handler t read first;
connection default;
revoke select (id, a, b, c) on db.t from u@localhost;
grant select on db.t to u@localhost;
connection con1;
let $ddl= flush tables db.t;
--source grant2_handler_reopen.inc
handler t read next;
connection default;
revoke select on db.t from u@localhost;
connection con1;
let $ddl= flush tables db.t;
--source grant2_handler_reopen.inc
--error ER_TABLEACCESS_DENIED_ERROR
handler t read next;
connection default;
grant select (id, a, b, c) on db.t to u@localhost;
connection con1;
handler t read next;
handler t close;
connection default;
revoke select (id, a, b, c) on db.t from u@localhost;
connection con1;
--echo # column grants through a role
connection default;
create role r;
grant select (id) on db.t to r;
grant r to u@localhost;
connection con1;
set role r;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
connection default;
grant select (a, b, c) on db.t to r;
connection con1;
handler t open;
handler t read first;
handler t close;
set role none;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
--echo # column grants to PUBLIC
connection default;
grant select (id) on db.t to public;
connection con1;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
connection default;
grant select (a, b, c) on db.t to public;
connection con1;
handler t open;
handler t read first;
handler t close;
--echo # column grants split between PUBLIC and a role
connection default;
revoke select (a, b, c) on db.t from public;
revoke select (id) on db.t from r;
connection con1;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
set role r;
handler t open;
handler t read first;
handler t close;
disconnect con1;
connection default;
revoke select (id) on db.t from public;
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
drop role r;
drop user u@localhost;
drop database db;
--echo # Invisible columns: INVISIBLE_USER (a) needs a grant,
--echo # INVISIBLE_SYSTEM (row_start, row_end) and INVISIBLE_FULL
--echo # (DB_ROW_HASH_1) need none, as for SELECT
create database db;
create table db.t (id int primary key, a int invisible, b blob, unique(b))
with system versioning;
set time_zone= '+00:00';
set timestamp= unix_timestamp('2001-01-01 00:00:00');
insert into db.t (id, a, b) values (1, 10, 'x');
set timestamp= default;
set time_zone= default;
create user u@localhost;
grant select (id, b) on db.t to u@localhost;
connect con1, localhost, u, , db;
--error ER_TABLEACCESS_DENIED_ERROR
handler t open;
connection default;
grant select (a) on db.t to u@localhost;
connection con1;
set time_zone= '+00:00';
select row_start, row_end from t;
handler t open;
--replace_column 6 #
handler t read first;
handler t close;
disconnect con1;
connection default;
drop user u@localhost;
drop database db;
--echo # End of 10.11 tests
--source include/wait_until_count_sessions.inc

View File

@@ -0,0 +1,17 @@
# Forces HANDLER tables of connection con1 to be reopened on next read:
# $ddl (exclusive MDL) waits for con1 to close the handler table, which
# happens when con1 opens any other table.
# Expects connection con1 to exist and con2 not to exist.
connect con2, localhost, root;
send_eval $ddl;
connection default;
let $wait_condition= select count(*) = 1 from information_schema.processlist
where state = 'Waiting for table metadata lock' and info = '$ddl';
--source include/wait_condition.inc
connection con1;
select 1 from information_schema.character_sets limit 1;
connection con2;
reap;
disconnect con2;
connection con1;

View File

@@ -1,4 +1,4 @@
call mtr.add_suppression("\\[Warning\\] (mysqld|mariadbd): Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEMLOCK) page size [0-9]+\\).*");
call mtr.add_suppression("\\[Warning\\] mariadbd: Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEM_LARGE_PAGES|MEMLOCK) page size [0-9]+\\).*");
call mtr.add_suppression("\\[ERROR\\]*Lock Pages in memory access rights required.*");
create table t1 (
a int not null auto_increment,

View File

@@ -2,7 +2,7 @@
--source include/have_innodb.inc
call mtr.add_suppression("\\[Warning\\] (mysqld|mariadbd): Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEMLOCK) page size [0-9]+\\).*");
call mtr.add_suppression("\\[Warning\\] mariadbd: Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEM_LARGE_PAGES|MEMLOCK) page size [0-9]+\\).*");
call mtr.add_suppression("\\[ERROR\\]*Lock Pages in memory access rights required.*");
create table t1 (
a int not null auto_increment,

View File

@@ -850,6 +850,20 @@ create table t(c int primary key, c2 blob unique) engine=innodb;
insert into t values (0, '');
replace into t values (0, '123');
drop table t;
#
# MDEV-30441 ASAN heap-use-after-free in Field_blob::pack/pack_row
#
create table t1 (a blob, va mediumtext as (a) stored, b varchar(3845),
unique key (b, va(64)))
engine=innodb default charset=utf8mb3;
insert into t1 (a, b) values ('111', '222');
delete from t1 order by b limit 1;
drop table t1;
create table t (a blob, b text as (a) stored, unique (b))
engine=innodb character set utf8mb3
as select 'x' as a;
delete from t;
drop table t;
# End of 10.11 tests
#
# MDEV-39559: Assertion `b` failed in `my_strnncoll_xxxx_nopad_ci`

View File

@@ -776,6 +776,22 @@ insert into t values (0, '');
replace into t values (0, '123');
drop table t;
--echo #
--echo # MDEV-30441 ASAN heap-use-after-free in Field_blob::pack/pack_row
--echo #
create table t1 (a blob, va mediumtext as (a) stored, b varchar(3845),
unique key (b, va(64)))
engine=innodb default charset=utf8mb3;
insert into t1 (a, b) values ('111', '222');
delete from t1 order by b limit 1;
drop table t1;
create table t (a blob, b text as (a) stored, unique (b))
engine=innodb character set utf8mb3
as select 'x' as a;
delete from t;
drop table t;
--echo # End of 10.11 tests
--echo #

View File

@@ -10,6 +10,13 @@ call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'");
call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example.com'");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
FOUND 1 /Host '192\.0\.2\.222' is not allowed to connect to this MariaDB server/ in mysqld.1.err
ok
# cat MYSQL_TMP_DIR/test_wl4435.out.log

View File

@@ -17,6 +17,12 @@ call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'");
call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example.com'");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
# We run with different binaries for normal and --embedded-server
#
@@ -28,6 +34,12 @@ call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example.
--write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test.out.log
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
# MDEV-40967: test_proxy_header_host_denied() must have caused this to be
# logged (log_warnings defaults to 2).
--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let SEARCH_PATTERN= Host '192\.0\.2\.222' is not allowed to connect to this MariaDB server
--source include/search_pattern_in_file.inc
# End of 4.1 tests
echo ok;

View File

@@ -1,5 +1,11 @@
SET @old_slow_query_log= @@global.slow_query_log;
call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'");
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
ok
SET @@global.slow_query_log= @old_slow_query_log;

View File

@@ -12,6 +12,12 @@ SET @old_slow_query_log= @@global.slow_query_log;
call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'");
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
--write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log 2>&1

View File

@@ -2,6 +2,12 @@ SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_log;
call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'");
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
ok
SET @@global.general_log= @old_general_log;
SET @@global.slow_query_log= @old_slow_query_log;

View File

@@ -11,6 +11,12 @@ SET @old_general_log= @@global.general_log;
SET @old_slow_query_log= @@global.slow_query_log;
call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'");
call mtr.add_suppression(" IP address .* could not be resolved");
call mtr.add_suppression("Failed to parse proxy header");
call mtr.add_suppression("Proxy header is not accepted from ");
call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors");
call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors");
call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server");
call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server");
# We run with different binaries for normal and --embedded-server
#

View File

@@ -787,8 +787,8 @@ The following specify which files/extra groups are read (specified before remain
MySQL versions. Any combination of: NO_DUP_KEY_WARNINGS_WITH_IGNORE,
NO_PROGRESS_INFO, ZERO_DATE_TIME_CAST, UTF8_IS_UTF8MB3, IGNORE_INDEX_ONLY_FOR_JOIN,
COMPAT_5_1_CHECKSUM, NO_NULL_COLLATION_IDS, LOCK_ALTER_TABLE_COPY,
OLD_FLUSH_STATUS, SESSION_USER_IS_USER, or ALL to set all
combinations
OLD_FLUSH_STATUS, SESSION_USER_IS_USER, X509_LENIENT_COMPARE,
or ALL to set all combinations
--old-passwords Use old password encryption method (needed for 4.0 and
older clients)
--old-style-user-limits

View File

@@ -216,7 +216,7 @@ CHANGE MASTER '' TO MASTER_HOST='master''host', MASTER_PORT=3306, MASTER_LOG_FIL
-- SET GLOBAL gtid_slave_pos='';
call mtr.add_suppression('Slave I/O: Fatal error: .* Connection attempt terminated');
reset slave;
reset slave all;
Warnings:
Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos'
change master to master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0;

View File

@@ -79,7 +79,7 @@ exec $MYSQL_DUMP --compact --dump-slave --include-master-host-port test;
# cleanup after mariadb-dump executed START SLAVE
call mtr.add_suppression('Slave I/O: Fatal error: .* Connection attempt terminated');
reset slave;
reset slave all;
change master to master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0;
--echo # End of 10.6 tests

View File

@@ -55,13 +55,18 @@ Multiple variables: 10 * 20 / 10 = 20
# ----------------------------------------------------------------------------
# Overflow edge cases
# ----------------------------------------------------------------------------
-9223372036854775808 / -1 -> -9223372036854775808
-9223372036854775808 / -1 -> error
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/'
-9223372036854775808 % -1 -> 0
-(-9223372036854775808) -> -9223372036854775808
-(-9223372036854775808) -> error
mysqltest: At line 1: Evaluation error: Signed integer overflow in unary '-'
-4611686018427387904 * 2 -> -9223372036854775808
-4611686018427387904 * 2 / -1 -> -9223372036854775808
-4611686018427387904 * -2 / -1 -> -9223372036854775808
18446744073709551615 / 2 / -1 -> 0
-4611686018427387904 * 2 / -1 -> error
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/'
-4611686018427387904 * -2 / -1 -> error
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '*'
18446744073709551615 / 2 / -1 -> error
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/'
# ----------------------------------------------------------------------------
# Comparison operators
# ----------------------------------------------------------------------------
@@ -505,6 +510,15 @@ mysqltest: At line 1: Evaluation error: Modulo by zero
# Test case: Overflow
mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type
mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type
# Signed arithmetic overflow
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '+'
mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '-'
mysqltest: At line 1: Evaluation error: Signed integer overflow in abs()
# Unsigned overflow
mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '+'
mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '*'
mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '*'
mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '+'
#
# MDEV-37865: IF() function is returning incorrect error
#

View File

@@ -112,13 +112,23 @@ let $multi_var = $($var_a * $var_b / $var_a);
--echo # Overflow edge cases
--echo # ----------------------------------------------------------------------------
--echo -9223372036854775808 / -1 -> $(-9223372036854775808 / -1)
--echo -9223372036854775808 / -1 -> error
--error 1
--exec echo "let \$a = \$(-9223372036854775808 / -1);" | $MYSQL_TEST 2>&1
--echo -9223372036854775808 % -1 -> $(-9223372036854775808 % -1)
--echo -(-9223372036854775808) -> $(-(-9223372036854775808))
--echo -(-9223372036854775808) -> error
--error 1
--exec echo "let \$a = \$(-(-9223372036854775808));" | $MYSQL_TEST 2>&1
--echo -4611686018427387904 * 2 -> $(-4611686018427387904 * 2)
--echo -4611686018427387904 * 2 / -1 -> $(-4611686018427387904 * 2 / -1)
--echo -4611686018427387904 * -2 / -1 -> $(-4611686018427387904 * -2 / -1)
--echo 18446744073709551615 / 2 / -1 -> $(18446744073709551615 / 2 / -1)
--echo -4611686018427387904 * 2 / -1 -> error
--error 1
--exec echo "let \$a = \$(-4611686018427387904 * 2 / -1);" | $MYSQL_TEST 2>&1
--echo -4611686018427387904 * -2 / -1 -> error
--error 1
--exec echo "let \$a = \$(-4611686018427387904 * -2 / -1);" | $MYSQL_TEST 2>&1
--echo 18446744073709551615 / 2 / -1 -> error
--error 1
--exec echo "let \$a = \$(18446744073709551615 / 2 / -1);" | $MYSQL_TEST 2>&1
--echo # ----------------------------------------------------------------------------
--echo # Comparison operators
@@ -894,6 +904,29 @@ let $large_xor = $(0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE);
--error 1
--exec echo "let \$a = \$(-18446744073709551616);" | $MYSQL_TEST 2>&1
--echo # Signed arithmetic overflow
--error 1
--exec echo "let \$a = \$(9223372036854775807 + 1);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$(-9223372036854775807 - 2);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$(abs(-9223372036854775808));" | $MYSQL_TEST 2>&1
--echo # Unsigned overflow
--error 1
--exec echo "let \$a = \$(18446744073709551615 + 1);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$(0x8000000000000000 * 2);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$(18446744073709551615 * 2);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "let \$a = \$((0xFFFFFFFFFFFFFFFF & 0xFFFFFFFFFFFFFFFF) + 1);" | $MYSQL_TEST 2>&1
--echo #
--echo # MDEV-37865: IF() function is returning incorrect error
--echo #

View File

@@ -32,3 +32,16 @@ a a
Warnings:
Warning 1052 Column 'a' in GROUP BY is ambiguous
drop table t;
#
# MDEV-41408 MTR prepared statement protocol skipping statements starting with '('
#
SELECT 1;
1
1
( ( SELECT 1));
1
1
SELECT $e2 - $e1 = $e1 - $e0 AS parens_same;
parens_same
1
# End of 10.11 tests

View File

@@ -32,3 +32,16 @@ select 1 + "2 a";
create table t (a int primary key, b blob default '');
select a, (2*a) AS a from t group by a;
drop table t;
--echo #
--echo # MDEV-41408 MTR prepared statement protocol skipping statements starting with '('
--echo #
let $e0= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1);
SELECT 1;
let $e1= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1);
( ( SELECT 1));
let $e2= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1);
evalp SELECT $e2 - $e1 = $e1 - $e0 AS parens_same;
--echo # End of 10.11 tests

View File

@@ -3813,6 +3813,60 @@ id key1
3 2
drop table t1;
#
# MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV
#
CREATE TABLE t1 (
c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT,
c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT,
c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT,
c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT,
c32 INT,
KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,
c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31)
);
INSERT INTO t1 (c0) VALUES (1), (2);
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32;
c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32 AND c32=33;
c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
truncate t1;
# test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF
INSERT INTO t1 (
c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31
)
SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000;
CREATE TABLE t2 (x INT);
INSERT INTO t2 VALUES (1),(2);
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status Table is already up to date
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status OK
EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32)
WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND
t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND
t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND
t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND
t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND
t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
1 SIMPLE t1 ref_or_null k32 k32 160 const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,test.t2.x 798 Using where; Using index
DROP TABLE t1, t2;
#
# End of 10.11 tests
#
set global innodb_stats_persistent= @innodb_stats_persistent_save;
@@ -3870,6 +3924,4 @@ l_orderkey
292
291
DROP TABLE lineitem;
#
# End of 11.0 tests
#

View File

@@ -1,4 +1,5 @@
--source include/no_valgrind_without_big.inc
--source include/have_sequence.inc
#
# Problem with range optimizer
#
@@ -2581,6 +2582,60 @@ evalp $query;
drop table t1;
--echo #
--echo # MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV
--echo #
CREATE TABLE t1 (
c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT,
c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT,
c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT,
c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT,
c32 INT,
KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,
c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31)
);
INSERT INTO t1 (c0) VALUES (1), (2);
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32;
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32 AND c32=33;
truncate t1;
--echo # test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF
INSERT INTO t1 (
c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31
)
SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000;
CREATE TABLE t2 (x INT);
INSERT INTO t2 VALUES (1),(2);
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32)
WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND
t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND
t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND
t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND
t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND
t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1;
DROP TABLE t1, t2;
--echo #
--echo # End of 10.11 tests
--echo #
@@ -2638,6 +2693,4 @@ EXPLAIN SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_re
SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate;
DROP TABLE lineitem;
--echo #
--echo # End of 11.0 tests
--echo #

View File

@@ -3811,6 +3811,60 @@ id key1
3 2
drop table t1;
#
# MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV
#
CREATE TABLE t1 (
c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT,
c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT,
c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT,
c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT,
c32 INT,
KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,
c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31)
);
INSERT INTO t1 (c0) VALUES (1), (2);
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32;
c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
SELECT * FROM t1
WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8
AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15
AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22
AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29
AND c29=30 AND c30=31 AND c31=32 AND c32=33;
c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
truncate t1;
# test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF
INSERT INTO t1 (
c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31
)
SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000;
CREATE TABLE t2 (x INT);
INSERT INTO t2 VALUES (1),(2);
ANALYZE TABLE t1, t2 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status Table is already up to date
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status OK
EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32)
WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND
t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND
t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND
t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND
t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND
t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
1 SIMPLE t1 ref_or_null k32 k32 160 const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,test.t2.x 798 Using where; Using index
DROP TABLE t1, t2;
#
# End of 10.11 tests
#
set global innodb_stats_persistent= @innodb_stats_persistent_save;
@@ -3868,7 +3922,5 @@ l_orderkey
292
291
DROP TABLE lineitem;
#
# End of 11.0 tests
#
set optimizer_switch=@mrr_icp_extra_tmp;

View File

@@ -2340,10 +2340,40 @@ TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT,
TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT,
TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT
) ENGINE=InnoDB;
insert into t1 (
TEXT1, TEXT2, TEXT3, TEXT4, TEXT5,
TEXT6, TEXT7, TEXT8, TEXT9, TEXT10,
TEXT11, TEXT12,TEXT13,TEXT14,TEXT15,
TEXT16,TEXT17,TEXT18,TEXT19,TEXT20,
TEXT21,TEXT22,TEXT23,TEXT24,TEXT25,
TEXT26,TEXT27,TEXT28,TEXT29,TEXT30,
TEXT31,TEXT32,TEXT33,TEXT34,TEXT35,
TEXT36,TEXT37,TEXT38,TEXT39,TEXT40,
TEXT41,TEXT42,TEXT43,TEXT44,TEXT45,
TEXT46,TEXT47,TEXT48,TEXT49,TEXT50
) values (
"TEXT1", "TEXT2", "TEXT3", "TEXT4", "TEXT5",
"TEXT6", "TEXT7", "TEXT8", "TEXT9", "TEXT10",
"TEXT11", "TEXT12","TEXT13","TEXT14","TEXT15",
"TEXT16","TEXT17","TEXT18","TEXT19","TEXT20",
"TEXT21","TEXT22","TEXT23","TEXT24","TEXT25",
"TEXT26","TEXT27","TEXT28","TEXT29","TEXT30",
"TEXT31","TEXT32","TEXT33","TEXT34","TEXT35",
"TEXT36","TEXT37","TEXT38","TEXT39","TEXT40",
"TEXT41","TEXT42","TEXT43","TEXT44","TEXT45",
"TEXT46","TEXT47","TEXT48","TEXT49","TEXT50"
);
# A second row, differing only in a column outside the hash key
INSERT INTO t1 SELECT * FROM t1;
UPDATE t1 SET TEXT50= 'X' LIMIT 1;
SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
1
1
1
EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where
1 SIMPLE t2 hash_ALL NULL #hash#$hj 150 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32,test.t1.TEXT33,test.t1.TEXT34,test.t1.TEXT35,test.t1.TEXT36,test.t1.TEXT37,test.t1.TEXT38,test.t1.TEXT39,test.t1.TEXT40,test.t1.TEXT41,test.t1.TEXT42,test.t1.TEXT43,test.t1.TEXT44,test.t1.TEXT45,test.t1.TEXT46,test.t1.TEXT47,test.t1.TEXT48,test.t1.TEXT49,test.t1.TEXT50 1 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t2 hash_ALL NULL #hash#$hj 96 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32 2 Using where; Using join buffer (flat, BNLH join)
set join_cache_level=@tmp_jcl;
drop table t1;
#

View File

@@ -211,6 +211,7 @@ drop table t1;
--echo #
SET join_cache_level=3;
CREATE TABLE t1 (
TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT,
TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT,
@@ -223,6 +224,36 @@ CREATE TABLE t1 (
TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT,
TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT
) ENGINE=InnoDB;
insert into t1 (
TEXT1, TEXT2, TEXT3, TEXT4, TEXT5,
TEXT6, TEXT7, TEXT8, TEXT9, TEXT10,
TEXT11, TEXT12,TEXT13,TEXT14,TEXT15,
TEXT16,TEXT17,TEXT18,TEXT19,TEXT20,
TEXT21,TEXT22,TEXT23,TEXT24,TEXT25,
TEXT26,TEXT27,TEXT28,TEXT29,TEXT30,
TEXT31,TEXT32,TEXT33,TEXT34,TEXT35,
TEXT36,TEXT37,TEXT38,TEXT39,TEXT40,
TEXT41,TEXT42,TEXT43,TEXT44,TEXT45,
TEXT46,TEXT47,TEXT48,TEXT49,TEXT50
) values (
"TEXT1", "TEXT2", "TEXT3", "TEXT4", "TEXT5",
"TEXT6", "TEXT7", "TEXT8", "TEXT9", "TEXT10",
"TEXT11", "TEXT12","TEXT13","TEXT14","TEXT15",
"TEXT16","TEXT17","TEXT18","TEXT19","TEXT20",
"TEXT21","TEXT22","TEXT23","TEXT24","TEXT25",
"TEXT26","TEXT27","TEXT28","TEXT29","TEXT30",
"TEXT31","TEXT32","TEXT33","TEXT34","TEXT35",
"TEXT36","TEXT37","TEXT38","TEXT39","TEXT40",
"TEXT41","TEXT42","TEXT43","TEXT44","TEXT45",
"TEXT46","TEXT47","TEXT48","TEXT49","TEXT50"
);
--echo # A second row, differing only in a column outside the hash key
INSERT INTO t1 SELECT * FROM t1;
UPDATE t1 SET TEXT50= 'X' LIMIT 1;
SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2;
set join_cache_level=@tmp_jcl;

View File

@@ -313,7 +313,7 @@ EXPLAIN
SELECT * FROM t1 AS a NATURAL JOIN t1 AS b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ALL NULL NULL NULL NULL 5 Using where
1 SIMPLE b hash_ALL NULL #hash#$hj 1341 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv,test.a.Delete_history_priv,test.a.ssl_type,test.a.ssl_cipher,test.a.x509_issuer,test.a.x509_subject,test.a.max_questions,test.a.max_updates,test.a.max_connections,test.a.max_user_connections,test.a.plugin,test.a.authentication_string,test.a.password_expired,test.a.is_role,test.a.default_role,test.a.max_statement_time 5 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE b hash_ALL NULL #hash#$hj 1268 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv 5 Using where; Using join buffer (flat, BNLH join)
DROP TABLE t1,t2,t3;
#
# MDEV-30529: Assertion `rnd_records <= s->found_records' failed in best_access_path

View File

@@ -6,3 +6,26 @@ set @old_dbug=@@global.debug_dbug;
set global debug_dbug='+d,CONNECT_wait';
select variable_value into @cons from information_schema.global_status where variable_name='connections';
# restart
#
# MDEV-25176 Shutdown hangs if event scheduler is started during shutdown
#
set global event_scheduler= 1;
connect con1, localhost, root;
set global debug_dbug= '+d,only_kill_system_threads';
shutdown;
disconnect con1;
connection default;
set global event_scheduler= 1;
# Must be 0: the scheduler is not started after Events::stop()
select count(*) as scheduler_started from information_schema.processlist
where user = 'event_scheduler';
scheduler_started
0
# ON: the skipped start reports no error
select @@global.event_scheduler;
@@global.event_scheduler
ON
set global event_scheduler= 0;
disconnect default;
connect default, localhost, root;
# End of 10.11 tests

View File

@@ -1,5 +1,7 @@
source include/not_embedded.inc;
source include/have_debug.inc;
# IO::Socket::UNIX in MDEV-25176
source include/not_windows.inc;
-- source include/no_view_protocol.inc
--echo #
@@ -15,3 +17,65 @@ exec $MYSQL -e "select sleep(3600)" >/dev/null 2>&1 &;
let $wait_condition= select variable_value>@cons from information_schema.global_status where variable_name='connections';
source include/wait_condition.inc;
source include/restart_mysqld.inc;
--echo #
--echo # MDEV-25176 Shutdown hangs if event scheduler is started during shutdown
--echo #
# How it works: the test starts the scheduler, then con1 sets
# only_kill_system_threads and does SHUTDOWN, so kill phase 1 of
# close_connections() leaves default connection alive. When the
# scheduler is gone from processlist, Events::stop() is done and default
# connection tries to start it again by setting event_scheduler= 1.
#
# With the bug Events::stop() works normally, so wait_condition does not
# halt, but the scheduler starts again (count 1) and shutdown would wait
# for it forever, so default connection stops it by setting
# event_scheduler= 0 before disconnecting. Then the test waits for the
# server to restart.
set global event_scheduler= 1;
let $wait_condition= select count(*) = 1 from information_schema.processlist
where user = 'event_scheduler';
source include/wait_condition.inc;
let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')`;
let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect;
write_line wait $_expect_file_name;
# Kill phase 1 of close_connections() skips client threads.
connect con1, localhost, root;
set global debug_dbug= '+d,only_kill_system_threads';
# shutdown_mysqld.inc cannot be used from con1 as it deadlocks: it waits
# for the server to exit, while the server waits for default connection
# to disconnect. The deadlock ends with the server killed by timeout and
# the bug is never checked.
shutdown;
disconnect con1;
# close_connections() did Events::stop()
connection default;
let $wait_condition= select count(*) = 0 from information_schema.processlist
where user = 'event_scheduler';
source include/wait_condition.inc;
set global event_scheduler= 1;
--echo # Must be 0: the scheduler is not started after Events::stop()
select count(*) as scheduler_started from information_schema.processlist
where user = 'event_scheduler';
--echo # ON: the skipped start reports no error
select @@global.event_scheduler;
set global event_scheduler= 0;
write_line restart $_expect_file_name;
disconnect default;
# Restart failure or hang is caught by --start-timeout or --testcase-timeout
perl;
use IO::Socket::UNIX;
until (IO::Socket::UNIX->new(Peer => $ENV{MASTER_MYSOCK}))
{
select(undef, undef, undef, 0.1);
}
EOF
connect default, localhost, root;
--echo # End of 10.11 tests

View File

@@ -2755,6 +2755,30 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1);
c
0
DROP TABLE t1;
#
# MDEV-24907: Empty the source list after merging an Item_equal
#
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0,0);
CREATE TABLE t2 (c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (2),(0);
CREATE TABLE t3 (d INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (1),(3);
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b NOT IN (SELECT d FROM t3)
) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b;
a b c d
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b > 3
) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND
t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND
t1.a = t1.b;
a b c d
DROP TABLE t1, t2, t3;
# end of 10.11 tests
#
# MDEV-41303 rand() in a semi-join subquery is checked on outer rows

View File

@@ -2781,6 +2781,30 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1);
c
0
DROP TABLE t1;
#
# MDEV-24907: Empty the source list after merging an Item_equal
#
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0,0);
CREATE TABLE t2 (c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (2),(0);
CREATE TABLE t3 (d INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (1),(3);
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b NOT IN (SELECT d FROM t3)
) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b;
a b c d
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b > 3
) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND
t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND
t1.a = t1.b;
a b c d
DROP TABLE t1, t2, t3;
# end of 10.11 tests
#
# MDEV-41303 rand() in a semi-join subquery is checked on outer rows

View File

@@ -2479,6 +2479,33 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1);
DROP TABLE t1;
--echo #
--echo # MDEV-24907: Empty the source list after merging an Item_equal
--echo #
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0,0);
CREATE TABLE t2 (c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (2),(0);
CREATE TABLE t3 (d INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (1),(3);
# Result should be empty.
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b NOT IN (SELECT d FROM t3)
) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b;
SELECT * FROM t1 LEFT JOIN (
t2 JOIN t3 ON (t3.d = t2.c)
) ON (
t1.b > 3
) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND
t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND
t1.a = t1.b;
DROP TABLE t1, t2, t3;
--echo # end of 10.11 tests
--echo #

View File

@@ -107,3 +107,38 @@ SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t;
SUM(DISTINCT a)
NULL
DROP TABLE t1;
#
# MDEV-39194: SUM DISTINCT of a bit literal
#
SELECT SUM(DISTINCT b'1100') AS r;
r
12
SELECT SUM(DISTINCT b'00000000') AS zero_value,
SUM(DISTINCT b'11111111') AS byte_value,
SUM(DISTINCT b'100000000') AS two_byte_value;
zero_value byte_value two_byte_value
0 255 256
SELECT SUM(DISTINCT 0xff) AS hex_value,
AVG(DISTINCT b'1100') = 12 AS bit_average_is_12;
hex_value bit_average_is_12
255 1
SELECT SUM(DISTINCT 0xffffffffffffffff) = SUM(0xffffffffffffffff)
AS unsigned_sum_matches,
AVG(DISTINCT 0xffffffffffffffff) = AVG(0xffffffffffffffff)
AS unsigned_average_matches;
unsigned_sum_matches unsigned_average_matches
1 1
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1), (2,1), (3,1);
SELECT SUM(DISTINCT b'1100') AS bit_sum,
AVG(DISTINCT b'1100') = 12 AS bit_average_is_12,
COUNT(DISTINCT b'1100') AS bit_count FROM t1;
bit_sum bit_average_is_12 bit_count
12 1 1
SELECT AVG(DISTINCT b / a) AS decimal_average FROM t1;
decimal_average
0.61110000
DROP TABLE t1;
#
# End of 11.4 tests
#

View File

@@ -105,3 +105,30 @@ SELECT SUM(DISTINCT a) FROM t1;
SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t;
DROP TABLE t1;
--echo #
--echo # MDEV-39194: SUM DISTINCT of a bit literal
--echo #
SELECT SUM(DISTINCT b'1100') AS r;
SELECT SUM(DISTINCT b'00000000') AS zero_value,
SUM(DISTINCT b'11111111') AS byte_value,
SUM(DISTINCT b'100000000') AS two_byte_value;
SELECT SUM(DISTINCT 0xff) AS hex_value,
AVG(DISTINCT b'1100') = 12 AS bit_average_is_12;
SELECT SUM(DISTINCT 0xffffffffffffffff) = SUM(0xffffffffffffffff)
AS unsigned_sum_matches,
AVG(DISTINCT 0xffffffffffffffff) = AVG(0xffffffffffffffff)
AS unsigned_average_matches;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1), (2,1), (3,1);
SELECT SUM(DISTINCT b'1100') AS bit_sum,
AVG(DISTINCT b'1100') = 12 AS bit_average_is_12,
COUNT(DISTINCT b'1100') AS bit_count FROM t1;
# DISTINCT inputs keep the argument's decimal scale, not AVG's result scale.
SELECT AVG(DISTINCT b / a) AS decimal_average FROM t1;
DROP TABLE t1;
--echo #
--echo # End of 11.4 tests
--echo #

View File

@@ -0,0 +1,16 @@
--- main/x509_oneline_separators.result
+++ main/x509_oneline_separators.reject
@@ -6,10 +6,10 @@
# Default old_mode: only one grant matches, library-dependent
#
# connect as escaped_user
-connect_test
-escaped_user@localhost connected
+ERROR 1045 (28000): Access denied for user 'escaped_user'@'localhost' (using password: NO)
# connect as raw_user
-ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO)
+connect_test
+raw_user@localhost connected
#
# old_mode=X509_LENIENT_COMPARE: both grants now match
#

View File

@@ -0,0 +1,16 @@
--- main/x509_oneline_separators.result
+++ main/x509_oneline_separators.reject
@@ -6,10 +6,10 @@
# Default old_mode: only one grant matches, library-dependent
#
# connect as escaped_user
-connect_test
-escaped_user@localhost connected
+ERROR 1045 (28000): Access denied for user 'escaped_user'@'localhost' (using password: NO)
# connect as raw_user
-ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO)
+connect_test
+raw_user@localhost connected
#
# old_mode=X509_LENIENT_COMPARE: both grants now match
#

View File

@@ -0,0 +1,5 @@
[wolfssl]
[openssl_1]
[openssl_3_or_later]

View File

@@ -0,0 +1,27 @@
create user escaped_user@localhost
require subject '/CN=a\\/b\\+c';
create user raw_user@localhost
require subject '/CN=a/b+c';
#
# Default old_mode: only one grant matches, library-dependent
#
# connect as escaped_user
connect_test
escaped_user@localhost connected
# connect as raw_user
ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO)
#
# old_mode=X509_LENIENT_COMPARE: both grants now match
#
set @old_mode_save= @@global.old_mode;
set global old_mode= concat(@@global.old_mode, ',X509_LENIENT_COMPARE');
Warnings:
Warning 1287 'X509_LENIENT_COMPARE' is deprecated and will be removed in a future release
# connect as escaped_user
connect_test
escaped_user@localhost connected
# connect as raw_user
connect_test
raw_user@localhost connected
set global old_mode= @old_mode_save;
drop user escaped_user@localhost, raw_user@localhost;

View File

@@ -0,0 +1,54 @@
#
# MDEV-41008 Parsing of forward slash '/' and plus '+' behaving
# differently between OpenSSL 3 vs OpenSSL 1 vs WolfSSL
#
# Real certificate whose subject has a single RDN, value "a/b+c" (literal
# '/' and '+' inside the value, not separators). A library that escapes
# (OpenSSL >= 3.0) renders this as /CN=a\/b\+c. One that doesn't (WolfSSL,
# OpenSSL < 3.0) renders it raw: /CN=a/b+c.
#
--source include/have_ssl_communication.inc
--source include/not_embedded.inc
let $lib_combination= `SELECT IF(@@version_ssl_library LIKE 'WolfSSL%', 'wolfssl',
IF(NATURAL_SORT_KEY(@@version_ssl_library) < NATURAL_SORT_KEY('OpenSSL 3.0.0'),
'openssl_1', 'openssl_3_or_later'))`;
if ($MTR_COMBINATIONS != $lib_combination)
{
skip Needs SSL library '$lib_combination';
}
let $MYSQL_CLIENT= $MYSQL --ssl-key=$MYSQL_TEST_DIR/std_data/client-slash-cn-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-slash-cn-cert.pem --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem;
create user escaped_user@localhost
require subject '/CN=a\\/b\\+c';
create user raw_user@localhost
require subject '/CN=a/b+c';
--echo #
--echo # Default old_mode: only one grant matches, library-dependent
--echo #
--disable_abort_on_error
--echo # connect as escaped_user
--exec $MYSQL_CLIENT --user=escaped_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1
--echo # connect as raw_user
--exec $MYSQL_CLIENT --user=raw_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1
--enable_abort_on_error
--echo #
--echo # old_mode=X509_LENIENT_COMPARE: both grants now match
--echo #
set @old_mode_save= @@global.old_mode;
set global old_mode= concat(@@global.old_mode, ',X509_LENIENT_COMPARE');
--disable_abort_on_error
--echo # connect as escaped_user
--exec $MYSQL_CLIENT --user=escaped_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1
--echo # connect as raw_user
--exec $MYSQL_CLIENT --user=raw_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1
--enable_abort_on_error
set global old_mode= @old_mode_save;
drop user escaped_user@localhost, raw_user@localhost;

View File

@@ -2321,6 +2321,19 @@ sub environment_setup {
$ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy;
}
# ----------------------------------------------------
# wsrep_notify (shipped example wsrep_notify_cmd script; tests point
# wsrep_notify_cmd at this instead of keeping a private std_data copy)
# ----------------------------------------------------
my $wsrep_notify=
mtr_pl_maybe_exists("$bindir/support-files/wsrep_notify") ||
mtr_pl_maybe_exists("$bindir/share/mariadb/wsrep_notify") ||
mtr_pl_maybe_exists("$bindir/share/mysql/wsrep_notify");
if ($wsrep_notify)
{
$ENV{'WSREP_NOTIFY_CMD'}= $wsrep_notify;
}
# ----------------------------------------------------
# perror
# ----------------------------------------------------

View File

@@ -0,0 +1,118 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB
Validity
Not Before: Sep 28 18:02:52 2026 GMT
Not After : Sep 23 18:02:52 2046 GMT
Subject: CN=a\/b\+c
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:86:2d:e1:df:5e:f0:6f:7f:11:95:72:3f:61:4c:
a1:f7:3f:c8:16:cd:37:1a:5b:00:fc:99:fd:2b:68:
f7:d5:87:f9:41:05:8e:97:73:0a:11:c8:6d:bb:f7:
68:dd:8d:b3:15:8f:db:aa:45:94:d0:b0:ad:55:91:
dd:36:34:a1:f7:e8:e8:69:a1:6e:78:0f:a1:45:06:
28:cc:5a:1d:bb:06:6f:c5:9b:dd:b5:a2:7a:31:25:
23:05:bf:91:a0:e3:25:b4:3b:58:df:b5:9d:7d:16:
11:aa:09:41:38:3d:3b:89:0d:59:b5:1d:4b:4d:25:
0d:e8:f0:a0:8e:8b:b4:48:bb:8b:25:79:93:6d:31:
55:7a:be:2d:df:8a:6d:76:ba:56:ce:c2:7a:9f:30:
30:f8:a5:4b:f5:79:ac:39:8c:50:0e:4f:b0:3d:52:
e3:c9:ff:3e:e1:ee:27:76:1e:a6:74:35:a4:87:05:
ec:44:5b:d9:a7:b0:82:82:14:b9:e1:e9:93:1f:10:
a0:93:67:76:a5:f8:02:79:b5:32:57:3a:7c:bc:1c:
69:44:ad:a4:6a:d2:0d:fd:40:f9:a2:9d:37:09:eb:
1d:f0:56:22:16:82:e3:87:6b:fc:68:08:00:88:cb:
9d:29:7e:9e:c1:15:3d:22:19:0a:7b:fb:8a:67:a6:
6c:99:a0:95:f6:b8:fc:e3:7a:36:35:ef:63:2a:5c:
8f:5b:a4:d9:57:ec:9a:ae:a1:8a:2c:0f:16:70:75:
54:35:99:13:a0:87:e0:af:90:52:67:f2:ee:85:c9:
f0:02:c5:b5:e2:58:93:a8:c8:13:63:a8:f6:8b:9b:
1a:a5:91:63:bf:b8:ec:65:24:46:bd:93:61:8b:55:
20:76:5c:e4:22:28:55:3c:0e:f5:f6:c0:29:4c:ba:
49:46:88:52:bf:78:51:7b:5a:1f:f4:9d:34:cf:c4:
8d:84:c6:ce:2a:15:0c:97:ad:c4:b9:51:6f:fd:81:
cf:db:c2:c5:5a:8f:21:52:8e:d7:d0:2f:09:41:26:
2d:53:26:e5:1d:82:f1:e6:0d:7e:51:f8:0f:6a:5c:
60:91:0d:c0:29:95:5a:dd:b2:dc:f4:ee:34:94:ae:
6c:07:9f:93:99:5d:9d:6f:34:25:be:05:d5:6c:fd:
56:c1:3b:2b:d3:41:e2:14:94:28:00:bb:d1:9d:5b:
70:3a:4e:83:2d:1e:b4:cb:6e:af:64:dc:02:f9:b4:
4a:4c:e2:f3:f8:be:22:9d:18:9b:ac:fe:fc:d8:0f:
58:34:ae:0d:0e:ac:f5:6c:c2:fd:b8:3a:a4:3d:5a:
14:0d:26:8d:55:8f:30:8a:63:3f:e5:6b:58:36:27:
4e:9e:b1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
93:EC:3D:13:75:A3:A1:3F:E0:01:F0:4C:DF:EE:D5:AA:D7:76:6A:28
X509v3 Authority Key Identifier:
4D:FC:7A:19:F3:2B:0C:7D:F6:C0:7C:4D:F8:72:34:4C:8C:35:52:74
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
10:9e:44:ec:2f:81:62:86:42:69:e1:8e:11:3d:bc:ae:79:bf:
d4:04:1c:45:9e:19:71:d0:ed:78:3c:53:ee:0a:8f:b3:af:96:
24:f5:cc:ac:49:13:73:05:f9:f3:37:bd:bd:06:97:01:2b:6c:
8e:27:80:b4:c8:fb:47:7c:f2:55:4b:c7:b0:d4:25:fb:35:c0:
17:ce:ac:4f:71:a7:5c:4f:a8:7f:91:21:2b:cc:d5:cf:99:63:
3c:b1:bf:c0:98:14:66:12:22:bc:f9:f9:3d:7d:ec:17:65:b5:
f9:04:1d:cb:76:a9:22:15:dd:29:4e:23:e0:94:7f:14:e2:5d:
5a:97:96:e6:c4:5b:3d:ab:d1:8f:dd:bc:be:96:11:65:6e:1b:
02:c2:a9:a3:f0:44:bb:37:5d:08:80:99:41:8a:76:60:18:fe:
46:2d:cc:5d:8d:84:ba:7e:c9:d3:82:21:e8:f9:07:10:ec:0b:
2d:99:2f:5c:b9:51:e9:2a:bf:ea:db:05:06:6d:e4:2d:41:e7:
72:bc:1b:16:dd:71:38:50:ed:a4:97:d6:76:b5:23:84:4c:67:
72:c9:7a:a4:d9:8a:00:ce:1e:3f:db:09:84:80:ba:94:f8:6c:
16:02:dc:95:8c:bd:ab:bb:00:d0:d8:cb:84:e7:15:aa:81:a3:
09:70:97:37:52:4c:2d:08:6b:38:aa:ba:e6:eb:67:ea:01:ec:
77:ca:81:78:b5:95:f6:87:3c:0f:a7:b8:20:ba:fd:df:aa:5e:
c6:0d:39:67:47:93:12:e6:2a:b9:4e:4d:19:b0:bb:dc:5e:5e:
70:ea:1e:d4:e3:29:ca:2c:3f:e4:c8:ea:a2:3d:e8:a2:82:6b:
56:dd:d4:e4:19:e2:d4:01:8b:08:13:13:75:4e:af:d1:cf:cf:
24:b9:9d:a3:b4:8e:86:27:93:07:07:63:fb:4a:c9:c1:9a:10:
26:51:83:b1:1f:1d:0c:0e:ca:0e:a0:1a:f7:77:73:05:93:eb:
cc:06:8d:66:2b:43:e2:81:6f:03:20:bc:39:5e:ec:09:1e:9d:
ce:8b:e1:26:47:30:63:22:03:80:7e:f2:05:2c:47:c2:fc:da:
c4:c4:fa:81:d8:b8:2c:67:11:4d:1b:7b:0e:65:97:7c:4e:1c:
64:c9:87:6b:22:65:79:f9:9d:fc:9c:9a:63:a2:08:a8:a2:f9:
79:bb:94:3c:b1:57:d1:ed:54:a5:82:62:c7:ce:b9:b7:db:d8:
40:cd:5e:6c:ca:95:ac:5f:af:de:31:bb:6f:08:f4:e1:35:72:
1b:cf:f5:9a:27:8e:dd:31:37:70:b1:6a:ca:9c:93:26:ab:36:
85:9a:89:de:1b:53:8e:95
-----BEGIN CERTIFICATE-----
MIIFLjCCAxagAwIBAgIBATANBgkqhkiG9w0BAQsFADBWMQ8wDQYDVQQDDAZjYWNl
cnQxCzAJBgNVBAYTAkZJMREwDwYDVQQIDAhIZWxzaW5raTERMA8GA1UEBwwISGVs
c2lua2kxEDAOBgNVBAoMB01hcmlhREIwHhcNMjYwOTI4MTgwMjUyWhcNNDYwOTIz
MTgwMjUyWjAQMQ4wDAYDVQQDDAVhL2IrYzCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAIYt4d9e8G9/EZVyP2FMofc/yBbNNxpbAPyZ/Sto99WH+UEFjpdz
ChHIbbv3aN2NsxWP26pFlNCwrVWR3TY0offo6GmhbngPoUUGKMxaHbsGb8Wb3bWi
ejElIwW/kaDjJbQ7WN+1nX0WEaoJQTg9O4kNWbUdS00lDejwoI6LtEi7iyV5k20x
VXq+Ld+KbXa6Vs7Cep8wMPilS/V5rDmMUA5PsD1S48n/PuHuJ3YepnQ1pIcF7ERb
2aewgoIUueHpkx8QoJNndqX4Anm1Mlc6fLwcaUStpGrSDf1A+aKdNwnrHfBWIhaC
44dr/GgIAIjLnSl+nsEVPSIZCnv7imembJmglfa4/ON6NjXvYypcj1uk2Vfsmq6h
iiwPFnB1VDWZE6CH4K+QUmfy7oXJ8ALFteJYk6jIE2Oo9oubGqWRY7+47GUkRr2T
YYtVIHZc5CIoVTwO9fbAKUy6SUaIUr94UXtaH/SdNM/EjYTGzioVDJetxLlRb/2B
z9vCxVqPIVKO19AvCUEmLVMm5R2C8eYNflH4D2pcYJENwCmVWt2y3PTuNJSubAef
k5ldnW80Jb4F1Wz9VsE7K9NB4hSUKAC70Z1bcDpOgy0etMtur2TcAvm0Skzi8/i+
Ip0Ym6z+/NgPWDSuDQ6s9WzC/bg6pD1aFA0mjVWPMIpjP+VrWDYnTp6xAgMBAAGj
TTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFJPsPRN1o6E/4AHwTN/u1arXdmooMB8G
A1UdIwQYMBaAFE38ehnzKwx99sB8TfhyNEyMNVJ0MA0GCSqGSIb3DQEBCwUAA4IC
AQAQnkTsL4FihkJp4Y4RPbyueb/UBBxFnhlx0O14PFPuCo+zr5Yk9cysSRNzBfnz
N729BpcBK2yOJ4C0yPtHfPJVS8ew1CX7NcAXzqxPcadcT6h/kSErzNXPmWM8sb/A
mBRmEiK8+fk9fewXZbX5BB3LdqkiFd0pTiPglH8U4l1al5bmxFs9q9GP3by+lhFl
bhsCwqmj8ES7N10IgJlBinZgGP5GLcxdjYS6fsnTgiHo+QcQ7AstmS9cuVHpKr/q
2wUGbeQtQedyvBsW3XE4UO2kl9Z2tSOETGdyyXqk2YoAzh4/2wmEgLqU+GwWAtyV
jL2ruwDQ2MuE5xWqgaMJcJc3UkwtCGs4qrrm62fqAex3yoF4tZX2hzwPp7gguv3f
ql7GDTlnR5MS5iq5Tk0ZsLvcXl5w6h7U4ynKLD/kyOqiPeiigmtW3dTkGeLUAYsI
ExN1Tq/Rz88kuZ2jtI6GJ5MHB2P7SsnBmhAmUYOxHx0MDsoOoBr3d3MFk+vMBo1m
K0PigW8DILw5XuwJHp3Oi+EmRzBjIgOAfvIFLEfC/NrExPqB2LgsZxFNG3sOZZd8
ThxkyYdrImV5+Z38nJpjogioovl5u5Q8sVfR7VSlgmLHzrm329hAzV5sypWsX6/e
MbtvCPThNXIbz/WaJ47dMTdwsWrKnJMmqzaFmoneG1OOlQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCGLeHfXvBvfxGV
cj9hTKH3P8gWzTcaWwD8mf0raPfVh/lBBY6XcwoRyG2792jdjbMVj9uqRZTQsK1V
kd02NKH36OhpoW54D6FFBijMWh27Bm/Fm921onoxJSMFv5Gg4yW0O1jftZ19FhGq
CUE4PTuJDVm1HUtNJQ3o8KCOi7RIu4sleZNtMVV6vi3fim12ulbOwnqfMDD4pUv1
eaw5jFAOT7A9UuPJ/z7h7id2HqZ0NaSHBexEW9mnsIKCFLnh6ZMfEKCTZ3al+AJ5
tTJXOny8HGlEraRq0g39QPminTcJ6x3wViIWguOHa/xoCACIy50pfp7BFT0iGQp7
+4pnpmyZoJX2uPzjejY172MqXI9bpNlX7JquoYosDxZwdVQ1mROgh+CvkFJn8u6F
yfACxbXiWJOoyBNjqPaLmxqlkWO/uOxlJEa9k2GLVSB2XOQiKFU8DvX2wClMuklG
iFK/eFF7Wh/0nTTPxI2Exs4qFQyXrcS5UW/9gc/bwsVajyFSjtfQLwlBJi1TJuUd
gvHmDX5R+A9qXGCRDcAplVrdstz07jSUrmwHn5OZXZ1vNCW+BdVs/VbBOyvTQeIU
lCgAu9GdW3A6ToMtHrTLbq9k3AL5tEpM4vP4viKdGJus/vzYD1g0rg0OrPVswv24
OqQ9WhQNJo1VjzCKYz/la1g2J06esQIDAQABAoICABap2kxtz0Ot3Uz2SqFHHdZS
xhuf1u5TL7P62InEBZRiDqY+Z4rKKgm95lcI34QIgpaiQVKdxRiItwZMiGY29qKW
iucIls2dqjor46k8kWf9GtTwUj7zLhtt79/xLwpTQ5ORMJ48oVi26Q3k2UjEAvHP
uPa/92+U0igluKDLFQzx7HtMcSvQ2OTOCZaH3ZxftfjfXXHU5HijBtT0E7R2sDDy
ocyB2yrLu5XSsYSggbIAO4V46SLUtss9o5WQJaN0Xd6x4sVzBNXcsaJYCiQ0o0vs
qpUolSxbxXQgzOl8D4dT2K83BTPzMLY3dZ8mttxkM+wF0I/BZB2FyEEPyB1gvVfo
7U6dlcBX66YEcbFheyQ/6Hb86i52sWWWV0URkD3eEJI0frpJZYtV9CgyWJDhwadh
zPgGmXeRmtorh9wmSFVcy3BPcGDOJpRQuPSekM5vRIp3QpjecMXr6zdU0SWA8hhx
c7W9SHNlQZmjMpv5NP+UMC0Se3eFwxNVYCjr3oIif6avU2QATWbp75tuSN6wo9ta
KocaKOyCQX+MqoIJpeij0A6oynN4W1ZWF1IMAje7CeNnZI2sEamF5ZRAJADmUf4l
dkroT1v/OrkphCClBinPZBDs5CXP2yezrTDGOzRgxx7ZOtz+VhclxsqTn/pqYLQ2
BC3Fz+jU6YXivJn5IDZpAoIBAQC5arwI6iZlI7WPmXtKzmI1Zv4fruKa8/wIGUsv
5/MdohF3z8LqSHlpC2urx5ohnJLziqVJp0u0JimVQ40bkfvhSSOEV4M5eWtg5AfW
z1066PxiETiPAXXFPt7zuxPVcdJkr55jIlgc11hInPmsB2sw2WjH3by50AiZ3Gga
MuIfg9fY5Ej4LqQwPTH+IRW6TirSIV88FZjfahGX4k3PN4rp+BDyE3uy/4F4hopa
o22rQnG7R4apcHV/IW4GgMe6AcogN/B9QQl+ZQW2EPfZ34tuHA7l18+maAWkRFuf
KY+N/uVRM51OIe7/SPVqioJndEnnUYGYe1i09jKhCpimHddVAoIBAQC5Qe1R+V7Q
dK/Z2F+RTt+3p5FIs8x30Vm+ASv1aMHy8LDuHihqm3lGczk8DfJXSHNVn/EhNepl
LSwMSrZ+HFVaHG/2NDV+cw8Hqu8wKuDW69U0frSSCpCIP/i73KlJZ/WQhbaDv8Yq
SNhf4/0P1UWfTXU5Xgh2cOlooq58qzuxyYqf2OAWvkhL8kZumHpZ/2/Ym9takkDa
KrZzKTLKGqLhN9f6WIR1bE+kqqiBNJ1QMAMyDo5+LqOCXZ56IOQOOMNMUsthwkDk
EUZzLKyCsS11576zalXXtCBbN21qya7jHdwyFVjf7bGv0ZGOHnhkiAtW0FcjVoKp
qnnzWmwrmzHtAoIBAHGBJGC0rhJl/MROaYpOsxIL3W8ZyQCgcV2n1j4aWNqAFv9o
QOLYwPIMGrqKsxD2X4MVEb/32MEMR5JnSt9gy3eLJWHjjKJHcPNcRGw8fs8MR0vl
TOFGPIklxqgfkrGsPuaCF4yKPrRRI2s4JSMpW3YI8TrAw8Jf1pQRt+ypz4EJXb4Z
aY38R2h8Xbk7Gaj2JwKBiWInunCx5tk6oPVEBBbcU8tNIAFgpipY+iMoPn+DakoC
LC5XeKX9mfQDK8DzTX/Rnreec6hbQVbGJmPKk/kw1fHf3e75aNK5Qfk6IPYE3u6J
kTd+UGcYi5vP9KpOJtujKplkkNYejLnG2dF/HQ0CggEAbL+Vl0RCcy28OK36U6sw
SnfUIhBhm4hKHO5FJrdK+thtlCoh4YrIoyFqXKV3N+NwyLet7affo2rj64dEHz10
oQQGeUlmiYbzMLYX2HejKqafrkQerYgEFecvlN/QhCXBkgfb/vTpV9MRKSEFYXD5
gK0Qfg+D+jsH2QN+V/KQhSng9TpzOQaUG/jpfWyGjiQTPN0o477s0OS321w400jV
ik2ku/GQN/nPusLvTYFcQ0Eb7xt6a/nmw9U+/UQne224vynu98D3JKo7Z8q2rbVi
EU9rs5hdMdUsFT+xPDmOLwZNRx0e4bx/TM1Bm2Kpm6H8vgZo0HatFvnawo625tYg
dQKCAQEAsFeRsBuArUBf8b9h9v3BFgCTGezZfOvgx/QtlVxDnNxYt2cut1cPgBLx
elp2C6SH6cJZiRWPgpYBlZuHbQh+RUwcXg5doTU6DX3x8remjPhA6pc7c3Jqb1lV
x4q5uDvLvHNzAtTGr99+Ci4se40/oKDcEcvJ8ShEptudmT2KWWbfpham3ECotMrs
NSavmBul473FxZrPOM7FLNWyjT/XOcGpsn8n0OgNC+qUSN9CzuC+CLiBuo6AHhrn
kPEo1ng06/7Ropzz0+nLfZ2nDwzeWSVVBKbsgfUABwOorMIj90nGYKhwAAz8p8uk
rNrrA26be3EZ5z7Pb/9PVMLQLJbKew==
-----END PRIVATE KEY-----

View File

@@ -1,203 +0,0 @@
#!/bin/sh -eu
# This is a simple example of wsrep notification script (wsrep_notify_cmd).
# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
# and fill them on every membership or node status change.
#
# Edit parameters below to specify the address and login to server:
#
USER='root'
PSWD=''
#
# If these parameters are not set, then the values
# passed by the server are taken:
#
HOST="127.0.0.1"
PORT=$NODE_MYPORT_1
#
# Edit parameters below to specify SSL parameters:
#
ssl_cert=""
ssl_key=""
ssl_ca=""
ssl_capath=""
ssl_cipher=""
ssl_crl=""
ssl_crlpath=""
ssl_verify_server_cert=0
#
# Client executable path:
#
CLIENT="$EXE_MYSQL"
#
# Name of schema and tables:
#
SCHEMA="mtr_wsrep_notify"
MEMB_TABLE="$SCHEMA.membership"
STATUS_TABLE="$SCHEMA.status"
WSREP_ON='SET wsrep_on=ON'
WSREP_OFF='SET wsrep_on=OFF'
BEGIN="$WSREP_OFF;
CREATE SCHEMA IF NOT EXISTS $SCHEMA;
CREATE TABLE IF NOT EXISTS $MEMB_TABLE (
idx INT,
uuid CHAR(40), /* node UUID */
name VARCHAR(32), /* node name */
addr VARCHAR(256) /* node address */
) ENGINE=MEMORY;
CREATE TABLE IF NOT EXISTS $STATUS_TABLE (
size INT, /* component size */
idx INT, /* this node index */
status CHAR(16), /* this node status */
uuid CHAR(40), /* cluster UUID */
prim BOOLEAN /* if component is primary */
) ENGINE=MEMORY;
BEGIN"
END="COMMIT; $WSREP_ON"
configuration_change()
{
echo "$BEGIN;"
local idx=0
for NODE in $(echo "$MEMBERS" | sed s/,/\ /g)
do
echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, "
# Don't forget to properly quote string values
echo "'$NODE'" | sed s/\\//\',\'/g
echo ");"
idx=$(( $idx+1 ))
done
echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);"
echo "$END;"
}
status_update()
{
echo "$BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;"
}
trim_string()
{
if [ -n "${BASH_VERSION:-}" ]; then
local pattern="[![:space:]${2:-}]"
local x="${1#*$pattern}"
local z=${#1}
x=${#x}
if [ $x -ne $z ]; then
local y="${1%$pattern*}"
y=${#y}
x=$(( z-x-1 ))
y=$(( y-x+1 ))
printf '%s' "${1:$x:$y}"
else
printf ''
fi
else
local pattern="[[:space:]${2:-}]"
echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
fi
}
COM='status_update' # not a configuration change by default
STATUS=""
CLUSTER_UUID=""
PRIMARY=0
INDEX=""
MEMBERS=""
while [ $# -gt 0 ]; do
case $1 in
'--status')
STATUS=$(trim_string "$2")
shift
;;
'--uuid')
CLUSTER_UUID=$(trim_string "$2")
shift
;;
'--primary')
arg=$(trim_string "$2")
[ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0
COM='configuration_change'
shift
;;
'--index')
INDEX=$(trim_string "$2")
shift
;;
'--members')
MEMBERS=$(trim_string "$2")
shift
;;
esac
shift
done
USER=$(trim_string "$USER")
PSWD=$(trim_string "$PSWD")
HOST=$(trim_string "$HOST")
PORT=$(trim_string "$PORT")
case "$HOST" in
\[*)
HOST="${HOST##\[}"
HOST=$(trim_string "${HOST%%\]}")
;;
esac
if [ -z "$HOST" ]; then
HOST="${NOTIFY_HOST:-}"
fi
if [ -z "$PORT" ]; then
PORT="${NOTIFY_PORT:-}"
fi
ssl_key=$(trim_string "$ssl_key");
ssl_cert=$(trim_string "$ssl_cert");
ssl_ca=$(trim_string "$ssl_ca");
ssl_capath=$(trim_string "$ssl_capath");
ssl_cipher=$(trim_string "$ssl_cipher");
ssl_crl=$(trim_string "$ssl_crl");
ssl_crlpath=$(trim_string "$ssl_crlpath");
ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert");
SSL_PARAM=""
if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ]
then
SSL_PARAM=' --ssl'
[ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'"
[ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'"
[ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'"
[ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'"
[ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'"
[ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'"
[ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'"
if [ -n "$ssl_verify_server_cert" ]; then
if [ "$ssl_verify_server_cert" != "0" -o \
"$ssl_verify_server_cert" = "on" ]
then
SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert"
fi
fi
fi
case "$STATUS" in
'joined' | 'donor' | 'synced')
"$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\
"-h'$HOST'" "-P$PORT"$SSL_PARAM
;;
*)
# The node might be shutting down or not initialized
;;
esac
exit 0

View File

@@ -0,0 +1,13 @@
#!/bin/sh
# Fake mysql client for the galera_wsrep_notify_pwd_injection test.
# Records argv and MYSQL_PWD instead of connecting anywhere, and drops
# the SQL the wsrep_notify script pipes into stdin.
: > "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.argv"
for arg in "$@"; do
printf '%s\n' "$arg" >> "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.argv"
done
printf 'MYSQL_PWD=%s\n' "${MYSQL_PWD-<unset>}" > "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.env"
cat >/dev/null
exit 0

View File

@@ -1,205 +0,0 @@
#!/bin/sh -eu
# This is a simple example of wsrep notification script (wsrep_notify_cmd).
# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
# and fill them on every membership or node status change.
#
# Edit parameters below to specify the address and login to server:
#
USER='root'
PSWD=''
#
# If these parameters are not set, then the values
# passed by the server are taken:
#
HOST="::1"
PORT=$NODE_MYPORT_1
#
# Edit parameters below to specify SSL parameters:
#
ssl_cert="$MYSQL_TEST_DIR/std_data/client-cert.pem"
ssl_key="$MYSQL_TEST_DIR/std_data/client-key.pem"
ssl_ca="$MYSQL_TEST_DIR/std_data/cacert.pem"
ssl_capath=""
ssl_cipher=""
ssl_crl=""
ssl_crlpath=""
ssl_verify_server_cert=0
#
# Client executable path:
#
CLIENT="$EXE_MYSQL"
#
# Name of schema and tables:
#
SCHEMA="mtr_wsrep_notify"
MEMB_TABLE="$SCHEMA.membership"
STATUS_TABLE="$SCHEMA.status"
WSREP_ON='SET wsrep_on=ON'
WSREP_OFF='SET wsrep_on=OFF'
BEGIN="$WSREP_OFF;
CREATE SCHEMA IF NOT EXISTS $SCHEMA;
CREATE TABLE IF NOT EXISTS $MEMB_TABLE (
idx INT,
uuid CHAR(40), /* node UUID */
name VARCHAR(32), /* node name */
addr VARCHAR(256) /* node address */
) ENGINE=MEMORY;
CREATE TABLE IF NOT EXISTS $STATUS_TABLE (
size INT, /* component size */
idx INT, /* this node index */
status CHAR(16), /* this node status */
uuid CHAR(40), /* cluster UUID */
prim BOOLEAN /* if component is primary */
) ENGINE=MEMORY;
BEGIN"
END="COMMIT; $WSREP_ON"
configuration_change()
{
echo "$BEGIN;"
local idx=0
for NODE in $(echo "$MEMBERS" | sed s/,/\ /g)
do
echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, "
# Don't forget to properly quote string values
echo "'$NODE'" | sed s/\\//\',\'/g
echo ");"
idx=$(( $idx+1 ))
done
echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);"
echo "$END;"
}
status_update()
{
echo "$BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;"
}
trim_string()
{
if [ -n "${BASH_VERSION:-}" ]; then
local pattern="[![:space:]${2:-}]"
local x="${1#*$pattern}"
local z=${#1}
x=${#x}
if [ $x -ne $z ]; then
local y="${1%$pattern*}"
y=${#y}
x=$(( z-x-1 ))
y=$(( y-x+1 ))
printf '%s' "${1:$x:$y}"
else
printf ''
fi
else
local pattern="[[:space:]${2:-}]"
echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
fi
}
COM='status_update' # not a configuration change by default
STATUS=""
CLUSTER_UUID=""
PRIMARY=0
INDEX=""
MEMBERS=""
while [ $# -gt 0 ]; do
case $1 in
'--status')
STATUS=$(trim_string "$2")
shift
;;
'--uuid')
CLUSTER_UUID=$(trim_string "$2")
shift
;;
'--primary')
arg=$(trim_string "$2")
[ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0
COM='configuration_change'
shift
;;
'--index')
INDEX=$(trim_string "$2")
shift
;;
'--members')
MEMBERS=$(trim_string "$2")
shift
;;
esac
shift
done
USER=$(trim_string "$USER")
PSWD=$(trim_string "$PSWD")
HOST=$(trim_string "$HOST")
PORT=$(trim_string "$PORT")
case "$HOST" in
\[*)
HOST="${HOST##\[}"
HOST=$(trim_string "${HOST%%\]}")
;;
esac
if [ -z "$HOST" ]; then
HOST="${NOTIFY_HOST:-}"
fi
if [ -z "$PORT" ]; then
PORT="${NOTIFY_PORT:-}"
fi
ssl_key=$(trim_string "$ssl_key");
ssl_cert=$(trim_string "$ssl_cert");
ssl_ca=$(trim_string "$ssl_ca");
ssl_capath=$(trim_string "$ssl_capath");
ssl_cipher=$(trim_string "$ssl_cipher");
ssl_crl=$(trim_string "$ssl_crl");
ssl_crlpath=$(trim_string "$ssl_crlpath");
ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert");
SSL_PARAM=""
if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ]
then
SSL_PARAM=' --ssl'
[ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'"
[ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'"
[ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'"
[ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'"
[ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'"
[ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'"
[ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'"
if [ -n "$ssl_verify_server_cert" ]; then
if [ "$ssl_verify_server_cert" != "0" -o \
"$ssl_verify_server_cert" = "on" ]
then
SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert"
else
SSL_PARAM="$SSL_PARAM --disable-ssl-verify-server-cert"
fi
fi
fi
case "$STATUS" in
'joined' | 'donor' | 'synced')
"$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\
"-h'$HOST'" "-P$PORT"$SSL_PARAM
;;
*)
# The node might be shutting down or not initialized
;;
esac
exit 0

View File

@@ -1,27 +0,0 @@
--echo Killing server ...
if (!$kill_signal)
{
--let $kill_signal = KILL
}
# Write file to make mysql-test-run.pl expect the crash, but don't start it
--let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')`
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect
--write_line wait $_expect_file_name
# Kill the connected server
--disable_reconnect
--let KILL_SIGNAL_VALUE = $kill_signal
--let KILL_NODE_PIDFILE = `SELECT @@pid_file`
--perl
my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'};
my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
my $mysqld_pid = `cat $pid_filename`;
chomp($mysqld_pid);
system("kill -s $kill_sig $mysqld_pid");
exit(0);
EOF
--source include/wait_until_disconnected.inc

View File

@@ -4,7 +4,13 @@
#
# Waits until the passed statement returns true, or the operation
# times out. If the operation times out, the additional error
# statement will be executed and server is killed.
# statement will be executed, the server is killed to leave a core
# for post-mortem analysis, and the test is aborted.
#
# The abort is essential: the node is gone once we return, so any
# statement the caller would execute next runs against a dead server
# and fails in an unrelated and non-deterministic way, hiding the
# timeout that actually caused the failure.
#
# USAGE
#
@@ -32,4 +38,5 @@
if (!$success)
{
--source include/kill_galera.inc
--die Timeout in wait_condition_with_debug_and_kill.inc for $wait_condition
}

View File

@@ -0,0 +1,4 @@
connection node_2;
connection node_1;
include/assert_grep.inc [provider must warn that evs.install_timeout is below evs.suspect_timeout]
include/assert_grep.inc [provider must warn that evs.inactive_check_period exceeds evs.keepalive_period]

View File

@@ -0,0 +1,22 @@
connection node_4;
connection node_3;
connection node_2;
connection node_1;
connection node_4;
connection node_3;
connection node_2;
connection node_1;
connection node_4;
SET SESSION wsrep_sync_wait = 0;
connection node_3;
SET SESSION wsrep_sync_wait = 0;
connection node_2;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
SET SESSION wsrep_sync_wait = 0;
include/assert_grep.inc [node_4 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)]
include/assert_grep.inc [node_3 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)]
include/assert_grep.inc [node_2 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)]
include/assert_grep.inc [node_1 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)]

View File

@@ -24,13 +24,9 @@ SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,abort_trx_end';
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=abort_trx_end';
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';

View File

@@ -10,5 +10,27 @@ START TRANSACTION;
INSERT INTO t1 VALUES (1);
disconnect node_1a;
connection node_1;
GRANT SELECT ON test.t1 TO user1;
connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1;
# Fresh connection
SET SESSION wsrep_sync_wait = 1;
SELECT COUNT(*) FROM test.t1;
COUNT(*)
0
include/assert.inc [SELECT did a causal read on a fresh connection]
# After COM_CHANGE_USER
SET SESSION wsrep_sync_wait = 1;
SELECT COUNT(*) FROM test.t1;
COUNT(*)
0
include/assert.inc [SELECT did a causal read after COM_CHANGE_USER]
# After COM_RESET_CONNECTION
SET SESSION wsrep_sync_wait = 1;
SELECT COUNT(*) FROM test.t1;
COUNT(*)
0
include/assert.inc [SELECT did a causal read after COM_RESET_CONNECTION]
disconnect node_1a;
connection node_1;
DROP TABLE t1;
DROP USER user1;

View File

@@ -1,5 +1,10 @@
connection node_2;
connection node_1;
connection node_1;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_2;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_1;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
connection node_1;
@@ -42,6 +47,7 @@ CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb;
INSERT IGNORE INTO t VALUES(@value);
Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1071 WSREP: Write set key for table 'test.t' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SELECT COUNT(*) FROM t;
COUNT(*)
1
@@ -70,6 +76,7 @@ CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8
INSERT IGNORE INTO t VALUES(@value);
Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1071 WSREP: Write set key for table 'test.t' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SELECT COUNT(*) FROM t;
COUNT(*)
1

View File

@@ -13,7 +13,7 @@ SET SESSION wsrep_sync_wait=0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
# DDL 1
ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000);;
ALTER TABLE t1 ADD COLUMN f3 INTEGER;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
@@ -21,14 +21,22 @@ SET GLOBAL wsrep_provider_options = 'dbug=';
# This will block on acquiring total order isolation
connection node_1;
# DDL 2
CREATE UNIQUE INDEX i1 ON t1(f2);;
CREATE UNIQUE INDEX i1 ON t1(f2);
connection node_2a;
# Neither DDL has been applied on node_1 yet
connection node_1a;
SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
EXPECT_2
2
SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
EXPECT_1
1
# Signal DDL 1
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
connection node_2;
connection node_1;
connection node_2;
INSERT INTO t1 VALUES (NULL, 10000, 10000);
SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
EXPECT_3
3

View File

@@ -7,7 +7,7 @@ EXPECT_2
SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status;
EXPECT_2
2
SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status;
EXPECT_2
2
SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE;
EXPECT_1
1
DROP SCHEMA mtr_wsrep_notify;

View File

@@ -7,7 +7,7 @@ EXPECT_2
SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status;
EXPECT_2
2
SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status;
EXPECT_2
2
SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE;
EXPECT_1
1
DROP SCHEMA mtr_wsrep_notify;

View File

@@ -0,0 +1,698 @@
connection node_2;
connection node_1;
connection node_1;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_2;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_1;
CREATE TABLE p (a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
d INT,
PRIMARY KEY (a,b,c)) ENGINE=InnoDB;
CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY,
a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
KEY k (a,b,c),
FOREIGN KEY (a,b,c) REFERENCES p (a,b,c)) ENGINE=InnoDB;
SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci;
SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254),
_utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci;
#
# Under strict mode a cut key fails the statement
#
INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v, 1);
ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# INSERT IGNORE turns the error back into a warning and the row goes in
#
INSERT IGNORE INTO p (a,b,c,d) VALUES (@v, @v, @v, 1);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# The child row goes down the foreign key path and behaves the same.
# Before the fix this statement took the server down with
# "[FATAL] InnoDB: Unknown error Generic error".
#
INSERT INTO ch (a,b,c) VALUES (@v, @v, @v);
ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT IGNORE INTO ch (a,b,c) VALUES (@v, @v, @v);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# Without strict mode the client also only gets the warning
#
SET SESSION sql_mode = '';
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
#
# A second parent row that differs only past the cut
#
connection node_1;
INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v2, 2);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SELECT COUNT(*) AS EXPECT_2 FROM p;
EXPECT_2
2
connection node_2;
SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci;
SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254),
_utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci;
#
# An UPDATE under strict mode fails with the same error
#
connection node_1;
SET SESSION sql_mode = DEFAULT;
UPDATE p SET d = 9 WHERE a = @v AND b = @v AND c = @v;
ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# UPDATE IGNORE turns it back into a warning as well
#
UPDATE IGNORE p SET d = 9 WHERE a = @v AND b = @v AND c = @v;
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# Without strict mode the same statement gets the warning and runs.
# False positive. The two rows are different rows, but their keys are
# equal up to the cut, so the transaction on node_1 loses
# certification against the one on node_2.
#
connection node_1;
SET SESSION sql_mode = '';
connection node_2;
SET SESSION sql_mode = '';
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_slave_enter_sync';
connection node_1;
BEGIN;
UPDATE p SET d = 10 WHERE a = @v AND b = @v AND c = @v;
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
connection node_2;
UPDATE p SET d = 20 WHERE a = @v AND b = @v AND c = @v2;
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
COMMIT;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_slave_enter_sync';
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
# Only the update from node_2 is there
connection node_1;
SELECT d FROM p ORDER BY d;
d
9
20
#
# Short values leave the key inside the buffer. The same pattern on
# two different rows then commits.
#
connection node_1;
CREATE TABLE p2 (a CHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
d INT,
PRIMARY KEY (a)) ENGINE=InnoDB;
INSERT INTO p2 (a,d) VALUES ('aaaaaaaa', 1), ('aaaaaaab', 2);
connection node_2;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_slave_enter_sync';
connection node_1;
BEGIN;
UPDATE p2 SET d = 10 WHERE a = 'aaaaaaaa';
connection node_2;
UPDATE p2 SET d = 20 WHERE a = 'aaaaaaab';
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
connection node_1;
COMMIT;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_slave_enter_sync';
connection node_1;
SELECT d FROM p2 ORDER BY d;
d
10
20
#
# Foreign keys on the other string types. InnoDB needs the whole
# column in a foreign key, so TEXT and BLOB cannot take part: they
# can only be indexed by a prefix. That leaves VARCHAR, VARBINARY and
# BINARY beside the CHAR columns above.
#
connection node_1;
SET SESSION sql_mode = DEFAULT;
CREATE TABLE fp_v (a VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
b VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
c VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
d INT,
PRIMARY KEY (a,b,c)) ENGINE=InnoDB;
CREATE TABLE fc_v (id INT AUTO_INCREMENT PRIMARY KEY,
a VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
b VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
c VARCHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
KEY k (a,b,c),
FOREIGN KEY (a,b,c) REFERENCES fp_v (a,b,c)) ENGINE=InnoDB;
# VARCHAR parent, row key path
INSERT INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1);
ERROR 42000: WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT IGNORE INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
# VARCHAR child, foreign key path
INSERT INTO fc_v (a,b,c) VALUES (@v, @v, @v);
ERROR 42000: WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT IGNORE INTO fc_v (a,b,c) VALUES (@v, @v, @v);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
# BINARY and VARBINARY are not collated, so the key stays inside the
# buffer and both statements run
CREATE TABLE fp_b (a BINARY(255),
b VARBINARY(1000),
c VARBINARY(1000),
d INT,
PRIMARY KEY (a,b,c)) ENGINE=InnoDB;
CREATE TABLE fc_b (id INT AUTO_INCREMENT PRIMARY KEY,
a BINARY(255),
b VARBINARY(1000),
c VARBINARY(1000),
KEY k (a,b,c),
FOREIGN KEY (a,b,c) REFERENCES fp_b (a,b,c)) ENGINE=InnoDB;
SET @b255 = REPEAT('a', 255);
SET @b1000 = REPEAT('a', 1000);
INSERT INTO fp_b (a,b,c,d) VALUES (@b255, @b1000, @b1000, 1);
INSERT INTO fc_b (a,b,c) VALUES (@b255, @b1000, @b1000);
# TEXT and BLOB can only be indexed by a prefix, and InnoDB refuses a
# foreign key on such a column
CREATE TABLE fc_t (id INT AUTO_INCREMENT PRIMARY KEY,
a TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
KEY k (a(255)),
FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`fc_t` (errno: 150 "Foreign key constraint is incorrectly formed")
# BLOB behaves the same way
CREATE TABLE fc_bl (id INT AUTO_INCREMENT PRIMARY KEY,
a BLOB,
KEY k (a(255)),
FOREIGN KEY (a) REFERENCES fp_b (a)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`fc_bl` (errno: 150 "Foreign key constraint is incorrectly formed")
# JSON is stored as LONGTEXT and behaves the same way
CREATE TABLE fc_j (id INT AUTO_INCREMENT PRIMARY KEY,
a JSON,
KEY k (a(255)),
FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`fc_j` (errno: 150 "Foreign key constraint is incorrectly formed")
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM fp_v;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM fc_v;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM fp_b;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM fc_b;
EXPECT_1
1
#
# Foreign keys on FLOAT, DOUBLE, TIMESTAMP, DATE and DATETIME. These
# are fixed width and not collated, so wsrep_store_key_val_for_row()
# and wsrep_rec_get_foreign_key() never cut the key for them; the
# point is to show the same key-building code path used above still
# produces a working, replicated foreign key for these types.
#
connection node_1;
CREATE TABLE fp_num (a FLOAT,
b DOUBLE,
c TIMESTAMP,
dt DATE,
e DATETIME,
f INT,
PRIMARY KEY (a,b,c,dt,e)) ENGINE=InnoDB;
CREATE TABLE fc_num (id INT AUTO_INCREMENT PRIMARY KEY,
a FLOAT,
b DOUBLE,
c TIMESTAMP,
dt DATE,
e DATETIME,
KEY k (a,b,c,dt,e),
FOREIGN KEY (a,b,c,dt,e)
REFERENCES fp_num (a,b,c,dt,e)) ENGINE=InnoDB;
INSERT INTO fp_num (a,b,c,dt,e,f) VALUES
(1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00', 1);
INSERT INTO fc_num (a,b,c,dt,e) VALUES
(1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00');
# No matching parent row for this combination, the insert is rejected
INSERT INTO fc_num (a,b,c,dt,e) VALUES
(9.5, 9.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00');
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`fc_num`, CONSTRAINT `fc_num_ibfk_1` FOREIGN KEY (`a`, `b`, `c`, `dt`, `e`) REFERENCES `fp_num` (`a`, `b`, `c`, `dt`, `e`))
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM fp_num;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM fc_num;
EXPECT_1
1
#
# Foreign key where part of the key is NULL. InnoDB foreign keys use
# MATCH SIMPLE: when any column of a multi-column foreign key is
# NULL, the row is not checked against the parent at all, whether or
# not a matching parent row exists.
#
connection node_1;
CREATE TABLE fp_n (a INT, b INT, c INT, d INT,
PRIMARY KEY (a,b,c)) ENGINE=InnoDB;
CREATE TABLE fc_n (id INT AUTO_INCREMENT PRIMARY KEY,
a INT, b INT, c INT,
KEY k (a,b,c),
FOREIGN KEY (a,b,c) REFERENCES fp_n (a,b,c)) ENGINE=InnoDB;
# No parent row for (1,2,3) at all, but c is NULL so the row is
# accepted anyway
INSERT INTO fc_n (a,b,c) VALUES (1,2,NULL);
# A parent row exists for (10,20,30), but the child is still not
# checked against it because c is NULL
INSERT INTO fp_n (a,b,c,d) VALUES (10,20,30,1);
INSERT INTO fc_n (a,b,c) VALUES (10,20,NULL);
# A row with every foreign key column NULL is accepted the same way
INSERT INTO fc_n (a,b,c) VALUES (NULL,NULL,NULL);
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM fp_n;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_3 FROM fc_n;
EXPECT_3
3
#
# The same MATCH SIMPLE rule with only the last column of the
# foreign key nullable, the other columns NOT NULL. Position does
# not matter: any NULL column, first, middle or last, is enough to
# skip the check.
#
connection node_1;
CREATE TABLE mfp (a INT, b INT, c INT, PRIMARY KEY (a,b,c)) ENGINE=InnoDB;
CREATE TABLE mfc (id INT AUTO_INCREMENT PRIMARY KEY,
a INT NOT NULL, b INT NOT NULL, c INT,
KEY k (a,b,c),
FOREIGN KEY (a,b,c) REFERENCES mfp (a,b,c)) ENGINE=InnoDB;
INSERT INTO mfp VALUES (1,2,3);
# Last column (c) is NULL: no matching parent row required
INSERT INTO mfc (a,b,c) VALUES (9,9,NULL);
# Last column (c) is non-NULL and matches: the constraint is
# checked and passes
INSERT INTO mfc (a,b,c) VALUES (1,2,3);
# Last column (c) is non-NULL and does not match: the constraint is
# checked and fails
INSERT INTO mfc (a,b,c) VALUES (1,2,99);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`mfc`, CONSTRAINT `mfc_ibfk_1` FOREIGN KEY (`a`, `b`, `c`) REFERENCES `mfp` (`a`, `b`, `c`))
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM mfp;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_2 FROM mfc;
EXPECT_2
2
#
# Every remaining fixed width data type built into the server, in a
# primary key, in a unique key, in a plain key on a table with no
# primary key, and in a foreign key that references a primary key
# and one that references a unique key. wsrep_store_key_val_for_row()
# copies these types with a plain memcpy (TINYINT .. VARBINARY below)
# or through the ENUM/SET branch that skips collation; FLOAT, DOUBLE,
# TIMESTAMP, DATE and DATETIME were already covered above. UUID and
# INET6 are in galera_ws_datatypes_plugin.test.
#
connection node_1;
CREATE TABLE g1_pk (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT,
bi BIGINT, de DECIMAL(10,2), bt BIT(8),
bn BINARY(4), vb VARBINARY(8), f INT,
PRIMARY KEY (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB;
CREATE TABLE g1_pk_child (id INT AUTO_INCREMENT PRIMARY KEY,
ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT,
bi BIGINT, de DECIMAL(10,2), bt BIT(8),
bn BINARY(4), vb VARBINARY(8),
KEY k (ti,si,mi,ii,bi,de,bt,bn,vb),
FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb)
REFERENCES g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb))
ENGINE=InnoDB;
CREATE TABLE g1_uk (id INT AUTO_INCREMENT PRIMARY KEY,
ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT,
bi BIGINT, de DECIMAL(10,2), bt BIT(8),
bn BINARY(4), vb VARBINARY(8),
UNIQUE KEY u (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB;
CREATE TABLE g1_uk_child (id INT AUTO_INCREMENT PRIMARY KEY,
ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT,
bi BIGINT, de DECIMAL(10,2), bt BIT(8),
bn BINARY(4), vb VARBINARY(8),
KEY k (ti,si,mi,ii,bi,de,bt,bn,vb),
FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb)
REFERENCES g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb))
ENGINE=InnoDB;
CREATE TABLE g1_key (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT,
bi BIGINT, de DECIMAL(10,2), bt BIT(8),
bn BINARY(4), vb VARBINARY(8),
KEY k (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB;
# TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, DECIMAL, BIT, BINARY,
# VARBINARY together, in a primary key and a foreign key that
# references it
INSERT INTO g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb,f)
VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh',1);
INSERT INTO g1_pk_child (ti,si,mi,ii,bi,de,bt,bn,vb)
VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh');
# The same types in a unique key and a foreign key that references it
INSERT INTO g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb)
VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh');
INSERT INTO g1_uk_child (ti,si,mi,ii,bi,de,bt,bn,vb)
VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh');
# The same types in a plain, non-unique key on a table with no
# primary key
INSERT INTO g1_key (ti,si,mi,ii,bi,de,bt,bn,vb)
VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh');
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM g1_pk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g1_pk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g1_uk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g1_uk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g1_key;
EXPECT_1
1
#
# TIME, YEAR, ENUM and SET, the same way. UUID and INET6 are provided
# by the mandatory type_uuid and type_inet plugins rather than being
# built into the server proper; they are covered by
# galera_ws_datatypes_plugin.test instead.
#
connection node_1;
CREATE TABLE g2_pk (tm TIME, yr YEAR, en ENUM('a','b','c'),
st SET('a','b','c'), f INT,
PRIMARY KEY (tm,yr,en,st)) ENGINE=InnoDB;
CREATE TABLE g2_pk_child (id INT AUTO_INCREMENT PRIMARY KEY,
tm TIME, yr YEAR, en ENUM('a','b','c'),
st SET('a','b','c'),
KEY k (tm,yr,en,st),
FOREIGN KEY (tm,yr,en,st)
REFERENCES g2_pk (tm,yr,en,st)) ENGINE=InnoDB;
CREATE TABLE g2_uk (id INT AUTO_INCREMENT PRIMARY KEY,
tm TIME, yr YEAR, en ENUM('a','b','c'),
st SET('a','b','c'),
UNIQUE KEY u (tm,yr,en,st)) ENGINE=InnoDB;
CREATE TABLE g2_uk_child (id INT AUTO_INCREMENT PRIMARY KEY,
tm TIME, yr YEAR, en ENUM('a','b','c'),
st SET('a','b','c'),
KEY k (tm,yr,en,st),
FOREIGN KEY (tm,yr,en,st)
REFERENCES g2_uk (tm,yr,en,st)) ENGINE=InnoDB;
CREATE TABLE g2_key (tm TIME, yr YEAR, en ENUM('a','b','c'),
st SET('a','b','c'),
KEY k (tm,yr,en,st)) ENGINE=InnoDB;
INSERT INTO g2_pk (tm,yr,en,st,f)
VALUES ('10:00:00',2026,'b','a,c',1);
INSERT INTO g2_pk_child (tm,yr,en,st)
VALUES ('10:00:00',2026,'b','a,c');
INSERT INTO g2_uk (tm,yr,en,st)
VALUES ('10:00:00',2026,'b','a,c');
INSERT INTO g2_uk_child (tm,yr,en,st)
VALUES ('10:00:00',2026,'b','a,c');
INSERT INTO g2_key (tm,yr,en,st)
VALUES ('10:00:00',2026,'b','a,c');
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM g2_pk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g2_pk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g2_uk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g2_uk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g2_key;
EXPECT_1
1
#
# SERIAL, an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
# as a primary key
#
connection node_1;
CREATE TABLE g_serial (id SERIAL PRIMARY KEY, f INT) ENGINE=InnoDB;
INSERT INTO g_serial (f) VALUES (1);
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM g_serial;
EXPECT_1
1
#
# Other string types and prefix indexes outside a foreign key. The
# indexes are
# unique because wsrep_append_keys() only builds a key for a unique
# index, one referenced by a foreign key, or any index of a table
# without a primary key. The key is cut when the collation weights of
# the indexed bytes pass the buffer; the binary types are not
# collated, so they never are.
#
connection node_1;
SET SESSION sql_mode = DEFAULT;
SET @c200 = REPEAT(_utf8mb4 0xEFAC84, 200) COLLATE utf8mb4_unicode_ci;
SET @c768 = REPEAT(_utf8mb4 0xEFAC84, 768) COLLATE utf8mb4_unicode_ci;
SET @bin255 = REPEAT('a', 255);
SET @bin3000 = REPEAT('a', 3000);
CREATE TABLE k1 (id INT AUTO_INCREMENT PRIMARY KEY,
v VARCHAR(768) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (v)) ENGINE=InnoDB;
CREATE TABLE k2 (id INT AUTO_INCREMENT PRIMARY KEY,
t TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (t(768))) ENGINE=InnoDB;
CREATE TABLE k3 (id INT AUTO_INCREMENT PRIMARY KEY,
c CHAR(255) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (c(200))) ENGINE=InnoDB;
CREATE TABLE k4 (id INT AUTO_INCREMENT PRIMARY KEY,
v VARCHAR(768) CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (v(700))) ENGINE=InnoDB;
CREATE TABLE k5 (id INT AUTO_INCREMENT PRIMARY KEY,
b BLOB,
UNIQUE KEY (b(3000))) ENGINE=InnoDB;
CREATE TABLE k6 (id INT AUTO_INCREMENT PRIMARY KEY,
bn BINARY(255),
vb VARBINARY(3000),
UNIQUE KEY (bn),
UNIQUE KEY (vb(3000))) ENGINE=InnoDB;
CREATE TABLE k7 (id INT AUTO_INCREMENT PRIMARY KEY,
t TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (t(50))) ENGINE=InnoDB;
CREATE TABLE k8 (id INT AUTO_INCREMENT PRIMARY KEY,
t MEDIUMTEXT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (t(768))) ENGINE=InnoDB;
CREATE TABLE k9 (id INT AUTO_INCREMENT PRIMARY KEY,
t LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
UNIQUE KEY (t(768))) ENGINE=InnoDB;
CREATE TABLE k10 (id INT AUTO_INCREMENT PRIMARY KEY,
b TINYBLOB,
UNIQUE KEY (b(50))) ENGINE=InnoDB;
CREATE TABLE k11 (id INT AUTO_INCREMENT PRIMARY KEY,
b MEDIUMBLOB,
UNIQUE KEY (b(3000))) ENGINE=InnoDB;
CREATE TABLE k12 (id INT AUTO_INCREMENT PRIMARY KEY,
b LONGBLOB,
UNIQUE KEY (b(3000))) ENGINE=InnoDB;
CREATE TABLE k13 (id INT AUTO_INCREMENT PRIMARY KEY,
j JSON,
UNIQUE KEY (j(768))) ENGINE=InnoDB;
# VARCHAR, whole column
INSERT INTO k1 (v) VALUES (@c768);
ERROR 42000: WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
# TEXT, prefix
INSERT INTO k2 (t) VALUES (@c768);
ERROR 42000: WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
# CHAR, prefix short enough to stay inside the buffer
INSERT INTO k3 (c) VALUES (@c200);
# VARCHAR, prefix
INSERT INTO k4 (v) VALUES (@c768);
ERROR 42000: WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
# BLOB, prefix. Bytes are not collated, so nothing is cut
INSERT INTO k5 (b) VALUES (@bin3000);
# BINARY and VARBINARY, whole column and prefix
INSERT INTO k6 (bn, vb) VALUES (@bin255, @bin3000);
SET @tiny = REPEAT('a', 50);
# TINYTEXT, prefix short enough to stay inside the buffer
INSERT INTO k7 (t) VALUES (@tiny);
# MEDIUMTEXT, prefix short enough to stay inside the buffer
INSERT INTO k8 (t) VALUES (@c200);
# LONGTEXT, prefix short enough to stay inside the buffer
INSERT INTO k9 (t) VALUES (@c200);
# TINYBLOB, prefix. Bytes are not collated, so nothing is cut
INSERT INTO k10 (b) VALUES (@tiny);
# MEDIUMBLOB, prefix
INSERT INTO k11 (b) VALUES (@bin3000);
# LONGBLOB, prefix
INSERT INTO k12 (b) VALUES (@bin3000);
# JSON, stored as LONGTEXT with a validity check, prefix
INSERT INTO k13 (j) VALUES ('{"a":1}');
# Without strict mode the cut ones go in with a warning
SET SESSION sql_mode = '';
INSERT INTO k1 (v) VALUES (@c768);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT INTO k2 (t) VALUES (@c768);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT INTO k4 (v) VALUES (@c768);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SET SESSION sql_mode = DEFAULT;
# The rows the server accepted reach node_2
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM k1;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k2;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k3;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k4;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k5;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k6;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k7;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k8;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k9;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k10;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k11;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k12;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM k13;
EXPECT_1
1
#
# GEOMETRY is stored as BLOB and behaves the same way: a key needs an
# explicit prefix length, and a foreign key is rejected regardless of
# length. POINT is fixed length (an SRID plus one X/Y pair), so it can
# be a whole-column primary or unique key without a prefix, but a
# foreign key on it is still rejected.
#
connection node_1;
CREATE TABLE g_pk (g GEOMETRY NOT NULL, PRIMARY KEY (g)) ENGINE=InnoDB;
ERROR 42000: BLOB/TEXT column 'g' used in key specification without a key length
CREATE TABLE g_uk (id INT AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL, UNIQUE KEY (g(25))) ENGINE=InnoDB;
INSERT INTO g_uk (g) VALUES (ST_PointFromText('POINT(1 1)'));
CREATE TABLE g_fk (id INT AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY,
KEY k (g(25)),
FOREIGN KEY (g) REFERENCES g_uk (g)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`g_fk` (errno: 150 "Foreign key constraint is incorrectly formed")
CREATE TABLE g_pk2 (p POINT NOT NULL, PRIMARY KEY (p)) ENGINE=InnoDB;
INSERT INTO g_pk2 (p) VALUES (ST_PointFromText('POINT(1 1)'));
CREATE TABLE g_uk2 (id INT AUTO_INCREMENT PRIMARY KEY,
p POINT NOT NULL, UNIQUE KEY (p)) ENGINE=InnoDB;
INSERT INTO g_uk2 (p) VALUES (ST_PointFromText('POINT(1 1)'));
CREATE TABLE g_fk2 (id INT AUTO_INCREMENT PRIMARY KEY,
p POINT,
KEY k (p),
FOREIGN KEY (p) REFERENCES g_pk2 (p)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`g_fk2` (errno: 150 "Foreign key constraint is incorrectly formed")
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM g_uk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g_pk2;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM g_uk2;
EXPECT_1
1
connection node_1;
DROP TABLE ch, p;
DROP TABLE p2;
DROP TABLE fc_v, fp_v;
DROP TABLE fc_b, fp_b;
DROP TABLE fc_num, fp_num;
DROP TABLE fc_n, fp_n;
DROP TABLE mfc, mfp;
DROP TABLE g1_pk_child, g1_pk, g1_uk_child, g1_uk, g1_key;
DROP TABLE g2_pk_child, g2_pk, g2_uk_child, g2_uk, g2_key;
DROP TABLE g_serial;
DROP TABLE g_uk, g_pk2, g_uk2;
DROP TABLE k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13;
disconnect node_1a;
disconnect node_2;
disconnect node_1;
# End of test

View File

@@ -0,0 +1,60 @@
connection node_2;
connection node_1;
connection node_1;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_2;
call mtr.add_suppression("WSREP: Write set key for table .* was cut to");
connection node_1;
CREATE TABLE p (a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
m VARBINARY(8) NOT NULL,
c FLOAT NOT NULL,
PRIMARY KEY (a,m,c)) ENGINE=InnoDB;
CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY,
a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
m VARBINARY(8) NOT NULL,
c FLOAT NOT NULL,
KEY k (a,m,c),
FOREIGN KEY (a,m,c) REFERENCES p (a,m,c)) ENGINE=InnoDB;
SET @v = REPEAT(_utf8mb4 0xEFAC84, 582) COLLATE utf8mb4_unicode_ci;
#
# Under strict mode a cut key fails the statement
#
INSERT INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5);
ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# INSERT IGNORE turns the error back into a warning and the row goes in
#
INSERT IGNORE INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
#
# The child row goes down the foreign key path and behaves the same.
# Before the fix this statement took the server down with
# "Assertion `len == sizeof(float)' failed."
#
INSERT INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5);
ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
INSERT IGNORE INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5);
Warnings:
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SHOW WARNINGS;
Level Code Message
Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification.
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
connection node_1;
DROP TABLE ch, p;

View File

@@ -0,0 +1,53 @@
connection node_2;
connection node_1;
connection node_1;
CREATE TABLE gp_pk (uu UUID, i6 INET6, f INT,
PRIMARY KEY (uu,i6)) ENGINE=InnoDB;
CREATE TABLE gp_pk_child (id INT AUTO_INCREMENT PRIMARY KEY,
uu UUID, i6 INET6,
KEY k (uu,i6),
FOREIGN KEY (uu,i6) REFERENCES gp_pk (uu,i6))
ENGINE=InnoDB;
CREATE TABLE gp_uk (id INT AUTO_INCREMENT PRIMARY KEY,
uu UUID, i6 INET6,
UNIQUE KEY u (uu,i6)) ENGINE=InnoDB;
CREATE TABLE gp_uk_child (id INT AUTO_INCREMENT PRIMARY KEY,
uu UUID, i6 INET6,
KEY k (uu,i6),
FOREIGN KEY (uu,i6) REFERENCES gp_uk (uu,i6))
ENGINE=InnoDB;
CREATE TABLE gp_key (uu UUID, i6 INET6,
KEY k (uu,i6)) ENGINE=InnoDB;
SET @uu = '11111111-1111-1111-1111-111111111111';
SET @i6 = '2001:db8::1';
# UUID and INET6 together, in a primary key and a foreign key that
# references it
INSERT INTO gp_pk (uu,i6,f) VALUES (@uu,@i6,1);
INSERT INTO gp_pk_child (uu,i6) VALUES (@uu,@i6);
# The same types in a unique key and a foreign key that references it
INSERT INTO gp_uk (uu,i6) VALUES (@uu,@i6);
INSERT INTO gp_uk_child (uu,i6) VALUES (@uu,@i6);
# The same types in a plain, non-unique key on a table with no
# primary key
INSERT INTO gp_key (uu,i6) VALUES (@uu,@i6);
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM gp_pk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM gp_pk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM gp_uk;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM gp_uk_child;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM gp_key;
EXPECT_1
1
connection node_1;
DROP TABLE gp_pk_child, gp_pk, gp_uk_child, gp_uk, gp_key;
disconnect node_2;
disconnect node_1;
# End of test

View File

@@ -0,0 +1,27 @@
connection node_2;
connection node_1;
connection node_1;
CREATE TABLE p (a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY,
a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
KEY k (a),
FOREIGN KEY (a) REFERENCES p (a)) ENGINE=InnoDB;
SET @v = REPEAT(_utf8mb4 0xEFAC84, 550) COLLATE utf8mb4_unicode_ci;
INSERT INTO p (a) VALUES (@v);
INSERT INTO ch (a) VALUES (@v);
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
connection node_2;
SELECT COUNT(*) AS EXPECT_1 FROM p;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_1 FROM ch;
EXPECT_1
1
UPDATE p SET a = a WHERE a = @v;
connection node_1;
DROP TABLE ch, p;

View File

@@ -0,0 +1,11 @@
connection node_2;
connection node_1;
connection node_1;
SELECT 1;
1
1
-B
-uroot
-h127.0.0.1
-P3306
MYSQL_PWD=x' y='z

View File

@@ -0,0 +1,36 @@
connection node_2;
connection node_1;
connect primary, 127.0.0.1, root, , test, $NODE_MYPORT_3;
connection node_1;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
connection node_2;
connection node_1;
START SLAVE;
# Many foreign-domain DDLs, each applied as TOI on node_2
connection primary;
connection node_2;
SELECT COUNT(*) AS EXPECT_150 FROM base;
EXPECT_150
150
connection node_1;
connection primary;
DROP TABLE base;
connection node_1;
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL wsrep_on = OFF;
RESET MASTER;
SET GLOBAL wsrep_on = ON;
SET GLOBAL gtid_slave_pos = "";
connection node_2;
SET GLOBAL wsrep_on = OFF;
RESET MASTER;
SET GLOBAL wsrep_on = ON;
SET GLOBAL gtid_slave_pos = "";
connection primary;
RESET MASTER;
connection node_1;
disconnect primary;
disconnect node_2;
disconnect node_1;
# End of test

Some files were not shown because too many files have changed in this diff Show More