Commit 46a6cea5 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.4 into 10.5

parents 74551b2b c793f078
#
# MDEV-20228 `mysql_upgrade` fails on every version upgrade: "ERROR 1267 (HY000) at line 7: Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE) and (utf8mb4_general_ci,COERCIBLE) for operation 'like'"
#
SET sql_mode="";
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
#
# Changing character_set_client and collation_connection
# for the VIEW mysql.user to utf8mb4/utf8mb4_unicode_ci,
# to emulate that mysql.user was created by 'mysqld --bootstrap'
# using mysqld compiled with
# -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci
#
SELECT CHARACTER_SET_CLIENT, COLLATION_CONNECTION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user';
CHARACTER_SET_CLIENT COLLATION_CONNECTION
utf8mb4 utf8mb4_unicode_ci
# Running mysql_upgrade
Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats OK
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
mysql.global_priv OK
mysql.gtid_slave_pos OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.index_stats OK
mysql.innodb_index_stats OK
mysql.innodb_table_stats OK
mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.proxies_priv OK
mysql.roles_mapping OK
mysql.servers OK
mysql.table_stats OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.transaction_registry OK
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
mysql.user OK
Phase 4/7: Running 'mysql_fix_privilege_tables'
Phase 5/7: Fixing table and database names
Phase 6/7: Checking and upgrading tables
Processing databases
information_schema
mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
performance_schema
test
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK
#
# Restoring character_set_client and collation_connection back
# so post-check returns the expected check-mysqld_1.result
#
SET NAMES latin1;
-- source include/mysql_upgrade_preparation.inc
-- source include/have_working_dns.inc
-- source include/have_innodb.inc
-- source include/have_partition.inc
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user'
AND CHARACTER_SET_CLIENT='latin1'
AND COLLATION_CONNECTION='latin1_swedish_ci'`)
{
Skip Needs character_set_client=latin1 and collation_connection=latin1_swedish_ci in mysql.views;
}
--echo #
--echo # MDEV-20228 `mysql_upgrade` fails on every version upgrade: "ERROR 1267 (HY000) at line 7: Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE) and (utf8mb4_general_ci,COERCIBLE) for operation 'like'"
--echo #
let $MYSQLD_DATADIR= `select @@datadir`;
SET sql_mode="";
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
--echo #
--echo # Changing character_set_client and collation_connection
--echo # for the VIEW mysql.user to utf8mb4/utf8mb4_unicode_ci,
--echo # to emulate that mysql.user was created by 'mysqld --bootstrap'
--echo # using mysqld compiled with
--echo # -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci
--echo #
--disable_query_log
let $def= `SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user'`;
--eval ALTER VIEW mysql.user AS $def;
--enable_query_log
SELECT CHARACTER_SET_CLIENT, COLLATION_CONNECTION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user';
--echo # Running mysql_upgrade
--exec $MYSQL_UPGRADE --default-character-set=utf8mb4 --force 2>&1
--file_exists $MYSQLD_DATADIR/mysql_upgrade_info
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo #
--echo # Restoring character_set_client and collation_connection back
--echo # so post-check returns the expected check-mysqld_1.result
--echo #
SET NAMES latin1;
--disable_query_log
let $def= `SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user'`;
--eval ALTER VIEW mysql.user AS $def;
--enable_query_log
......@@ -2970,7 +2970,7 @@ explain extended select * from t1 where a in (select pk from t10) {
"read_time": 27.129
},
{
"chosen_strategy": "SJ-Materialize"
"chosen_strategy": "SJ-Materialization"
}
],
"estimated_join_cardinality": 3
......@@ -4609,7 +4609,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_
"read_time": 18.315
},
{
"chosen_strategy": "SJ-Materialize"
"chosen_strategy": "SJ-Materialization"
}
],
"estimated_join_cardinality": 3
......@@ -6309,7 +6309,14 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
]
},
{
"fix_semijoin_strategies_for_picked_join_order": []
"fix_semijoin_strategies_for_picked_join_order": [
{
"semi_join_strategy": "DuplicateWeedout"
},
{
"semi_join_strategy": "DuplicateWeedout"
}
]
},
{
"best_join_order": [
......@@ -6833,7 +6840,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"read_time": 37.226
},
{
"chosen_strategy": "SJ-Materialize"
"chosen_strategy": "SJ-Materialization"
}
],
"rest_of_plan": [
......@@ -6935,7 +6942,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
"read_time": 294.96
},
{
"chosen_strategy": "SJ-Materialize"
"chosen_strategy": "SJ-Materialization"
}
],
"estimated_join_cardinality": 27
......
......@@ -43,3 +43,4 @@ galera_wan : MDEV-17259 Test failure on galera.galera_wan
mysql-wsrep#198 : MDEV-18935 Galera test mysql-wsrep#198 sporaric assertion transaction.cpp:362: int wsrep::transaction::before_commit(): Assertion `state() == s_executing || state() == s_committing || state() == s_must_abort || state() == s_replaying' failed.
partition : MDEV-19958 Galera test failure on galera.partition
query_cache: MDEV-15805 Test failure on galera.query_cache
galera_var_notify_cmd : MDEV-20600 Galera test galera_var_notify_cmd causes hang
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
......
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
......
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
SET GLOBAL wsrep_provider_options = 'pc.weight=2';
connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1';
SET SESSION wsrep_sync_wait = 0;
connection node_1;
SET GLOBAL wsrep_provider_options = 'pc.weight = 1';
connection node_2;
connection node_1;
Setting SST method to mysqldump ...
call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to '127.0.0.1'");
call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos");
......@@ -214,4 +216,5 @@ CALL mtr.add_suppression("Can't open and lock time zone table");
CALL mtr.add_suppression("Can't open and lock privilege tables");
CALL mtr.add_suppression("Info table is not ready to be used");
CALL mtr.add_suppression("Native table .* has the wrong structure");
CALL mtr.add_suppression("Table \'mysql.gtid_slave_pos\' doesn\'t exist");
DROP USER sslsst;
#
# Check that server can be shut down in non-primary configuration.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--let $node_1 = node_1
--let $node_2 = node_2
--source include/auto_increment_offset_save.inc
--connection node_1
# Set higher weight for node_1 to keep it in primary
# while node_2 is isolated.
SET GLOBAL wsrep_provider_options = 'pc.weight=2';
--connection node_2
# Isolate node_2 from the group and wait until wsrep_ready becomes OFF.
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1';
SET SESSION wsrep_sync_wait = 0;
--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'
--source include/wait_condition.inc
# Verify that graceful shutdown succeeds.
--source include/shutdown_mysqld.inc
--source include/start_mysqld.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
--connection node_1
--source include/wait_condition.inc
# Restore original settings.
SET GLOBAL wsrep_provider_options = 'pc.weight = 1';
--source include/auto_increment_offset_restore.inc
......@@ -5,17 +5,12 @@
[mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'
wsrep_causal_reads=0
wsrep_sync_wait=0
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
wsrep_causal_reads=0
wsrep_sync_wait=0
[mysqld]
wsrep_debug=1
[client]
ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem
ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem
......
......@@ -20,7 +20,7 @@ GRANT USAGE ON *.* TO sslsst REQUIRE SSL;
SET GLOBAL wsrep_sst_auth = 'sslsst:';
# We set the required mysqldump SST options here so that they are used every time the server is restarted during the test
--let $start_mysqld_params = --wsrep_sst_auth=sst:'sslsst:' --wsrep_sst_method=mysqldump --wsrep-sst-receive-address=127.0.0.1:$NODE_MYPORT_2 --skip-grant-tables
--let $start_mysqld_params = --wsrep_sst_auth=sst:'sslsst:' --wsrep_sst_method=mysqldump --wsrep-sst-receive-address=127.0.0.1:$NODE_MYPORT_2
--source suite/galera/include/galera_st_shutdown_slave.inc
--source suite/galera/include/galera_st_kill_slave.inc
......
......@@ -487,12 +487,18 @@ DROP TABLE t;
--echo # Bug#21807818: Generated columns not updated with empty insert list
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t (
a BLOB GENERATED ALWAYS AS ('') VIRTUAL,
b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL,
KEY (a(183),b)
);
CREATE TABLE t (
a BLOB GENERATED ALWAYS AS ('') VIRTUAL,
b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL
);
INSERT IGNORE INTO t VALUES(), (), ();
DELETE IGNORE FROM t;
......
......@@ -549,11 +549,12 @@ a BLOB GENERATED ALWAYS AS ('') VIRTUAL,
b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL,
KEY (a(183),b)
);
ERROR HY000: Function or expression '''' cannot be used in the GENERATED ALWAYS AS clause of `b`
CREATE TABLE t (
a BLOB GENERATED ALWAYS AS ('') VIRTUAL,
b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL
);
INSERT IGNORE INTO t VALUES(), (), ();
Warnings:
Warning 1265 Data truncated for column 'b' at row 1
Warning 1265 Data truncated for column 'b' at row 2
Warning 1265 Data truncated for column 'b' at row 3
DELETE IGNORE FROM t;
DROP TABLE t;
#
......
......@@ -239,7 +239,7 @@ col_dec decimal(18,9) not null default 0,
col_enum enum('','a','b','c','d','e','f','foo','bar') not null default '',
col_date date not null default '1900-01-01',
col_timestamp timestamp(3) not null default '1971-01-01 00:00:00',
vcol_datetime datetime as (col_datetime) virtual,
vcol_datetime datetime as (truncate(col_datetime,0)) virtual,
vcol_dec decimal(18,9) zerofill as (col_dec) virtual,
vcol_bit bit(63) as (col_bit) virtual,
vcol_char binary(51) as (col_char) virtual,
......
......@@ -26,7 +26,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (a CHAR(5), v TIME AS (a) VIRTUAL, KEY(v));
DROP TABLE t1;
ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (c CHAR(8), v BINARY(8) AS (c), KEY(v));
ERROR HY000: Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
SHOW WARNINGS;
......
#
# Start of 10.4 tests
#
#
# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
#
SET sql_mode=DEFAULT;
# OK: same FSP + virtual index
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
# OK: lower FSP + no virtual index
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
# NOT OK: lower FSP + virtual index
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (t) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
# OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
t d v
2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.050
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
# OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
t d v
2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.049
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
#
# End of 10.4 tests
#
#
# Start of 10.4 tests
#
#
# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
#
SET sql_mode=DEFAULT;
# OK: same FSP + virtual index
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(4) AS ('10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
# OK: lower FSP + no virtual index
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
# NOT OK: lower FSP + virtual index
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (t) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
# OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
SELECT * FROM t1;
t d v
12:44:34.0496 21:27:53 12:44:34.050
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = CURRENT_TIME;
DROP TABLE t1;
SET sql_mode=DEFAULT;
# OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
SELECT * FROM t1;
t d v
12:44:34.0496 21:27:53 12:44:34.049
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = CURRENT_TIME;
DROP TABLE t1;
SET sql_mode=DEFAULT;
#
# End of 10.4 tests
#
#
# Start of 10.4 tests
#
#
# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
#
SET sql_mode=DEFAULT;
# OK: same FSP + virtual index
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
# OK: lower FSP + no virtual index
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
# NOT OK: lower FSP + virtual index
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (t) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
# OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
t d v
2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.050
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
# OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
t d v
2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.049
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
#
# End of 10.4 tests
#
......@@ -80,7 +80,7 @@ create table t1 (
col_enum enum('','a','b','c','d','e','f','foo','bar') not null default '',
col_date date not null default '1900-01-01',
col_timestamp timestamp(3) not null default '1971-01-01 00:00:00',
vcol_datetime datetime as (col_datetime) virtual,
vcol_datetime datetime as (truncate(col_datetime,0)) virtual,
vcol_dec decimal(18,9) zerofill as (col_dec) virtual,
vcol_bit bit(63) as (col_bit) virtual,
vcol_char binary(51) as (col_char) virtual,
......
......@@ -18,8 +18,8 @@ CREATE TABLE t1 (a CHAR(5), v INT AS (a) VIRTUAL, KEY(v));
SHOW CREATE TABLE t1;
DROP TABLE t1;
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (a CHAR(5), v TIME AS (a) VIRTUAL, KEY(v));
DROP TABLE t1;
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (c CHAR(8), v BINARY(8) AS (c), KEY(v));
......
--echo #
--echo # Start of 10.4 tests
--echo #
--echo #
--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
--echo #
SET sql_mode=DEFAULT;
--echo # OK: same FSP + virtual index
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
--echo # OK: lower FSP + no virtual index
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
--echo # NOT OK: lower FSP + virtual index
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (t) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
--echo # OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo # OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t DATETIME(4),
d DATETIME,
v DATETIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.4 tests
--echo #
--echo #
--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
--echo #
SET sql_mode=DEFAULT;
--echo # OK: same FSP + virtual index
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(4) AS ('10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
--echo # OK: lower FSP + no virtual index
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
--echo # NOT OK: lower FSP + virtual index
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (t) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
--echo # OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = CURRENT_TIME;
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo # OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIME(4),
d TIME,
v TIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = CURRENT_TIME;
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.4 tests
--echo #
--echo #
--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
--echo #
SET sql_mode=DEFAULT;
--echo # OK: same FSP + virtual index
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(4) AS (t) VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
DROP TABLE t1;
--echo # OK: lower FSP + no virtual index
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (t) VIRTUAL
);
DROP TABLE t1;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
);
DROP TABLE t1;
--echo # NOT OK: lower FSP + virtual index
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (t) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (COALESCE(t)) VIRTUAL,
KEY(v,d)
);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
KEY(v,d)
);
--echo # OK: lower FSP + ROUND + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (ROUND(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo # OK: lower FSP + TRUNCATE + virtual index
SET sql_mode=DEFAULT;
CREATE TABLE t1 (
t TIMESTAMP(4),
d DATETIME,
v TIMESTAMP(3) AS (TRUNCATE(t,3)) VIRTUAL,
KEY(v,d)
);
INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
SELECT * FROM t1;
SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
UPDATE IGNORE t1 SET d = NOW();
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.4 tests
--echo #
......@@ -12,3 +12,4 @@
foreign_key : Sporadic failure "WSREP has not yet prepared node for application use"
wsrep.pool_of_threads : Sporadic failure "WSREP has not yet prepared node for application use"
variables : MDEV-20581 Crash on wsrep.variables test case
......@@ -34,7 +34,7 @@ ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N'
# Detect whether or not we had the Grant_priv column
SET @hadGrantPriv:=0;
SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv LIKE '%';
SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv IS NOT NULL;
ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
......@@ -119,7 +119,7 @@ ALTER TABLE func add type enum ('function','aggregate') COLLATE utf8_general_ci
# Detect whether we had Show_db_priv
SET @hadShowDbPriv:=0;
SELECT @hadShowDbPriv:=1 FROM user WHERE Show_db_priv LIKE '%';
SELECT @hadShowDbPriv:=1 FROM user WHERE Show_db_priv IS NOT NULL;
ALTER TABLE user
ADD Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_priv,
......@@ -267,7 +267,7 @@ ALTER TABLE plugin
# Detect whether we had Create_view_priv
#
SET @hadCreateViewPriv:=0;
SELECT @hadCreateViewPriv:=1 FROM user WHERE Create_view_priv LIKE '%';
SELECT @hadCreateViewPriv:=1 FROM user WHERE Create_view_priv IS NOT NULL;
#
# Create VIEWs privileges (v5.0)
......@@ -297,7 +297,7 @@ UPDATE user SET Create_view_priv=Create_priv, Show_view_priv=Create_priv where u
#
#
SET @hadCreateRoutinePriv:=0;
SELECT @hadCreateRoutinePriv:=1 FROM user WHERE Create_routine_priv LIKE '%';
SELECT @hadCreateRoutinePriv:=1 FROM user WHERE Create_routine_priv IS NOT NULL;
#
# Create PROCEDUREs privileges (v5.0)
......@@ -339,7 +339,7 @@ ALTER TABLE user MODIFY max_user_connections int(11) DEFAULT '0' NOT NULL AFTER
#
SET @hadCreateUserPriv:=0;
SELECT @hadCreateUserPriv:=1 FROM user WHERE Create_user_priv LIKE '%';
SELECT @hadCreateUserPriv:=1 FROM user WHERE Create_user_priv IS NOT NULL;
ALTER TABLE user ADD Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv;
ALTER TABLE user MODIFY Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv;
......@@ -505,7 +505,7 @@ ALTER TABLE proc ADD aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL
# EVENT privilege
#
SET @hadEventPriv := 0;
SELECT @hadEventPriv :=1 FROM user WHERE Event_priv LIKE '%';
SELECT @hadEventPriv :=1 FROM user WHERE Event_priv IS NOT NULL;
ALTER TABLE user ADD Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv;
ALTER TABLE user MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv;
......@@ -599,7 +599,7 @@ set global event_scheduler=original;
#
SET @hadTriggerPriv := 0;
SELECT @hadTriggerPriv :=1 FROM user WHERE Trigger_priv LIKE '%';
SELECT @hadTriggerPriv :=1 FROM user WHERE Trigger_priv IS NOT NULL;
ALTER TABLE user ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Event_priv;
ALTER TABLE user MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Event_priv;
......@@ -614,7 +614,7 @@ UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0;
#
SET @hadCreateTablespacePriv := 0;
SELECT @hadCreateTablespacePriv :=1 FROM user WHERE Create_tablespace_priv LIKE '%';
SELECT @hadCreateTablespacePriv :=1 FROM user WHERE Create_tablespace_priv IS NOT NULL;
ALTER TABLE user ADD Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Trigger_priv;
ALTER TABLE user MODIFY Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Trigger_priv;
......@@ -629,7 +629,7 @@ ALTER TABLE user change Truncate_versioning_priv Delete_history_priv enum('N','Y
ALTER TABLE db change Truncate_versioning_priv Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
SET @had_user_delete_history_priv := 0;
SELECT @had_user_delete_history_priv :=1 FROM user WHERE Delete_history_priv LIKE '%';
SELECT @had_user_delete_history_priv :=1 FROM user WHERE Delete_history_priv IS NOT NULL;
ALTER TABLE user add Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N' after Create_tablespace_priv;
ALTER TABLE user modify Delete_history_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL DEFAULT 'N';
......
......@@ -1407,8 +1407,10 @@ bool Field::check_vcol_sql_mode_dependency(THD *thd, vcol_init_mode mode) const
DBUG_ASSERT(vcol_info);
if ((flags & PART_KEY_FLAG) != 0 || stored_in_db())
{
Sql_mode_dependency valdep= vcol_info->expr->value_depends_on_sql_mode();
sql_mode_t cnvdep= conversion_depends_on_sql_mode(thd, vcol_info->expr);
Sql_mode_dependency dep=
vcol_info->expr->value_depends_on_sql_mode() &
(valdep | Sql_mode_dependency(0, cnvdep)) &
Sql_mode_dependency(~0, ~can_handle_sql_mode_dependency_on_store());
if (dep)
{
......@@ -5063,6 +5065,14 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
}
sql_mode_t
Field_timestamp::conversion_depends_on_sql_mode(THD *thd, Item *expr) const
{
return expr->datetime_precision(thd) > decimals() ?
MODE_TIME_ROUND_FRACTIONAL : 0;
}
int Field_timestamp::save_in_field(Field *to)
{
ulong sec_part;
......@@ -5829,6 +5839,14 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
** In number context: HHMMSS
** Stored as a 3 byte unsigned int
****************************************************************************/
sql_mode_t
Field_time::conversion_depends_on_sql_mode(THD *thd, Item *expr) const
{
return expr->time_precision(thd) > decimals() ?
MODE_TIME_ROUND_FRACTIONAL : 0;
}
int Field_time::store_TIME_with_warning(const Time *t,
const ErrConv *str, int warn)
{
......@@ -6737,6 +6755,15 @@ void Field_datetime::store_TIME(const MYSQL_TIME *ltime)
int8store(ptr,tmp);
}
sql_mode_t
Field_datetime::conversion_depends_on_sql_mode(THD *thd, Item *expr) const
{
return expr->datetime_precision(thd) > decimals() ?
MODE_TIME_ROUND_FRACTIONAL : 0;
}
bool Field_datetime::send_binary(Protocol *protocol)
{
MYSQL_TIME tm;
......
......@@ -1340,6 +1340,11 @@ class Field: public Value_source
{
return 0;
}
virtual sql_mode_t conversion_depends_on_sql_mode(THD *thd,
Item *expr) const
{
return (sql_mode_t) 0;
}
virtual sql_mode_t can_handle_sql_mode_dependency_on_store() const
{
return 0;
......@@ -3024,6 +3029,7 @@ class Field_timestamp :public Field_temporal {
const Relay_log_info *rli,
const Conv_param &param) const override;
Copy_func *get_copy_func(const Field *from) const override;
sql_mode_t conversion_depends_on_sql_mode(THD *, Item *) const override;
int store(const char *to,size_t length,CHARSET_INFO *charset) override;
int store(double nr) override;
int store(longlong nr, bool unsigned_val) override;
......@@ -3398,6 +3404,7 @@ class Field_time :public Field_temporal {
return real_type() == from->real_type() &&
decimals() == from->decimals();
}
sql_mode_t conversion_depends_on_sql_mode(THD *, Item *) const override;
int store_time_dec(const MYSQL_TIME *ltime, uint dec) override;
int store(const char *to,size_t length,CHARSET_INFO *charset) override;
int store(double nr) override;
......@@ -3547,6 +3554,7 @@ class Field_datetime :public Field_temporal_with_date {
{ return &type_handler_datetime; }
enum ha_base_keytype key_type() const override
{ return HA_KEYTYPE_ULONGLONG; }
sql_mode_t conversion_depends_on_sql_mode(THD *, Item *) const override;
enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli,
const Conv_param &param) const override;
......
......@@ -2938,10 +2938,10 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
const char *sname;
switch (pos->sj_strategy) {
case SJ_OPT_MATERIALIZE:
sname= "SJ-Materialize";
sname= "SJ-Materialization";
break;
case SJ_OPT_MATERIALIZE_SCAN:
sname= "SJ-Materialize-Scan";
sname= "SJ-Materialization-Scan";
break;
case SJ_OPT_FIRST_MATCH:
sname= "FirstMatch";
......@@ -3203,7 +3203,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
(new_join_tab->table->map & loosescan_need_tables))
{
Json_writer_object trace(join->thd);
trace.add("strategy", "SJ-Materialization-Scan");
trace.add("strategy", "LooseScan");
/*
Ok we have LooseScan plan and also have all LooseScan sj-nest's
inner tables and outer correlated tables into the prefix.
......@@ -3899,6 +3899,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
if (pos->sj_strategy == SJ_OPT_DUPS_WEEDOUT)
{
Json_writer_object semijoin_strategy(thd);
semijoin_strategy.add("semi_join_strategy","DuplicateWeedout");
/*
Duplicate Weedout starting at pos->first_dupsweedout_table, ending at
this table.
......
......@@ -17,7 +17,7 @@
#include "mariadb.h"
#include "set_var.h"
void Sql_mode_dependency::push_dependency_warnings(THD *thd)
void Sql_mode_dependency::push_dependency_warnings(THD *thd) const
{
sql_mode_t all= m_hard | m_soft;
for (uint i= 0; all ; i++, all >>= 1)
......
......@@ -155,7 +155,7 @@ class Sql_mode_dependency
m_soft= 0;
return *this;
}
void push_dependency_warnings(THD *thd);
void push_dependency_warnings(THD *thd) const;
};
......
......@@ -527,7 +527,6 @@ void init_update_queries(void)
server_command_flags[COM_STMT_SEND_LONG_DATA]= CF_SKIP_WSREP_CHECK;
server_command_flags[COM_REGISTER_SLAVE]= CF_SKIP_WSREP_CHECK;
server_command_flags[COM_MULTI]= CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI;
server_command_flags[CF_NO_COM_MULTI]= CF_NO_COM_MULTI;
/* Initialize the sql command flags array. */
memset(sql_command_flags, 0, sizeof(sql_command_flags));
......
......@@ -455,8 +455,8 @@ void wsrep_delete_threadvars()
DBUG_ASSERT(pthread_getspecific(THR_KEY_mysys));
/* Reset psi state to avoid deallocating applier thread
psi_thread. */
PSI_thread *psi_thread= PSI_CALL_get_thread();
#ifdef HAVE_PSI_INTERFACE
PSI_thread *psi_thread= PSI_CALL_get_thread();
if (PSI_server)
{
PSI_server->set_thread(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment