Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä 2021-10-21 15:26:25 +03:00
commit 5f8561a6bc
84 changed files with 2228 additions and 595 deletions

View File

@ -866,7 +866,25 @@ int main()
long long int *ptr= &var;
return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
}"
HAVE_GCC_C11_ATOMICS)
HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
IF (HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
SET(HAVE_GCC_C11_ATOMICS True)
ELSE()
SET(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
LIST(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
CHECK_CXX_SOURCE_COMPILES("
int main()
{
long long int var= 1;
long long int *ptr= &var;
return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
}"
HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
SET(HAVE_GCC_C11_ATOMICS True)
ENDIF()
SET(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
ENDIF()
IF(WITH_VALGRIND)
SET(HAVE_valgrind 1)

View File

@ -3000,5 +3000,38 @@ DROP TABLE t1;
#
SET DEFAULT_STORAGE_ENGINE=Default;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection= utf16le;
CREATE TABLE kv (v TEXT CHARACTER SET latin1);
CREATE TABLE t (a INT);
CREATE VIEW v AS SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
LOAD DATA INFILE 'MYSQLD_DATADIR/test/v.frm' REPLACE INTO TABLE kv CHARACTER SET latin1;
SELECT LOWER(v) FROM kv WHERE v LIKE _binary'query=%';
LOWER(v)
query=select `information_schema`.`tables`.`table_catalog` as `table_catalog`,`information_schema`.`tables`.`table_schema` as `table_schema`,`information_schema`.`tables`.`table_name` as `table_name`,`information_schema`.`tables`.`table_type` as `table_type`,`information_schema`.`tables`.`engine` as `engine`,`information_schema`.`tables`.`version` as `version`,`information_schema`.`tables`.`row_format` as `row_format`,`information_schema`.`tables`.`table_rows` as `table_rows`,`information_schema`.`tables`.`avg_row_length` as `avg_row_length`,`information_schema`.`tables`.`data_length` as `data_length`,`information_schema`.`tables`.`max_data_length` as `max_data_length`,`information_schema`.`tables`.`index_length` as `index_length`,`information_schema`.`tables`.`data_free` as `data_free`,`information_schema`.`tables`.`auto_increment` as `auto_increment`,`information_schema`.`tables`.`create_time` as `create_time`,`information_schema`.`tables`.`update_time` as `update_time`,`information_schema`.`tables`.`check_time` as `check_time`,`information_schema`.`tables`.`table_collation` as `table_collation`,`information_schema`.`tables`.`checksum` as `checksum`,`information_schema`.`tables`.`create_options` as `create_options`,`information_schema`.`tables`.`table_comment` as `table_comment`,`information_schema`.`tables`.`max_index_length` as `max_index_length`,`information_schema`.`tables`.`temporary` as `temporary` from `information_schema`.`tables` where `information_schema`.`tables`.`table_name` = 't1'
TRUNCATE TABLE kv;
SELECT * FROM v;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP VIEW v;
DROP TABLE t;
DROP TABLE kv;
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP TABLE t;
CREATE TABLE t (a INT);
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_NAME HEX(TABLE_NAME)
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
TABLE_NAME TABLE_SCHEMA HEX(TABLE_NAME)
DROP TABLE t;
SET NAMES utf8;
#
# End of 10.2 tests
#

View File

@ -3,6 +3,7 @@
-- source include/have_utf32.inc
-- source include/have_utf8mb4.inc
let $MYSQLD_DATADIR= `select @@datadir`;
SET TIME_ZONE='+03:00';
@ -810,6 +811,42 @@ let $coll='utf16le_nopad_bin';
let $coll_pad='utf16le_bin';
--source include/ctype_pad_all_engines.inc
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection= utf16le;
CREATE TABLE kv (v TEXT CHARACTER SET latin1);
CREATE TABLE t (a INT);
CREATE VIEW v AS SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v.frm' REPLACE INTO TABLE kv CHARACTER SET latin1;
SELECT LOWER(v) FROM kv WHERE v LIKE _binary'query=%';
TRUNCATE TABLE kv;
SELECT * FROM v;
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP VIEW v;
DROP TABLE t;
DROP TABLE kv;
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP TABLE t;
CREATE TABLE t (a INT);
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
DROP TABLE t;
SET NAMES utf8;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -11244,6 +11244,23 @@ DROP TABLE t1;
#
SET DEFAULT_STORAGE_ENGINE=Default;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE VIEW v1 AS SELECT 'ä' AS c1;
SELECT c1, HEX(c1) FROM v1;
c1 HEX(c1)
ä E4
CREATE TABLE kv (v BLOB);
LOAD DATA INFILE 'MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv;
SELECT * FROM kv WHERE v LIKE _binary'query=%';
v
query=select 'ä' AS `c1`
DROP TABLE kv;
DROP VIEW v1;
SET NAMES utf8;
#
# End of 10.2 tests
#
#

View File

@ -2,6 +2,8 @@
# Tests with the utf8 character set
#
let $MYSQLD_DATADIR= `select @@datadir`;
let collation=utf8_unicode_ci;
--source include/have_collation.inc
SET TIME_ZONE='+03:00';
@ -2166,6 +2168,22 @@ let $coll='utf8_nopad_bin';
let $coll_pad='utf8_bin';
--source include/ctype_pad_all_engines.inc
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE VIEW v1 AS SELECT 'ä' AS c1;
SELECT c1, HEX(c1) FROM v1;
CREATE TABLE kv (v BLOB);
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv;
SELECT * FROM kv WHERE v LIKE _binary'query=%';
DROP TABLE kv;
DROP VIEW v1;
SET NAMES utf8;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -934,6 +934,12 @@ CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
cf cd
0 0
#
# MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice.
#
SELECT JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' );
JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' )
["x"]
#
# End of 10.2 tests
#
#

View File

@ -551,6 +551,12 @@ SELECT
CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
--echo #
--echo # MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice.
--echo #
SELECT JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' );
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -2242,6 +2242,26 @@ SELECT * FROM v LIMIT ROWS EXAMINED 9;
ERROR HY000: Sort aborted:
DROP VIEW v;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
DROP TABLE t;
CREATE TABLE `a/~.b` (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='a/~.b';
TABLE_SCHEMA TABLE_NAME
test a/~.b
DROP TABLE `a/~.b`;
CREATE DATABASE `a/~.b`;
CREATE TABLE `a/~.b`.t1 (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='a/~.b';
TABLE_SCHEMA TABLE_NAME
a/~.b t1
DROP DATABASE `a/~.b`;
#
# End of 10.2 Test
#
#

View File

@ -1948,6 +1948,27 @@ SELECT * FROM v LIMIT ROWS EXAMINED 9;
DROP VIEW v;
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
# Expect empty sets if requested TABLE_NAME or TABLE_SCHEMA with zero bytes
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
DROP TABLE t;
# Make sure check_table_name() does not reject special characters
CREATE TABLE `a/~.b` (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='a/~.b';
DROP TABLE `a/~.b`;
# Make sure check_db_name() does not reject special characters
CREATE DATABASE `a/~.b`;
CREATE TABLE `a/~.b`.t1 (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='a/~.b';
DROP DATABASE `a/~.b`;
--echo #
--echo # End of 10.2 Test
--echo #

View File

@ -0,0 +1 @@
--innodb-page-size=8K

View File

@ -131,3 +131,6 @@ connection default;
drop table t1;
disconnect con1;
disconnect con2;
# MDEV-20131 Assertion `!pk->has_virtual()' failed
create table t1 (a text, primary key(a(1871))) engine=innodb;
ERROR 42000: Specified key was too long; max key length is 1536 bytes

View File

@ -138,3 +138,8 @@ connection default;
drop table t1;
disconnect con1;
disconnect con2;
--echo # MDEV-20131 Assertion `!pk->has_virtual()' failed
--error ER_TOO_LONG_KEY
create table t1 (a text, primary key(a(1871))) engine=innodb;

View File

@ -79,7 +79,7 @@ Database: ``
Table: ``
Org_table: ``
Type: LONG_BLOB (format=json)
Collation: binary (63)
Collation: latin1_swedish_ci (8)
Length: 4294967295
Max_length: 0
Decimals: 0

View File

@ -842,6 +842,78 @@ count(*)
5
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
#
# Ensure that mysql_upgrade accounted for 0 password_last_changed
# and doesn't PASSWORD EXPIRE a user account because < 10.4 zeroed it.
#
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
drop table mysql.user;
truncate table mysql.tables_priv;
FLUSH TABLES mysql.user;
FLUSH PRIVILEGES;
CREATE USER mariadb_102;
UPDATE mysql.user SET password_last_changed=0 WHERE user='mariadb_102';
FLUSH PRIVILEGES;
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_bak 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
mysql.user OK
Upgrading from a version before MariaDB-10.1
Phase 2/7: Installing used storage engines
Checking for tables with unknown storage engine
Phase 3/7: Fixing views
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
SHOW CREATE USER mariadb_102;
CREATE USER for mariadb_102@%
CREATE USER `mariadb_102`@`%`
connect con1,localhost,mariadb_102;
select current_user();
current_user()
mariadb_102@%
disconnect con1;
connection default;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# End of 10.4 tests
#
# Check that mysql_upgrade can be run on mysqldump

View File

@ -356,6 +356,44 @@ select count(*) from mysql.global_priv;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
#
# MDEV-26363 Former mysql-5.7 tables have password_last_changed to 0
# on MariaDB updates, resulting in mysql_upgrade leaving them
# with password expired.
#
--echo #
--echo # Ensure that mysql_upgrade accounted for 0 password_last_changed
--echo # and doesn't PASSWORD EXPIRE a user account because < 10.4 zeroed it.
--echo #
--source include/switch_to_mysql_user.inc
drop view mysql.user_bak;
drop table mysql.user;
truncate table mysql.tables_priv;
--copy_file std_data/mysql57user.frm $MYSQLD_DATADIR/mysql/user.frm
--copy_file std_data/mysql57user.MYI $MYSQLD_DATADIR/mysql/user.MYI
--copy_file std_data/mysql57user.MYD $MYSQLD_DATADIR/mysql/user.MYD
FLUSH TABLES mysql.user;
FLUSH PRIVILEGES;
CREATE USER mariadb_102;
# manually set the value like <10.4 previously did for testing mysql_upgrade.
UPDATE mysql.user SET password_last_changed=0 WHERE user='mariadb_102';
FLUSH PRIVILEGES;
--exec $MYSQL_UPGRADE --force 2>&1
# Should not have "PASSWORD EXPIRED"
SHOW CREATE USER mariadb_102;
connect con1,localhost,mariadb_102;
select current_user();
disconnect con1;
connection default;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo # End of 10.4 tests
#

View File

@ -972,6 +972,30 @@ DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
#END OF BUG#11763507 test.
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE PROCEDURE p1()
BEGIN
DECLARE a VARCHAR(10) CHARACTER SET utf8;
SET a='ä';
SELECT a, 'ä' AS b;
END;
$$
SHOW PROCEDURE CODE p1;
Pos Instruction
0 set a@0 NULL
1 set a@0 'ä'
2 stmt 0 "SELECT a, 'ä' AS b"
CALL p1;
a b
ä ä
DROP PROCEDURE p1;
#
# End of 10.2 tests
#
#
# MDEV-13581 ROW TYPE OF t1 and t1%ROWTYPE for routine parameters
#
CREATE TABLE t1 (a INT, b TEXT);
@ -1330,6 +1354,9 @@ Pos Instruction
5 hpop 1
drop function f1;
#
# End of 10.3 tests
#
#
# MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr
#
CREATE OR REPLACE PROCEDURE p1()
@ -1344,3 +1371,6 @@ Pos Instruction
1 stmt 31 "SET GLOBAL max_error_count=60"
2 stmt 0 "SELECT @@GLOBAL.max_allowed_packet, @..."
DROP PROCEDURE p1;
#
# End of 10.5 tests
#

View File

@ -737,6 +737,30 @@ DROP FUNCTION testf_bug11763507;
--echo #END OF BUG#11763507 test.
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE a VARCHAR(10) CHARACTER SET utf8;
SET a='ä';
SELECT a, 'ä' AS b;
END;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
CALL p1;
DROP PROCEDURE p1;
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # MDEV-13581 ROW TYPE OF t1 and t1%ROWTYPE for routine parameters
--echo #
@ -948,6 +972,10 @@ delimiter ;|
show function code f1;
drop function f1;
--echo #
--echo # End of 10.3 tests
--echo #
--echo #
--echo # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr
@ -963,3 +991,7 @@ $$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@ -121,8 +121,8 @@ js0 js1 js2 js3
SELECT js0, JSON_COMPACT(js0), JSON_COMPACT('{}') FROM t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t1 t1 js0 js0 252 (format=json) 4294967295 0 Y 144 0 33
def JSON_COMPACT(js0) 251 (format=json) 4294967295 0 Y 128 0 63
def JSON_COMPACT('{}') 253 (format=json) 6 0 Y 128 0 63
def JSON_COMPACT(js0) 251 (format=json) 4294967295 0 Y 128 0 33
def JSON_COMPACT('{}') 253 (format=json) 6 0 Y 0 0 33
js0 JSON_COMPACT(js0) JSON_COMPACT('{}')
DROP TABLE t1;
#

View File

@ -6835,6 +6835,17 @@ SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
drop view v1;
drop table t1;
#
# MDEV-26299: Some views force server (and mysqldump) to generate
# invalid SQL for their definitions
#
create view v1 as
select * from
(select
"12345678901234567890123456789012345678901234567890123456789012345") as t1;
drop view v1;
CREATE VIEW v1 AS select `t1`.`12345678901234567890123456789012345678901234567890123456789012345` AS `Name_exp_1` from (select '12345678901234567890123456789012345678901234567890123456789012345') `t1`;
drop view v1;
#
# End of 10.2 tests
#
#

View File

@ -6549,6 +6549,25 @@ SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
drop view v1;
drop table t1;
--echo #
--echo # MDEV-26299: Some views force server (and mysqldump) to generate
--echo # invalid SQL for their definitions
--echo #
create view v1 as
select * from
(select
"12345678901234567890123456789012345678901234567890123456789012345") as t1;
let $definition=`select VIEW_DEFINITION from information_schema.views where TABLE_NAME="v1"`;
drop view v1;
eval CREATE VIEW v1 AS $definition;
drop view v1;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -453,6 +453,21 @@ Message XAER_RMFAIL: The command cannot be executed when global transaction is i
xa commit 'foo';
drop table t1;
#
# MDEV-22445 Crash on HANDLER READ NEXT after XA PREPARE
#
CREATE TABLE t (a INT KEY) ENGINE=InnoDB;
HANDLER t OPEN AS t;
XA START '0';
SELECT * FROM t;
a
XA END '0';
XA PREPARE '0';
HANDLER t READ NEXT;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
# Cleanup
XA COMMIT '0';
DROP TABLE t;
#
# End of 10.2 tests
#
XA BEGIN 'xid';

View File

@ -596,6 +596,23 @@ show status like 'foo';
xa commit 'foo';
drop table t1;
--echo #
--echo # MDEV-22445 Crash on HANDLER READ NEXT after XA PREPARE
--echo #
CREATE TABLE t (a INT KEY) ENGINE=InnoDB;
HANDLER t OPEN AS t;
XA START '0';
SELECT * FROM t;
XA END '0';
XA PREPARE '0';
--error ER_XAER_RMFAIL
HANDLER t READ NEXT;
--echo # Cleanup
XA COMMIT '0';
DROP TABLE t;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -10,9 +10,9 @@ connection node_2;
SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
SELECT COUNT(*) AS EXPECT_0 FROM t1;
EXPECT_0
0
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
FLUSH TABLES WITH READ LOCK;;
@ -29,12 +29,12 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
connection node_2a;
UNLOCK TABLES;
connection node_2;
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
SELECT COUNT(*) AS EXPECT_1 FROM t1;
EXPECT_1
1
INSERT INTO t1 VALUES (3);
connection node_1;
SELECT COUNT(*) = 2 FROM t1;
COUNT(*) = 2
1
SELECT COUNT(*) AS EXPECT_2 FROM t1;
EXPECT_2
2
DROP TABLE t1;

View File

@ -18,7 +18,8 @@
CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'
--source include/wait_condition.inc
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
@ -31,7 +32,7 @@ SET SESSION wsrep_sync_wait = 0;
# Wait until applier has blocked
--source include/galera_wait_sync_point.inc
SELECT COUNT(*) = 0 FROM t1;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2a
@ -61,9 +62,11 @@ INSERT INTO t1 VALUES (2);
UNLOCK TABLES;
--connection node_2
SELECT COUNT(*) = 1 FROM t1;
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1 FROM t1;
INSERT INTO t1 VALUES (3);
--connection node_1
SELECT COUNT(*) = 2 FROM t1;
SELECT COUNT(*) AS EXPECT_2 FROM t1;
DROP TABLE t1;

View File

@ -589,3 +589,14 @@ ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 7,
--disable_info
DROP TABLE t1;
--enable_warnings
--echo #
--echo # MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
--echo #
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let SEARCH_PATTERN=Incorrect information in file: './test/MDEV_26262.frm'
--source include/search_pattern_in_file.inc

View File

@ -703,6 +703,12 @@ ADD COLUMN c INT AS (1 + DEFAULT(a)) VIRTUAL;
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
DROP TABLE t1;
#
# MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
#
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
ERROR 01000: Expression for field `b` is referring to uninitialized field `b`
NOT FOUND /Incorrect information in file: './test/MDEV_26262.frm'/ in mysqld.1.err
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;

View File

@ -703,6 +703,12 @@ ADD COLUMN c INT AS (1 + DEFAULT(a)) VIRTUAL;
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
DROP TABLE t1;
#
# MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
#
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
ERROR 01000: Expression for field `b` is referring to uninitialized field `b`
NOT FOUND /Incorrect information in file: './test/MDEV_26262.frm'/ in mysqld.1.err
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;

View File

@ -20,3 +20,12 @@
SET @save_format = @@GLOBAL.innodb_default_row_format;
SET GLOBAL innodb_default_row_format = redundant;
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
@@ -49,7 +49,7 @@
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
SHOW WARNINGS;
Level Code Message
-Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0
+Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=REDUNDANT
Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options")
Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;

View File

@ -42,3 +42,26 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
SET @save_level=@@GLOBAL.innodb_compression_level;
SET GLOBAL innodb_compression_level=0;
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0
Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options")
Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC page_compressed=1;
SET GLOBAL innodb_compression_level=0;
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=INPLACE;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'PAGE_COMPRESSED'
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=COPY;
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
DROP TABLE t;
SET GLOBAL innodb_compression_level=@save_level;

View File

@ -24,8 +24,7 @@ SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
COUNT(*)
1
# INSERT lots of data in table 'big': begin
# INSERT lots of data in table 'big': end
INSERT INTO big SELECT REPEAT('a', 1024) FROM seq_1_to_10240;
SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
COUNT(*)

View File

@ -44,3 +44,28 @@ TRUNCATE TABLE t1;
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
SHOW TABLE STATUS LIKE 't1';
DROP TABLE t1;
SET @save_level=@@GLOBAL.innodb_compression_level;
SET GLOBAL innodb_compression_level=0;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
SHOW WARNINGS;
--disable_warnings
--error 0,ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
--error 0,ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
DROP TABLE IF EXISTS t;
--enable_warnings
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC page_compressed=1;
SET GLOBAL innodb_compression_level=0;
--error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=INPLACE;
--error ER_CANT_CREATE_TABLE
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=COPY;
DROP TABLE t;
SET GLOBAL innodb_compression_level=@save_level;

View File

@ -1 +1 @@
--innodb-buffer-pool-size=10M
--innodb-buffer-pool-size=5M

View File

@ -10,6 +10,7 @@
-- source include/not_embedded.inc
# This test is slow on buildbot.
--source include/big_test.inc
--source include/have_sequence.inc
CREATE TABLE t (a INT) ENGINE=INNODB;
@ -33,18 +34,7 @@ SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
# evict table 't' by inserting as much data as the BP size itself
-- echo # INSERT lots of data in table 'big': begin
-- disable_query_log
BEGIN;
-- let $i = 10240
while ($i)
{
INSERT INTO big VALUES (REPEAT('a', 1024));
dec $i;
}
COMMIT;
-- enable_query_log
-- echo # INSERT lots of data in table 'big': end
INSERT INTO big SELECT REPEAT('a', 1024) FROM seq_1_to_10240;
# confirm that all pages for table 't' have been evicted
SELECT COUNT(*) FROM information_schema.innodb_buffer_page

View File

@ -313,9 +313,7 @@ FTS_DOC_ID
65536
131071
drop table t1;
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
ERROR HY000: Invalid InnoDB FTS Doc ID
DROP TABLE t1;

View File

@ -0,0 +1,131 @@
#
# Bug#32831765 SERVER HITS OOM CONDITION WHEN LOADING TWO
# INNODB TABLES WITH FTS INDEXES
#
create table t1 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t2 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t3 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t4 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
#create procedure to inset into the table.
CREATE PROCEDURE `proc_insert`(IN tab_name VARCHAR(40))
BEGIN
DECLARE i INT DEFAULT 1;
SET @insert_tbl =CONCAT('INSERT INTO ', tab_name, '( `col01`, `col02`,
`col03`, `col04`, `col05`, `col06`, `col07`, `col08`, `col09`, `col10`,
`col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`,
`col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`,
`col27`, `col28`, `col29`, `col30`)
VALUES ( MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()))');
PREPARE ins_stmt FROM @insert_tbl;
while (i <= 2000) DO
EXECUTE ins_stmt;
SET i = i + 1;
END WHILE;
DEALLOCATE PREPARE ins_stmt;
END |
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,fts_optimize_wq_count_check";
connect con1,localhost,root,,;
call proc_insert('t1');
connect con2,localhost,root,,;
call proc_insert('t1');
connect con3,localhost,root,,;
call proc_insert('t2');
connect con4,localhost,root,,;
call proc_insert('t2');
connect con5,localhost,root,,;
call proc_insert('t3');
connect con6,localhost,root,,;
call proc_insert('t3');
connect con7,localhost,root,,;
call proc_insert('t4');
connection default;
call proc_insert('t4');
SET GLOBAL debug_dbug= @save_dbug;
connection con1;
disconnect con1;
connection con2;
disconnect con2;
connection con3;
disconnect con3;
connection con4;
disconnect con4;
connection con5;
disconnect con5;
connection con6;
disconnect con6;
connection con7;
disconnect con7;
connection default;
DROP TABLE t1,t2,t3,t4;
DROP PROCEDURE proc_insert;

View File

@ -972,3 +972,24 @@ SELECT * FROM information_schema.innodb_ft_deleted;
DOC_ID
DROP TABLE t1;
SET GLOBAL innodb_ft_aux_table=DEFAULT;
#
# MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
# is greater than 4294967295
#
CREATE TABLE t1(
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
FULLTEXT KEY (f1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'txt','bbb');
UPDATE t1 SET FTS_DOC_ID = 4294967298;
SELECT * FROM t1 WHERE match(f1) against("txt");
FTS_DOC_ID f1 f2
4294967298 txt bbb
SET @@session.insert_id = 100000000000;
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
CREATE FULLTEXT INDEX i ON t1 (f2);
SELECT * FROM t1 WHERE match(f2) against("bbb");
FTS_DOC_ID f1 f2
4294967298 txt bbb
100000000000 aaa bbb
DROP TABLE t1;

View File

@ -277,9 +277,7 @@ insert into t1(f1, f2) values(3, "This is the third record");
select FTS_DOC_ID from t1;
drop table t1;
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
--error 182
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
DROP TABLE t1;

View File

@ -0,0 +1,164 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/big_test.inc
--echo #
--echo # Bug#32831765 SERVER HITS OOM CONDITION WHEN LOADING TWO
--echo # INNODB TABLES WITH FTS INDEXES
--echo #
create table t1 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t2 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t3 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t4 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
delimiter |;
--echo #create procedure to inset into the table.
CREATE PROCEDURE `proc_insert`(IN tab_name VARCHAR(40))
BEGIN
DECLARE i INT DEFAULT 1;
SET @insert_tbl =CONCAT('INSERT INTO ', tab_name, '( `col01`, `col02`,
`col03`, `col04`, `col05`, `col06`, `col07`, `col08`, `col09`, `col10`,
`col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`,
`col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`,
`col27`, `col28`, `col29`, `col30`)
VALUES ( MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()))');
PREPARE ins_stmt FROM @insert_tbl;
while (i <= 2000) DO
EXECUTE ins_stmt;
SET i = i + 1;
END WHILE;
DEALLOCATE PREPARE ins_stmt;
END |
delimiter ;|
# Ensure that the number of SYNC requests will not exceed 1000.
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,fts_optimize_wq_count_check";
connect (con1,localhost,root,,);
send call proc_insert('t1');
connect (con2,localhost,root,,);
send call proc_insert('t1');
connect (con3,localhost,root,,);
send call proc_insert('t2');
connect (con4,localhost,root,,);
send call proc_insert('t2');
connect (con5,localhost,root,,);
send call proc_insert('t3');
connect (con6,localhost,root,,);
send call proc_insert('t3');
connect (con7,localhost,root,,);
send call proc_insert('t4');
connection default;
call proc_insert('t4');
SET GLOBAL debug_dbug= @save_dbug;
connection con1;
reap;
disconnect con1;
connection con2;
reap;
disconnect con2;
connection con3;
reap;
disconnect con3;
connection con4;
reap;
disconnect con4;
connection con5;
reap;
disconnect con5;
connection con6;
reap;
disconnect con6;
connection con7;
reap;
disconnect con7;
connection default;
DROP TABLE t1,t2,t3,t4;
DROP PROCEDURE proc_insert;

View File

@ -942,3 +942,21 @@ SET GLOBAL innodb_ft_aux_table='test/t1';
SELECT * FROM information_schema.innodb_ft_deleted;
DROP TABLE t1;
SET GLOBAL innodb_ft_aux_table=DEFAULT;
--echo #
--echo # MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
--echo # is greater than 4294967295
--echo #
CREATE TABLE t1(
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
FULLTEXT KEY (f1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'txt','bbb');
UPDATE t1 SET FTS_DOC_ID = 4294967298;
SELECT * FROM t1 WHERE match(f1) against("txt");
SET @@session.insert_id = 100000000000;
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
CREATE FULLTEXT INDEX i ON t1 (f2);
SELECT * FROM t1 WHERE match(f2) against("bbb");
# Cleanup
DROP TABLE t1;

View File

@ -165,3 +165,23 @@ flush privileges;
uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
drop user foo1;
#
# MDEV-26650: Failed ALTER USER/GRANT statement removes the
# password from the cache
#
create user foo1@localhost identified by '<GDFH:3ghj';
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
install soname "simple_password_check";
ALTER USER foo1@localhost identified by 'foo1';
ERROR HY000: Operation ALTER USER failed for 'foo1'@'localhost'
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
flush privileges;
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
drop user foo1@localhost;
uninstall plugin simple_password_check;

View File

@ -122,3 +122,17 @@ uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
drop user foo1;
--echo #
--echo # MDEV-26650: Failed ALTER USER/GRANT statement removes the
--echo # password from the cache
--echo #
create user foo1@localhost identified by '<GDFH:3ghj';
show grants for foo1@localhost;
install soname "simple_password_check";
--error ER_CANNOT_USER
ALTER USER foo1@localhost identified by 'foo1';
show grants for foo1@localhost;
flush privileges;
show grants for foo1@localhost;
drop user foo1@localhost;
uninstall plugin simple_password_check;

View File

@ -65,3 +65,269 @@ drop role look, isp, xxx, ppp;
connection default;
disconnect con1;
drop user nnnn@'%';
CREATE USER u@localhost;
CREATE ROLE r1;
CREATE ROLE r2;
CREATE ROLE r3;
CREATE ROLE r4;
CREATE ROLE r5;
CREATE ROLE r6;
CREATE ROLE r7;
CREATE ROLE r8;
CREATE ROLE r9;
CREATE ROLE r10;
CREATE ROLE r11;
CREATE ROLE r12;
CREATE ROLE r13;
CREATE ROLE r14;
CREATE ROLE r15;
CREATE ROLE r16;
CREATE ROLE r17;
CREATE ROLE r18;
CREATE ROLE r19;
CREATE ROLE r20;
CREATE ROLE r21;
CREATE ROLE r22;
CREATE ROLE r23;
CREATE ROLE r24;
CREATE ROLE r25;
CREATE ROLE r26;
CREATE ROLE r27;
CREATE ROLE r28;
CREATE ROLE r29;
CREATE ROLE r30;
CREATE ROLE r31;
CREATE ROLE r32;
CREATE ROLE r33;
CREATE ROLE r34;
CREATE ROLE r35;
CREATE ROLE r36;
CREATE ROLE r37;
CREATE ROLE r38;
CREATE ROLE r39;
CREATE ROLE r40;
CREATE ROLE r41;
CREATE ROLE r42;
CREATE ROLE r43;
CREATE ROLE r44;
CREATE ROLE r45;
CREATE ROLE r46;
CREATE ROLE r47;
CREATE ROLE r48;
CREATE ROLE r49;
CREATE ROLE r50;
CREATE ROLE r51;
CREATE ROLE r52;
CREATE ROLE r53;
CREATE ROLE r54;
CREATE ROLE r55;
CREATE ROLE r56;
CREATE ROLE r57;
CREATE ROLE r58;
CREATE ROLE r59;
CREATE ROLE r60;
CREATE ROLE r61;
CREATE ROLE r62;
CREATE ROLE r63;
CREATE ROLE r64;
CREATE ROLE r65;
CREATE ROLE r66;
CREATE ROLE r67;
CREATE ROLE r68;
CREATE ROLE r69;
CREATE ROLE r70;
CREATE ROLE r71;
CREATE ROLE r72;
CREATE ROLE r73;
CREATE ROLE r74;
CREATE ROLE r75;
CREATE ROLE r76;
CREATE ROLE r77;
CREATE ROLE r78;
CREATE ROLE r79;
CREATE ROLE r80;
CREATE ROLE r81;
CREATE ROLE r82;
CREATE ROLE r83;
CREATE ROLE r84;
CREATE ROLE r85;
CREATE ROLE r86;
CREATE ROLE r87;
CREATE ROLE r88;
CREATE ROLE r89;
CREATE ROLE r90;
CREATE ROLE r91;
CREATE ROLE r92;
CREATE ROLE r93;
CREATE ROLE r94;
CREATE ROLE r95;
CREATE ROLE r96;
CREATE ROLE r97;
CREATE ROLE r98;
CREATE ROLE r99;
CREATE ROLE r100;
CREATE ROLE r101;
CREATE ROLE r102;
CREATE ROLE r103;
CREATE ROLE r104;
CREATE ROLE r105;
CREATE ROLE r106;
CREATE ROLE r107;
CREATE ROLE r108;
CREATE ROLE r109;
CREATE ROLE r110;
CREATE ROLE r111;
CREATE ROLE r112;
CREATE ROLE r113;
CREATE ROLE r114;
CREATE ROLE r115;
CREATE ROLE r116;
CREATE ROLE r117;
CREATE ROLE r118;
CREATE ROLE r119;
CREATE ROLE r120;
CREATE ROLE r121;
CREATE ROLE r122;
CREATE ROLE r123;
CREATE ROLE r124;
CREATE ROLE r125;
CREATE ROLE r126;
CREATE ROLE r127;
CREATE ROLE r128;
CREATE ROLE n;
CREATE ROLE d WITH ADMIN n;
CREATE ROLE '%' WITH ADMIN u@localhost;
DROP ROLE n;
CREATE USER 't';
DROP ROLE r1;
DROP ROLE r2;
DROP ROLE r3;
DROP ROLE r4;
DROP ROLE r5;
DROP ROLE r6;
DROP ROLE r7;
DROP ROLE r8;
DROP ROLE r9;
DROP ROLE r10;
DROP ROLE r11;
DROP ROLE r12;
DROP ROLE r13;
DROP ROLE r14;
DROP ROLE r15;
DROP ROLE r16;
DROP ROLE r17;
DROP ROLE r18;
DROP ROLE r19;
DROP ROLE r20;
DROP ROLE r21;
DROP ROLE r22;
DROP ROLE r23;
DROP ROLE r24;
DROP ROLE r25;
DROP ROLE r26;
DROP ROLE r27;
DROP ROLE r28;
DROP ROLE r29;
DROP ROLE r30;
DROP ROLE r31;
DROP ROLE r32;
DROP ROLE r33;
DROP ROLE r34;
DROP ROLE r35;
DROP ROLE r36;
DROP ROLE r37;
DROP ROLE r38;
DROP ROLE r39;
DROP ROLE r40;
DROP ROLE r41;
DROP ROLE r42;
DROP ROLE r43;
DROP ROLE r44;
DROP ROLE r45;
DROP ROLE r46;
DROP ROLE r47;
DROP ROLE r48;
DROP ROLE r49;
DROP ROLE r50;
DROP ROLE r51;
DROP ROLE r52;
DROP ROLE r53;
DROP ROLE r54;
DROP ROLE r55;
DROP ROLE r56;
DROP ROLE r57;
DROP ROLE r58;
DROP ROLE r59;
DROP ROLE r60;
DROP ROLE r61;
DROP ROLE r62;
DROP ROLE r63;
DROP ROLE r64;
DROP ROLE r65;
DROP ROLE r66;
DROP ROLE r67;
DROP ROLE r68;
DROP ROLE r69;
DROP ROLE r70;
DROP ROLE r71;
DROP ROLE r72;
DROP ROLE r73;
DROP ROLE r74;
DROP ROLE r75;
DROP ROLE r76;
DROP ROLE r77;
DROP ROLE r78;
DROP ROLE r79;
DROP ROLE r80;
DROP ROLE r81;
DROP ROLE r82;
DROP ROLE r83;
DROP ROLE r84;
DROP ROLE r85;
DROP ROLE r86;
DROP ROLE r87;
DROP ROLE r88;
DROP ROLE r89;
DROP ROLE r90;
DROP ROLE r91;
DROP ROLE r92;
DROP ROLE r93;
DROP ROLE r94;
DROP ROLE r95;
DROP ROLE r96;
DROP ROLE r97;
DROP ROLE r98;
DROP ROLE r99;
DROP ROLE r100;
DROP ROLE r101;
DROP ROLE r102;
DROP ROLE r103;
DROP ROLE r104;
DROP ROLE r105;
DROP ROLE r106;
DROP ROLE r107;
DROP ROLE r108;
DROP ROLE r109;
DROP ROLE r110;
DROP ROLE r111;
DROP ROLE r112;
DROP ROLE r113;
DROP ROLE r114;
DROP ROLE r115;
DROP ROLE r116;
DROP ROLE r117;
DROP ROLE r118;
DROP ROLE r119;
DROP ROLE r120;
DROP ROLE r121;
DROP ROLE r122;
DROP ROLE r123;
DROP ROLE r124;
DROP ROLE r125;
DROP ROLE r126;
DROP ROLE r127;
DROP ROLE r128;
DROP ROLE d;
DROP ROLE '%';
DROP USER 't';
DROP USER u@localhost;

View File

@ -67,3 +67,34 @@ drop role look, isp, xxx, ppp;
connection default;
disconnect con1;
drop user nnnn@'%';
#
# MDEV-17964 Assertion `status == 0' failed in add_role_user_mapping_action
# upon CREATE USER and DROP ROLE
#
CREATE USER u@localhost;
--let $n= 1
while ($n < 129)
{
eval CREATE ROLE r$n;
inc $n;
}
CREATE ROLE n;
CREATE ROLE d WITH ADMIN n;
CREATE ROLE '%' WITH ADMIN u@localhost;
DROP ROLE n;
CREATE USER 't';
--let $n= 1
while ($n < 129)
{
eval DROP ROLE r$n;
inc $n;
}
DROP ROLE d;
DROP ROLE '%';
DROP USER 't';
DROP USER u@localhost;

View File

@ -0,0 +1,48 @@
# This file ensures that a slave's id filtering variables (i.e. DO_DOMAIN_IDS,
# IGNORE_DOMAIN_IDS, and IGNORE_SERVER_IDS) are cleared after issuing
# `RESET SLAVE ALL`.
#
# param $_do_domain_ids Integer list of values to use for DO_DOMAIN_IDS
# param $_ignore_domain_ids Integer list of values to use for IGNORE_DOMAIN_IDS
# param $_ignore_server_ids Integer list of values to use for IGNORE_SERVER_IDS
#
--echo # Id filtering variable values should be empty initially
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
if (`SELECT "$do_domain_ids_before" != "" OR
"$ignore_domain_ids_before" != "" OR
"$ignore_server_ids_before" != ""`)
{
die("CHANGE MASTER TO id filter variables are not empty initially");
}
--echo # Set id filtering variables
eval CHANGE MASTER TO DO_DOMAIN_IDS=$_do_domain_ids, IGNORE_DOMAIN_IDS=$_ignore_domain_ids, IGNORE_SERVER_IDS=$_ignore_server_ids, MASTER_USE_GTID=SLAVE_POS;
let $do_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
--echo # do domain id list: $do_domain_ids_set
--echo # ignore domain id list: $ignore_domain_ids_set
--echo # ignore server id list: $ignore_server_ids_set
--echo # RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--source include/stop_slave.inc
let $do_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
if (`SELECT "$do_domain_ids_cleared" != "" OR
"$ignore_domain_ids_cleared" != "" OR
"$ignore_server_ids_cleared" != ""`)
{
die("RESET SLAVE ALL did not clear id filtering variables");
}

View File

@ -0,0 +1,43 @@
include/master-slave.inc
[connection master]
#
# Failed CHANGE MASTER TO should not change relay log status
#
connection slave;
include/stop_slave.inc
SET @@debug_dbug="d,simulate_find_log_pos_error";
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
ERROR HY000: Target log not found in binlog index
SET @@debug_dbug="";
include/start_slave.inc
#
# Ensure relay log can be updated after a failed CHANGE MASTER
#
FLUSH RELAY LOGS;
include/wait_for_slave_param.inc [Relay_Log_File]
#
# Slave should continue to receive data from old master after failed
# CHANGE MASTER TO
#
connection master;
CREATE TABLE t1 (a int);
insert into t1 values (1);
connection slave;
connection slave;
#
# Future CHANGE MASTER calls should succeed
#
include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
include/start_slave.inc
########################
# Cleanup
########################
connection master;
DROP TABLE t1;
connection slave;
include/stop_slave.inc
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/rpl_end.inc

View File

@ -0,0 +1,54 @@
include/master-slave.inc
[connection master]
connection slave;
include/stop_slave.inc
#
# Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(), IGNORE_SERVER_IDS=(3), MASTER_USE_GTID=SLAVE_POS;
# do domain id list: 1
# ignore domain id list:
# ignore server id list: 3
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
#
# Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(2), IGNORE_SERVER_IDS=(3), MASTER_USE_GTID=SLAVE_POS;
# do domain id list:
# ignore domain id list: 2
# ignore server id list: 3
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
#
# Category 3) Null check - edge case with all empty lists to ensure a
# lack of specification doesn't break anything
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), IGNORE_SERVER_IDS=(), MASTER_USE_GTID=SLAVE_POS;
# do domain id list:
# ignore domain id list:
# ignore server id list:
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
############################
# Cleanup
############################
connection slave;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/rpl_end.inc

View File

@ -0,0 +1,93 @@
#
# Purpose:
# This test ensures that issuing a CHANGE MASTER will not put a replica into
# an inconsistent state if the slave cannot find the log files (i.e. the call to
# find_log_pos in reset_logs fails). More specifically, right before a replica
# purges the relay logs (part of the `CHANGE MASTER TO` logic), the relay log is
# temporarily closed with state LOG_TO_BE_OPENED. If the server is issued a
# CHANGE MASTER and it errors in-between the temporary log closure and purge,
# i.e. during the function find_log_pos, the log should be closed. The bug
# reported by MDEV-25284 revealed the log is not properly closed, such that
# future relay log updates fail, and future CHANGE MASTER calls crash the
# server.
#
# Methodology:
# This test ensures that the relay log is properly closed by ensuring future
# updates and CHANGE MASTER calls succeed.
#
# References:
# MDEV-25284: Assertion `info->type == READ_CACHE ||
# info->type == WRITE_CACHE' failed
#
--source include/master-slave.inc
--source include/have_debug.inc
--echo #
--echo # Failed CHANGE MASTER TO should not change relay log status
--echo #
--connection slave
--source include/stop_slave.inc
SET @@debug_dbug="d,simulate_find_log_pos_error";
error 1373;
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
SET @@debug_dbug="";
--source include/start_slave.inc
--echo #
--echo # Ensure relay log can be updated after a failed CHANGE MASTER
--echo #
FLUSH RELAY LOGS;
--let $slave_param= Relay_Log_File
--let $slave_param_value= slave-relay-bin.000003
--source include/wait_for_slave_param.inc
--echo #
--echo # Slave should continue to receive data from old master after failed
--echo # CHANGE MASTER TO
--echo #
--connection master
CREATE TABLE t1 (a int);
insert into t1 values (1);
--let $master_checksum= `CHECKSUM TABLE t1`
--sync_slave_with_master
--connection slave
if ($master_checksum != `CHECKSUM TABLE t1`)
{
die("Replica failed to pull data from primary after failed CHANGE MASTER TO");
}
--echo #
--echo # Future CHANGE MASTER calls should succeed
--echo #
--source include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
--source include/start_slave.inc
--echo ########################
--echo # Cleanup
--echo ########################
--connection master
DROP TABLE t1;
--connection slave
--source include/stop_slave.inc
RESET SLAVE ALL;
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--disable_query_log
call mtr.add_suppression("Failed to locate old binlog or relay log files");
--enable_query_log
--source include/rpl_end.inc

View File

@ -0,0 +1,72 @@
#
# Purpose:
# This test validates that after issuing the `SLAVE RESET ALL` command,
# any corresponding IGNORE_DOMAIN_IDS/DO_DOMAIN_IDS and IGNORE_SERVER_IDS
# values are cleared.
#
#
# Methodology:
# To ensure the filtering variables are properly cleared after issuing
# SLAVE RESET ALL, we categorize different combinations of allowable input
# into three different options, and ensure that the variables are cleared for
# each category. The categories are as follows:
# Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
# Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
# Category 3) Null check - edge case with all empty lists to ensure a lack
# of specification doesn't break anything
#
# To specify the values, the variables are set in `CHANGE MASTER TO`. To
# ensure the slave state is correct, we test the domain/server id filtering
# variable values at the following times while testing each category.
#
# Before CHANGE MASTER TO the filtering variables are tested to all be
# empty.
#
# After CHANGE MASTER TO the variables are tested to ensure they reflect
# those set in the CHANGE MASTER command.
#
# After RESET SLAVE ALL the filtering variables are tested to all be
# empty.
#
--source include/master-slave.inc
--source include/have_debug.inc
--connection slave
--source include/stop_slave.inc
--echo #
--echo # Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
--echo #
--let $_do_domain_ids= (1)
--let $_ignore_domain_ids= ()
--let $_ignore_server_ids= (3)
--source include/rpl_reset_slave_all_check.inc
--echo #
--echo # Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
--echo #
--let $_do_domain_ids= ()
--let $_ignore_domain_ids= (2)
--let $_ignore_server_ids= (3)
--source include/rpl_reset_slave_all_check.inc
--echo #
--echo # Category 3) Null check - edge case with all empty lists to ensure a
--echo # lack of specification doesn't break anything
--echo #
--let $_do_domain_ids= ()
--let $_ignore_domain_ids= ()
--let $_ignore_server_ids= ()
--source include/rpl_reset_slave_all_check.inc
--echo ############################
--echo # Cleanup
--echo ############################
--connection slave
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--source include/rpl_end.inc

View File

@ -169,6 +169,10 @@ TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY}
${LIBNSL} ${LIBM} ${LIBRT} ${CMAKE_DL_LIBS} ${LIBSOCKET} ${LIBEXECINFO})
DTRACE_INSTRUMENT(mysys)
IF (HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
TARGET_LINK_LIBRARIES(mysys atomic)
ENDIF()
IF(HAVE_BFD_H)
TARGET_LINK_LIBRARIES(mysys bfd)
ENDIF(HAVE_BFD_H)

View File

@ -815,7 +815,7 @@ IF 'BASE TABLE' = (select table_type from information_schema.tables where table_
'max_statement_time', max_statement_time,
'plugin', if(plugin>'',plugin,if(length(password)=16,'mysql_old_password','mysql_native_password')),
'authentication_string', if(plugin>'' and authentication_string>'',authentication_string,password),
'password_last_changed', if(password_expired='Y', 0, UNIX_TIMESTAMP(password_last_changed)),
'password_last_changed', if(password_expired='Y', 0, if(password_last_changed, UNIX_TIMESTAMP(password_last_changed), UNIX_TIMESTAMP())),
'password_lifetime', ifnull(password_lifetime, -1),
'account_locked', 'Y'=account_locked,
'default_role', default_role,

View File

@ -3812,8 +3812,48 @@ void Item_string::print(String *str, enum_query_type query_type)
}
else
{
// Caller wants a result in the charset of str_value.
str_value.print(str);
/*
We're restoring a parse-able statement from an Item tree.
Make sure to revert character set conversions that previously
happened in the parser when Item_string was created.
*/
if (print_introducer)
{
/*
Print the string as is, without conversion:
Strings with introducers are not converted in the parser.
*/
str_value.print(str);
}
else
{
/*
Print the string with conversion.
Strings without introducers are converted in the parser,
from character_set_client to character_set_connection.
When restoring a CREATE VIEW statement,
- str_value.charsets() contains parse time character_set_connection
- str->charset() contains parse time character_set_client
So we convert the string back from parse-time character_set_connection
to parse time character_set_client.
In some cases, e.g. SHOW PROCEDURE CODE, it's also possible
that str->charset() is "utf8mb3" instead of parse time
character_set_client. In these cases we convert
here from the parse-time character_set_connection to utf8mb3.
QQ: perhaps the code behind SHOW PROCEDURE CODE should
also request the result in the parse-time character_set_client
(like the code restoring CREATE VIEW statements does),
rather than in utf8mb3:
- utf8mb3 does not work well with non-BMP characters (e.g. emoji).
- Simply changing utf8mb3 to utf8mb4 will not fully help:
some character sets have unassigned characters,
they get lost during during cs->utf8mb4->cs round trip.
*/
str_value.print_with_conversion(str, str->charset());
}
}
str->append('\'');

View File

@ -3569,6 +3569,7 @@ const char *Item_func_json_format::func_name() const
bool Item_func_json_format::fix_length_and_dec()
{
decimals= 0;
collation.set(args[0]->collation);
max_length= args[0]->max_length;
maybe_null= 1;
return FALSE;

View File

@ -945,6 +945,20 @@ public:
void unlock_binlog_end_pos() { mysql_mutex_unlock(&LOCK_binlog_end_pos); }
mysql_mutex_t* get_binlog_end_pos_lock() { return &LOCK_binlog_end_pos; }
/*
Ensures the log's state is either LOG_OPEN or LOG_CLOSED. If something
failed along the desired path and left the log in invalid state, i.e.
LOG_TO_BE_OPENED, forces the state to be LOG_CLOSED.
*/
void try_fix_log_state()
{
mysql_mutex_lock(get_log_lock());
/* Only change the log state if it is LOG_TO_BE_OPENED */
if (log_state == LOG_TO_BE_OPENED)
log_state= LOG_CLOSED;
mysql_mutex_unlock(get_log_lock());
}
int wait_for_update_binlog_end_pos(THD* thd, struct timespec * timeout);
/*

View File

@ -5573,20 +5573,14 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
}
}
#ifdef HAVE_QUERY_CACHE
#ifdef WITH_WSREP
#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
/*
Moved invalidation right before the call to rows_event_stmt_cleanup(),
to avoid query cache being polluted with stale entries,
*/
if (! (WSREP(thd) && wsrep_thd_is_applying(thd)))
{
#endif /* WITH_WSREP */
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#ifdef WITH_WSREP
}
#endif /* WITH_WSREP */
#endif
if (WSREP(thd) && wsrep_thd_is_applying(thd))
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#endif /* WITH_WSREP && HAVE_QUERY_CACHE */
}
table= m_table= rgi->m_table_map.get_table(m_table_id);
@ -5787,19 +5781,20 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
restore_empty_query_table_list(thd->lex);
#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
if (WSREP(thd) && wsrep_thd_is_applying(thd))
{
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
}
if (WSREP(thd) && wsrep_thd_is_applying(thd))
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#endif /* WITH_WSREP && HAVE_QUERY_CACHE */
if (unlikely(get_flags(STMT_END_F) &&
(error= rows_event_stmt_cleanup(rgi, thd))))
slave_rows_error_report(ERROR_LEVEL,
thd->is_error() ? 0 : error,
rgi, thd, table,
get_type_str(),
RPL_LOG_NAME, log_pos);
if (get_flags(STMT_END_F))
{
if (unlikely((error= rows_event_stmt_cleanup(rgi, thd))))
slave_rows_error_report(ERROR_LEVEL, thd->is_error() ? 0 : error,
rgi, thd, table, get_type_str(),
RPL_LOG_NAME, log_pos);
if (thd->slave_thread)
free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
}
DBUG_RETURN(error);
err:

View File

@ -170,6 +170,8 @@ void Master_info::clear_in_memory_info(bool all)
{
port= MYSQL_PORT;
host[0] = 0; user[0] = 0; password[0] = 0;
domain_id_filter.clear_ids();
reset_dynamic(&ignore_server_ids);
}
}
@ -1797,6 +1799,12 @@ void Domain_id_filter::reset_filter()
m_filter= false;
}
void Domain_id_filter::clear_ids()
{
reset_dynamic(&m_domain_ids[DO_DOMAIN_IDS]);
reset_dynamic(&m_domain_ids[IGNORE_DOMAIN_IDS]);
}
/**
Update the do/ignore domain id filter lists.

View File

@ -78,6 +78,11 @@ public:
*/
void reset_filter();
/*
Clear do_ids and ignore_ids to disable domain id filtering
*/
void clear_ids();
/*
Update the do/ignore domain id filter lists.

View File

@ -3359,21 +3359,22 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
const Account_options &options,
const privilege_t privileges)
{
ACL_USER_PARAM::AUTH *work_copy= NULL;
if (nauth)
{
if (acl_user->nauth >= nauth)
acl_user->nauth= nauth;
else
acl_user->alloc_auth(&acl_memroot, nauth);
if (!(work_copy= (ACL_USER_PARAM::AUTH*)
alloc_root(thd->mem_root, nauth * sizeof(ACL_USER_PARAM::AUTH))))
return 1;
USER_AUTH *auth= combo.auth;
for (uint i= 0; i < nauth; i++, auth= auth->next)
{
acl_user->auth[i].plugin= auth->plugin;
acl_user->auth[i].auth_string= safe_lexcstrdup_root(&acl_memroot, auth->auth_str);
if (fix_user_plugin_ptr(acl_user->auth + i))
acl_user->auth[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
if (set_user_auth(thd, acl_user->user, acl_user->auth + i, auth->pwtext))
work_copy[i].plugin= auth->plugin;
work_copy[i].auth_string= safe_lexcstrdup_root(&acl_memroot,
auth->auth_str);
if (fix_user_plugin_ptr(work_copy + i))
work_copy[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
if (set_user_auth(thd, acl_user->user, work_copy + i, auth->pwtext))
return 1;
}
}
@ -3401,11 +3402,34 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
if (options.account_locked != ACCOUNTLOCK_UNSPECIFIED)
acl_user->account_locked= options.account_locked == ACCOUNTLOCK_LOCKED;
/* Unexpire the user password */
if (thd->is_error())
{
// If something went wrong (including OOM) we will not spoil acl cache
return 1;
}
/* Unexpire the user password and copy AUTH (when no more errors possible)*/
if (nauth)
{
acl_user->password_expired= false;
acl_user->password_last_changed= thd->query_start();;
acl_user->password_last_changed= thd->query_start();
if (acl_user->nauth >= nauth)
{
acl_user->nauth= nauth;
}
else
{
if (acl_user->alloc_auth(&acl_memroot, nauth))
{
/*
acl_user is a copy, so NULL assigned in case of an error do not
change the acl cache
*/
return 1;
}
}
DBUG_ASSERT(work_copy); // allocated under the same condinition
memcpy(acl_user->auth, work_copy, nauth * sizeof(ACL_USER_PARAM::AUTH));
}
switch (options.password_expire) {
@ -10195,8 +10219,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
LEX_USER *user_from, LEX_USER *user_to)
{
int result= 0;
int idx;
int elements;
bool restart;
const char *UNINIT_VAR(user);
const char *UNINIT_VAR(host);
ACL_USER *acl_user= NULL;
@ -10304,82 +10328,98 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
DBUG_RETURN(-1);
}
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u search user: '%s' host: '%s'",
struct_no, user_from->user.str, user_from->host.str));
#endif
/* Loop over all elements *backwards* (see the comment below). */
for (idx= elements - 1; idx >= 0; idx--)
{
/*
Get a pointer to the element.
*/
switch (struct_no) {
case USER_ACL:
acl_user= dynamic_element(&acl_users, idx, ACL_USER*);
user= acl_user->user.str;
host= acl_user->host.hostname;
break;
/* Loop over elements backwards as it may reduce the number of mem-moves
for dynamic arrays.
case DB_ACL:
acl_db= &acl_dbs.at(idx);
user= acl_db->user;
host= acl_db->host.hostname;
We restart the loop, if we deleted or updated anything in a hash table
because calling my_hash_delete or my_hash_update shuffles elements indices
and we can miss some if we do only one scan.
*/
do {
restart= false;
for (int idx= elements - 1; idx >= 0; idx--)
{
/*
Get a pointer to the element.
*/
switch (struct_no) {
case USER_ACL:
acl_user= dynamic_element(&acl_users, idx, ACL_USER*);
user= acl_user->user.str;
host= acl_user->host.hostname;
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
grant_name= (GRANT_NAME*) my_hash_element(grant_name_hash, idx);
user= grant_name->user;
host= grant_name->host.hostname;
break;
case DB_ACL:
acl_db= &acl_dbs.at(idx);
user= acl_db->user;
host= acl_db->host.hostname;
break;
case PROXY_USERS_ACL:
acl_proxy_user= dynamic_element(&acl_proxy_users, idx, ACL_PROXY_USER*);
user= acl_proxy_user->get_user();
host= acl_proxy_user->get_host();
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
grant_name= (GRANT_NAME*) my_hash_element(grant_name_hash, idx);
user= grant_name->user;
host= grant_name->host.hostname;
break;
case ROLES_MAPPINGS_HASH:
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
user= role_grant_pair->u_uname;
host= role_grant_pair->u_hname;
break;
case PROXY_USERS_ACL:
acl_proxy_user= dynamic_element(&acl_proxy_users, idx, ACL_PROXY_USER*);
user= acl_proxy_user->get_user();
host= acl_proxy_user->get_host();
break;
default:
DBUG_ASSERT(0);
}
if (! host)
host= "";
case ROLES_MAPPINGS_HASH:
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
user= role_grant_pair->u_uname;
host= role_grant_pair->u_hname;
break;
default:
DBUG_ASSERT(0);
}
if (! host)
host= "";
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
struct_no, idx, user, host));
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
struct_no, idx, user, host));
#endif
if (struct_no == ROLES_MAPPINGS_HASH)
{
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
if (user_from->is_role())
if (struct_no == ROLES_MAPPINGS_HASH)
{
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
to check both the user field as well as the role field for a match.
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
if (user_from->is_role())
{
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
to check both the user field as well as the role field for a match.
It is possible to have a role granted to a role. If we are going
to modify the mapping entry, it needs to be done on either on the
"user" end (here represented by a role) or the "role" end. At least
one part must match.
It is possible to have a role granted to a role. If we are going
to modify the mapping entry, it needs to be done on either on the
"user" end (here represented by a role) or the "role" end. At least
one part must match.
If the "user" end has a not-empty host string, it can never match
as we are searching for a role here. A role always has an empty host
string.
*/
if ((*host || strcmp(user_from->user.str, user)) &&
strcmp(user_from->user.str, role))
continue;
If the "user" end has a not-empty host string, it can never match
as we are searching for a role here. A role always has an empty host
string.
*/
if ((*host || strcmp(user_from->user.str, user)) &&
strcmp(user_from->user.str, role))
continue;
}
else
{
if (strcmp(user_from->user.str, user) ||
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
}
else
{
@ -10387,157 +10427,134 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
}
else
{
if (strcmp(user_from->user.str, user) ||
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
result= 1; /* At least one element found. */
if ( drop )
{
elements--;
switch ( struct_no ) {
case USER_ACL:
free_acl_user(dynamic_element(&acl_users, idx, ACL_USER*));
delete_dynamic_element(&acl_users, idx);
break;
result= 1; /* At least one element found. */
if ( drop )
{
elements--;
switch ( struct_no ) {
case USER_ACL:
free_acl_user(dynamic_element(&acl_users, idx, ACL_USER*));
delete_dynamic_element(&acl_users, idx);
break;
case DB_ACL:
acl_dbs.del(idx);
break;
case DB_ACL:
acl_dbs.del(idx);
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
my_hash_delete(grant_name_hash, (uchar*) grant_name);
/*
In our HASH implementation on deletion one elements
is moved into a place where a deleted element was,
and the last element is moved into the empty space.
Thus we need to re-examine the current element, but
we don't have to restart the search from the beginning.
*/
if (idx != elements)
idx++;
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
my_hash_delete(grant_name_hash, (uchar*) grant_name);
restart= true;
break;
case PROXY_USERS_ACL:
delete_dynamic_element(&acl_proxy_users, idx);
break;
case PROXY_USERS_ACL:
delete_dynamic_element(&acl_proxy_users, idx);
break;
case ROLES_MAPPINGS_HASH:
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
if (idx != elements)
idx++;
break;
case ROLES_MAPPINGS_HASH:
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
restart= true;
break;
default:
DBUG_ASSERT(0);
break;
default:
DBUG_ASSERT(0);
break;
}
}
}
else if ( user_to )
{
switch ( struct_no ) {
case USER_ACL:
acl_user->user= safe_lexcstrdup_root(&acl_memroot, user_to->user);
update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str));
acl_user->hostname_length= strlen(acl_user->host.hostname);
break;
else if ( user_to )
{
switch ( struct_no ) {
case USER_ACL:
acl_user->user= safe_lexcstrdup_root(&acl_memroot, user_to->user);
update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str));
acl_user->hostname_length= strlen(acl_user->host.hostname);
break;
case DB_ACL:
acl_db->user= strdup_root(&acl_memroot, user_to->user.str);
update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str));
break;
case DB_ACL:
acl_db->user= strdup_root(&acl_memroot, user_to->user.str);
update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str));
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= grant_name->hash_key;
size_t old_key_length= grant_name->key_length;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= grant_name->hash_key;
size_t old_key_length= grant_name->key_length;
/*
Update the grant structure with the new user name and host name.
*/
grant_name->set_user_details(user_to->host.str, grant_name->db,
user_to->user.str, grant_name->tname,
TRUE);
/*
Update the grant structure with the new user name and host name.
*/
grant_name->set_user_details(user_to->host.str, grant_name->db,
user_to->user.str, grant_name->tname,
TRUE);
/*
Since username is part of the hash key, when the user name
is renamed, the hash key is changed. Update the hash to
ensure that the position matches the new hash key value
*/
my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
old_key_length);
/*
hash_update() operation could have moved element from the tail or
the head of the hash to the current position. But it can never
move an element from the head to the tail or from the tail to the
head over the current element.
So we need to examine the current element once again, but
we don't need to restart the search from the beginning.
*/
idx++;
/*
Since username is part of the hash key, when the user name
is renamed, the hash key is changed. Update the hash to
ensure that the position matches the new hash key value
*/
my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
old_key_length);
restart= true;
break;
}
case PROXY_USERS_ACL:
acl_proxy_user->set_user (&acl_memroot, user_to->user.str);
acl_proxy_user->set_host (&acl_memroot, user_to->host.str);
break;
case ROLES_MAPPINGS_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= role_grant_pair->hashkey.str;
size_t old_key_length= role_grant_pair->hashkey.length;
bool oom;
if (user_to->is_role())
oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname,
role_grant_pair->u_hname,
user_to->user.str, false);
else
oom= role_grant_pair->init(&acl_memroot, user_to->user.str,
user_to->host.str,
role_grant_pair->r_uname, false);
if (oom)
DBUG_RETURN(-1);
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
(uchar*) old_key, old_key_length);
restart= true;
break;
}
default:
DBUG_ASSERT(0);
break;
}
case PROXY_USERS_ACL:
acl_proxy_user->set_user (&acl_memroot, user_to->user.str);
acl_proxy_user->set_host (&acl_memroot, user_to->host.str);
break;
case ROLES_MAPPINGS_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= role_grant_pair->hashkey.str;
size_t old_key_length= role_grant_pair->hashkey.length;
bool oom;
if (user_to->is_role())
oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname,
role_grant_pair->u_hname,
user_to->user.str, false);
else
oom= role_grant_pair->init(&acl_memroot, user_to->user.str,
user_to->host.str,
role_grant_pair->r_uname, false);
if (oom)
DBUG_RETURN(-1);
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
(uchar*) old_key, old_key_length);
idx++; // see the comment above
break;
}
default:
DBUG_ASSERT(0);
}
else
{
/* If search is requested, we do not need to search further. */
break;
}
}
else
{
/* If search is requested, we do not need to search further. */
break;
}
}
} while (restart);
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u result %d", struct_no, result));
#endif

View File

@ -784,6 +784,9 @@ retry:
if (!(handler= mysql_ha_find_handler(thd, &tables->alias)))
goto err0;
if (thd->transaction->xid_state.check_has_uncommitted_xa())
goto err0;
table= handler->table;
tables->table= table; // This is used by fix_fields
table->pos_in_table_list= tables;

View File

@ -3949,6 +3949,16 @@ err:
mi->unlock_slave_threads();
if (ret == FALSE)
my_ok(thd);
else
{
/*
Depending on where CHANGE MASTER failed, the logs may be waiting to be
reopened. This would break future log updates and CHANGE MASTER calls.
`try_fix_log_state()` allows the relay log to fix its state to no longer
expect to be reopened.
*/
mi->rli.relay_log.try_fix_log_state();
}
DBUG_RETURN(ret);
}

View File

@ -27971,6 +27971,11 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
//Item List
bool first= 1;
/*
outer_select() can not be used here because it is for name resolution
and will return NULL at any end of name resolution chain (view/derived)
*/
bool top_level= (get_master()->get_master() == 0);
List_iterator_fast<Item> it(item_list);
Item *item;
while ((item= it++))
@ -27980,7 +27985,8 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
else
str->append(',');
if (is_subquery_function() && item->is_autogenerated_name())
if ((is_subquery_function() && item->is_autogenerated_name()) ||
!item->name.str)
{
/*
Do not print auto-generated aliases in subqueries. It has no purpose
@ -27989,7 +27995,20 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
item->print(str, query_type);
}
else
item->print_item_w_name(str, query_type);
{
/*
Do not print illegal names (if it is not top level SELECT).
Top level view checked (and correct name are assigned),
other cases of top level SELECT are not important, because
it is not "table field".
*/
if (top_level ||
!item->is_autogenerated_name() ||
!check_column_name(item->name.str))
item->print_item_w_name(str, query_type);
else
item->print(str, query_type);
}
}
/*

View File

@ -4450,7 +4450,9 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
if (!lookup_field_vals->wild_table_value &&
lookup_field_vals->table_value.str)
{
if (lookup_field_vals->table_value.length > NAME_LEN)
if (check_table_name(lookup_field_vals->table_value.str,
lookup_field_vals->table_value.length,
false))
{
/*
Impossible value for a table name,
@ -4487,6 +4489,9 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
return (schema_tables_add(thd, table_names,
lookup_field_vals->table_value.str));
if (check_db_name((LEX_STRING*)db_name))
return 0; // Impossible TABLE_SCHEMA name
find_files_result res= find_files(thd, table_names, db_name, path,
&lookup_field_vals->table_value);
if (res != FIND_FILES_OK)

View File

@ -4229,8 +4229,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
else
is_hash_field_needed= true;
}
}
// Catch invalid use of partial keys
@ -4276,11 +4274,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
else
{
if (key->type == Key::UNIQUE)
{
is_hash_field_needed= true;
}
else
if (key->type != Key::UNIQUE)
{
key_part_length= MY_MIN(max_key_length, file->max_key_part_length());
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
@ -4289,6 +4283,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
if (key->type == Key::UNIQUE
&& key_part_length > MY_MIN(max_key_length,
file->max_key_part_length()))
is_hash_field_needed= true;
/* We can not store key_part_length more then 2^16 - 1 in frm */
if (is_hash_field_needed && column->length > UINT_MAX16)
{
@ -4323,7 +4322,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
unique_key=1;
key_info->key_length=(uint16) key_length;
if (key_info->key_length > max_key_length && key->type == Key::UNIQUE)
is_hash_field_needed= true;
is_hash_field_needed= true; // for case "a BLOB UNIQUE"
if (key_length > max_key_length && key->type != Key::FULLTEXT &&
!is_hash_field_needed)
{

View File

@ -4946,6 +4946,21 @@ bool check_table_name(const char *name, size_t length, bool check_for_path_chars
if (check_for_path_chars &&
(*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
return 1;
/*
We don't allow zero byte in table/schema names:
- Some code still uses NULL-terminated strings.
Zero bytes will confuse this code.
- There is a little practical use of zero bytes in names anyway.
Note, if the string passed as "name" comes here
from the parser as an identifier, it does not contain zero bytes,
as the parser rejects zero bytes in identifiers.
But "name" can also come here from queries like this:
SELECT * FROM I_S.TABLES WHERE TABLE_NAME='str';
In this case "name" is a general string expression
and it can have any arbitrary bytes, including zero bytes.
*/
if (*name == 0x00)
return 1;
name++;
name_length++;
}

View File

@ -268,14 +268,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
template <class TYPE>
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
{
sprintf(p, Fmt, Typp[n]);
sprintf(p, Fmt, UnalignedRead(n));
return p;
} // end of GetCharString
template <>
char *TYPBLK<double>::GetCharString(char *p, int n)
{
sprintf(p, Fmt, Prec, Typp[n]);
sprintf(p, Fmt, Prec, UnalignedRead(n));
return p;
} // end of GetCharString
@ -291,7 +291,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, int n)
ChkTyp(valp);
if (!(b = valp->IsNull()))
Typp[n] = GetTypedValue(valp);
UnalignedWrite(n, GetTypedValue(valp));
else
Reset(n);
@ -353,9 +353,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int n)
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
if (minus && val < maxval)
Typp[n] = (TYPE)(-(signed)val);
UnalignedWrite(n, (TYPE)(-(signed)val));
else
Typp[n] = (TYPE)val;
UnalignedWrite(n, (TYPE)val);
SetNull(n, false);
} // end of SetValue
@ -398,7 +398,7 @@ void TYPBLK<double>::SetValue(PCSZ p, int n)
throw Type;
} // endif Check
Typp[n] = atof(p);
UnalignedWrite(n, atof(p));
SetNull(n, false);
} // end of SetValue
@ -430,7 +430,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, int n1, int n2)
ChkTyp(pv);
if (!(b = pv->IsNull(n2) && Nullable))
Typp[n1] = GetTypedValue(pv, n2);
UnalignedWrite(n1, GetTypedValue(pv, n2));
else
Reset(n1);
@ -481,10 +481,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
TYPE tval = GetTypedValue(valp);
TYPE& tmin = Typp[n];
TYPE tmin = UnalignedRead(n);
if (tval < tmin)
tmin = tval;
UnalignedWrite(n, tval);
} // end of SetMin
@ -496,10 +496,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
TYPE tval = GetTypedValue(valp);
TYPE& tmin = Typp[n];
TYPE tmin = UnalignedRead(n);
if (tval > tmin)
tmin = tval;
UnalignedWrite(n, tval);
} // end of SetMax
@ -513,8 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
CheckType(pv)
TYPE *lp = ((TYPBLK*)pv)->Typp;
for (int i = k; i < n; i++) // TODO
Typp[i] = lp[i];
memcpy(Typp + k, lp + k, sizeof(TYPE) * n);
} // end of SetValues
#endif // 0
@ -525,7 +524,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
template <class TYPE>
void TYPBLK<TYPE>::Move(int i, int j)
{
Typp[j] = Typp[i];
UnalignedWrite(j, UnalignedRead(i));
MoveNull(i, j);
} // end of Move
@ -539,7 +538,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
ChkIndx(n);
ChkTyp(vp);
#endif // _DEBUG
TYPE mlv = Typp[n];
TYPE mlv = UnalignedRead(n);
TYPE vlv = GetTypedValue(vp);
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
@ -551,8 +550,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
template <class TYPE>
int TYPBLK<TYPE>::CompVal(int i1, int i2)
{
TYPE lv1 = Typp[i1];
TYPE lv2 = Typp[i2];
TYPE lv1 = UnalignedRead(i1);
TYPE lv2 = UnalignedRead(i2);
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
} // end of CompVal
@ -589,7 +588,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
TYPE n = GetTypedValue(vp);
for (i = 0; i < Nval; i++)
if (n == Typp[i])
if (n == UnalignedRead(i))
break;
return (i < Nval) ? i : (-1);
@ -605,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
int i, n, m;
for (i = n = 0; i < Nval; i++) {
m = sprintf(buf, Fmt, Typp[i]);
m = sprintf(buf, Fmt, UnalignedRead(i));
n = MY_MAX(n, m);
} // endfor i
@ -1335,7 +1334,7 @@ char *DATBLK::GetCharString(char *p, int n)
char *vp;
if (Dvalp) {
Dvalp->SetValue(Typp[n]);
Dvalp->SetValue(UnalignedRead(n));
vp = Dvalp->GetCharString(p);
} else
vp = TYPBLK<int>::GetCharString(p, n);
@ -1351,7 +1350,7 @@ void DATBLK::SetValue(PCSZ p, int n)
if (Dvalp) {
// Decode the string according to format
Dvalp->SetValue_psz(p);
Typp[n] = Dvalp->GetIntValue();
UnalignedWrite(n, Dvalp->GetIntValue());
} else
TYPBLK<int>::SetValue(p, n);

View File

@ -151,40 +151,41 @@ class TYPBLK : public VALBLK {
// Implementation
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];}
virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];}
virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);}
virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);}
virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);}
virtual char *GetCharString(char *p, int n);
virtual void Reset(int n) {Typp[n] = 0;}
virtual void Reset(int n) {UnalignedWrite(n, 0);}
// Methods
using VALBLK::SetValue;
virtual void SetValue(PCSZ sp, int n);
virtual void SetValue(const char *sp, uint len, int n);
virtual void SetValue(short sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
virtual void SetValue(ushort sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
virtual void SetValue(int lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(uint lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(longlong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(ulonglong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(double fval, int n)
{Typp[n] = (TYPE)fval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
virtual void SetValue(char cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
virtual void SetValue(uchar cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
virtual void SetValue(PVAL valp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void SetMin(PVAL valp, int n);
@ -206,6 +207,17 @@ class TYPBLK : public VALBLK {
// Members
TYPE* const &Typp;
const char *Fmt;
// Unaligned access
TYPE UnalignedRead(int n) const {
TYPE result;
memcpy(&result, Typp + n, sizeof(TYPE));
return result;
}
void UnalignedWrite(int n, TYPE value) {
memcpy(Typp + n, &value, sizeof(TYPE));
}
}; // end of class TYPBLK
/***********************************************************************/

View File

@ -150,7 +150,7 @@ SET(INNOBASE_SOURCES
include/fts0tokenize.h
include/fts0types.h
include/fts0types.ic
include/fts0vlc.ic
include/fts0vlc.h
include/fut0fut.h
include/fut0lst.h
include/gis0geo.h
@ -399,3 +399,7 @@ IF(NOT (PLUGIN_INNOBASE STREQUAL DYNAMIC))
TARGET_LINK_LIBRARIES(innobase tpool mysys)
ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup)
ENDIF()
IF(WITH_UNIT_TESTS)
ADD_SUBDIRECTORY(unittest)
ENDIF()

View File

@ -32,7 +32,7 @@ Full Text Search interface
#include "fts0priv.h"
#include "fts0types.h"
#include "fts0types.ic"
#include "fts0vlc.ic"
#include "fts0vlc.h"
#include "fts0plugin.h"
#include "dict0priv.h"
#include "dict0stats.h"
@ -579,6 +579,7 @@ fts_cache_init(
cache->sync_heap->arg = mem_heap_create(1024);
cache->total_size = 0;
cache->total_size_at_sync = 0;
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = ib_vector_create(
@ -1233,7 +1234,7 @@ fts_cache_node_add_positions(
ulint enc_len;
ulint last_pos;
byte* ptr_start;
ulint doc_id_delta;
doc_id_t doc_id_delta;
#ifdef UNIV_DEBUG
if (cache) {
@ -1244,7 +1245,7 @@ fts_cache_node_add_positions(
ut_ad(doc_id >= node->last_doc_id);
/* Calculate the space required to store the ilist. */
doc_id_delta = (ulint)(doc_id - node->last_doc_id);
doc_id_delta = doc_id - node->last_doc_id;
enc_len = fts_get_encoded_len(doc_id_delta);
last_pos = 0;
@ -1293,14 +1294,14 @@ fts_cache_node_add_positions(
ptr_start = ptr;
/* Encode the new fragment. */
ptr += fts_encode_int(doc_id_delta, ptr);
ptr = fts_encode_int(doc_id_delta, ptr);
last_pos = 0;
for (i = 0; i < ib_vector_size(positions); i++) {
ulint pos = *(static_cast<ulint*>(
ib_vector_get(positions, i)));
ptr += fts_encode_int(pos - last_pos, ptr);
ptr = fts_encode_int(pos - last_pos, ptr);
last_pos = pos;
}
@ -3523,11 +3524,14 @@ fts_add_doc_by_id(
get_doc->index_cache,
doc_id, doc.tokens);
bool need_sync = false;
if ((cache->total_size > fts_max_cache_size / 10
|| fts_need_sync)
&& !cache->sync->in_progress) {
need_sync = true;
bool need_sync = !cache->sync->in_progress
&& (fts_need_sync
|| (cache->total_size
- cache->total_size_at_sync)
> fts_max_cache_size / 10);
if (need_sync) {
cache->total_size_at_sync =
cache->total_size;
}
rw_lock_x_unlock(&table->fts->cache->lock);

View File

@ -36,6 +36,7 @@ Completed 2011/7/10 Sunny and Jimmy Yang
#include "ut0list.h"
#include "zlib.h"
#include "fts0opt.h"
#include "fts0vlc.h"
/** The FTS optimize thread's work queue. */
ib_wqueue_t* fts_optimize_wq;
@ -1122,7 +1123,7 @@ fts_optimize_encode_node(
ulint pos_enc_len;
doc_id_t doc_id_delta;
dberr_t error = DB_SUCCESS;
byte* src = enc->src_ilist_ptr;
const byte* src = enc->src_ilist_ptr;
if (node->first_doc_id == 0) {
ut_a(node->last_doc_id == 0);
@ -1179,7 +1180,7 @@ fts_optimize_encode_node(
/* Encode the doc id. Cast to ulint, the delta should be small and
therefore no loss of precision. */
dst += fts_encode_int((ulint) doc_id_delta, dst);
dst = fts_encode_int(doc_id_delta, dst);
/* Copy the encoded pos array. */
memcpy(dst, src, pos_enc_len);
@ -1226,7 +1227,8 @@ fts_optimize_node(
doc_id_t delta;
doc_id_t del_doc_id = FTS_NULL_DOC_ID;
delta = fts_decode_vlc(&enc->src_ilist_ptr);
delta = fts_decode_vlc(
(const byte**)&enc->src_ilist_ptr);
test_again:
/* Check whether the doc id is in the delete list, if
@ -1254,7 +1256,7 @@ test_again:
/* Skip the entries for this document. */
while (*enc->src_ilist_ptr) {
fts_decode_vlc(&enc->src_ilist_ptr);
fts_decode_vlc((const byte**)&enc->src_ilist_ptr);
}
/* Skip the end of word position marker. */
@ -2667,6 +2669,9 @@ fts_optimize_request_sync_table(
table->fts->sync_message = true;
DBUG_EXECUTE_IF("fts_optimize_wq_count_check",
DBUG_ASSERT(fts_optimize_wq->length <= 1000););
mutex_exit(&fts_optimize_wq->mutex);
}

View File

@ -34,6 +34,7 @@ Completed 2011/7/10 Sunny and Jimmy Yang
#include "fts0pars.h"
#include "fts0types.h"
#include "fts0plugin.h"
#include "fts0vlc.h"
#include <iomanip>
#include <vector>
@ -3225,7 +3226,7 @@ fts_query_filter_doc_ids(
ulint len, /*!< in: doc id ilist size */
ibool calc_doc_count) /*!< in: whether to remember doc count */
{
byte* ptr = static_cast<byte*>(data);
const byte* ptr = static_cast<byte*>(data);
doc_id_t doc_id = 0;
ulint decoded = 0;
ib_rbt_t* doc_freqs = word_freq->doc_freqs;
@ -3235,8 +3236,8 @@ fts_query_filter_doc_ids(
ulint freq = 0;
fts_doc_freq_t* doc_freq;
fts_match_t* match = NULL;
ulint last_pos = 0;
ulint pos = fts_decode_vlc(&ptr);
doc_id_t last_pos = 0;
doc_id_t pos = fts_decode_vlc(&ptr);
/* Some sanity checks. */
if (doc_id == 0) {

View File

@ -7965,8 +7965,7 @@ calc_row_difference(
&& prebuilt->table->fts
&& innobase_strcasecmp(
field->field_name.str, FTS_DOC_ID_COL_NAME) == 0) {
doc_id = (doc_id_t) mach_read_from_n_little_endian(
n_ptr, 8);
doc_id = mach_read_uint64_little_endian(n_ptr);
if (doc_id == 0) {
return(DB_FTS_INVALID_DOCID);
}
@ -8209,16 +8208,6 @@ calc_row_difference(
<< innodb_table->name;
return(DB_FTS_INVALID_DOCID);
} else if ((doc_id
- prebuilt->table->fts->cache->next_doc_id)
>= FTS_DOC_ID_MAX_STEP) {
ib::warn() << "Doc ID " << doc_id << " is too"
" big. Its difference with largest"
" Doc ID used " << prebuilt->table->fts
->cache->next_doc_id - 1
<< " cannot exceed or equal to "
<< FTS_DOC_ID_MAX_STEP;
}
@ -11351,10 +11340,6 @@ bool create_table_info_t::innobase_table_flags()
ut_min(static_cast<ulint>(UNIV_PAGE_SSIZE_MAX),
static_cast<ulint>(PAGE_ZIP_SSIZE_MAX));
/* Cache the value of innobase_compression_level, in case it is
modified by another thread while the table is being created. */
const ulint default_compression_level = page_zip_level;
ha_table_option_struct *options= m_form->s->option_struct;
m_flags = 0;
@ -11543,12 +11528,23 @@ index_bad:
m_flags2 |= DICT_TF2_USE_FILE_PER_TABLE;
}
ulint level = ulint(options->page_compression_level);
if (!level) {
level = page_zip_level;
if (!level && options->page_compressed) {
push_warning_printf(
m_thd, Sql_condition::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: PAGE_COMPRESSED requires"
" PAGE_COMPRESSION_LEVEL or"
" innodb_compression_level > 0");
DBUG_RETURN(false);
}
}
/* Set the table flags */
dict_tf_set(&m_flags, innodb_row_format, zip_ssize,
m_use_data_dir,
options->page_compressed,
options->page_compression_level == 0 ?
default_compression_level : ulint(options->page_compression_level));
m_use_data_dir, options->page_compressed, level);
if (m_form->s->table_type == TABLE_TYPE_SEQUENCE) {
m_flags |= DICT_TF_MASK_NO_ROLLBACK;

View File

@ -7728,6 +7728,8 @@ check_if_ok_to_rename:
}
if (!info.innobase_table_flags()) {
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
table_type(), "PAGE_COMPRESSED");
goto err_exit_no_heap;
}

View File

@ -58,6 +58,7 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "fil0fil.h"
#include "fil0crypt.h"
#include "dict0crea.h"
#include "fts0vlc.h"
/** The latest successfully looked up innodb_fts_aux_table */
UNIV_INTERN table_id_t innodb_ft_aux_table_id;
@ -2717,7 +2718,7 @@ i_s_fts_index_cache_fill_one_index(
/* Decrypt the ilist, and display Dod ID and word position */
for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
fts_node_t* node;
byte* ptr;
const byte* ptr;
ulint decoded = 0;
doc_id_t doc_id = 0;
@ -2727,13 +2728,11 @@ i_s_fts_index_cache_fill_one_index(
ptr = node->ilist;
while (decoded < node->ilist_size) {
ulint pos = fts_decode_vlc(&ptr);
doc_id += pos;
doc_id += fts_decode_vlc(&ptr);
/* Get position info */
while (*ptr) {
pos = fts_decode_vlc(&ptr);
OK(field_store_string(
fields[I_S_FTS_WORD],
@ -2754,7 +2753,7 @@ i_s_fts_index_cache_fill_one_index(
doc_id, true));
OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
pos, true));
fts_decode_vlc(&ptr), true));
OK(schema_table_store_record(
thd, table));
@ -3088,7 +3087,7 @@ i_s_fts_index_table_fill_one_fetch(
/* Decrypt the ilist, and display Dod ID and word position */
for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
fts_node_t* node;
byte* ptr;
const byte* ptr;
ulint decoded = 0;
doc_id_t doc_id = 0;
@ -3098,13 +3097,10 @@ i_s_fts_index_table_fill_one_fetch(
ptr = node->ilist;
while (decoded < node->ilist_size) {
ulint pos = fts_decode_vlc(&ptr);
doc_id += pos;
doc_id += fts_decode_vlc(&ptr);
/* Get position info */
while (*ptr) {
pos = fts_decode_vlc(&ptr);
OK(field_store_string(
fields[I_S_FTS_WORD],
@ -3123,7 +3119,7 @@ i_s_fts_index_table_fill_one_fetch(
longlong(doc_id), true));
OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
pos, true));
fts_decode_vlc(&ptr), true));
OK(schema_table_store_record(
thd, table));

View File

@ -95,10 +95,6 @@ those defined in mysql file ft_global.h */
/** Threshold where our optimize thread automatically kicks in */
#define FTS_OPTIMIZE_THRESHOLD 10000000
/** Threshold to avoid exhausting of doc ids. Consecutive doc id difference
should not exceed FTS_DOC_ID_MAX_STEP */
#define FTS_DOC_ID_MAX_STEP 65535
/** Maximum possible Fulltext word length in bytes (assuming mbmaxlen=4) */
#define FTS_MAX_WORD_LEN (HA_FT_MAXCHARLEN * 4)

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -150,6 +150,9 @@ struct fts_cache_t {
size_t total_size; /*!< total size consumed by the ilist
field of all nodes. SYNC is run
whenever this gets too big */
/** total_size at the time of the previous SYNC request */
size_t total_size_at_sync;
fts_sync_t* sync; /*!< sync structure to sync data to
disk */
ib_alloc_t* sync_heap; /*!< The heap allocator, for indexes
@ -314,16 +317,6 @@ int fts_doc_id_cmp(
const void* p1, /*!< in: id1 */
const void* p2); /*!< in: id2 */
/******************************************************************//**
Decode and return the integer that was encoded using our VLC scheme.*/
UNIV_INLINE
ulint
fts_decode_vlc(
/*===========*/
/*!< out: value decoded */
byte** ptr); /*!< in: ptr to decode from, this ptr is
incremented by the number of bytes decoded */
/******************************************************************//**
Duplicate a string. */
UNIV_INLINE
@ -338,28 +331,6 @@ fts_string_dup(
const fts_string_t* src, /*!< in: src string */
mem_heap_t* heap); /*!< in: heap to use */
/******************************************************************//**
Return length of val if it were encoded using our VLC scheme. */
UNIV_INLINE
ulint
fts_get_encoded_len(
/*================*/
/*!< out: length of value
encoded, in bytes */
ulint val); /*!< in: value to encode */
/******************************************************************//**
Encode an integer using our VLC scheme and return the length in bytes. */
UNIV_INLINE
ulint
fts_encode_int(
/*===========*/
/*!< out: length of value
encoded, in bytes */
ulint val, /*!< in: value to encode */
byte* buf); /*!< in: buffer, must have
enough space */
/******************************************************************//**
Get the selected FTS aux INDEX suffix. */
UNIV_INLINE
@ -381,6 +352,5 @@ fts_select_index(
ulint len);
#include "fts0types.ic"
#include "fts0vlc.ic"
#endif /* INNOBASE_FTS0TYPES_H */

View File

@ -0,0 +1,124 @@
/**
Copyright (c) 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
**/
/**
@file include/fts0vlc.h
Full text variable length integer encoding/decoding.
Created 2021-10-19 Thirunarayanan Balathandayuthapani
**/
/** Return length of val if it were encoded using our VLC scheme.
@param val value to encode
@return length of value encoded, in bytes */
inline size_t fts_get_encoded_len(doc_id_t val)
{
if (val < static_cast<doc_id_t>(1) << 7)
return 1;
if (val < static_cast<doc_id_t>(1) << 14)
return 2;
if (val < static_cast<doc_id_t>(1) << 21)
return 3;
if (val < static_cast<doc_id_t>(1) << 28)
return 4;
if (val < static_cast<doc_id_t>(1) << 35)
return 5;
if (val < static_cast<doc_id_t>(1) << 42)
return 6;
if (val < static_cast<doc_id_t>(1) << 49)
return 7;
if (val < static_cast<doc_id_t>(1) << 56)
return 8;
if (val < static_cast<doc_id_t>(1) << 63)
return 9;
return 10;
}
/** Encode an integer using our VLC scheme and return the
length in bytes.
@param val value to encode
@param buf buffer, must have enough space
@return length of value encoded, in bytes */
inline byte *fts_encode_int(doc_id_t val, byte *buf)
{
if (val < static_cast<doc_id_t>(1) << 7)
goto add_1;
if (val < static_cast<doc_id_t>(1) << 14)
goto add_2;
if (val < static_cast<doc_id_t>(1) << 21)
goto add_3;
if (val < static_cast<doc_id_t>(1) << 28)
goto add_4;
if (val < static_cast<doc_id_t>(1) << 35)
goto add_5;
if (val < static_cast<doc_id_t>(1) << 42)
goto add_6;
if (val < static_cast<doc_id_t>(1) << 49)
goto add_7;
if (val < static_cast<doc_id_t>(1) << 56)
goto add_8;
if (val < static_cast<doc_id_t>(1) << 63)
goto add_9;
*buf++= static_cast<byte>(val >> 63);
add_9:
*buf++= static_cast<byte>(val >> 56) & 0x7F;
add_8:
*buf++= static_cast<byte>(val >> 49) & 0x7F;
add_7:
*buf++= static_cast<byte>(val >> 42) & 0x7F;
add_6:
*buf++= static_cast<byte>(val >> 35) & 0x7F;
add_5:
*buf++= static_cast<byte>(val >> 28) & 0x7F;
add_4:
*buf++= static_cast<byte>(val >> 21) & 0x7F;
add_3:
*buf++= static_cast<byte>(val >> 14) & 0x7F;
add_2:
*buf++= static_cast<byte>(val >> 7) & 0x7F;
add_1:
*buf++= static_cast<byte>(val) | 0x80;
return buf;
}
/** Decode and return the integer that was encoded using
our VLC scheme.
@param ptr pointer to decode from, this ptr is
incremented by the number of bytes decoded
@return value decoded */
inline doc_id_t fts_decode_vlc(const byte **ptr)
{
ut_d(const byte *const start= *ptr);
ut_ad(*start);
doc_id_t val= 0;
for (;;)
{
byte b= *(*ptr)++;
val|= (b & 0x7F);
/* High-bit on means "last byte in the encoded integer". */
if (b & 0x80)
break;
ut_ad(val < static_cast<doc_id_t>(1) << (64 - 7));
val <<= 7;
}
ut_ad(*ptr - start <= 10);
return(val);
}

View File

@ -1,142 +0,0 @@
/*****************************************************************************
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/******************************************************************//**
@file include/fts0vlc.ic
Full text variable length integer encoding/decoding.
Created 2007-03-27 Sunny Bains
*******************************************************/
#ifndef INNOBASE_FTS0VLC_IC
#define INNOBASE_FTS0VLC_IC
#include "fts0types.h"
/******************************************************************//**
Return length of val if it were encoded using our VLC scheme.
FIXME: We will need to be able encode 8 bytes value
@return length of value encoded, in bytes */
UNIV_INLINE
ulint
fts_get_encoded_len(
/*================*/
ulint val) /* in: value to encode */
{
if (val <= 127) {
return(1);
} else if (val <= 16383) {
return(2);
} else if (val <= 2097151) {
return(3);
} else if (val <= 268435455) {
return(4);
} else {
/* Possibly we should care that on 64-bit machines ulint can
contain values that we can't encode in 5 bytes, but
fts_encode_int doesn't handle them either so it doesn't much
matter. */
return(5);
}
}
/******************************************************************//**
Encode an integer using our VLC scheme and return the length in bytes.
@return length of value encoded, in bytes */
UNIV_INLINE
ulint
fts_encode_int(
/*===========*/
ulint val, /* in: value to encode */
byte* buf) /* in: buffer, must have enough space */
{
ulint len;
if (val <= 127) {
*buf = (byte) val;
len = 1;
} else if (val <= 16383) {
*buf++ = (byte)(val >> 7);
*buf = (byte)(val & 0x7F);
len = 2;
} else if (val <= 2097151) {
*buf++ = (byte)(val >> 14);
*buf++ = (byte)((val >> 7) & 0x7F);
*buf = (byte)(val & 0x7F);
len = 3;
} else if (val <= 268435455) {
*buf++ = (byte)(val >> 21);
*buf++ = (byte)((val >> 14) & 0x7F);
*buf++ = (byte)((val >> 7) & 0x7F);
*buf = (byte)(val & 0x7F);
len = 4;
} else {
/* Best to keep the limitations of the 32/64 bit versions
identical, at least for the time being. */
ut_ad(val <= 4294967295u);
*buf++ = (byte)(val >> 28);
*buf++ = (byte)((val >> 21) & 0x7F);
*buf++ = (byte)((val >> 14) & 0x7F);
*buf++ = (byte)((val >> 7) & 0x7F);
*buf = (byte)(val & 0x7F);
len = 5;
}
/* High-bit on means "last byte in the encoded integer". */
*buf |= 0x80;
return(len);
}
/******************************************************************//**
Decode and return the integer that was encoded using our VLC scheme.
@return value decoded */
UNIV_INLINE
ulint
fts_decode_vlc(
/*===========*/
byte** ptr) /* in: ptr to decode from, this ptr is
incremented by the number of bytes decoded */
{
ulint val = 0;
for (;;) {
byte b = **ptr;
++*ptr;
val |= (b & 0x7F);
/* High-bit on means "last byte in the encoded integer". */
if (b & 0x80) {
break;
} else {
val <<= 7;
}
}
return(val);
}
#endif

View File

@ -296,6 +296,28 @@ mach_read_from_n_little_endian(
const byte* buf, /*!< in: from where to read */
ulint buf_size) /*!< in: from how many bytes to read */
MY_ATTRIBUTE((warn_unused_result));
/** Reads a 64 bit stored in big endian format
@param buf From where to read
@return uint64_t */
UNIV_INLINE
uint64_t
mach_read_uint64_little_endian(const byte* buf)
{
#ifdef WORDS_BIGENDIAN
return
uint64_t(buf[0]) | uint64_t(buf[1]) << 8 |
uint64_t(buf[2]) << 16 | uint64_t(buf[3]) << 24 |
uint64_t(buf[4]) << 32 | uint64_t(buf[5]) << 40 |
uint64_t(buf[6]) << 48 | uint64_t(buf[7]) << 56;
#else
uint64_t n;
memcpy(&n, buf, sizeof(uint64_t));
return n;
#endif
}
/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation.
Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -46,6 +46,8 @@ struct ib_wqueue_t
ib_mutex_t mutex;
/** Work item list */
ib_list_t* items;
/** ib_list_len(*items) */
size_t length;
};
/****************************************************************//**
@ -83,12 +85,5 @@ void*
ib_wqueue_nowait(
/*=============*/
ib_wqueue_t* wq); /*<! in: work queue */
/********************************************************************
Get number of items on queue.
@return number of items on queue */
ulint
ib_wqueue_len(
/*==========*/
ib_wqueue_t* wq); /*<! in: work queue */
#endif /* IB_WORK_QUEUE_H */

View File

@ -1457,23 +1457,6 @@ error_exit:
trx->error_state = DB_FTS_INVALID_DOCID;
goto error_exit;
}
/* Difference between Doc IDs are restricted within
4 bytes integer. See fts_get_encoded_len(). Consecutive
doc_ids difference should not exceed
FTS_DOC_ID_MAX_STEP value. */
if (doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) {
ib::error() << "Doc ID " << doc_id
<< " is too big. Its difference with"
" largest used Doc ID "
<< next_doc_id - 1 << " cannot"
" exceed or equal to "
<< FTS_DOC_ID_MAX_STEP;
err = DB_FTS_INVALID_DOCID;
trx->error_state = DB_FTS_INVALID_DOCID;
goto error_exit;
}
}
if (table->skip_alter_undo) {

View File

@ -1349,14 +1349,6 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
ut_ad(!rsegs.m_redo.undo);
ut_ad(UT_LIST_GET_LEN(lock.evicted_tables) == 0);
if (trx_rseg_t *rseg= rsegs.m_redo.rseg)
{
mutex_enter(&rseg->mutex);
ut_ad(rseg->trx_ref_count > 0);
--rseg->trx_ref_count;
mutex_exit(&rseg->mutex);
}
if (mtr)
{
if (trx_undo_t *&undo= rsegs.m_noredo.undo)
@ -1405,6 +1397,16 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
ut_ad(!rsegs.m_noredo.undo);
/* Only after trx_undo_commit_cleanup() it is safe to release
our rseg reference. */
if (trx_rseg_t *rseg= rsegs.m_redo.rseg)
{
mutex_enter(&rseg->mutex);
ut_ad(rseg->trx_ref_count > 0);
--rseg->trx_ref_count;
mutex_exit(&rseg->mutex);
}
/* Free all savepoints, starting from the first. */
trx_named_savept_t *savep= UT_LIST_GET_FIRST(trx_savepoints);

View File

@ -0,0 +1,22 @@
# Copyright (c) 2021, MariaDB Corporation.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/unittest/mytap
${CMAKE_SOURCE_DIR}/storage/innobase/include)
ADD_EXECUTABLE(innodb_fts-t innodb_fts-t.cc)
TARGET_LINK_LIBRARIES(innodb_fts-t mysys mytap)
ADD_DEPENDENCIES(innodb_fts-t GenError)
MY_ADD_TEST(innodb_fts)

View File

@ -0,0 +1,52 @@
#include "tap.h"
#include "fts0fts.h"
#include "fts0vlc.h"
struct fts_encode_info
{
const byte buf[10];
size_t len;
doc_id_t val;
};
/* Contains fts encoding min & max value for each length bytes */
static const fts_encode_info fts_info[]=
{
{{0x80}, 1, 0},
{{0xFF}, 1, (1 << 7) - 1},
{{0x01, 0x80}, 2, 1 << 7},
{{0x7F, 0XFF}, 2, (1 << 14) - 1},
{{0x01, 0x00, 0x80}, 3, 1 << 14},
{{0x7F, 0X7F, 0XFF}, 3, (1 << 21) - 1},
{{0x01, 0x00, 0x00, 0x80}, 4, 1 << 21},
{{0x7F, 0X7F, 0X7F, 0xFF}, 4, (1 << 28) - 1},
{{0x01, 0x00, 0x00, 0x00, 0x80}, 5, 1 << 28},
{{0x7F, 0X7F, 0X7F, 0x7F, 0xFF}, 5, (1ULL << 35) - 1},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x80}, 6, 1ULL << 35},
{{0x7F, 0X7F, 0X7F, 0x7F, 0x7F, 0xFF}, 6, (1ULL << 42) - 1},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, 7, 1ULL << 42},
{{0x7F, 0X7F, 0X7F, 0x7F, 0x7F, 0x7F, 0XFF}, 7, (1ULL << 49) - 1},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, 8, 1ULL << 49},
{{0x7F, 0X7F, 0X7F, 0x7F, 0x7F, 0x7F, 0X7F, 0XFF}, 8, (1ULL << 56) -1},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, 9, 1ULL << 56},
{{0x7F, 0X7F, 0X7F, 0x7F, 0x7F, 0x7F, 0X7F, 0x7F, 0XFF}, 9, (1ULL << 63) -1},
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, 10, 1ULL << 63},
{{0x01, 0X7F, 0X7F, 0x7F, 0x7F, 0x7F, 0X7F, 0x7F, 0x7F, 0xFF}, 10, ~0ULL}
};
int main(int, char**)
{
for (int i= array_elements(fts_info); i--;)
{
byte buf[10];
const byte* fts_buf= buf;
size_t len= fts_encode_int(fts_info[i].val, buf) - &buf[0];
if (fts_info[i].len == len &&
!memcmp(&fts_info[i].buf, buf, len) &&
fts_decode_vlc(&fts_buf) == fts_info[i].val &&
fts_buf == &buf[len])
ok(true, "FTS Encoded for %d bytes", fts_info[i].len);
else
ok(false, "FTS Encoded for %d bytes", fts_info[i].len);
}
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, 2020, MariaDB Corporation.
Copyright (c) 2019, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -44,6 +44,7 @@ ib_wqueue_create(void)
mutex_create(LATCH_ID_WORK_QUEUE, &wq->mutex);
wq->items = ib_list_create();
wq->length = 0;
return(wq);
}
@ -74,6 +75,8 @@ ib_wqueue_add(ib_wqueue_t* wq, void* item, mem_heap_t* heap, bool wq_locked)
}
ib_list_add_last(wq->items, item, heap);
wq->length++;
ut_ad(wq->length == ib_list_len(wq->items));
if (!wq_locked) {
mutex_exit(&wq->mutex);
@ -97,6 +100,8 @@ ib_wqueue_nowait(
if (node) {
ib_list_remove(wq->items, node);
--wq->length;
ut_ad(wq->length == ib_list_len(wq->items));
}
}
@ -114,20 +119,3 @@ bool ib_wqueue_is_empty(ib_wqueue_t* wq)
mutex_exit(&wq->mutex);
return is_empty;
}
/********************************************************************
Get number of items on queue.
@return number of items on queue */
ulint
ib_wqueue_len(
/*==========*/
ib_wqueue_t* wq) /*<! in: work queue */
{
ulint len = 0;
mutex_enter(&wq->mutex);
len = ib_list_len(wq->items);
mutex_exit(&wq->mutex);
return(len);
}

View File

@ -89,7 +89,12 @@ else()
endif()
set_target_properties(libgroonga PROPERTIES OUTPUT_NAME "groonga")
if (HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
set(ATOMIC_LIBS atomic)
endif()
set(GRN_ALL_LIBRARIES
${ATOMIC_LIBS}
${EXECINFO_LIBS}
${RT_LIBS}
${PTHREAD_LIBS}