1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.7 into 10.8

This commit is contained in:
Marko Mäkelä
2022-04-06 13:28:25 +03:00
95 changed files with 1044 additions and 1370 deletions

View File

@@ -1047,6 +1047,7 @@ static const char *expected_errors[]=
"ERROR 1347", /* 'mysql.user' is not of type 'BASE TABLE' */ "ERROR 1347", /* 'mysql.user' is not of type 'BASE TABLE' */
"ERROR 1348", /* Column 'Show_db_priv' is not updatable */ "ERROR 1348", /* Column 'Show_db_priv' is not updatable */
"ERROR 1356", /* definer of view lack rights (UPDATE) */ "ERROR 1356", /* definer of view lack rights (UPDATE) */
"ERROR 1449", /* definer ('mariadb.sys'@'localhost') of mysql.user does not exist */
0 0
}; };

View File

@@ -8663,7 +8663,10 @@ void run_prepare_stmt(struct st_connection *cn, struct st_command *command, cons
separate string separate string
*/ */
if (!disable_warnings) if (!disable_warnings)
{
append_warnings(&ds_prepare_warnings, mysql); append_warnings(&ds_prepare_warnings, mysql);
dynstr_free(&ds_prepare_warnings);
}
end: end:
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -8742,7 +8745,7 @@ void run_bind_stmt(struct st_connection *cn, struct st_command *command,
else else
{ {
ps_params[i].buffer_type= MYSQL_TYPE_STRING; ps_params[i].buffer_type= MYSQL_TYPE_STRING;
ps_params[i].buffer= strdup(p); ps_params[i].buffer= my_strdup(PSI_NOT_INSTRUMENTED, p, MYF(MY_WME));
ps_params[i].buffer_length= (unsigned long)strlen(p); ps_params[i].buffer_length= (unsigned long)strlen(p);
} }
} }

View File

@@ -811,7 +811,7 @@ parse_page(
is_leaf = (!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL))); is_leaf = (!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tIndex page\t\t\t|" fprintf(file, "#::" UINT32PF "\t\t|\t\tIndex page\t\t\t|"
"\tindex id=%llu,", cur_page_num, id); "\tindex id=%llu,", cur_page_num, id);
@@ -863,7 +863,7 @@ parse_page(
index.total_data_bytes += data_bytes; index.total_data_bytes += data_bytes;
index.pages_in_size_range[size_range_id] ++; index.pages_in_size_range[size_range_id] ++;
} }
} else { } else if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tEncrypted Index page\t\t\t|" fprintf(file, "#::" UINT32PF "\t\t|\t\tEncrypted Index page\t\t\t|"
"\tkey_version " UINT32PF ",%s\n", cur_page_num, key_version, str); "\tkey_version " UINT32PF ",%s\n", cur_page_num, key_version, str);
} }
@@ -874,7 +874,7 @@ parse_page(
page_type.n_fil_page_undo_log++; page_type.n_fil_page_undo_log++;
undo_page_type = mach_read_from_2(page + undo_page_type = mach_read_from_2(page +
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE); TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE);
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tUndo log page\t\t\t|", fprintf(file, "#::" UINT32PF "\t\t|\t\tUndo log page\t\t\t|",
cur_page_num); cur_page_num);
} }
@@ -884,7 +884,7 @@ parse_page(
switch (undo_page_type) { switch (undo_page_type) {
case TRX_UNDO_ACTIVE: case TRX_UNDO_ACTIVE:
page_type.n_undo_state_active++; page_type.n_undo_state_active++;
if (page_type_dump) { if (file) {
fprintf(file, ", %s", "Undo log of " fprintf(file, ", %s", "Undo log of "
"an active transaction"); "an active transaction");
} }
@@ -892,7 +892,7 @@ parse_page(
case TRX_UNDO_CACHED: case TRX_UNDO_CACHED:
page_type.n_undo_state_cached++; page_type.n_undo_state_cached++;
if (page_type_dump) { if (file) {
fprintf(file, ", %s", "Page is " fprintf(file, ", %s", "Page is "
"cached for quick reuse"); "cached for quick reuse");
} }
@@ -900,7 +900,7 @@ parse_page(
case TRX_UNDO_TO_PURGE: case TRX_UNDO_TO_PURGE:
page_type.n_undo_state_to_purge++; page_type.n_undo_state_to_purge++;
if (page_type_dump) { if (file) {
fprintf(file, ", %s", "Will be " fprintf(file, ", %s", "Will be "
"freed in purge when all undo" "freed in purge when all undo"
"data in it is removed"); "data in it is removed");
@@ -909,7 +909,7 @@ parse_page(
case TRX_UNDO_PREPARED: case TRX_UNDO_PREPARED:
page_type.n_undo_state_prepared++; page_type.n_undo_state_prepared++;
if (page_type_dump) { if (file) {
fprintf(file, ", %s", "Undo log of " fprintf(file, ", %s", "Undo log of "
"an prepared transaction"); "an prepared transaction");
} }
@@ -919,14 +919,14 @@ parse_page(
page_type.n_undo_state_other++; page_type.n_undo_state_other++;
break; break;
} }
if(page_type_dump) { if(file) {
fprintf(file, ", %s\n", str); fprintf(file, ", %s\n", str);
} }
break; break;
case FIL_PAGE_INODE: case FIL_PAGE_INODE:
page_type.n_fil_page_inode++; page_type.n_fil_page_inode++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tInode page\t\t\t|" fprintf(file, "#::" UINT32PF "\t\t|\t\tInode page\t\t\t|"
"\t%s\n",cur_page_num, str); "\t%s\n",cur_page_num, str);
} }
@@ -934,7 +934,7 @@ parse_page(
case FIL_PAGE_IBUF_FREE_LIST: case FIL_PAGE_IBUF_FREE_LIST:
page_type.n_fil_page_ibuf_free_list++; page_type.n_fil_page_ibuf_free_list++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert buffer free list" fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert buffer free list"
" page\t|\t%s\n", cur_page_num, str); " page\t|\t%s\n", cur_page_num, str);
} }
@@ -942,7 +942,7 @@ parse_page(
case FIL_PAGE_TYPE_ALLOCATED: case FIL_PAGE_TYPE_ALLOCATED:
page_type.n_fil_page_type_allocated++; page_type.n_fil_page_type_allocated++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tFreshly allocated " fprintf(file, "#::" UINT32PF "\t\t|\t\tFreshly allocated "
"page\t\t|\t%s\n", cur_page_num, str); "page\t\t|\t%s\n", cur_page_num, str);
} }
@@ -950,7 +950,7 @@ parse_page(
case FIL_PAGE_IBUF_BITMAP: case FIL_PAGE_IBUF_BITMAP:
page_type.n_fil_page_ibuf_bitmap++; page_type.n_fil_page_ibuf_bitmap++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert Buffer " fprintf(file, "#::" UINT32PF "\t\t|\t\tInsert Buffer "
"Bitmap\t\t|\t%s\n", cur_page_num, str); "Bitmap\t\t|\t%s\n", cur_page_num, str);
} }
@@ -958,7 +958,7 @@ parse_page(
case FIL_PAGE_TYPE_SYS: case FIL_PAGE_TYPE_SYS:
page_type.n_fil_page_type_sys++; page_type.n_fil_page_type_sys++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tSystem page\t\t\t|" fprintf(file, "#::" UINT32PF "\t\t|\t\tSystem page\t\t\t|"
"\t%s\n", cur_page_num, str); "\t%s\n", cur_page_num, str);
} }
@@ -966,7 +966,7 @@ parse_page(
case FIL_PAGE_TYPE_TRX_SYS: case FIL_PAGE_TYPE_TRX_SYS:
page_type.n_fil_page_type_trx_sys++; page_type.n_fil_page_type_trx_sys++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tTransaction system " fprintf(file, "#::" UINT32PF "\t\t|\t\tTransaction system "
"page\t\t|\t%s\n", cur_page_num, str); "page\t\t|\t%s\n", cur_page_num, str);
} }
@@ -974,7 +974,7 @@ parse_page(
case FIL_PAGE_TYPE_FSP_HDR: case FIL_PAGE_TYPE_FSP_HDR:
page_type.n_fil_page_type_fsp_hdr++; page_type.n_fil_page_type_fsp_hdr++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tFile Space " fprintf(file, "#::" UINT32PF "\t\t|\t\tFile Space "
"Header\t\t|\t%s\n", cur_page_num, str); "Header\t\t|\t%s\n", cur_page_num, str);
} }
@@ -982,7 +982,7 @@ parse_page(
case FIL_PAGE_TYPE_XDES: case FIL_PAGE_TYPE_XDES:
page_type.n_fil_page_type_xdes++; page_type.n_fil_page_type_xdes++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tExtent descriptor " fprintf(file, "#::" UINT32PF "\t\t|\t\tExtent descriptor "
"page\t\t|\t%s\n", cur_page_num, str); "page\t\t|\t%s\n", cur_page_num, str);
} }
@@ -990,7 +990,7 @@ parse_page(
case FIL_PAGE_TYPE_BLOB: case FIL_PAGE_TYPE_BLOB:
page_type.n_fil_page_type_blob++; page_type.n_fil_page_type_blob++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tBLOB page\t\t\t|\t%s\n", fprintf(file, "#::" UINT32PF "\t\t|\t\tBLOB page\t\t\t|\t%s\n",
cur_page_num, str); cur_page_num, str);
} }
@@ -998,7 +998,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB: case FIL_PAGE_TYPE_ZBLOB:
page_type.n_fil_page_type_zblob++; page_type.n_fil_page_type_zblob++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tCompressed BLOB " fprintf(file, "#::" UINT32PF "\t\t|\t\tCompressed BLOB "
"page\t\t|\t%s\n", cur_page_num, str); "page\t\t|\t%s\n", cur_page_num, str);
} }
@@ -1006,7 +1006,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB2: case FIL_PAGE_TYPE_ZBLOB2:
page_type.n_fil_page_type_zblob2++; page_type.n_fil_page_type_zblob2++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tSubsequent Compressed " fprintf(file, "#::" UINT32PF "\t\t|\t\tSubsequent Compressed "
"BLOB page\t|\t%s\n", cur_page_num, str); "BLOB page\t|\t%s\n", cur_page_num, str);
} }
@@ -1014,7 +1014,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED: case FIL_PAGE_PAGE_COMPRESSED:
page_type.n_fil_page_type_page_compressed++; page_type.n_fil_page_type_page_compressed++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed " fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed "
"page\t|\t%s\n", cur_page_num, str); "page\t|\t%s\n", cur_page_num, str);
} }
@@ -1022,7 +1022,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED: case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
page_type.n_fil_page_type_page_compressed_encrypted++; page_type.n_fil_page_type_page_compressed_encrypted++;
if (page_type_dump) { if (file) {
fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed encrypted " fprintf(file, "#::" UINT32PF "\t\t|\t\tPage compressed encrypted "
"page\t|\t%s\n", cur_page_num, str); "page\t|\t%s\n", cur_page_num, str);
} }

View File

@@ -244,9 +244,12 @@ static inline void my_time_trunc(MYSQL_TIME *ltime, uint decimals)
!ltime->hour && !ltime->minute && !ltime->second) !ltime->hour && !ltime->minute && !ltime->second)
ltime->neg= FALSE; ltime->neg= FALSE;
} }
#ifdef _WIN32
#define suseconds_t long
#endif
static inline void my_timeval_trunc(struct timeval *tv, uint decimals) static inline void my_timeval_trunc(struct timeval *tv, uint decimals)
{ {
tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals); tv->tv_usec-= (suseconds_t) my_time_fraction_remainder(tv->tv_usec, decimals);
} }

View File

@@ -1,6 +0,0 @@
--source include/have_innodb.inc
if (`SELECT COUNT(*) = 0 from INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME = 'INNODB_DISALLOW_WRITES'`) {
--skip Test requires 'innodb_disallow_writes'
}

View File

@@ -49,7 +49,7 @@ create sequence seq2;
backup lock seq1; backup lock seq1;
connection con1; connection con1;
CREATE OR REPLACE SEQUENCE seq1 START -28; CREATE OR REPLACE SEQUENCE seq1 START -28;
ERROR HY000: Sequence 'test.seq1' values are conflicting ERROR HY000: Sequence 'test.seq1' has out of range value for options
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50; SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded) ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE; SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;

View File

@@ -2524,5 +2524,11 @@ DROP TABLE t1;
DROP TABLE t1; DROP TABLE t1;
SET SQL_MODE=DEFAULT; SET SQL_MODE=DEFAULT;
# #
# MDEV-27673 Warning after "select progress from information_schema.processlist"
#
select progress from information_schema.processlist limit 1;
progress
0.000
#
# End of 10.3 tests # End of 10.3 tests
# #

View File

@@ -2103,7 +2103,10 @@ DROP TABLE t1;
DROP TABLE t1; DROP TABLE t1;
SET SQL_MODE=DEFAULT; SET SQL_MODE=DEFAULT;
--echo #
--echo # MDEV-27673 Warning after "select progress from information_schema.processlist"
--echo #
select progress from information_schema.processlist limit 1;
--echo # --echo #
--echo # End of 10.3 tests --echo # End of 10.3 tests

View File

@@ -5576,6 +5576,28 @@ a
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or
# different plan upon 2nd execution of PS with EXPLAIN
#
CREATE TABLE t1 (a INT);
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1 HAVING 6 IN ( SELECT 6 UNION SELECT 5 )';
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
# Without the patch the second execution of the 'stmt' prepared statement
# would result in server crash.
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
# End of 10.2 tests # End of 10.2 tests
# #
# #
@@ -5640,5 +5662,18 @@ connection default;
SET GLOBAL disconnect_on_expired_password=@disconnect_on_expired_password_save; SET GLOBAL disconnect_on_expired_password=@disconnect_on_expired_password_save;
DROP USER user1@localhost; DROP USER user1@localhost;
# #
# MDEV-21173: Assertion `m_thd == __null' failed in sp_head::~sp_head
#
CREATE TABLE t1 (a INT);
EXECUTE IMMEDIATE "CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1));";
ERROR 42000: PROCEDURE does not support subqueries or stored functions
DROP TABLE t1;
BEGIN NOT ATOMIC
PREPARE stmt FROM 'SELECT ?';
EXECUTE stmt USING ((SELECT 1));
END;
$
ERROR 42000: EXECUTE..USING does not support subqueries or stored functions
#
# End of 10.4 tests # End of 10.4 tests
# #

View File

@@ -5006,6 +5006,19 @@ DEALLOCATE PREPARE stmt;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or
--echo # different plan upon 2nd execution of PS with EXPLAIN
--echo #
CREATE TABLE t1 (a INT);
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1 HAVING 6 IN ( SELECT 6 UNION SELECT 5 )';
EXECUTE stmt;
--echo # Without the patch the second execution of the 'stmt' prepared statement
--echo # would result in server crash.
EXECUTE stmt;
# Cleanup
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #
@@ -5083,6 +5096,25 @@ connection default;
SET GLOBAL disconnect_on_expired_password=@disconnect_on_expired_password_save; SET GLOBAL disconnect_on_expired_password=@disconnect_on_expired_password_save;
DROP USER user1@localhost; DROP USER user1@localhost;
--echo #
--echo # MDEV-21173: Assertion `m_thd == __null' failed in sp_head::~sp_head
--echo #
CREATE TABLE t1 (a INT);
--error ER_SUBQUERIES_NOT_SUPPORTED
EXECUTE IMMEDIATE "CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1));";
DROP TABLE t1;
delimiter $;
--error ER_SUBQUERIES_NOT_SUPPORTED
BEGIN NOT ATOMIC
PREPARE stmt FROM 'SELECT ?';
EXECUTE stmt USING ((SELECT 1));
END;
$
delimiter ;$
--echo # --echo #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #

View File

@@ -8897,6 +8897,19 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
BEGIN BEGIN
RETURN ''; RETURN '';
END' at line 2 END' at line 2
#
# MDEV-28220: Assert failure in sp_head::~sp_head on parsing a syntax incorrect statement CREATE SEQUENCE ... RESTART inside CREATE PROCEDURE/CREATE FUNCTION
# Specifying the RESTART clause for the statement CREATE SEQUENCE is a syntax error.
# Check that CREATE PROCEDURE doesn't crash server if the statement
# CREATE SEQUNCE ... RESTART is specified in its body.
#
CREATE PROCEDURE sp1() CREATE SEQUENCE s1 START WITH 300 INCREMENT BY 30 RESTART;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'RESTART' at line 1
# CREATE SEQUNCE ... RESTART and CREATE SEQUNCE ... RESTART WITH ... are
# handled by different grammar rules, so check the both cases.
CREATE PROCEDURE sp1() CREATE SEQUENCE s1 START WITH 300 INCREMENT BY 30 RESTART WITH 100;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'RESTART' at line 1
# End of 10.3 tests # End of 10.3 tests
# #
# Start of 10.4 tests # Start of 10.4 tests
@@ -8911,6 +8924,12 @@ END;
$$ $$
ERROR 42000: Incorrect usage/placement of 'HIGH_PRIORITY' ERROR 42000: Incorrect usage/placement of 'HIGH_PRIORITY'
# #
# MDEV-21173: Assertion `m_thd == __null' failed in sp_head::~sp_head
#
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1));
ERROR 42000: PROCEDURE does not support subqueries or stored functions
DROP TABLE t1;
# End of 10.4 tests # End of 10.4 tests
# #
# #

View File

@@ -10460,6 +10460,21 @@ END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--echo #
--echo # MDEV-28220: Assert failure in sp_head::~sp_head on parsing a syntax incorrect statement CREATE SEQUENCE ... RESTART inside CREATE PROCEDURE/CREATE FUNCTION
--echo
--echo # Specifying the RESTART clause for the statement CREATE SEQUENCE is a syntax error.
--echo # Check that CREATE PROCEDURE doesn't crash server if the statement
--echo # CREATE SEQUNCE ... RESTART is specified in its body.
--echo #
--error ER_PARSE_ERROR
CREATE PROCEDURE sp1() CREATE SEQUENCE s1 START WITH 300 INCREMENT BY 30 RESTART;
--echo # CREATE SEQUNCE ... RESTART and CREATE SEQUNCE ... RESTART WITH ... are
--echo # handled by different grammar rules, so check the both cases.
--error ER_PARSE_ERROR
CREATE PROCEDURE sp1() CREATE SEQUENCE s1 START WITH 300 INCREMENT BY 30 RESTART WITH 100;
--echo # End of 10.3 tests --echo # End of 10.3 tests
@@ -10480,8 +10495,15 @@ END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--echo # --echo #
--echo # MDEV-21173: Assertion `m_thd == __null' failed in sp_head::~sp_head
--echo #
CREATE TABLE t1 (a INT);
--error ER_SUBQUERIES_NOT_SUPPORTED
CREATE PROCEDURE p1() SELECT 1 FROM t1 PROCEDURE ANALYSE( 10, (SELECT a FROM t1));
DROP TABLE t1;
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #

View File

@@ -319,7 +319,7 @@ drop table t1;
drop table t3; drop table t3;
create temporary table t1 (i int); create temporary table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1; create trigger trg before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger's 't1' is view or temporary table ERROR HY000: Trigger's 't1' is a view, temporary table or sequence
drop table t1; drop table t1;
create table t1 (x1col char); create table t1 (x1col char);
create trigger tx1 before insert on t1 for each row set new.x1col = 'x'; create trigger tx1 before insert on t1 for each row set new.x1col = 'x';

View File

@@ -7,7 +7,7 @@ CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FOR
CREATE TABLE t4 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1; CREATE TABLE t4 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1;
CREATE TABLE t5 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; CREATE TABLE t5 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4;
CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
# Run innochecksum on t1 # Run innochecksum on t1, check -S does not cause crash for encrypted file
# Run innochecksum on t2 # Run innochecksum on t2
# Run innochecksum on t3 # Run innochecksum on t3
# Run innochecksum on t4 # Run innochecksum on t4

View File

@@ -63,9 +63,9 @@ let MYSQLD_DATADIR=`select @@datadir`;
--source include/shutdown_mysqld.inc --source include/shutdown_mysqld.inc
--echo # Run innochecksum on t1
-- disable_result_log -- disable_result_log
--exec $INNOCHECKSUM $t1_IBD --echo # Run innochecksum on t1, check -S does not cause crash for encrypted file
--exec $INNOCHECKSUM -S $t1_IBD
--echo # Run innochecksum on t2 --echo # Run innochecksum on t2

View File

@@ -237,7 +237,7 @@ Testcase 3.5.5.2:
Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned); Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned);
Create trigger trg2 before INSERT Create trigger trg2 before INSERT
on t1_temp for each row set new.f2=9999; on t1_temp for each row set new.f2=9999;
ERROR HY000: Trigger's 't1_temp' is view or temporary table ERROR HY000: Trigger's 't1_temp' is a view, temporary table or sequence
drop table t1_temp; drop table t1_temp;
Testcase 3.5.5.3: Testcase 3.5.5.3:

View File

@@ -237,7 +237,7 @@ Testcase 3.5.5.2:
Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned); Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned);
Create trigger trg2 before INSERT Create trigger trg2 before INSERT
on t1_temp for each row set new.f2=9999; on t1_temp for each row set new.f2=9999;
ERROR HY000: Trigger's 't1_temp' is view or temporary table ERROR HY000: Trigger's 't1_temp' is a view, temporary table or sequence
drop table t1_temp; drop table t1_temp;
Testcase 3.5.5.3: Testcase 3.5.5.3:

View File

@@ -237,7 +237,7 @@ Testcase 3.5.5.2:
Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned); Create temporary table t1_temp (f1 bigint signed, f2 bigint unsigned);
Create trigger trg2 before INSERT Create trigger trg2 before INSERT
on t1_temp for each row set new.f2=9999; on t1_temp for each row set new.f2=9999;
ERROR HY000: Trigger's 't1_temp' is view or temporary table ERROR HY000: Trigger's 't1_temp' is a view, temporary table or sequence
drop table t1_temp; drop table t1_temp;
Testcase 3.5.5.3: Testcase 3.5.5.3:

View File

@@ -44,4 +44,4 @@ pxc-421: wsrep_provider is read-only for security reasons
query_cache: MDEV-15805 Test failure on galera.query_cache query_cache: MDEV-15805 Test failure on galera.query_cache
versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch
galera_bf_abort_at_after_statement : Unstable galera_bf_abort_at_after_statement : Unstable
galera_bf_abort_ps_bind : MDEV-28193 Galera test failure on galera_bf_abort_ps_bind

View File

@@ -28,6 +28,7 @@ PS_execute;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
PS_execute; PS_execute;
commit; commit;
PS_close;
select * from t; select * from t;
i j i j
1 node2 1 node2

View File

@@ -5,6 +5,7 @@ connection node_2;
connection node_1; connection node_1;
CREATE TABLE t1 (f1 INT PRIMARY KEY); CREATE TABLE t1 (f1 INT PRIMARY KEY);
connection node_2; connection node_2;
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue'; SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue';
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;

View File

@@ -48,3 +48,6 @@ SHOW TABLES;
Tables_in_fts Tables_in_fts
DROP DATABASE fts; DROP DATABASE fts;
connection node_2; connection node_2;
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
Warnings:
Note 1049 Unknown database 'fts'

View File

@@ -111,6 +111,7 @@ f1 f2
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event';
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
connection node_1; connection node_1;
SELECT * FROM t1; SELECT * FROM t1;
f1 f2 f1 f2

View File

@@ -41,6 +41,7 @@ f1 f2
connection node_2; connection node_2;
Starting server ... Starting server ...
Starting server ... Starting server ...
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
SELECT * FROM t1; SELECT * FROM t1;
f1 f2 f1 f2
1 a 1 a

View File

@@ -1,30 +0,0 @@
connection node_2;
connection node_1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SET GLOBAL innodb_disallow_writes=ON;
INSERT INTO t1 (f2) SELECT 'abcde ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;;
connection node_2;
INSERT INTO t1 (f2) SELECT 'fghij ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
SELECT COUNT(*) AS EXPECT_10000 FROM t1;
EXPECT_10000
10000
connection node_1a;
SET GLOBAL innodb_disallow_writes=OFF;
connection node_1;
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
EXPECT_20000
20000
connection node_2;
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
EXPECT_20000
20000
connection node_1;
connection node_2;
DROP TABLE t1;
DROP TABLE ten;
disconnect node_1a;

View File

@@ -53,6 +53,8 @@ update t set j='node2' where i=1;
--PS_execute --PS_execute
commit; commit;
--PS_close
select * from t; select * from t;
drop table t; drop table t;

View File

@@ -18,6 +18,7 @@
CREATE TABLE t1 (f1 INT PRIMARY KEY); CREATE TABLE t1 (f1 INT PRIMARY KEY);
--connection node_2 --connection node_2
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue'; SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue';
--send INSERT INTO t1 VALUES (1) --send INSERT INTO t1 VALUES (1)

View File

@@ -56,6 +56,7 @@ SHOW TABLES;
DROP DATABASE fts; DROP DATABASE fts;
--connection node_2 --connection node_2
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t1'; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t1';
--source include/wait_condition.inc --source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t2'; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t2';

View File

@@ -137,6 +137,8 @@ SELECT * FROM t1;
--echo # node_2 Event should be SERVERSIDE_DISABLED --echo # node_2 Event should be SERVERSIDE_DISABLED
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event';
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
--connection node_1 --connection node_1
SELECT * FROM t1; SELECT * FROM t1;
--echo # node_1 Event should be ENABLED --echo # node_1 Event should be ENABLED

View File

@@ -125,6 +125,7 @@ SELECT * FROM t1;
# Sanity check (node 2 is running now and can perform SQL operators): # Sanity check (node 2 is running now and can perform SQL operators):
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
SELECT * FROM t1; SELECT * FROM t1;
--connection node_1 --connection node_1

View File

@@ -5,10 +5,10 @@ wsrep_sst_method=rsync
[mysqld.1] [mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'
log_bin=@ENV.MYSQLTEST_VARDIR/server1_binlog log_bin=@ENV.MYSQLTEST_VARDIR/mysqld.1/server1_binlog
log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server1_binlog_index.index log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server1_binlog_index.index
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
log_bin=@ENV.MYSQLTEST_VARDIR/server2_binlog log_bin=@ENV.MYSQLTEST_VARDIR/mysqld.2/server2_binlog
log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index

View File

@@ -7,6 +7,8 @@
--source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_shutdown_slave.inc
--source suite/galera/include/galera_st_clean_slave.inc --source suite/galera/include/galera_st_clean_slave.inc
--let $wsrep_recover_additional=--log-bin=$MYSQLTEST_VARDIR/mysqld.2/server2_binlog --log-bin-index=$MYSQLTEST_VARDIR/tmp/server2_binlog_index.index
--source suite/galera/include/galera_st_kill_slave.inc --source suite/galera/include/galera_st_kill_slave.inc
--source suite/galera/include/galera_st_kill_slave_ddl.inc --source suite/galera/include/galera_st_kill_slave_ddl.inc
--source include/auto_increment_offset_restore.inc --source include/auto_increment_offset_restore.inc

View File

@@ -1,72 +0,0 @@
#
# This test checks that innodb_disallow_writes works as expected
#
# Note that we need to enable binlog for this test: If the commit
# to InnoDB is done in one phase, the transaction is committed in
# memory before it is persisted to disk. This means that the
# innodb_disallow_writes=ON may not prevent transaction to
# become visible to other readers. On the other hand, if the
# commit is two phase (as it is with binlog), the transaction
# will be blocked in prepare phase.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_log_bin.inc
--let $datadir= `SELECT @@datadir`
# Open a separate connection to be used to run SHOW PROCESSLIST
--let $galera_connection_name = node_1a
--let $galera_server_number = 1
--source include/galera_connect.inc
--connection node_1a
SET SESSION wsrep_sync_wait = 0;
--connection node_1
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SET GLOBAL innodb_disallow_writes=ON;
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
#
# This insert has no effect before innodb_disallow_writes is OFF
#
--send INSERT INTO t1 (f2) SELECT 'abcde ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
--connection node_2
INSERT INTO t1 (f2) SELECT 'fghij ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
SELECT COUNT(*) AS EXPECT_10000 FROM t1;
--connection node_1a
--sleep 5
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
SET GLOBAL innodb_disallow_writes=OFF;
--connection node_1
--reap
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
--connection node_1
--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
--connection node_2
DROP TABLE t1;
DROP TABLE ten;
--disconnect node_1a

View File

@@ -1,6 +1,7 @@
CREATE TABLE t(i INT) ENGINE INNODB; CREATE TABLE t(i INT) ENGINE INNODB;
INSERT INTO t VALUES(1); INSERT INTO t VALUES(1);
# xtrabackup backup # xtrabackup backup
NOT FOUND /InnoDB: Allocated tablespace ID/ in backup.log
INSERT INTO t VALUES(2); INSERT INTO t VALUES(2);
# xtrabackup prepare # xtrabackup prepare
# shutdown server # shutdown server

View File

@@ -4,11 +4,18 @@ CREATE TABLE t(i INT) ENGINE INNODB;
INSERT INTO t VALUES(1); INSERT INTO t VALUES(1);
echo # xtrabackup backup; echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--let $backup_log=$MYSQLTEST_VARDIR/tmp/backup.log
--disable_result_log --disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backup_log 2>&1;
--enable_result_log --enable_result_log
# The following warning must not appear after MDEV-27343 fix
--let SEARCH_PATTERN=InnoDB: Allocated tablespace ID
--let SEARCH_FILE=$backup_log
--source include/search_pattern_in_file.inc
--remove_file $backup_log
INSERT INTO t VALUES(2); INSERT INTO t VALUES(2);

View File

@@ -14,6 +14,5 @@ rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition
rpl_row_binlog_max_cache_size : MDEV-11092 rpl_row_binlog_max_cache_size : MDEV-11092
rpl_row_index_choice : MDEV-11666 rpl_row_index_choice : MDEV-11666
rpl_semi_sync_after_sync : fails after MDEV-16172 rpl_semi_sync_after_sync : fails after MDEV-16172
rpl_semi_sync_slave_compressed_protocol : MDEV-25580 2021-05-05 Sujatha
rpl_auto_increment_update_failure : disabled for now rpl_auto_increment_update_failure : disabled for now
rpl_current_user : waits for MDEV-22374 fix rpl_current_user : waits for MDEV-22374 fix

View File

@@ -29,7 +29,7 @@ select * from t1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
3 -100 9223372036854775806 50 1 0 0 0 3 -100 9223372036854775806 50 1 0 0 0
alter sequence t1 minvalue=100 start=100; alter sequence t1 minvalue=100 start=100;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
alter sequence t1 minvalue=100 start=100 restart=100; alter sequence t1 minvalue=100 start=100 restart=100;
show create sequence t1; show create sequence t1;
Table Create Table Table Create Table
@@ -200,21 +200,20 @@ next_not_cached_value minimum_value maximum_value start_value increment cache_si
drop sequence t1; drop sequence t1;
CREATE SEQUENCE t1 engine=myisam; CREATE SEQUENCE t1 engine=myisam;
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
drop sequence t1; drop sequence t1;
CREATE SEQUENCE t1 engine=myisam; CREATE SEQUENCE t1 engine=myisam;
alter sequence t1 minvalue=25 maxvalue=20; alter sequence t1 minvalue=25 maxvalue=20;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
drop sequence t1; drop sequence t1;
create table t1 (a int); create table t1 (a int);
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
ERROR 42S02: 'test.t1' is not a SEQUENCE ERROR 42S02: 'test.t1' is not a SEQUENCE
drop table t1; drop table t1;
alter sequence if exists t1 minvalue=100; alter sequence if exists t1 minvalue=100;
Warnings: ERROR 42S02: Unknown SEQUENCE: 't1'
Note 4091 Unknown SEQUENCE: 'test.t1'
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR 42S02: Unknown SEQUENCE: 't1'
create sequence t1; create sequence t1;
alter sequence t1; alter sequence t1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

View File

@@ -119,8 +119,9 @@ create table t1 (a int);
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
drop table t1; drop table t1;
--error ER_UNKNOWN_SEQUENCES
alter sequence if exists t1 minvalue=100; alter sequence if exists t1 minvalue=100;
--error ER_NO_SUCH_TABLE --error ER_UNKNOWN_SEQUENCES
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
create sequence t1; create sequence t1;

View File

@@ -53,7 +53,7 @@ next value for s1
drop sequence s1; drop sequence s1;
CREATE SEQUENCE t1; CREATE SEQUENCE t1;
alter sequence t1 minvalue=100; alter sequence t1 minvalue=100;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
alter sequence t1 minvalue=100 start=100 restart=100; alter sequence t1 minvalue=100 start=100 restart=100;
rename table t1 to t2; rename table t1 to t2;
select next value for t2; select next value for t2;

View File

@@ -167,11 +167,11 @@ drop sequence if exists t1;
Warnings: Warnings:
Note 4090 'test.t1' is not a SEQUENCE Note 4090 'test.t1' is not a SEQUENCE
create sequence t1 start with 10 maxvalue=9; create sequence t1 start with 10 maxvalue=9;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
create sequence t1 minvalue= 100 maxvalue=10; create sequence t1 minvalue= 100 maxvalue=10;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
create sequence t1 start with 9 minvalue=10; create sequence t1 start with 9 minvalue=10;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
create or replace sequence t1 maxvalue=13, increment by -1; create or replace sequence t1 maxvalue=13, increment by -1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' increment by -1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' increment by -1' at line 1
create or replace sequence t1 start with= 10 maxvalue=13; create or replace sequence t1 start with= 10 maxvalue=13;
@@ -183,7 +183,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
create or replace sequence t1 start with 10 min_value=1 NO MINVALUE; create or replace sequence t1 start with 10 min_value=1 NO MINVALUE;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NO MINVALUE' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NO MINVALUE' at line 1
create sequence t1 start with 10 maxvalue=9223372036854775807; create sequence t1 start with 10 maxvalue=9223372036854775807;
ERROR HY000: Sequence 'test.t1' values are conflicting ERROR HY000: Sequence 'test.t1' has out of range value for options
create sequence t1 start with 10 minvalue=-9223372036854775808; create sequence t1 start with 10 minvalue=-9223372036854775808;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '9223372036854775808' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '9223372036854775808' at line 1
create sequence t1 RESTART WITH 10; create sequence t1 RESTART WITH 10;
@@ -477,7 +477,7 @@ next value for t1
1 1
drop temporary table t1; drop temporary table t1;
select previous value for t1; select previous value for t1;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR 42S02: Unknown SEQUENCE: 't1'
CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10; CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10;
select next value for t1; select next value for t1;
next value for t1 next value for t1
@@ -506,7 +506,7 @@ next value for t1
1 1
drop temporary table t1; drop temporary table t1;
select previous value for t1; select previous value for t1;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR 42S02: Unknown SEQUENCE: 't1'
CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10 engine=innodb; CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10 engine=innodb;
select next value for t1; select next value for t1;
next value for t1 next value for t1
@@ -686,3 +686,33 @@ set global innodb_force_primary_key=default;
ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value); ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value);
ERROR HY000: Sequence 'test.s1' table structure is invalid (Sequence tables cannot have any keys) ERROR HY000: Sequence 'test.s1' table structure is invalid (Sequence tables cannot have any keys)
DROP SEQUENCE s1; DROP SEQUENCE s1;
#
# Beginning of 10.4 Test
#
# MDEV-13005: Fixing bugs in SEQUENCE, part 3
#
# Task 1:
SET @x = PREVIOUS VALUE FOR x;
ERROR 42S02: Unknown SEQUENCE: 'x'
# Task 2:
CREATE SEQUENCE x START WITH 1 INCREMENT BY 123456789012345678;
ERROR HY000: Sequence 'test.x' has out of range value for options
# Task 3:
CREATE SEQUENCE seq1 START WITH 1 cache -1;
ERROR HY000: Sequence 'test.seq1' has out of range value for options
# Task 4:
CREATE TEMPORARY TABLE s1 (s1 INT);
DROP TEMPORARY SEQUENCE s1;
ERROR 42S02: Unknown SEQUENCE: 'test.s1'
DROP TEMPORARY TABLE s1;
# Task 5:
CREATE TEMPORARY TABLE s1 (s1 INT);
CREATE TEMPORARY SEQUENCE s1 (s1 INT);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(s1 INT)' at line 1
DROP TEMPORARY TABLE s1;
# Task 6:
CREATE SEQUENCE seq1 START WITH 2;
CREATE TRIGGER s1 BEFORE UPDATE ON seq1 FOR EACH ROW SET @a= 5;
ERROR HY000: Trigger's 'seq1' is a view, temporary table or sequence
DROP SEQUENCE seq1;
# End of 10.4 test

View File

@@ -382,7 +382,7 @@ drop view v1;
CREATE TEMPORARY SEQUENCE t1; CREATE TEMPORARY SEQUENCE t1;
select next value for t1; select next value for t1;
drop temporary table t1; drop temporary table t1;
--error ER_NO_SUCH_TABLE --error ER_UNKNOWN_SEQUENCES
select previous value for t1; select previous value for t1;
CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10; CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10;
select next value for t1; select next value for t1;
@@ -398,7 +398,7 @@ drop sequence t1;
CREATE TEMPORARY SEQUENCE t1 engine=innodb; CREATE TEMPORARY SEQUENCE t1 engine=innodb;
select next value for t1; select next value for t1;
drop temporary table t1; drop temporary table t1;
--error ER_NO_SUCH_TABLE --error ER_UNKNOWN_SEQUENCES
select previous value for t1; select previous value for t1;
CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10 engine=innodb; CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 10 increment by 1 cache 10 engine=innodb;
select next value for t1; select next value for t1;
@@ -515,3 +515,41 @@ set global innodb_force_primary_key=default;
--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE --error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value); ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value);
DROP SEQUENCE s1; DROP SEQUENCE s1;
--echo #
--echo # Beginning of 10.4 Test
--echo #
--echo # MDEV-13005: Fixing bugs in SEQUENCE, part 3
--echo #
--echo # Task 1:
--error ER_UNKNOWN_SEQUENCES
SET @x = PREVIOUS VALUE FOR x;
--echo # Task 2:
--error ER_SEQUENCE_INVALID_DATA
CREATE SEQUENCE x START WITH 1 INCREMENT BY 123456789012345678;
--echo # Task 3:
--error ER_SEQUENCE_INVALID_DATA
CREATE SEQUENCE seq1 START WITH 1 cache -1;
--echo # Task 4:
CREATE TEMPORARY TABLE s1 (s1 INT);
--error ER_UNKNOWN_SEQUENCES
DROP TEMPORARY SEQUENCE s1;
DROP TEMPORARY TABLE s1;
--echo # Task 5:
CREATE TEMPORARY TABLE s1 (s1 INT);
--error ER_PARSE_ERROR
CREATE TEMPORARY SEQUENCE s1 (s1 INT);
DROP TEMPORARY TABLE s1;
--echo # Task 6:
CREATE SEQUENCE seq1 START WITH 2;
--error ER_TRG_ON_VIEW_OR_TEMP_TABLE
CREATE TRIGGER s1 BEFORE UPDATE ON seq1 FOR EACH ROW SET @a= 5;
DROP SEQUENCE seq1;
--echo # End of 10.4 test

View File

@@ -109,28 +109,28 @@ maxvalue 100000
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 5 maxvalue 5
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 4 maxvalue 4
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 4 maxvalue 4
increment by 0 increment by 0
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
########################################### ###########################################
global read lock prevent query sequence global read lock prevent query sequence
########################################### ###########################################
@@ -314,7 +314,7 @@ next_not_cached_value minimum_value maximum_value start_value increment cache_si
update s_t set next_not_cached_value= 11,start_value=10, minimum_value=11; update s_t set next_not_cached_value= 11,start_value=10, minimum_value=11;
ERROR HY000: Storage engine SEQUENCE of the table `s_db`.`s_t` doesn't have this option ERROR HY000: Storage engine SEQUENCE of the table `s_db`.`s_t` doesn't have this option
ALTER SEQUENCE s_t restart with 11 start=10 minvalue=11; ALTER SEQUENCE s_t restart with 11 start=10 minvalue=11;
ERROR HY000: Sequence 's_db.s_t' values are conflicting ERROR HY000: Sequence 's_db.s_t' has out of range value for options
commit; commit;
create table t_1(id int); create table t_1(id int);
insert into t_1 value(1111); insert into t_1 value(1111);

View File

@@ -387,7 +387,7 @@ previous value for t1
1 1
drop sequence t1; drop sequence t1;
select previous value for t1; select previous value for t1;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR 42S02: Unknown SEQUENCE: 't1'
CREATE SEQUENCE t1 start with 5 minvalue 1 maxvalue 10 increment by 1 cache 5 cycle; CREATE SEQUENCE t1 start with 5 minvalue 1 maxvalue 10 increment by 1 cache 5 cycle;
select previous value for t1; select previous value for t1;
previous value for t1 previous value for t1

View File

@@ -166,7 +166,7 @@ select previous value for t1;
flush tables; flush tables;
select previous value for t1; select previous value for t1;
drop sequence t1; drop sequence t1;
--error ER_NO_SUCH_TABLE --error ER_UNKNOWN_SEQUENCES
select previous value for t1; select previous value for t1;
CREATE SEQUENCE t1 start with 5 minvalue 1 maxvalue 10 increment by 1 cache 5 cycle; CREATE SEQUENCE t1 start with 5 minvalue 1 maxvalue 10 increment by 1 cache 5 cycle;
select previous value for t1; select previous value for t1;

View File

@@ -50,9 +50,9 @@ ERROR HY000: Field 'maximum_value' doesn't have a default value
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0); insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
ERROR HY000: Table 's1' is specified twice, both as a target for 'INSERT' and as a separate source for data ERROR HY000: Table 's1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0); insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
ERROR HY000: Sequence 'test.s1' values are conflicting ERROR HY000: Sequence 'test.s1' has out of range value for options
insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0); insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0);
ERROR HY000: Sequence 'test.s1' values are conflicting ERROR HY000: Sequence 'test.s1' has out of range value for options
select * from s1; select * from s1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 9223372036854775806 1 1 1000 0 0 1 1 9223372036854775806 1 1 1000 0 0
@@ -67,7 +67,7 @@ select * from s1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
2000 1 9223372036854775806 1 1 1000 0 0 2000 1 9223372036854775806 1 1 1000 0 0
insert into s2 values(0, 1, 10, 1, 2, 1, 1, 0); insert into s2 values(0, 1, 10, 1, 2, 1, 1, 0);
ERROR HY000: Sequence 'test.s2' values are conflicting ERROR HY000: Sequence 'test.s2' has out of range value for options
select * from s1; select * from s1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
2000 1 9223372036854775806 1 1 1000 0 0 2000 1 9223372036854775806 1 1 1000 0 0

View File

@@ -227,28 +227,28 @@ maxvalue 100000
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 5 maxvalue 5
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 4 maxvalue 4
increment by 1 increment by 1
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
create sequence s2 start with 1 create sequence s2 start with 1
minvalue 5 minvalue 5
maxvalue 4 maxvalue 4
increment by 0 increment by 0
nocache nocache
nocycle; nocycle;
ERROR HY000: Sequence 's_db.s2' values are conflicting ERROR HY000: Sequence 's_db.s2' has out of range value for options
########################################### ###########################################
global read lock prevent query sequence global read lock prevent query sequence
########################################### ###########################################
@@ -412,12 +412,12 @@ select * from s_t;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
16 1 20 1 1 5 1 0 16 1 20 1 1 5 1 0
alter sequence s_t minvalue=11 maxvalue=9; alter sequence s_t minvalue=11 maxvalue=9;
ERROR HY000: Sequence 's_db.s_t' values are conflicting ERROR HY000: Sequence 's_db.s_t' has out of range value for options
select * from s_t; select * from s_t;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
16 1 20 1 1 5 1 0 16 1 20 1 1 5 1 0
alter sequence s_t restart= 12 start=10 minvalue=11 maxvalue=20; alter sequence s_t restart= 12 start=10 minvalue=11 maxvalue=20;
ERROR HY000: Sequence 's_db.s_t' values are conflicting ERROR HY000: Sequence 's_db.s_t' has out of range value for options
select * from s_t; select * from s_t;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
16 1 20 1 1 5 1 0 16 1 20 1 1 5 1 0

View File

@@ -1,45 +0,0 @@
#
# innodb_disallow_writes
#
# save the initial value
SET @innodb_disallow_writes_global_saved = @@global.innodb_disallow_writes;
# default
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
0
# scope
SELECT @@session.innodb_disallow_writes;
ERROR HY000: Variable 'innodb_disallow_writes' is a GLOBAL variable
SET @@global.innodb_disallow_writes=OFF;
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
0
SET @@global.innodb_disallow_writes=ON;
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
1
# valid values
SET @@global.innodb_disallow_writes='OFF';
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
0
SET @@global.innodb_disallow_writes=ON;
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
1
SET @@global.innodb_disallow_writes=default;
SELECT @@global.innodb_disallow_writes;
@@global.innodb_disallow_writes
0
# invalid values
SET @@global.innodb_disallow_writes=NULL;
ERROR 42000: Variable 'innodb_disallow_writes' can't be set to the value of 'NULL'
SET @@global.innodb_disallow_writes='junk';
ERROR 42000: Variable 'innodb_disallow_writes' can't be set to the value of 'junk'
# restore the initial value
SET @@global.innodb_disallow_writes = @innodb_disallow_writes_global_saved;
# End of test

View File

@@ -2,9 +2,7 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP
where variable_name like 'innodb%' and where variable_name like 'innodb%' and
variable_name not in ( variable_name not in (
'innodb_version', # always the same as the server version 'innodb_version', # always the same as the server version
'innodb_disallow_writes', # only available WITH_WSREP
'innodb_numa_interleave', # only available WITH_NUMA 'innodb_numa_interleave', # only available WITH_NUMA
'innodb_sched_priority_cleaner', # linux only
'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_evict_tables_on_commit_debug', # one may want to override this
'innodb_use_native_aio', # default value depends on OS 'innodb_use_native_aio', # default value depends on OS
'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing

View File

@@ -1,42 +0,0 @@
--source include/have_innodb_disallow_writes.inc
--echo #
--echo # innodb_disallow_writes
--echo #
--echo # save the initial value
SET @innodb_disallow_writes_global_saved = @@global.innodb_disallow_writes;
--echo # default
SELECT @@global.innodb_disallow_writes;
--echo
--echo # scope
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT @@session.innodb_disallow_writes;
SET @@global.innodb_disallow_writes=OFF;
SELECT @@global.innodb_disallow_writes;
SET @@global.innodb_disallow_writes=ON;
SELECT @@global.innodb_disallow_writes;
--echo
--echo # valid values
SET @@global.innodb_disallow_writes='OFF';
SELECT @@global.innodb_disallow_writes;
SET @@global.innodb_disallow_writes=ON;
SELECT @@global.innodb_disallow_writes;
SET @@global.innodb_disallow_writes=default;
SELECT @@global.innodb_disallow_writes;
--echo
--echo # invalid values
--error ER_WRONG_VALUE_FOR_VAR
SET @@global.innodb_disallow_writes=NULL;
--error ER_WRONG_VALUE_FOR_VAR
SET @@global.innodb_disallow_writes='junk';
--echo
--echo # restore the initial value
SET @@global.innodb_disallow_writes = @innodb_disallow_writes_global_saved;
--echo # End of test

View File

@@ -9,9 +9,7 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP
where variable_name like 'innodb%' and where variable_name like 'innodb%' and
variable_name not in ( variable_name not in (
'innodb_version', # always the same as the server version 'innodb_version', # always the same as the server version
'innodb_disallow_writes', # only available WITH_WSREP
'innodb_numa_interleave', # only available WITH_NUMA 'innodb_numa_interleave', # only available WITH_NUMA
'innodb_sched_priority_cleaner', # linux only
'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_evict_tables_on_commit_debug', # one may want to override this
'innodb_use_native_aio', # default value depends on OS 'innodb_use_native_aio', # default value depends on OS
'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing

View File

@@ -50,5 +50,17 @@ t4 CREATE TABLE `t4` (
`row_end` timestamp(6) GENERATED ALWAYS AS ROW END, `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
set global debug_dbug=@old_dbug;
drop table t1, t2, t3, t4; drop table t1, t2, t3, t4;
#
# MDEV-19525 remove ER_VERS_FIELD_WRONG_TYPE from init_from_binary_frm_image()
#
create table t1 (x int) with system versioning;
set debug_dbug='+d,error_vers_wrong_type';
show create table t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
show warnings;
Level Code Message
Warning 4110 `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
Error 1033 Incorrect information in file: './test/t1.frm'
drop table t1;
set global debug_dbug=@old_dbug;

View File

@@ -411,6 +411,17 @@ check_row_ts(row_start, row_end)
CURRENT ROW CURRENT ROW
drop table t1; drop table t1;
# #
# MDEV-22973 Assertion in compare_record upon multi-update involving versioned table via view
#
create or replace table t1 (a int, primary key (a)) engine=myisam;
insert into t1 values (0);
create or replace table t2 (pk int, b int, primary key (pk), key(b)) engine=innodb with system versioning;
insert into t2 values (1, 0), (2, 0);
create or replace view v as select a, b from t1, t2;
update v set b= null where a = 0 order by b;
drop view v;
drop table t1, t2;
#
# MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob # MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob
# #
create table t1 (a int, b int, c text, unique(c), key (b)) engine=myisam with system versioning; create table t1 (a int, b int, c text, unique(c), key (b)) engine=myisam with system versioning;
@@ -426,3 +437,4 @@ update t1 set a = 3 where b <= 9;
update t2 set a = 3 where b <= 9; update t2 set a = 3 where b <= 9;
update t1, t2 set t1.a = 3, t2.a = 3 where t1.b <= 10 and t2.b <= 10 and t1.b = t2.b; update t1, t2 set t1.a = 3, t2.a = 3 where t1.b <= 10 and t2.b <= 10 and t1.b = t2.b;
drop tables t1, t2; drop tables t1, t2;
# End of 10.4 tests

View File

@@ -1,5 +1,7 @@
--source include/have_debug.inc --source include/have_debug.inc
--let $datadir=`select @@datadir`
create table t1 (a int); create table t1 (a int);
show create table t1; show create table t1;
@@ -30,6 +32,18 @@ set debug_dbug='+d,sysvers_show';
show create table t3; show create table t3;
create table t4 (a int); create table t4 (a int);
show create table t4; show create table t4;
set global debug_dbug=@old_dbug;
drop table t1, t2, t3, t4; drop table t1, t2, t3, t4;
--echo #
--echo # MDEV-19525 remove ER_VERS_FIELD_WRONG_TYPE from init_from_binary_frm_image()
--echo #
create table t1 (x int) with system versioning;
set debug_dbug='+d,error_vers_wrong_type';
--replace_result $datadir ./
--error ER_NOT_FORM_FILE
show create table t1;
--replace_result $datadir ./
show warnings;
drop table t1;
set global debug_dbug=@old_dbug;

View File

@@ -336,6 +336,19 @@ select row_start into @r from t1;
select check_row_ts(row_start, row_end) from t1 for system_time all where row_start = @r; select check_row_ts(row_start, row_end) from t1 for system_time all where row_start = @r;
drop table t1; drop table t1;
--echo #
--echo # MDEV-22973 Assertion in compare_record upon multi-update involving versioned table via view
--echo #
create or replace table t1 (a int, primary key (a)) engine=myisam;
insert into t1 values (0);
create or replace table t2 (pk int, b int, primary key (pk), key(b)) engine=innodb with system versioning;
insert into t2 values (1, 0), (2, 0);
create or replace view v as select a, b from t1, t2;
update v set b= null where a = 0 order by b;
# cleanup
drop view v;
drop table t1, t2;
--echo # --echo #
--echo # MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob --echo # MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob
--echo # --echo #
@@ -360,4 +373,6 @@ update t1, t2 set t1.a = 3, t2.a = 3 where t1.b <= 10 and t2.b <= 10 and t1.b =
# cleanup # cleanup
drop tables t1, t2; drop tables t1, t2;
--echo # End of 10.4 tests
source suite/versioning/common_finish.inc; source suite/versioning/common_finish.inc;

View File

@@ -30,7 +30,8 @@ template <TR_table::field_id_t TRT_FIELD>
class Create_func_trt : public Create_native_func class Create_func_trt : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_trt<TRT_FIELD> s_singleton; static Create_func_trt<TRT_FIELD> s_singleton;
@@ -44,7 +45,7 @@ Create_func_trt<TRT_FIELD> Create_func_trt<TRT_FIELD>::s_singleton;
template <TR_table::field_id_t TRT_FIELD> template <TR_table::field_id_t TRT_FIELD>
Item* Item*
Create_func_trt<TRT_FIELD>::create_native(THD *thd, LEX_CSTRING *name, Create_func_trt<TRT_FIELD>::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -103,7 +104,8 @@ template <class Item_func_trt_trx_seesX>
class Create_func_trt_trx_sees : public Create_native_func class Create_func_trt_trx_sees : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
int arg_count= 0; int arg_count= 0;

View File

@@ -35,17 +35,15 @@ set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS global_priv (Host char(255) binary DEFAULT '', User char(128) binary DEFAULT '', Priv JSON NOT NULL DEFAULT '{}' CHECK(JSON_VALID(Priv)), PRIMARY KEY (Host,User)) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; CREATE TABLE IF NOT EXISTS global_priv (Host char(255) binary DEFAULT '', User char(128) binary DEFAULT '', Priv JSON NOT NULL DEFAULT '{}' CHECK(JSON_VALID(Priv)), PRIMARY KEY (Host,User)) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
set @had_sys_user= 0 <> (select count(*) from mysql.global_priv where Host="localhost" and User="mariadb.sys");
set @exists_user_view= EXISTS (SELECT * FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user'); set @exists_user_view= EXISTS (SELECT * FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user');
set @exists_user_view_by_root= EXISTS (SELECT * FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and DEFINER = 'mariadb.sys@localhost'); set @exists_user_view_by_root= EXISTS (SELECT * FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and DEFINER = 'mariadb.sys@localhost');
set @need_sys_user_creation= (NOT @had_sys_user) AND (( NOT @exists_user_view) OR @exists_user_view_by_root); set @need_sys_user_creation= (( NOT @exists_user_view) OR @exists_user_view_by_root);
CREATE TEMPORARY TABLE tmp_user_sys LIKE global_priv; CREATE TEMPORARY TABLE tmp_user_sys LIKE global_priv;
INSERT INTO tmp_user_sys (Host,User,Priv) VALUES ('localhost','mariadb.sys','{"access":0,"plugin":"mysql_native_password","authentication_string":"","account_locked":true,"password_last_changed":0}'); INSERT INTO tmp_user_sys (Host,User,Priv) VALUES ('localhost','mariadb.sys','{"access":0,"plugin":"mysql_native_password","authentication_string":"","account_locked":true,"password_last_changed":0}');
INSERT INTO global_priv SELECT * FROM tmp_user_sys WHERE 0 <> @need_sys_user_creation; INSERT IGNORE INTO global_priv SELECT * FROM tmp_user_sys WHERE 0 <> @need_sys_user_creation;
DROP TABLE tmp_user_sys; DROP TABLE tmp_user_sys;
@@ -117,7 +115,7 @@ CREATE TABLE IF NOT EXISTS tables_priv ( Host char(255) binary DEFAULT '' NOT NU
CREATE TEMPORARY TABLE tmp_user_sys LIKE tables_priv; CREATE TEMPORARY TABLE tmp_user_sys LIKE tables_priv;
INSERT INTO tmp_user_sys (Host,Db,User,Table_name,Grantor,Timestamp,Table_priv) VALUES ('localhost','mysql','mariadb.sys','global_priv','root@localhost','0','Select,Delete'); INSERT INTO tmp_user_sys (Host,Db,User,Table_name,Grantor,Timestamp,Table_priv) VALUES ('localhost','mysql','mariadb.sys','global_priv','root@localhost','0','Select,Delete');
INSERT INTO tables_priv SELECT * FROM tmp_user_sys WHERE 0 <> @need_sys_user_creation; INSERT IGNORE INTO tables_priv SELECT * FROM tmp_user_sys WHERE 0 <> @need_sys_user_creation;
DROP TABLE tmp_user_sys; DROP TABLE tmp_user_sys;
CREATE TABLE IF NOT EXISTS columns_priv ( Host char(255) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(128) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges'; CREATE TABLE IF NOT EXISTS columns_priv ( Host char(255) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(128) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';

View File

@@ -472,7 +472,7 @@ read_cnf()
encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) encrypt=$(parse_cnf "$encgroups" 'encrypt' 0)
tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \
tr [:lower:] [:upper:]) tr '[[:lower:]]' '[[:upper:]]')
case "$tmode" in case "$tmode" in
'VERIFY_IDENTITY'|'VERIFY_CA'|'REQUIRED'|'DISABLED') 'VERIFY_IDENTITY'|'VERIFY_CA'|'REQUIRED'|'DISABLED')

View File

@@ -3,7 +3,7 @@
set -ue set -ue
# Copyright (C) 2017-2022 MariaDB # Copyright (C) 2017-2022 MariaDB
# Copyright (C) 2010-2014 Codership Oy # Copyright (C) 2010-2022 Codership Oy
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -224,7 +224,7 @@ SSTCERT="$tpem"
SSTCA="$tcert" SSTCA="$tcert"
SSTCAP="$tcap" SSTCAP="$tcap"
SSLMODE=$(parse_cnf "$encgroups" 'ssl-mode' | tr [:lower:] [:upper:]) SSLMODE=$(parse_cnf "$encgroups" 'ssl-mode' | tr '[[:lower:]]' '[[:upper:]]')
if [ -z "$SSLMODE" ]; then if [ -z "$SSLMODE" ]; then
# Implicit verification if CA is set and the SSL mode # Implicit verification if CA is set and the SSL mode
@@ -416,6 +416,8 @@ EOF
sync sync
wsrep_log_info "Tables flushed"
if [ -n "$WSREP_SST_OPT_BINLOG" ]; then if [ -n "$WSREP_SST_OPT_BINLOG" ]; then
# Change the directory to binlog base (if possible): # Change the directory to binlog base (if possible):
cd "$DATA" cd "$DATA"
@@ -557,6 +559,8 @@ FILTER="-f '- /lost+found'
exit $RC exit $RC
fi fi
wsrep_log_info "Transfer of normal directories done"
# Transfer InnoDB data files # Transfer InnoDB data files
rsync ${STUNNEL:+--rsh="$STUNNEL"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
@@ -570,6 +574,8 @@ FILTER="-f '- /lost+found'
exit 255 # unknown error exit 255 # unknown error
fi fi
wsrep_log_info "Transfer of InnoDB data files done"
# second, we transfer InnoDB and Aria log files # second, we transfer InnoDB and Aria log files
rsync ${STUNNEL:+--rsh="$STUNNEL"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
@@ -583,6 +589,8 @@ FILTER="-f '- /lost+found'
exit 255 # unknown error exit 255 # unknown error
fi fi
wsrep_log_info "Transfer of InnoDB and Aria log files done"
# then, we parallelize the transfer of database directories, # then, we parallelize the transfer of database directories,
# use '.' so that path concatenation works: # use '.' so that path concatenation works:
@@ -610,6 +618,9 @@ FILTER="-f '- /lost+found'
exit 255 # unknown error exit 255 # unknown error
fi fi
wsrep_log_info "Transfer of data done"
else # BYPASS else # BYPASS
wsrep_log_info "Bypassing state dump." wsrep_log_info "Bypassing state dump."
@@ -620,6 +631,7 @@ FILTER="-f '- /lost+found'
fi fi
wsrep_log_info "Sending continue to donor"
echo 'continue' # now server can resume updating data echo 'continue' # now server can resume updating data
echo "$STATE" > "$MAGIC_FILE" echo "$STATE" > "$MAGIC_FILE"

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2017, 2022, MariaDB corporation.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -105,16 +106,12 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name,
goto err; goto err;
} }
/* engine_name is 0 if we only want to know if table is view or not */
if (!engine_name)
goto err;
if (!is_binary_frm_header(header)) if (!is_binary_frm_header(header))
goto err; goto err;
dbt= header[3]; dbt= header[3];
if (((header[39] >> 4) & 3) == HA_CHOICE_YES) if ((header[39] & 0x30) == (HA_CHOICE_YES << 4))
{ {
DBUG_PRINT("info", ("Sequence found")); DBUG_PRINT("info", ("Sequence found"));
type= TABLE_TYPE_SEQUENCE; type= TABLE_TYPE_SEQUENCE;
@@ -134,6 +131,7 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name,
handlerton *ht= ha_resolve_by_legacy_type(thd, (legacy_db_type) dbt); handlerton *ht= ha_resolve_by_legacy_type(thd, (legacy_db_type) dbt);
if (ht) if (ht)
{ {
if (engine_name)
*engine_name= hton2plugin[ht->slot]->name; *engine_name= hton2plugin[ht->slot]->name;
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
if (partition_engine_name && dbt == DB_TYPE_PARTITION_DB) if (partition_engine_name && dbt == DB_TYPE_PARTITION_DB)
@@ -155,6 +153,7 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name,
cont: cont:
#endif #endif
/* read the true engine name */ /* read the true engine name */
if (engine_name)
{ {
MY_STAT state; MY_STAT state;
uchar *frm_image= 0; uchar *frm_image= 0;

View File

@@ -670,6 +670,7 @@ Events::drop_schema_events(THD *thd, const char *db)
{ {
db_repository->drop_schema_events(thd, &db_lex); db_repository->drop_schema_events(thd, &db_lex);
delete db_repository; delete db_repository;
db_repository= 0;
} }
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;

View File

@@ -3,7 +3,7 @@
/* /*
Copyright (c) 2005, 2012, Oracle and/or its affiliates. Copyright (c) 2005, 2012, Oracle and/or its affiliates.
Copyright (c) 2009, 2021, MariaDB Corporation. Copyright (c) 2009, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -1108,10 +1108,6 @@ public:
NOTE: This cannot be cached since it can depend on TRANSACTION ISOLATION NOTE: This cannot be cached since it can depend on TRANSACTION ISOLATION
LEVEL which is dynamic, see bug#39084. LEVEL which is dynamic, see bug#39084.
HA_READ_RND_SAME:
Not currently used. (Means that the handler supports the rnd_same() call)
(MyISAM, HEAP)
HA_TABLE_SCAN_ON_INDEX: HA_TABLE_SCAN_ON_INDEX:
Used to avoid scanning full tables on an index. If this flag is set then Used to avoid scanning full tables on an index. If this flag is set then
the handler always has a primary key (hidden if not defined) and this the handler always has a primary key (hidden if not defined) and this

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. /* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2021, MariaDB Corporation. Copyright (c) 2009, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -932,6 +932,22 @@ void ha_kill_query(THD* thd, enum thd_kill_levels level)
} }
static my_bool plugin_disable_internal_writes(THD *, plugin_ref plugin,
void *disable)
{
if (void(*diw)(bool)= plugin_hton(plugin)->disable_internal_writes)
diw(*static_cast<bool*>(disable));
return FALSE;
}
void ha_disable_internal_writes(bool disable)
{
plugin_foreach(NULL, plugin_disable_internal_writes,
MYSQL_STORAGE_ENGINE_PLUGIN, &disable);
}
static my_bool signal_ddl_recovery_done(THD *, plugin_ref plugin, void *) static my_bool signal_ddl_recovery_done(THD *, plugin_ref plugin, void *)
{ {
handlerton *hton= plugin_hton(plugin); handlerton *hton= plugin_hton(plugin);
@@ -6093,6 +6109,8 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share)
found= plugin_foreach(thd, discover_handlerton, found= plugin_foreach(thd, discover_handlerton,
MYSQL_STORAGE_ENGINE_PLUGIN, share); MYSQL_STORAGE_ENGINE_PLUGIN, share);
if (thd->lex->query_tables && thd->lex->query_tables->sequence && !found)
my_error(ER_UNKNOWN_SEQUENCES, MYF(0),share->table_name.str);
if (!found) if (!found)
open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); // not found open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); // not found
@@ -7829,17 +7847,6 @@ void handler::unlock_shared_ha_data()
mysql_mutex_unlock(&table_share->LOCK_ha_data); mysql_mutex_unlock(&table_share->LOCK_ha_data);
} }
/** @brief
Dummy function which accept information about log files which is not need
by handlers
*/
void signal_log_not_needed(struct handlerton, char *log_file)
{
DBUG_ENTER("signal_log_not_needed");
DBUG_PRINT("enter", ("logfile '%s'", log_file));
DBUG_VOID_RETURN;
}
void handler::set_lock_type(enum thr_lock_type lock) void handler::set_lock_type(enum thr_lock_type lock)
{ {
table->reginfo.lock_type= lock; table->reginfo.lock_type= lock;
@@ -7908,177 +7915,6 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
#ifdef TRANS_LOG_MGM_EXAMPLE_CODE
/*
Example of transaction log management functions based on assumption that logs
placed into a directory
*/
#include <my_dir.h>
#include <my_sys.h>
int example_of_iterator_using_for_logs_cleanup(handlerton *hton)
{
void *buffer;
int res= 1;
struct handler_iterator iterator;
struct handler_log_file_data data;
if (!hton->create_iterator)
return 1; /* iterator creator is not supported */
if ((*hton->create_iterator)(hton, HA_TRANSACTLOG_ITERATOR, &iterator) !=
HA_ITERATOR_OK)
{
/* error during creation of log iterator or iterator is not supported */
return 1;
}
while((*iterator.next)(&iterator, (void*)&data) == 0)
{
printf("%s\n", data.filename.str);
if (data.status == HA_LOG_STATUS_FREE &&
mysql_file_delete(INSTRUMENT_ME,
data.filename.str, MYF(MY_WME)))
goto err;
}
res= 0;
err:
(*iterator.destroy)(&iterator);
return res;
}
/*
Here we should get info from handler where it save logs but here is
just example, so we use constant.
IMHO FN_ROOTDIR ("/") is safe enough for example, because nobody has
rights on it except root and it consist of directories only at lest for
*nix (sorry, can't find windows-safe solution here, but it is only example).
*/
#define fl_dir FN_ROOTDIR
/** @brief
Dummy function to return log status should be replaced by function which
really detect the log status and check that the file is a log of this
handler.
*/
enum log_status fl_get_log_status(char *log)
{
MY_STAT stat_buff;
if (mysql_file_stat(INSTRUMENT_ME, log, &stat_buff, MYF(0)))
return HA_LOG_STATUS_INUSE;
return HA_LOG_STATUS_NOSUCHLOG;
}
struct fl_buff
{
LEX_STRING *names;
enum log_status *statuses;
uint32 entries;
uint32 current;
};
int fl_log_iterator_next(struct handler_iterator *iterator,
void *iterator_object)
{
struct fl_buff *buff= (struct fl_buff *)iterator->buffer;
struct handler_log_file_data *data=
(struct handler_log_file_data *) iterator_object;
if (buff->current >= buff->entries)
return 1;
data->filename= buff->names[buff->current];
data->status= buff->statuses[buff->current];
buff->current++;
return 0;
}
void fl_log_iterator_destroy(struct handler_iterator *iterator)
{
my_free(iterator->buffer);
}
/** @brief
returns buffer, to be assigned in handler_iterator struct
*/
enum handler_create_iterator_result
fl_log_iterator_buffer_init(struct handler_iterator *iterator)
{
MY_DIR *dirp;
struct fl_buff *buff;
char *name_ptr;
uchar *ptr;
FILEINFO *file;
uint32 i;
/* to be able to make my_free without crash in case of error */
iterator->buffer= 0;
if (!(dirp = my_dir(fl_dir, MYF(MY_THREAD_SPECIFIC))))
{
return HA_ITERATOR_ERROR;
}
if ((ptr= (uchar*)my_malloc(ALIGN_SIZE(sizeof(fl_buff)) +
((ALIGN_SIZE(sizeof(LEX_STRING)) +
sizeof(enum log_status) +
+ FN_REFLEN + 1) *
(uint) dirp->number_off_files),
MYF(MY_THREAD_SPECIFIC))) == 0)
{
return HA_ITERATOR_ERROR;
}
buff= (struct fl_buff *)ptr;
buff->entries= buff->current= 0;
ptr= ptr + (ALIGN_SIZE(sizeof(fl_buff)));
buff->names= (LEX_STRING*) (ptr);
ptr= ptr + ((ALIGN_SIZE(sizeof(LEX_STRING)) *
(uint) dirp->number_off_files));
buff->statuses= (enum log_status *)(ptr);
name_ptr= (char *)(ptr + (sizeof(enum log_status) *
(uint) dirp->number_off_files));
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{
enum log_status st;
file= dirp->dir_entry + i;
if ((file->name[0] == '.' &&
((file->name[1] == '.' && file->name[2] == '\0') ||
file->name[1] == '\0')))
continue;
if ((st= fl_get_log_status(file->name)) == HA_LOG_STATUS_NOSUCHLOG)
continue;
name_ptr= strxnmov(buff->names[buff->entries].str= name_ptr,
FN_REFLEN, fl_dir, file->name, NullS);
buff->names[buff->entries].length= (name_ptr -
buff->names[buff->entries].str);
buff->statuses[buff->entries]= st;
buff->entries++;
}
iterator->buffer= buff;
iterator->next= &fl_log_iterator_next;
iterator->destroy= &fl_log_iterator_destroy;
my_dirend(dirp);
return HA_ITERATOR_OK;
}
/* An example of a iterator creator */
enum handler_create_iterator_result
fl_create_iterator(enum handler_iterator_type type,
struct handler_iterator *iterator)
{
switch(type) {
case HA_TRANSACTLOG_ITERATOR:
return fl_log_iterator_buffer_init(iterator);
default:
return HA_ITERATOR_UNSUPPORTED;
}
}
#endif /*TRANS_LOG_MGM_EXAMPLE_CODE*/
bool HA_CREATE_INFO::check_conflicting_charset_declarations(CHARSET_INFO *cs) bool HA_CREATE_INFO::check_conflicting_charset_declarations(CHARSET_INFO *cs)
{ {
if ((used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && if ((used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&

View File

@@ -1069,31 +1069,6 @@ extern MYSQL_PLUGIN_IMPORT st_plugin_int *hton2plugin[MAX_HA];
struct handlerton; struct handlerton;
#define view_pseudo_hton ((handlerton *)1) #define view_pseudo_hton ((handlerton *)1)
/* Transaction log maintains type definitions */
enum log_status
{
HA_LOG_STATUS_FREE= 0, /* log is free and can be deleted */
HA_LOG_STATUS_INUSE= 1, /* log can't be deleted because it is in use */
HA_LOG_STATUS_NOSUCHLOG= 2 /* no such log (can't be returned by
the log iterator status) */
};
/*
Function for signaling that the log file changed its state from
LOG_STATUS_INUSE to LOG_STATUS_FREE
Now it do nothing, will be implemented as part of new transaction
log management for engines.
TODO: implement the function.
*/
void signal_log_not_needed(struct handlerton, char *log_file);
/*
Data of transaction log iterator.
*/
struct handler_log_file_data {
LEX_STRING filename;
enum log_status status;
};
/* /*
Definitions for engine-specific table/field/index options in the CREATE TABLE. Definitions for engine-specific table/field/index options in the CREATE TABLE.
@@ -1208,46 +1183,6 @@ typedef struct st_ha_create_table_option {
struct st_mysql_sys_var *var; struct st_mysql_sys_var *var;
} ha_create_table_option; } ha_create_table_option;
enum handler_iterator_type
{
/* request of transaction log iterator */
HA_TRANSACTLOG_ITERATOR= 1
};
enum handler_create_iterator_result
{
HA_ITERATOR_OK, /* iterator created */
HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */
HA_ITERATOR_ERROR /* error during iterator creation */
};
/*
Iterator structure. Can be used by handler/handlerton for different purposes.
Iterator should be created in the way to point "before" the first object
it iterate, so next() call move it to the first object or return !=0 if
there is nothing to iterate through.
*/
struct handler_iterator {
/*
Moves iterator to next record and return 0 or return !=0
if there is no records.
iterator_object will be filled by this function if next() returns 0.
Content of the iterator_object depend on iterator type.
*/
int (*next)(struct handler_iterator *, void *iterator_object);
/*
Free resources allocated by iterator, after this call iterator
is not usable.
*/
void (*destroy)(struct handler_iterator *);
/*
Pointer to buffer for the iterator to use.
Should be allocated by function which created the iterator and
destroyed by freed by above "destroy" call
*/
void *buffer;
};
class handler; class handler;
class group_by_handler; class group_by_handler;
class derived_handler; class derived_handler;
@@ -1511,22 +1446,6 @@ struct handlerton
const char *query, uint query_length, const char *query, uint query_length,
const char *db, const char *table_name); const char *db, const char *table_name);
/*
Get log status.
If log_status is null then the handler do not support transaction
log information (i.e. log iterator can't be created).
(see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
*/
enum log_status (*get_log_status)(handlerton *hton, char *log);
/*
Iterators creator.
Presence of the pointer should be checked before using
*/
enum handler_create_iterator_result
(*create_iterator)(handlerton *hton, enum handler_iterator_type type,
struct handler_iterator *fill_this_in);
void (*abort_transaction)(handlerton *hton, THD *bf_thd, void (*abort_transaction)(handlerton *hton, THD *bf_thd,
THD *victim_thd, my_bool signal); THD *victim_thd, my_bool signal);
int (*set_checkpoint)(handlerton *hton, const XID* xid); int (*set_checkpoint)(handlerton *hton, const XID* xid);
@@ -1723,6 +1642,9 @@ struct handlerton
@retval 0 if no system-versioned data was affected by the transaction */ @retval 0 if no system-versioned data was affected by the transaction */
ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id); ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
/** Disable or enable the internal writes of a storage engine */
void (*disable_internal_writes)(bool disable);
/* backup */ /* backup */
void (*prepare_for_backup)(void); void (*prepare_for_backup)(void);
void (*end_backup)(void); void (*end_backup)(void);
@@ -4069,15 +3991,13 @@ public:
inline int ha_read_first_row(uchar *buf, uint primary_key); inline int ha_read_first_row(uchar *buf, uint primary_key);
/** /**
The following 3 function is only needed for tables that may be The following 2 function is only needed for tables that may be
internal temporary tables during joins. internal temporary tables during joins.
*/ */
virtual int remember_rnd_pos() virtual int remember_rnd_pos()
{ return HA_ERR_WRONG_COMMAND; } { return HA_ERR_WRONG_COMMAND; }
virtual int restart_rnd_next(uchar *buf) virtual int restart_rnd_next(uchar *buf)
{ return HA_ERR_WRONG_COMMAND; } { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, const key_range *min_key, virtual ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, const key_range *max_key,
@@ -5290,6 +5210,8 @@ void ha_prepare_for_backup();
void ha_end_backup(); void ha_end_backup();
void ha_pre_shutdown(); void ha_pre_shutdown();
void ha_disable_internal_writes(bool disable);
/* statistics and info */ /* statistics and info */
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);

View File

@@ -81,7 +81,9 @@ extern Native_func_registry_array native_func_registry_array_geom;
class Create_sp_func : public Create_qfunc class Create_sp_func : public Create_qfunc
{ {
public: public:
virtual Item *create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, virtual Item *create_with_db(THD *thd,
const LEX_CSTRING *db,
const LEX_CSTRING *name,
bool use_explicit_name, List<Item> *item_list); bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton; static Create_sp_func s_singleton;
@@ -181,7 +183,8 @@ protected:
class Create_func_atan : public Create_native_func class Create_func_atan : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_atan s_singleton; static Create_func_atan s_singleton;
@@ -372,7 +375,8 @@ protected:
class Create_func_concat : public Create_native_func class Create_func_concat : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_concat s_singleton; static Create_func_concat s_singleton;
@@ -385,7 +389,8 @@ protected:
class Create_func_concat_operator_oracle : public Create_native_func class Create_func_concat_operator_oracle : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_concat_operator_oracle s_singleton; static Create_func_concat_operator_oracle s_singleton;
@@ -411,7 +416,8 @@ protected:
class Create_func_decode_oracle : public Create_native_func class Create_func_decode_oracle : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_decode_oracle s_singleton; static Create_func_decode_oracle s_singleton;
@@ -424,7 +430,8 @@ protected:
class Create_func_concat_ws : public Create_native_func class Create_func_concat_ws : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_concat_ws s_singleton; static Create_func_concat_ws s_singleton;
@@ -515,7 +522,8 @@ protected:
class Create_func_crc32 : public Create_native_func class Create_func_crc32 : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *, List<Item> *item_list) override; Item *create_native(THD *thd, const LEX_CSTRING *, List<Item> *item_list)
override;
static Create_func_crc32 s_singleton; static Create_func_crc32 s_singleton;
@@ -528,7 +536,8 @@ protected:
class Create_func_crc32c : public Create_native_func class Create_func_crc32c : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *, List<Item> *item_list) override; Item *create_native(THD *thd, const LEX_CSTRING *, List<Item> *item_list)
override;
static Create_func_crc32c s_singleton; static Create_func_crc32c s_singleton;
@@ -619,7 +628,8 @@ protected:
class Create_func_des_decrypt : public Create_native_func class Create_func_des_decrypt : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_des_decrypt s_singleton; static Create_func_des_decrypt s_singleton;
@@ -632,7 +642,8 @@ protected:
class Create_func_des_encrypt : public Create_native_func class Create_func_des_encrypt : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_des_encrypt s_singleton; static Create_func_des_encrypt s_singleton;
@@ -645,7 +656,8 @@ protected:
class Create_func_elt : public Create_native_func class Create_func_elt : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_elt s_singleton; static Create_func_elt s_singleton;
@@ -671,7 +683,8 @@ protected:
class Create_func_encrypt : public Create_native_func class Create_func_encrypt : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_encrypt s_singleton; static Create_func_encrypt s_singleton;
@@ -697,7 +710,8 @@ protected:
class Create_func_export_set : public Create_native_func class Create_func_export_set : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_export_set s_singleton; static Create_func_export_set s_singleton;
@@ -710,7 +724,8 @@ protected:
class Create_func_field : public Create_native_func class Create_func_field : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_field s_singleton; static Create_func_field s_singleton;
@@ -749,7 +764,8 @@ protected:
class Create_func_format : public Create_native_func class Create_func_format : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_format s_singleton; static Create_func_format s_singleton;
@@ -801,7 +817,8 @@ protected:
class Create_func_from_unixtime : public Create_native_func class Create_func_from_unixtime : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_from_unixtime s_singleton; static Create_func_from_unixtime s_singleton;
@@ -827,7 +844,8 @@ protected:
class Create_func_greatest : public Create_native_func class Create_func_greatest : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_greatest s_singleton; static Create_func_greatest s_singleton;
@@ -996,7 +1014,8 @@ protected:
class Create_func_json_detailed: public Create_native_func class Create_func_json_detailed: public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_detailed s_singleton; static Create_func_json_detailed s_singleton;
@@ -1061,7 +1080,8 @@ protected:
class Create_func_json_keys: public Create_native_func class Create_func_json_keys: public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_keys s_singleton; static Create_func_json_keys s_singleton;
@@ -1074,7 +1094,8 @@ protected:
class Create_func_json_contains: public Create_native_func class Create_func_json_contains: public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_contains s_singleton; static Create_func_json_contains s_singleton;
@@ -1087,7 +1108,8 @@ protected:
class Create_func_json_contains_path : public Create_native_func class Create_func_json_contains_path : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_contains_path s_singleton; static Create_func_json_contains_path s_singleton;
@@ -1100,7 +1122,8 @@ protected:
class Create_func_json_extract : public Create_native_func class Create_func_json_extract : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_extract s_singleton; static Create_func_json_extract s_singleton;
@@ -1113,7 +1136,8 @@ protected:
class Create_func_json_search : public Create_native_func class Create_func_json_search : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_search s_singleton; static Create_func_json_search s_singleton;
@@ -1126,7 +1150,8 @@ protected:
class Create_func_json_array : public Create_native_func class Create_func_json_array : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_array s_singleton; static Create_func_json_array s_singleton;
@@ -1139,7 +1164,8 @@ protected:
class Create_func_json_array_append : public Create_native_func class Create_func_json_array_append : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_array_append s_singleton; static Create_func_json_array_append s_singleton;
@@ -1152,7 +1178,8 @@ protected:
class Create_func_json_array_insert : public Create_native_func class Create_func_json_array_insert : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_array_insert s_singleton; static Create_func_json_array_insert s_singleton;
@@ -1165,7 +1192,8 @@ protected:
class Create_func_json_insert : public Create_native_func class Create_func_json_insert : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_insert s_singleton; static Create_func_json_insert s_singleton;
@@ -1178,7 +1206,8 @@ protected:
class Create_func_json_set : public Create_native_func class Create_func_json_set : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_set s_singleton; static Create_func_json_set s_singleton;
@@ -1191,7 +1220,8 @@ protected:
class Create_func_json_replace : public Create_native_func class Create_func_json_replace : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_replace s_singleton; static Create_func_json_replace s_singleton;
@@ -1204,7 +1234,8 @@ protected:
class Create_func_json_remove : public Create_native_func class Create_func_json_remove : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_remove s_singleton; static Create_func_json_remove s_singleton;
@@ -1217,7 +1248,8 @@ protected:
class Create_func_json_object : public Create_native_func class Create_func_json_object : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_object s_singleton; static Create_func_json_object s_singleton;
@@ -1230,7 +1262,8 @@ protected:
class Create_func_json_length : public Create_native_func class Create_func_json_length : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_length s_singleton; static Create_func_json_length s_singleton;
@@ -1243,7 +1276,8 @@ protected:
class Create_func_json_merge : public Create_native_func class Create_func_json_merge : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_merge s_singleton; static Create_func_json_merge s_singleton;
@@ -1256,7 +1290,8 @@ protected:
class Create_func_json_merge_patch : public Create_native_func class Create_func_json_merge_patch : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_json_merge_patch s_singleton; static Create_func_json_merge_patch s_singleton;
@@ -1308,7 +1343,8 @@ protected:
class Create_func_last_insert_id : public Create_native_func class Create_func_last_insert_id : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_last_insert_id s_singleton; static Create_func_last_insert_id s_singleton;
@@ -1334,7 +1370,8 @@ protected:
class Create_func_least : public Create_native_func class Create_func_least : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_least s_singleton; static Create_func_least s_singleton;
@@ -1426,7 +1463,8 @@ protected:
class Create_func_locate : public Create_native_func class Create_func_locate : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_locate s_singleton; static Create_func_locate s_singleton;
@@ -1439,7 +1477,8 @@ protected:
class Create_func_log : public Create_native_func class Create_func_log : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_log s_singleton; static Create_func_log s_singleton;
@@ -1478,7 +1517,7 @@ protected:
class Create_func_lpad : public Create_native_func class Create_func_lpad : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
return thd->variables.sql_mode & MODE_ORACLE ? return thd->variables.sql_mode & MODE_ORACLE ?
@@ -1490,15 +1529,18 @@ public:
protected: protected:
Create_func_lpad() {} Create_func_lpad() {}
virtual ~Create_func_lpad() {} virtual ~Create_func_lpad() {}
Item *create_native_std(THD *thd, LEX_CSTRING *name, List<Item> *items); Item *create_native_std(THD *thd, const LEX_CSTRING *name,
Item *create_native_oracle(THD *thd, LEX_CSTRING *name, List<Item> *items); List<Item> *items);
Item *create_native_oracle(THD *thd, const LEX_CSTRING *name,
List<Item> *items);
}; };
class Create_func_lpad_oracle : public Create_func_lpad class Create_func_lpad_oracle : public Create_func_lpad
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
return create_native_oracle(thd, name, item_list); return create_native_oracle(thd, name, item_list);
} }
@@ -1561,7 +1603,8 @@ protected:
class Create_func_make_set : public Create_native_func class Create_func_make_set : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_make_set s_singleton; static Create_func_make_set s_singleton;
@@ -1574,7 +1617,8 @@ protected:
class Create_func_master_pos_wait : public Create_native_func class Create_func_master_pos_wait : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_master_pos_wait s_singleton; static Create_func_master_pos_wait s_singleton;
@@ -1587,7 +1631,8 @@ protected:
class Create_func_master_gtid_wait : public Create_native_func class Create_func_master_gtid_wait : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_master_gtid_wait s_singleton; static Create_func_master_gtid_wait s_singleton;
@@ -1804,7 +1849,8 @@ protected:
class Create_func_rand : public Create_native_func class Create_func_rand : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_rand s_singleton; static Create_func_rand s_singleton;
@@ -1865,7 +1911,8 @@ protected:
class Create_func_round : public Create_native_func class Create_func_round : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_round s_singleton; static Create_func_round s_singleton;
@@ -1878,7 +1925,7 @@ protected:
class Create_func_rpad : public Create_native_func class Create_func_rpad : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
return thd->variables.sql_mode & MODE_ORACLE ? return thd->variables.sql_mode & MODE_ORACLE ?
@@ -1890,15 +1937,18 @@ public:
protected: protected:
Create_func_rpad() {} Create_func_rpad() {}
virtual ~Create_func_rpad() {} virtual ~Create_func_rpad() {}
Item *create_native_std(THD *thd, LEX_CSTRING *name, List<Item> *items); Item *create_native_std(THD *thd, const LEX_CSTRING *name,
Item *create_native_oracle(THD *thd, LEX_CSTRING *name, List<Item> *items); List<Item> *items);
Item *create_native_oracle(THD *thd, const LEX_CSTRING *name,
List<Item> *items);
}; };
class Create_func_rpad_oracle : public Create_func_rpad class Create_func_rpad_oracle : public Create_func_rpad
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
return create_native_oracle(thd, name, item_list); return create_native_oracle(thd, name, item_list);
} }
@@ -1947,8 +1997,8 @@ protected:
class Create_func_sformat : public Create_native_func class Create_func_sformat : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
List<Item> *item_list); override;
static Create_func_sformat s_singleton; static Create_func_sformat s_singleton;
protected: protected:
Create_func_sformat() {} Create_func_sformat() {}
@@ -2101,7 +2151,7 @@ protected:
class Create_func_substr_oracle : public Create_native_func class Create_func_substr_oracle : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list); List<Item> *item_list);
static Create_func_substr_oracle s_singleton; static Create_func_substr_oracle s_singleton;
@@ -2193,7 +2243,8 @@ protected:
class Create_func_to_char : public Create_native_func class Create_func_to_char : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_to_char s_singleton; static Create_func_to_char s_singleton;
@@ -2283,7 +2334,8 @@ protected:
class Create_func_unix_timestamp : public Create_native_func class Create_func_unix_timestamp : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_unix_timestamp s_singleton; static Create_func_unix_timestamp s_singleton;
@@ -2375,7 +2427,8 @@ protected:
class Create_func_wsrep_sync_wait_upto : public Create_native_func class Create_func_wsrep_sync_wait_upto : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_wsrep_sync_wait_upto s_singleton; static Create_func_wsrep_sync_wait_upto s_singleton;
@@ -2415,7 +2468,8 @@ protected:
class Create_func_year_week : public Create_native_func class Create_func_year_week : public Create_native_func
{ {
public: public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list);
static Create_func_year_week s_singleton; static Create_func_year_week s_singleton;
@@ -2456,7 +2510,8 @@ static bool has_named_parameters(List<Item> *params)
Item* Item*
Create_qfunc::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_qfunc::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
LEX_CSTRING db; LEX_CSTRING db;
@@ -2489,7 +2544,8 @@ Create_qfunc::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
Create_udf_func Create_udf_func::s_singleton; Create_udf_func Create_udf_func::s_singleton;
Item* Item*
Create_udf_func::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_udf_func::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
udf_func *udf= find_udf(name->str, name->length); udf_func *udf= find_udf(name->str, name->length);
DBUG_ASSERT(udf); DBUG_ASSERT(udf);
@@ -2599,7 +2655,9 @@ Create_udf_func::create(THD *thd, udf_func *udf, List<Item> *item_list)
Create_sp_func Create_sp_func::s_singleton; Create_sp_func Create_sp_func::s_singleton;
Item* Item*
Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, Create_sp_func::create_with_db(THD *thd,
const LEX_CSTRING *db,
const LEX_CSTRING *name,
bool use_explicit_name, List<Item> *item_list) bool use_explicit_name, List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2646,7 +2704,8 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name,
Item* Item*
Create_native_func::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_native_func::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
if (unlikely(has_named_parameters(item_list))) if (unlikely(has_named_parameters(item_list)))
{ {
@@ -2659,7 +2718,8 @@ Create_native_func::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_li
Item* Item*
Create_func_arg0::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_func_arg0::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2677,7 +2737,8 @@ Create_func_arg0::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list
Item* Item*
Create_func_arg1::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_func_arg1::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2703,7 +2764,8 @@ Create_func_arg1::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list
Item* Item*
Create_func_arg2::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_func_arg2::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2731,7 +2793,8 @@ Create_func_arg2::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list
Item* Item*
Create_func_arg3::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Create_func_arg3::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2817,7 +2880,7 @@ Create_func_asin::create_1_arg(THD *thd, Item *arg1)
Create_func_atan Create_func_atan::s_singleton; Create_func_atan Create_func_atan::s_singleton;
Item* Item*
Create_func_atan::create_native(THD *thd, LEX_CSTRING *name, Create_func_atan::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item* func= NULL; Item* func= NULL;
@@ -2979,7 +3042,7 @@ Create_func_dyncol_json::create_1_arg(THD *thd, Item *arg1)
Create_func_concat Create_func_concat::s_singleton; Create_func_concat Create_func_concat::s_singleton;
Item* Item*
Create_func_concat::create_native(THD *thd, LEX_CSTRING *name, Create_func_concat::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3002,7 +3065,7 @@ Create_func_concat_operator_oracle
Create_func_concat_operator_oracle::s_singleton; Create_func_concat_operator_oracle::s_singleton;
Item* Item*
Create_func_concat_operator_oracle::create_native(THD *thd, LEX_CSTRING *name, Create_func_concat_operator_oracle::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3030,7 +3093,7 @@ Create_func_decode_histogram::create_2_arg(THD *thd, Item *arg1, Item *arg2)
Create_func_decode_oracle Create_func_decode_oracle::s_singleton; Create_func_decode_oracle Create_func_decode_oracle::s_singleton;
Item* Item*
Create_func_decode_oracle::create_native(THD *thd, LEX_CSTRING *name, Create_func_decode_oracle::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
uint arg_count= item_list ? item_list->elements : 0; uint arg_count= item_list ? item_list->elements : 0;
@@ -3045,7 +3108,7 @@ Create_func_decode_oracle::create_native(THD *thd, LEX_CSTRING *name,
Create_func_concat_ws Create_func_concat_ws::s_singleton; Create_func_concat_ws Create_func_concat_ws::s_singleton;
Item* Item*
Create_func_concat_ws::create_native(THD *thd, LEX_CSTRING *name, Create_func_concat_ws::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3131,7 +3194,7 @@ Create_func_cot::create_1_arg(THD *thd, Item *arg1)
Create_func_crc32 Create_func_crc32::s_singleton; Create_func_crc32 Create_func_crc32::s_singleton;
Item* Item*
Create_func_crc32::create_native(THD *thd, LEX_CSTRING *name, Create_func_crc32::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int argc= item_list ? item_list->elements : 0; int argc= item_list ? item_list->elements : 0;
@@ -3157,7 +3220,7 @@ Create_func_crc32::create_native(THD *thd, LEX_CSTRING *name,
Create_func_crc32c Create_func_crc32c::s_singleton; Create_func_crc32c Create_func_crc32c::s_singleton;
Item* Item*
Create_func_crc32c::create_native(THD *thd, LEX_CSTRING *name, Create_func_crc32c::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int argc= item_list ? item_list->elements : 0; int argc= item_list ? item_list->elements : 0;
@@ -3241,7 +3304,7 @@ Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
Create_func_des_decrypt Create_func_des_decrypt::s_singleton; Create_func_des_decrypt Create_func_des_decrypt::s_singleton;
Item* Item*
Create_func_des_decrypt::create_native(THD *thd, LEX_CSTRING *name, Create_func_des_decrypt::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3278,7 +3341,7 @@ Create_func_des_decrypt::create_native(THD *thd, LEX_CSTRING *name,
Create_func_des_encrypt Create_func_des_encrypt::s_singleton; Create_func_des_encrypt Create_func_des_encrypt::s_singleton;
Item* Item*
Create_func_des_encrypt::create_native(THD *thd, LEX_CSTRING *name, Create_func_des_encrypt::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3315,7 +3378,7 @@ Create_func_des_encrypt::create_native(THD *thd, LEX_CSTRING *name,
Create_func_elt Create_func_elt::s_singleton; Create_func_elt Create_func_elt::s_singleton;
Item* Item*
Create_func_elt::create_native(THD *thd, LEX_CSTRING *name, Create_func_elt::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3345,7 +3408,7 @@ Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
Create_func_encrypt Create_func_encrypt::s_singleton; Create_func_encrypt Create_func_encrypt::s_singleton;
Item* Item*
Create_func_encrypt::create_native(THD *thd, LEX_CSTRING *name, Create_func_encrypt::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3392,7 +3455,7 @@ Create_func_exp::create_1_arg(THD *thd, Item *arg1)
Create_func_export_set Create_func_export_set::s_singleton; Create_func_export_set Create_func_export_set::s_singleton;
Item* Item*
Create_func_export_set::create_native(THD *thd, LEX_CSTRING *name, Create_func_export_set::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3445,7 +3508,7 @@ Create_func_export_set::create_native(THD *thd, LEX_CSTRING *name,
Create_func_field Create_func_field::s_singleton; Create_func_field Create_func_field::s_singleton;
Item* Item*
Create_func_field::create_native(THD *thd, LEX_CSTRING *name, Create_func_field::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3484,7 +3547,7 @@ Create_func_floor::create_1_arg(THD *thd, Item *arg1)
Create_func_format Create_func_format::s_singleton; Create_func_format Create_func_format::s_singleton;
Item* Item*
Create_func_format::create_native(THD *thd, LEX_CSTRING *name, Create_func_format::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3549,7 +3612,7 @@ Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
Create_func_from_unixtime Create_func_from_unixtime::s_singleton; Create_func_from_unixtime Create_func_from_unixtime::s_singleton;
Item* Item*
Create_func_from_unixtime::create_native(THD *thd, LEX_CSTRING *name, Create_func_from_unixtime::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3599,7 +3662,7 @@ Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
Create_func_greatest Create_func_greatest::s_singleton; Create_func_greatest Create_func_greatest::s_singleton;
Item* Item*
Create_func_greatest::create_native(THD *thd, LEX_CSTRING *name, Create_func_greatest::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3707,7 +3770,7 @@ Create_func_json_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2)
Create_func_json_detailed Create_func_json_detailed::s_singleton; Create_func_json_detailed Create_func_json_detailed::s_singleton;
Item* Item*
Create_func_json_detailed::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_detailed::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3834,7 +3897,7 @@ Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
Create_func_json_array Create_func_json_array::s_singleton; Create_func_json_array Create_func_json_array::s_singleton;
Item* Item*
Create_func_json_array::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_array::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func; Item *func;
@@ -3856,7 +3919,7 @@ Create_func_json_array::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_array_append Create_func_json_array_append::s_singleton; Create_func_json_array_append Create_func_json_array_append::s_singleton;
Item* Item*
Create_func_json_array_append::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_array_append::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3882,7 +3945,7 @@ Create_func_json_array_append::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_array_insert Create_func_json_array_insert::s_singleton; Create_func_json_array_insert Create_func_json_array_insert::s_singleton;
Item* Item*
Create_func_json_array_insert::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_array_insert::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3908,7 +3971,7 @@ Create_func_json_array_insert::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_insert Create_func_json_insert::s_singleton; Create_func_json_insert Create_func_json_insert::s_singleton;
Item* Item*
Create_func_json_insert::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_insert::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3935,7 +3998,7 @@ Create_func_json_insert::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_set Create_func_json_set::s_singleton; Create_func_json_set Create_func_json_set::s_singleton;
Item* Item*
Create_func_json_set::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_set::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3962,7 +4025,7 @@ Create_func_json_set::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_replace Create_func_json_replace::s_singleton; Create_func_json_replace Create_func_json_replace::s_singleton;
Item* Item*
Create_func_json_replace::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_replace::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3989,7 +4052,7 @@ Create_func_json_replace::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_remove Create_func_json_remove::s_singleton; Create_func_json_remove Create_func_json_remove::s_singleton;
Item* Item*
Create_func_json_remove::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_remove::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4015,7 +4078,7 @@ Create_func_json_remove::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_object Create_func_json_object::s_singleton; Create_func_json_object Create_func_json_object::s_singleton;
Item* Item*
Create_func_json_object::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_object::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func; Item *func;
@@ -4048,7 +4111,7 @@ Create_func_json_object::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_length Create_func_json_length::s_singleton; Create_func_json_length Create_func_json_length::s_singleton;
Item* Item*
Create_func_json_length::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_length::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func; Item *func;
@@ -4073,7 +4136,7 @@ Create_func_json_length::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_merge Create_func_json_merge::s_singleton; Create_func_json_merge Create_func_json_merge::s_singleton;
Item* Item*
Create_func_json_merge::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_merge::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func; Item *func;
@@ -4098,7 +4161,7 @@ Create_func_json_merge::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_merge_patch Create_func_json_merge_patch::s_singleton; Create_func_json_merge_patch Create_func_json_merge_patch::s_singleton;
Item* Item*
Create_func_json_merge_patch::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_merge_patch::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func; Item *func;
@@ -4122,7 +4185,7 @@ Create_func_json_merge_patch::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_contains Create_func_json_contains::s_singleton; Create_func_json_contains Create_func_json_contains::s_singleton;
Item* Item*
Create_func_json_contains::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_contains::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4148,7 +4211,7 @@ Create_func_json_contains::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_keys Create_func_json_keys::s_singleton; Create_func_json_keys Create_func_json_keys::s_singleton;
Item* Item*
Create_func_json_keys::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_keys::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4174,7 +4237,7 @@ Create_func_json_keys::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_contains_path Create_func_json_contains_path::s_singleton; Create_func_json_contains_path Create_func_json_contains_path::s_singleton;
Item* Item*
Create_func_json_contains_path::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_contains_path::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4200,7 +4263,7 @@ Create_func_json_contains_path::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_extract Create_func_json_extract::s_singleton; Create_func_json_extract Create_func_json_extract::s_singleton;
Item* Item*
Create_func_json_extract::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_extract::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4226,7 +4289,7 @@ Create_func_json_extract::create_native(THD *thd, LEX_CSTRING *name,
Create_func_json_search Create_func_json_search::s_singleton; Create_func_json_search Create_func_json_search::s_singleton;
Item* Item*
Create_func_json_search::create_native(THD *thd, LEX_CSTRING *name, Create_func_json_search::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4252,7 +4315,7 @@ Create_func_json_search::create_native(THD *thd, LEX_CSTRING *name,
Create_func_last_insert_id Create_func_last_insert_id::s_singleton; Create_func_last_insert_id Create_func_last_insert_id::s_singleton;
Item* Item*
Create_func_last_insert_id::create_native(THD *thd, LEX_CSTRING *name, Create_func_last_insert_id::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4298,7 +4361,7 @@ Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
Create_func_least Create_func_least::s_singleton; Create_func_least Create_func_least::s_singleton;
Item* Item*
Create_func_least::create_native(THD *thd, LEX_CSTRING *name, Create_func_least::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -4380,7 +4443,7 @@ Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
Create_func_locate Create_func_locate::s_singleton; Create_func_locate Create_func_locate::s_singleton;
Item* Item*
Create_func_locate::create_native(THD *thd, LEX_CSTRING *name, Create_func_locate::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4421,7 +4484,7 @@ Create_func_locate::create_native(THD *thd, LEX_CSTRING *name,
Create_func_log Create_func_log::s_singleton; Create_func_log Create_func_log::s_singleton;
Item* Item*
Create_func_log::create_native(THD *thd, LEX_CSTRING *name, Create_func_log::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4478,7 +4541,7 @@ Create_func_lpad Create_func_lpad::s_singleton;
Create_func_lpad_oracle Create_func_lpad_oracle::s_singleton; Create_func_lpad_oracle Create_func_lpad_oracle::s_singleton;
Item* Item*
Create_func_lpad::create_native_std(THD *thd, LEX_CSTRING *name, Create_func_lpad::create_native_std(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4510,7 +4573,7 @@ Create_func_lpad::create_native_std(THD *thd, LEX_CSTRING *name,
Item* Item*
Create_func_lpad::create_native_oracle(THD *thd, LEX_CSTRING *name, Create_func_lpad::create_native_oracle(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= item_list ? item_list->elements : 0; int arg_count= item_list ? item_list->elements : 0;
@@ -4576,7 +4639,7 @@ Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_make_set Create_func_make_set::s_singleton; Create_func_make_set Create_func_make_set::s_singleton;
Item* Item*
Create_func_make_set::create_native(THD *thd, LEX_CSTRING *name, Create_func_make_set::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -4597,7 +4660,7 @@ Create_func_make_set::create_native(THD *thd, LEX_CSTRING *name,
Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton; Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton;
Item* Item*
Create_func_master_pos_wait::create_native(THD *thd, LEX_CSTRING *name, Create_func_master_pos_wait::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
@@ -4648,7 +4711,7 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_CSTRING *name,
Create_func_master_gtid_wait Create_func_master_gtid_wait::s_singleton; Create_func_master_gtid_wait Create_func_master_gtid_wait::s_singleton;
Item* Item*
Create_func_master_gtid_wait::create_native(THD *thd, LEX_CSTRING *name, Create_func_master_gtid_wait::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4852,7 +4915,7 @@ Create_func_radians::create_1_arg(THD *thd, Item *arg1)
Create_func_rand Create_func_rand::s_singleton; Create_func_rand Create_func_rand::s_singleton;
Item* Item*
Create_func_rand::create_native(THD *thd, LEX_CSTRING *name, Create_func_rand::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4943,7 +5006,7 @@ Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
Create_func_round Create_func_round::s_singleton; Create_func_round Create_func_round::s_singleton;
Item* Item*
Create_func_round::create_native(THD *thd, LEX_CSTRING *name, Create_func_round::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -4983,7 +5046,7 @@ Create_func_rpad Create_func_rpad::s_singleton;
Create_func_rpad_oracle Create_func_rpad_oracle::s_singleton; Create_func_rpad_oracle Create_func_rpad_oracle::s_singleton;
Item* Item*
Create_func_rpad::create_native_std(THD *thd, LEX_CSTRING *name, Create_func_rpad::create_native_std(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -5015,7 +5078,7 @@ Create_func_rpad::create_native_std(THD *thd, LEX_CSTRING *name,
Item* Item*
Create_func_rpad::create_native_oracle(THD *thd, LEX_CSTRING *name, Create_func_rpad::create_native_oracle(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= item_list ? item_list->elements : 0; int arg_count= item_list ? item_list->elements : 0;
@@ -5071,7 +5134,7 @@ Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
Create_func_sformat Create_func_sformat::s_singleton; Create_func_sformat Create_func_sformat::s_singleton;
Item* Item*
Create_func_sformat::create_native(THD *thd, LEX_CSTRING *name, Create_func_sformat::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -5193,7 +5256,7 @@ Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *a
Create_func_substr_oracle Create_func_substr_oracle::s_singleton; Create_func_substr_oracle Create_func_substr_oracle::s_singleton;
Item* Item*
Create_func_substr_oracle::create_native(THD *thd, LEX_CSTRING *name, Create_func_substr_oracle::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -5281,7 +5344,7 @@ Create_func_to_base64::create_1_arg(THD *thd, Item *arg1)
Create_func_to_char Create_func_to_char::s_singleton; Create_func_to_char Create_func_to_char::s_singleton;
Item* Item*
Create_func_to_char::create_native(THD *thd, LEX_CSTRING *name, Create_func_to_char::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -5373,7 +5436,7 @@ Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton; Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton;
Item* Item*
Create_func_unix_timestamp::create_native(THD *thd, LEX_CSTRING *name, Create_func_unix_timestamp::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -5479,7 +5542,7 @@ Create_func_wsrep_sync_wait_upto::s_singleton;
Item* Item*
Create_func_wsrep_sync_wait_upto::create_native(THD *thd, Create_func_wsrep_sync_wait_upto::create_native(THD *thd,
LEX_CSTRING *name, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -5530,7 +5593,7 @@ Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg
Create_func_year_week Create_func_year_week::s_singleton; Create_func_year_week Create_func_year_week::s_singleton;
Item* Item*
Create_func_year_week::create_native(THD *thd, LEX_CSTRING *name, Create_func_year_week::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. /* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
Copyright (c) 2008-2011 Monty Program Ab Copyright (c) 2008, 2022, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -58,7 +58,8 @@ public:
@param item_list The list of arguments to the function, can be NULL @param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call, or NULL @return An item representing the parsed function call, or NULL
*/ */
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) = 0; virtual Item *create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) = 0;
protected: protected:
/** Constructor */ /** Constructor */
@@ -75,8 +76,8 @@ protected:
class Create_func_arg0 : public Create_func class Create_func_arg0 : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
List<Item> *item_list); override;
/** /**
Builder method, with no arguments. Builder method, with no arguments.
@@ -100,7 +101,8 @@ protected:
class Create_func_arg1 : public Create_func class Create_func_arg1 : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
/** /**
Builder method, with one argument. Builder method, with one argument.
@@ -125,7 +127,8 @@ protected:
class Create_func_arg2 : public Create_func class Create_func_arg2 : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
/** /**
Builder method, with two arguments. Builder method, with two arguments.
@@ -151,7 +154,8 @@ protected:
class Create_func_arg3 : public Create_func class Create_func_arg3 : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
/** /**
Builder method, with three arguments. Builder method, with three arguments.
@@ -184,8 +188,8 @@ protected:
class Create_native_func : public Create_func class Create_native_func : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
List<Item> *item_list); override;
/** /**
Builder method, with no arguments. Builder method, with no arguments.
@@ -194,7 +198,7 @@ public:
@param item_list The function parameters, none of which are named @param item_list The function parameters, none of which are named
@return An item representing the function call @return An item representing the function call
*/ */
virtual Item *create_native(THD *thd, LEX_CSTRING *name, virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) = 0; List<Item> *item_list) = 0;
protected: protected:
@@ -222,8 +226,8 @@ public:
@param item_list The list of arguments to the function, can be NULL @param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call @return An item representing the parsed function call
*/ */
virtual Item *create_func(THD *thd, LEX_CSTRING *name, Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
List<Item> *item_list); override;
/** /**
The builder create method, for qualified functions. The builder create method, for qualified functions.
@@ -234,7 +238,9 @@ public:
@param item_list The list of arguments to the function, can be NULL @param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call @return An item representing the parsed function call
*/ */
virtual Item *create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, virtual Item *create_with_db(THD *thd,
const LEX_CSTRING *db,
const LEX_CSTRING *name,
bool use_explicit_name, bool use_explicit_name,
List<Item> *item_list) = 0; List<Item> *item_list) = 0;
@@ -272,8 +278,8 @@ extern Create_qfunc * find_qualified_function_builder(THD *thd);
class Create_udf_func : public Create_func class Create_udf_func : public Create_func
{ {
public: public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, Item *create_func(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
List<Item> *item_list); override;
/** /**
The builder create method, for User Defined Functions. The builder create method, for User Defined Functions.

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2003, 2016, Oracle and/or its affiliates. /* Copyright (c) 2003, 2016, Oracle and/or its affiliates.
Copyright (c) 2011, 2021, MariaDB Copyright (c) 2011, 2022, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -2991,7 +2991,7 @@ protected:
class Create_func_distance_sphere: public Create_native_func class Create_func_distance_sphere: public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override; override;
static Create_func_distance_sphere s_singleton; static Create_func_distance_sphere s_singleton;
@@ -3002,7 +3002,7 @@ class Create_func_distance_sphere: public Create_native_func
Item* Item*
Create_func_distance_sphere::create_native(THD *thd, LEX_CSTRING *name, Create_func_distance_sphere::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -3122,7 +3122,8 @@ protected:
class Create_func_geometry_from_text : public Create_native_func class Create_func_geometry_from_text : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_geometry_from_text s_singleton; static Create_func_geometry_from_text s_singleton;
@@ -3133,7 +3134,8 @@ protected:
Item* Item*
Create_func_geometry_from_text::create_native(THD *thd, LEX_CSTRING *name, Create_func_geometry_from_text::create_native(THD *thd,
const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3171,7 +3173,8 @@ Create_func_geometry_from_text::create_native(THD *thd, LEX_CSTRING *name,
class Create_func_geometry_from_wkb : public Create_native_func class Create_func_geometry_from_wkb : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_geometry_from_wkb s_singleton; static Create_func_geometry_from_wkb s_singleton;
@@ -3182,7 +3185,7 @@ protected:
Item* Item*
Create_func_geometry_from_wkb::create_native(THD *thd, LEX_CSTRING *name, Create_func_geometry_from_wkb::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3220,7 +3223,8 @@ Create_func_geometry_from_wkb::create_native(THD *thd, LEX_CSTRING *name,
class Create_func_geometry_from_json : public Create_native_func class Create_func_geometry_from_json : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_geometry_from_json s_singleton; static Create_func_geometry_from_json s_singleton;
@@ -3231,7 +3235,8 @@ protected:
Item* Item*
Create_func_geometry_from_json::create_native(THD *thd, LEX_CSTRING *name, Create_func_geometry_from_json::create_native(THD *thd,
const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
@@ -3278,7 +3283,8 @@ Create_func_geometry_from_json::create_native(THD *thd, LEX_CSTRING *name,
class Create_func_as_geojson : public Create_native_func class Create_func_as_geojson : public Create_native_func
{ {
public: public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_as_geojson s_singleton; static Create_func_as_geojson s_singleton;
@@ -3289,7 +3295,7 @@ protected:
Item* Item*
Create_func_as_geojson::create_native(THD *thd, LEX_CSTRING *name, Create_func_as_geojson::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;

View File

@@ -5499,9 +5499,10 @@ ER_TRG_DOES_NOT_EXIST
hindi "TRIGGER मौजूद नहीं है" hindi "TRIGGER मौजूद नहीं है"
spa "El disparador no existe" spa "El disparador no existe"
ER_TRG_ON_VIEW_OR_TEMP_TABLE ER_TRG_ON_VIEW_OR_TEMP_TABLE
eng "Trigger's '%-.192s' is view or temporary table" eng "Trigger's '%-.192s' is a view, temporary table or sequence"
ger "'%-.192s' des Triggers ist View oder temporäre Tabelle" ger "'%-.192s' des Triggers ist ein View, temporäre Tabelle oder Sequence"
spa "El disparador '%-.192s' es una vista o tabla temporal" spa "El disparador '%-.192s' es una vista, tabla temporal o secuencia"
hindi "Trigger का '%-.192s' एक व्यू, टेम्पररी टेबल या सीक्वेंस है"
ER_TRG_CANT_CHANGE_ROW ER_TRG_CANT_CHANGE_ROW
eng "Updating of %s row is not allowed in %strigger" eng "Updating of %s row is not allowed in %strigger"
ger "Aktualisieren einer %s-Zeile ist in einem %s-Trigger nicht erlaubt" ger "Aktualisieren einer %s-Zeile ist in einem %s-Trigger nicht erlaubt"
@@ -8574,8 +8575,8 @@ ER_SEQUENCE_RUN_OUT
eng "Sequence '%-.64s.%-.64s' has run out" eng "Sequence '%-.64s.%-.64s' has run out"
spa "La secuencia '%-.64s.%-.64s' se ha agotado" spa "La secuencia '%-.64s.%-.64s' se ha agotado"
ER_SEQUENCE_INVALID_DATA ER_SEQUENCE_INVALID_DATA
eng "Sequence '%-.64s.%-.64s' values are conflicting" eng "Sequence '%-.64s.%-.64s' has out of range value for options"
spa "Los valores de secuencia '%-.64s.%-.64s' son conflictivos" spa "La secuencia '%-.64s.%-.64s' tiene un valor fuera de rango para las opciones"
ER_SEQUENCE_INVALID_TABLE_STRUCTURE ER_SEQUENCE_INVALID_TABLE_STRUCTURE
eng "Sequence '%-.64s.%-.64s' table structure is invalid (%s)" eng "Sequence '%-.64s.%-.64s' table structure is invalid (%s)"
spa "La estuctura de tabla de secuencia '%-.64s.%-.64s' es inválida (%s)" spa "La estuctura de tabla de secuencia '%-.64s.%-.64s' es inválida (%s)"

View File

@@ -9285,18 +9285,18 @@ bool LEX::call_statement_start(THD *thd,
(static_cast<const LEX_CSTRING*>(db))))) (static_cast<const LEX_CSTRING*>(db)))))
{ {
my_error(ER_WRONG_DB_NAME, MYF(0), db->str); my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
return NULL; return true;
} }
if (check_routine_name(pkg) || if (check_routine_name(pkg) ||
check_routine_name(proc)) check_routine_name(proc))
return NULL; return true;
// Concat `pkg` and `name` to `pkg.name` // Concat `pkg` and `name` to `pkg.name`
LEX_CSTRING pkg_dot_proc; LEX_CSTRING pkg_dot_proc;
if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) || if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) ||
check_ident_length(&pkg_dot_proc) || check_ident_length(&pkg_dot_proc) ||
!(spname= new (thd->mem_root) sp_name(db, &pkg_dot_proc, true))) !(spname= new (thd->mem_root) sp_name(db, &pkg_dot_proc, true)))
return NULL; return true;
sp_handler_package_function.add_used_routine(thd->lex, thd, spname); sp_handler_package_function.add_used_routine(thd->lex, thd, spname);
sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg); sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. /* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
Copyright (c) 2008, 2021, MariaDB Copyright (c) 2008, 2022, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -9201,6 +9201,7 @@ THD *find_thread_by_id(longlong id, bool query_id)
return arg.thd; return arg.thd;
} }
/** /**
kill one thread. kill one thread.
@@ -9216,7 +9217,7 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
THD *tmp; THD *tmp;
uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD); uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD);
DBUG_ENTER("kill_one_thread"); DBUG_ENTER("kill_one_thread");
DBUG_PRINT("enter", ("id: %lld signal: %u", id, (uint) kill_signal)); DBUG_PRINT("enter", ("id: %lld signal: %d", id, kill_signal));
tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY); tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY);
if (!tmp) if (!tmp)
DBUG_RETURN(error); DBUG_RETURN(error);
@@ -9244,7 +9245,8 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
faster and do a harder kill than KILL_SYSTEM_THREAD; faster and do a harder kill than KILL_SYSTEM_THREAD;
*/ */
mysql_mutex_lock(&tmp->LOCK_thd_data); // for various wsrep* checks below mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from concurrent usage
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) || if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) ||
thd->security_ctx->user_matches(tmp->security_ctx)) && thd->security_ctx->user_matches(tmp->security_ctx)) &&
@@ -9259,27 +9261,28 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id) if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
{ {
/* victim is in hit list already, bail out */ /* victim is in hit list already, bail out */
WSREP_DEBUG("victim has wsrep aborter: %lu, skipping awake()", WSREP_DEBUG("victim %lld has wsrep aborter: %lu, skipping awake()",
tmp->wsrep_aborter); id, tmp->wsrep_aborter);
error= 0; error= 0;
} }
else else
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
{ {
WSREP_DEBUG("kill_one_thread %llu, victim: %llu wsrep_aborter %llu by signal %d", WSREP_DEBUG("kill_one_thread victim: %lld wsrep_aborter %lu"
thd->thread_id, id, tmp->wsrep_aborter, kill_signal); " by signal %d",
id, tmp->wsrep_aborter, kill_signal);
tmp->awake_no_mutex(kill_signal); tmp->awake_no_mutex(kill_signal);
WSREP_DEBUG("victim: %llu taken care of", id);
error= 0; error= 0;
} }
} }
else else
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR : error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR); ER_KILL_DENIED_ERROR);
mysql_mutex_unlock(&tmp->LOCK_thd_data); mysql_mutex_unlock(&tmp->LOCK_thd_data);
} }
mysql_mutex_unlock(&tmp->LOCK_thd_kill); mysql_mutex_unlock(&tmp->LOCK_thd_kill);
DBUG_PRINT("exit", ("%d", error)); DBUG_PRINT("exit", ("%u", error));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@@ -9390,6 +9393,18 @@ static
void sql_kill(THD *thd, longlong id, killed_state state, killed_type type) void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
{ {
uint error; uint error;
#ifdef WITH_WSREP
if (WSREP(thd))
{
WSREP_DEBUG("sql_kill called");
if (thd->wsrep_applier)
{
WSREP_DEBUG("KILL in applying, bailing out here");
return;
}
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
}
#endif /* WITH_WSREP */
if (likely(!(error= kill_one_thread(thd, id, state, type)))) if (likely(!(error= kill_one_thread(thd, id, state, type))))
{ {
if (!thd->killed) if (!thd->killed)
@@ -9399,6 +9414,11 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
} }
else else
my_error(error, MYF(0), id); my_error(error, MYF(0), id);
#ifdef WITH_WSREP
return;
wsrep_error_label:
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
#endif /* WITH_WSREP */
} }
@@ -9407,6 +9427,18 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
{ {
uint error; uint error;
ha_rows rows; ha_rows rows;
#ifdef WITH_WSREP
if (WSREP(thd))
{
WSREP_DEBUG("sql_kill_user called");
if (thd->wsrep_applier)
{
WSREP_DEBUG("KILL in applying, bailing out here");
return;
}
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
}
#endif /* WITH_WSREP */
switch (error= kill_threads_for_user(thd, user, state, &rows)) switch (error= kill_threads_for_user(thd, user, state, &rows))
{ {
case 0: case 0:
@@ -9419,6 +9451,11 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
default: default:
my_error(error, MYF(0)); my_error(error, MYF(0));
} }
#ifdef WITH_WSREP
return;
wsrep_error_label:
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
#endif /* WITH_WSREP */
} }

View File

@@ -27790,8 +27790,11 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
if (unit->is_unit_op() || unit->fake_select_lex) if (unit->is_unit_op() || unit->fake_select_lex)
{ {
ulonglong save_options= 0;
if (unit->union_needs_tmp_table() && unit->fake_select_lex) if (unit->union_needs_tmp_table() && unit->fake_select_lex)
{ {
save_options= unit->fake_select_lex->options;
unit->fake_select_lex->select_number= FAKE_SELECT_LEX_ID; // just for initialization unit->fake_select_lex->select_number= FAKE_SELECT_LEX_ID; // just for initialization
unit->fake_select_lex->type= unit_operation_text[unit->common_op()]; unit->fake_select_lex->type= unit_operation_text[unit->common_op()];
unit->fake_select_lex->options|= SELECT_DESCRIBE; unit->fake_select_lex->options|= SELECT_DESCRIBE;
@@ -27802,6 +27805,9 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
if (!is_pushed_union) if (!is_pushed_union)
res= unit->exec(); res= unit->exec();
} }
if (unit->union_needs_tmp_table() && unit->fake_select_lex)
unit->fake_select_lex->options= save_options;
} }
else else
{ {

View File

@@ -122,7 +122,7 @@ bool sequence_definition::check_and_adjust(bool set_reserved_until)
start >= min_value && start >= min_value &&
max_value != LONGLONG_MAX && max_value != LONGLONG_MAX &&
min_value != LONGLONG_MIN && min_value != LONGLONG_MIN &&
cache < (LONGLONG_MAX - max_increment) / max_increment && cache >= 0 && cache < (LONGLONG_MAX - max_increment) / max_increment &&
((real_increment > 0 && reserved_until >= min_value) || ((real_increment > 0 && reserved_until >= min_value) ||
(real_increment < 0 && reserved_until <= max_value))) (real_increment < 0 && reserved_until <= max_value)))
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);

View File

@@ -3331,16 +3331,6 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg)
arg->table->field[11]->store((double) tmp->progress.counter / arg->table->field[11]->store((double) tmp->progress.counter /
(double) max_counter*100.0); (double) max_counter*100.0);
} }
else
{
/*
This is a DECIMAL column without DEFAULT.
restore_record() fills its Field::ptr to zero bytes,
according to pack_length(). But an array of zero bytes
is not a valid decimal. Set it explicitly to 0.
*/
arg->table->field[11]->store((longlong) 0, true);
}
mysql_mutex_unlock(&tmp->LOCK_thd_data); mysql_mutex_unlock(&tmp->LOCK_thd_data);
} }
@@ -8655,6 +8645,7 @@ bool optimize_schema_tables_memory_usage(List<TABLE_LIST> &tables)
if (bitmap_is_set(table->read_set, i)) if (bitmap_is_set(table->read_set, i))
{ {
field->move_field(cur); field->move_field(cur);
field->reset();
*to_recinfo++= *from_recinfo; *to_recinfo++= *from_recinfo;
cur+= from_recinfo->length; cur+= from_recinfo->length;
} }
@@ -8676,6 +8667,7 @@ bool optimize_schema_tables_memory_usage(List<TABLE_LIST> &tables)
to_recinfo->type= FIELD_NORMAL; to_recinfo->type= FIELD_NORMAL;
to_recinfo++; to_recinfo++;
} }
store_record(table, s->default_values);
p->recinfo= to_recinfo; p->recinfo= to_recinfo;
// TODO switch from Aria to Memory if all blobs were optimized away? // TODO switch from Aria to Memory if all blobs were optimized away?

View File

@@ -1,6 +1,6 @@
/* /*
Copyright (c) 2004, 2012, Oracle and/or its affiliates. Copyright (c) 2004, 2012, Oracle and/or its affiliates.
Copyright (c) 2010, 2021, MariaDB Copyright (c) 2010, 2022, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -439,6 +439,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
Query_tables_list backup; Query_tables_list backup;
DDL_LOG_STATE ddl_log_state, ddl_log_state_tmp_file; DDL_LOG_STATE ddl_log_state, ddl_log_state_tmp_file;
char trn_path_buff[FN_REFLEN]; char trn_path_buff[FN_REFLEN];
char path[FN_REFLEN + 1];
DBUG_ENTER("mysql_create_or_drop_trigger"); DBUG_ENTER("mysql_create_or_drop_trigger");
/* Charset of the buffer for statement must be system one. */ /* Charset of the buffer for statement must be system one. */
@@ -568,8 +570,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
/* We should have only one table in table list. */ /* We should have only one table in table list. */
DBUG_ASSERT(tables->next_global == 0); DBUG_ASSERT(tables->next_global == 0);
/* We do not allow creation of triggers on temporary tables. */ build_table_filename(path, sizeof(path) - 1, tables->db.str, tables->alias.str, ".frm", 0);
if (create && thd->find_tmp_table_share(tables)) tables->required_type= dd_frm_type(NULL, path, NULL, NULL, NULL);
/* We do not allow creation of triggers on temporary tables or sequence. */
if (tables->required_type == TABLE_TYPE_SEQUENCE ||
(create && thd->find_tmp_table_share(tables)))
{ {
my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias.str); my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias.str);
goto end; goto end;

View File

@@ -2681,7 +2681,7 @@ sequence_def:
if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE))
{ {
thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT; MYSQL_YYABORT;
} }
if (unlikely(Lex->create_info.seq_create_info->used_fields & if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_restart)) seq_field_used_restart))
@@ -2693,7 +2693,7 @@ sequence_def:
if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE))
{ {
thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
YYABORT; MYSQL_YYABORT;
} }
if (unlikely(Lex->create_info.seq_create_info->used_fields & if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_restart)) seq_field_used_restart))
@@ -8624,7 +8624,7 @@ subselect:
query_expression query_expression
{ {
if (!($$= Lex->parsed_subselect($1))) if (!($$= Lex->parsed_subselect($1)))
YYABORT; MYSQL_YYABORT;
} }
; ;
@@ -8669,14 +8669,14 @@ subquery:
else else
$1->fake_select_lex->braces= false; $1->fake_select_lex->braces= false;
if (!($$= Lex->parsed_subselect($1))) if (!($$= Lex->parsed_subselect($1)))
YYABORT; MYSQL_YYABORT;
} }
| '(' with_clause query_expression_no_with_clause ')' | '(' with_clause query_expression_no_with_clause ')'
{ {
$3->set_with_clause($2); $3->set_with_clause($2);
$2->attach_to($3->first_select()); $2->attach_to($3->first_select());
if (!($$= Lex->parsed_subselect($3))) if (!($$= Lex->parsed_subselect($3)))
YYABORT; MYSQL_YYABORT;
} }
; ;

View File

@@ -2660,8 +2660,11 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (flags & VERS_SYSTEM_FIELD) if (flags & VERS_SYSTEM_FIELD)
{ {
switch (handler->real_field_type()) auto field_type= handler->real_field_type();
{
DBUG_EXECUTE_IF("error_vers_wrong_type", field_type= MYSQL_TYPE_BLOB;);
switch (field_type) {
case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIMESTAMP2:
break; break;
case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_LONGLONG:
@@ -2672,8 +2675,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
} }
/* Fallthrough */ /* Fallthrough */
default: default:
my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), fieldnames.type_names[i], my_error(ER_VERS_FIELD_WRONG_TYPE,
versioned == VERS_TIMESTAMP ? "TIMESTAMP(6)" : "BIGINT(20) UNSIGNED", (field_type == MYSQL_TYPE_LONGLONG ?
MYF(0) : MYF(ME_WARNING)),
fieldnames.type_names[i],
(versioned == VERS_TIMESTAMP ?
"TIMESTAMP(6)" : "BIGINT(20) UNSIGNED"),
table_name.str); table_name.str);
goto err; goto err;
} }
@@ -8983,9 +8990,6 @@ bool TABLE::check_period_overlaps(const KEY &key,
void TABLE::vers_update_fields() void TABLE::vers_update_fields()
{ {
bitmap_set_bit(write_set, vers_start_field()->field_index);
bitmap_set_bit(write_set, vers_end_field()->field_index);
if (!vers_write) if (!vers_write)
{ {
file->column_bitmaps_signal(); file->column_bitmaps_signal();
@@ -8994,17 +8998,21 @@ void TABLE::vers_update_fields()
if (versioned(VERS_TIMESTAMP)) if (versioned(VERS_TIMESTAMP))
{ {
bitmap_set_bit(write_set, vers_start_field()->field_index);
if (vers_start_field()->store_timestamp(in_use->query_start(), if (vers_start_field()->store_timestamp(in_use->query_start(),
in_use->query_start_sec_part())) in_use->query_start_sec_part()))
{ {
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
vers_start_field()->set_has_explicit_value(); vers_start_field()->set_has_explicit_value();
bitmap_set_bit(read_set, vers_start_field()->field_index);
} }
bitmap_set_bit(write_set, vers_end_field()->field_index);
vers_end_field()->set_max(); vers_end_field()->set_max();
vers_end_field()->set_has_explicit_value(); vers_end_field()->set_has_explicit_value();
bitmap_set_bit(read_set, vers_end_field()->field_index); bitmap_set_bit(read_set, vers_end_field()->field_index);
file->column_bitmaps_signal(); file->column_bitmaps_signal();
if (vfield) if (vfield)
update_virtual_fields(file, VCOL_UPDATE_FOR_READ); update_virtual_fields(file, VCOL_UPDATE_FOR_READ);

View File

@@ -1,4 +1,5 @@
/* Copyright 2008-2022 Codership Oy <http://www.codership.com> /* Copyright 2008-2022 Codership Oy <http://www.codership.com>
Copyright (c) 2008, 2022, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -1501,44 +1502,14 @@ static int run_sql_command(THD *thd, const char *query)
if (thd->is_error()) if (thd->is_error())
{ {
int const err= thd->get_stmt_da()->sql_errno(); int const err= thd->get_stmt_da()->sql_errno();
WSREP_WARN ("Error executing '%s': %d (%s)%s", WSREP_WARN ("Error executing '%s': %d (%s)",
query, err, thd->get_stmt_da()->message(), query, err, thd->get_stmt_da()->message());
err == ER_UNKNOWN_SYSTEM_VARIABLE ?
". Was mysqld built with --with-innodb-disallow-writes ?" : "");
thd->clear_error(); thd->clear_error();
return -1; return -1;
} }
return 0; return 0;
} }
static void sst_disallow_writes (THD* thd, bool yes)
{
char query_str[64]= { 0, };
ssize_t const query_max= sizeof(query_str) - 1;
CHARSET_INFO *current_charset;
current_charset= thd->variables.character_set_client;
if (!is_supported_parser_charset(current_charset))
{
/* Do not use non-supported parser character sets */
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->cs_name.str);
thd->variables.character_set_client= &my_charset_latin1;
WSREP_WARN("For SST temporally setting character set to : %s",
my_charset_latin1.cs_name.str);
}
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
yes ? 1 : 0);
if (run_sql_command(thd, query_str))
{
WSREP_ERROR("Failed to disallow InnoDB writes");
}
thd->variables.character_set_client= current_charset;
}
static int sst_flush_tables(THD* thd) static int sst_flush_tables(THD* thd)
{ {
WSREP_INFO("Flushing tables for SST..."); WSREP_INFO("Flushing tables for SST...");
@@ -1598,16 +1569,11 @@ static int sst_flush_tables(THD* thd)
} }
else else
{ {
ha_disable_internal_writes(true);
WSREP_INFO("Tables flushed."); WSREP_INFO("Tables flushed.");
/* disable further disk IO */ // Create a file with cluster state ID and wsrep_gtid_domain_id.
sst_disallow_writes(thd, true);
WSREP_INFO("Disabled further disk IO.");
/*
Tables have been flushed. Create a file with cluster state ID and
wsrep_gtid_domain_id.
*/
char content[100]; char content[100];
snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid, snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid,
(long long)wsrep_locked_seqno, wsrep_gtid_server.domain_id); (long long)wsrep_locked_seqno, wsrep_gtid_server.domain_id);
@@ -1650,6 +1616,8 @@ static int sst_flush_tables(THD* thd)
} }
free(real_name); free(real_name);
free(tmp_name); free(tmp_name);
if (err)
ha_disable_internal_writes(false);
} }
return err; return err;
@@ -1700,19 +1668,17 @@ wait_signal:
if (!strcasecmp (out, magic_flush)) if (!strcasecmp (out, magic_flush))
{ {
err= sst_flush_tables (thd.ptr); err= sst_flush_tables (thd.ptr);
if (!err) if (!err)
{ {
locked= true;
/* /*
Lets also keep statements that modify binary logs (like RESET LOGS, Lets also keep statements that modify binary logs (like RESET LOGS,
RESET MASTER) from proceeding until the files have been transferred RESET MASTER) from proceeding until the files have been transferred
to the joiner node. to the joiner node.
*/ */
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{
mysql_mutex_lock(mysql_bin_log.get_log_lock()); mysql_mutex_lock(mysql_bin_log.get_log_lock());
}
locked= true;
WSREP_INFO("Donor state reached"); WSREP_INFO("Donor state reached");
@@ -1725,6 +1691,7 @@ wait_signal:
assert(!debug_sync_set_action(thd.ptr, assert(!debug_sync_set_action(thd.ptr,
STRING_WITH_LEN(act))); STRING_WITH_LEN(act)));
};); };);
goto wait_signal; goto wait_signal;
} }
} }
@@ -1732,14 +1699,11 @@ wait_signal:
{ {
if (locked) if (locked)
{ {
if (mysql_bin_log.is_open())
{
mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
mysql_mutex_unlock(mysql_bin_log.get_log_lock());
}
sst_disallow_writes (thd.ptr, false);
thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr);
locked= false; locked= false;
ha_disable_internal_writes(false);
if (mysql_bin_log.is_open())
mysql_mutex_unlock(mysql_bin_log.get_log_lock());
thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr);
} }
err= 0; err= 0;
goto wait_signal; goto wait_signal;
@@ -1770,12 +1734,12 @@ wait_signal:
if (locked) // don't forget to unlock server before return if (locked) // don't forget to unlock server before return
{ {
ha_disable_internal_writes(false);
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
mysql_mutex_assert_owner(mysql_bin_log.get_log_lock()); mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
mysql_mutex_unlock(mysql_bin_log.get_log_lock()); mysql_mutex_unlock(mysql_bin_log.get_log_lock());
} }
sst_disallow_writes (thd.ptr, false);
thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr); thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr);
} }

View File

@@ -297,6 +297,13 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
PTDB utp; PTDB utp;
if (!(utp = tdbp->Duplicate(g))) { if (!(utp = tdbp->Duplicate(g))) {
/* If table type is of type virtual retrieve global parameter as it was.*/
if (tdbp->GetAmType() == TYPE_AM_VIR) {
if (tdbp->OpenDB(g)) {
printf("%s\n", g->Message);
throw 7;
}
}
sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName()); sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
throw 4; throw 4;
} // endif tp } // endif tp

View File

@@ -16,3 +16,17 @@ SELECT * FROM t1;
a a
10 10
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-23626: CONNECT VIR tables return inconsistent error for UPDATE
#
CREATE TABLE numbers
ENGINE=CONNECT,
TABLE_TYPE=VIR,
BLOCK_SIZE=3;
TRUNCATE TABLE numbers;
ERROR HY000: Got error 174 'Virtual tables are read only' from CONNECT
DELETE FROM numbers WHERE n = 1;
ERROR HY000: Got error 174 'Virtual tables are read only' from CONNECT
UPDATE numbers SET n = 10 WHERE n = 1;
ERROR HY000: Got error 174 'Virtual tables are read only' from CONNECT
DROP TABLE numbers;

View File

@@ -14,3 +14,20 @@ SELECT * FROM t1;
ALTER TABLE t1 TABLE_TYPE=NON_EXISTING; ALTER TABLE t1 TABLE_TYPE=NON_EXISTING;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-23626: CONNECT VIR tables return inconsistent error for UPDATE
--echo #
CREATE TABLE numbers
ENGINE=CONNECT,
TABLE_TYPE=VIR,
BLOCK_SIZE=3;
--error ER_GET_ERRMSG
TRUNCATE TABLE numbers;
--error ER_GET_ERRMSG
DELETE FROM numbers WHERE n = 1;
--error ER_GET_ERRMSG
UPDATE numbers SET n = 10 WHERE n = 1;
DROP TABLE numbers;

View File

@@ -1,6 +1,6 @@
/* /*
Copyright (c) 2008-2009, Patrick Galbraith & Antony Curtis Copyright (c) 2008-2009, Patrick Galbraith & Antony Curtis
Copyright (c) 2020, MariaDB Corporation. Copyright (c) 2020, 2022, MariaDB Corporation.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1799,7 +1799,6 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
#endif #endif
ut_ad(oldest_lsn <= end_lsn); ut_ad(oldest_lsn <= end_lsn);
ut_ad(end_lsn == log_sys.get_lsn()); ut_ad(end_lsn == log_sys.get_lsn());
ut_ad(!recv_no_log_write);
if (oldest_lsn == log_sys.last_checkpoint_lsn || if (oldest_lsn == log_sys.last_checkpoint_lsn ||
(oldest_lsn == end_lsn && oldest_lsn == log_sys.last_checkpoint_lsn + (oldest_lsn == end_lsn && oldest_lsn == log_sys.last_checkpoint_lsn +
@@ -1813,6 +1812,7 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
return true; return true;
} }
ut_ad(!recv_no_log_write);
ut_ad(oldest_lsn > log_sys.last_checkpoint_lsn); ut_ad(oldest_lsn > log_sys.last_checkpoint_lsn);
/* Repeat the FILE_MODIFY records after the checkpoint, in case some /* Repeat the FILE_MODIFY records after the checkpoint, in case some
log records between the checkpoint and log_sys.lsn need them. log records between the checkpoint and log_sys.lsn need them.

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software

View File

@@ -991,6 +991,9 @@ fil_space_t *fil_space_t::create(uint32_t id, uint32_t flags,
if (UNIV_LIKELY(id <= fil_system.max_assigned_id)) { if (UNIV_LIKELY(id <= fil_system.max_assigned_id)) {
break; break;
} }
if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP)) {
break;
}
if (!fil_system.space_id_reuse_warned) { if (!fil_system.space_id_reuse_warned) {
ib::warn() << "Allocated tablespace ID " << id ib::warn() << "Allocated tablespace ID " << id
<< ", old maximum was " << ", old maximum was "

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2021, MariaDB Corporation. Copyright (c) 2016, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -37,6 +37,13 @@ Completed 2011/7/10 Sunny and Jimmy Yang
#include "zlib.h" #include "zlib.h"
#include "fts0opt.h" #include "fts0opt.h"
#include "fts0vlc.h" #include "fts0vlc.h"
#include "wsrep.h"
#ifdef WITH_WSREP
extern Atomic_relaxed<bool> wsrep_sst_disable_writes;
#else
constexpr bool wsrep_sst_disable_writes= false;
#endif
/** The FTS optimize thread's work queue. */ /** The FTS optimize thread's work queue. */
ib_wqueue_t* fts_optimize_wq; ib_wqueue_t* fts_optimize_wq;
@@ -2831,6 +2838,20 @@ static void fts_optimize_callback(void *)
&& ib_wqueue_is_empty(fts_optimize_wq) && ib_wqueue_is_empty(fts_optimize_wq)
&& n_tables > 0 && n_tables > 0
&& n_optimize > 0) { && n_optimize > 0) {
/* The queue is empty but we have tables
to optimize. */
if (UNIV_UNLIKELY(wsrep_sst_disable_writes)) {
retry_later:
if (fts_is_sync_needed()) {
fts_need_sync = true;
}
if (n_tables) {
timer->set_time(5000, 0);
}
return;
}
fts_slot_t* slot = static_cast<fts_slot_t*>( fts_slot_t* slot = static_cast<fts_slot_t*>(
ib_vector_get(fts_slots, current)); ib_vector_get(fts_slots, current));
@@ -2845,19 +2866,13 @@ static void fts_optimize_callback(void *)
n_optimize = fts_optimize_how_many(); n_optimize = fts_optimize_how_many();
current = 0; current = 0;
} }
} else if (n_optimize == 0 } else if (n_optimize == 0
|| !ib_wqueue_is_empty(fts_optimize_wq)) { || !ib_wqueue_is_empty(fts_optimize_wq)) {
fts_msg_t* msg = static_cast<fts_msg_t*> fts_msg_t* msg = static_cast<fts_msg_t*>
(ib_wqueue_nowait(fts_optimize_wq)); (ib_wqueue_nowait(fts_optimize_wq));
/* Timeout ? */ /* Timeout ? */
if (msg == NULL) { if (!msg) {
if (fts_is_sync_needed()) { goto retry_later;
fts_need_sync = true;
}
if (n_tables)
timer->set_time(5000, 0);
return;
} }
switch (msg->type) { switch (msg->type) {
@@ -2883,6 +2898,11 @@ static void fts_optimize_callback(void *)
break; break;
case FTS_MSG_SYNC_TABLE: case FTS_MSG_SYNC_TABLE:
if (UNIV_UNLIKELY(wsrep_sst_disable_writes)) {
add_msg(msg);
goto retry_later;
}
DBUG_EXECUTE_IF( DBUG_EXECUTE_IF(
"fts_instrument_msg_sync_sleep", "fts_instrument_msg_sync_sleep",
std::this_thread::sleep_for( std::this_thread::sleep_for(
@@ -2941,7 +2961,6 @@ fts_optimize_init(void)
/* Create FTS optimize work queue */ /* Create FTS optimize work queue */
fts_optimize_wq = ib_wqueue_create(); fts_optimize_wq = ib_wqueue_create();
ut_a(fts_optimize_wq != NULL);
timer = srv_thread_pool->create_timer(timer_callback); timer = srv_thread_pool->create_timer(timer_callback);
/* Create FTS vector to store fts_slot_t */ /* Create FTS vector to store fts_slot_t */

View File

@@ -1910,6 +1910,57 @@ thd_to_trx_id(
return(thd_to_trx(thd)->id); return(thd_to_trx(thd)->id);
} }
Atomic_relaxed<bool> wsrep_sst_disable_writes;
static void sst_disable_innodb_writes()
{
const uint old_count= srv_n_fil_crypt_threads;
fil_crypt_set_thread_cnt(0);
srv_n_fil_crypt_threads= old_count;
wsrep_sst_disable_writes= true;
dict_stats_shutdown();
purge_sys.stop();
/* We are holding a global MDL thanks to FLUSH TABLES WITH READ LOCK.
That will prevent any writes from arriving into InnoDB, but it will
not prevent writes of modified pages from the buffer pool, or log
checkpoints.
Let us perform a log checkpoint to ensure that the entire buffer
pool is clean, so that no writes to persistent files will be
possible during the snapshot, and to guarantee that no crash
recovery will be necessary when starting up on the snapshot. */
log_make_checkpoint();
/* If any FILE_MODIFY records were written by the checkpoint, an
extra write of a FILE_CHECKPOINT record could still be invoked by
buf_flush_page_cleaner(). Let us prevent that by invoking another
checkpoint (which will write the FILE_CHECKPOINT record). */
log_make_checkpoint();
ut_d(recv_no_log_write= true);
/* If this were not a no-op, an assertion would fail due to
recv_no_log_write. */
ut_d(log_make_checkpoint());
}
static void sst_enable_innodb_writes()
{
ut_ad(recv_no_log_write);
ut_d(recv_no_log_write= false);
dict_stats_start();
purge_sys.resume();
wsrep_sst_disable_writes= false;
fil_crypt_set_thread_cnt(srv_n_fil_crypt_threads);
}
static void innodb_disable_internal_writes(bool disable)
{
if (disable)
sst_disable_innodb_writes();
else
sst_enable_innodb_writes();
}
static void wsrep_abort_transaction(handlerton*, THD *, THD *, my_bool); static void wsrep_abort_transaction(handlerton*, THD *, THD *, my_bool);
static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid); static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid);
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid); static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
@@ -3573,11 +3624,6 @@ ha_innobase::init_table_handle_for_HANDLER(void)
m_prebuilt->trx->bulk_insert = false; m_prebuilt->trx->bulk_insert = false;
} }
#ifdef WITH_INNODB_DISALLOW_WRITES
/** Condition variable for innodb_disallow_writes */
static pthread_cond_t allow_writes_cond;
#endif /* WITH_INNODB_DISALLOW_WRITES */
/*********************************************************************//** /*********************************************************************//**
Free any resources that were allocated and return failure. Free any resources that were allocated and return failure.
@return always return 1 */ @return always return 1 */
@@ -3595,9 +3641,6 @@ static int innodb_init_abort()
} }
srv_tmp_space.shutdown(); srv_tmp_space.shutdown();
#ifdef WITH_INNODB_DISALLOW_WRITES
pthread_cond_destroy(&allow_writes_cond);
#endif /* WITH_INNODB_DISALLOW_WRITES */
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@@ -4092,6 +4135,7 @@ static int innodb_init(void* p)
innobase_hton->abort_transaction=wsrep_abort_transaction; innobase_hton->abort_transaction=wsrep_abort_transaction;
innobase_hton->set_checkpoint=innobase_wsrep_set_checkpoint; innobase_hton->set_checkpoint=innobase_wsrep_set_checkpoint;
innobase_hton->get_checkpoint=innobase_wsrep_get_checkpoint; innobase_hton->get_checkpoint=innobase_wsrep_get_checkpoint;
innobase_hton->disable_internal_writes=innodb_disable_internal_writes;
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
innobase_hton->check_version = innodb_check_version; innobase_hton->check_version = innodb_check_version;
@@ -4137,10 +4181,6 @@ static int innodb_init(void* p)
/* After this point, error handling has to use /* After this point, error handling has to use
innodb_init_abort(). */ innodb_init_abort(). */
#ifdef WITH_INNODB_DISALLOW_WRITES
pthread_cond_init(&allow_writes_cond, nullptr);
#endif /* WITH_INNODB_DISALLOW_WRITES */
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
/* Register keys with MySQL performance schema */ /* Register keys with MySQL performance schema */
int count; int count;
@@ -4253,9 +4293,6 @@ innobase_end(handlerton*, ha_panic_function)
innodb_shutdown(); innodb_shutdown();
#ifdef WITH_INNODB_DISALLOW_WRITES
pthread_cond_destroy(&allow_writes_cond);
#endif /* WITH_INNODB_DISALLOW_WRITES */
mysql_mutex_destroy(&log_requests.mutex); mysql_mutex_destroy(&log_requests.mutex);
} }
@@ -19397,42 +19434,6 @@ static MYSQL_SYSVAR_ULONG(buf_dump_status_frequency, srv_buf_dump_status_frequen
"dumped. Default is 0 (only start and end status is printed).", "dumped. Default is 0 (only start and end status is printed).",
NULL, NULL, 0, 0, 100, 0); NULL, NULL, 0, 0, 100, 0);
#ifdef WITH_INNODB_DISALLOW_WRITES
my_bool innodb_disallow_writes;
void innodb_wait_allow_writes()
{
if (UNIV_UNLIKELY(innodb_disallow_writes))
{
mysql_mutex_lock(&LOCK_global_system_variables);
while (innodb_disallow_writes)
my_cond_wait(&allow_writes_cond, &LOCK_global_system_variables.m_mutex);
mysql_mutex_unlock(&LOCK_global_system_variables);
}
}
/**************************************************************************
An "update" method for innobase_disallow_writes variable. */
static
void
innobase_disallow_writes_update(THD*, st_mysql_sys_var*,
void* var_ptr, const void* save)
{
const my_bool val = *static_cast<const my_bool*>(save);
*static_cast<my_bool*>(var_ptr) = val;
mysql_mutex_unlock(&LOCK_global_system_variables);
if (!val) {
pthread_cond_broadcast(&allow_writes_cond);
}
mysql_mutex_lock(&LOCK_global_system_variables);
}
static MYSQL_SYSVAR_BOOL(disallow_writes, innodb_disallow_writes,
PLUGIN_VAR_NOCMDOPT,
"Tell InnoDB to stop any writes to disk",
NULL, innobase_disallow_writes_update, FALSE);
#endif /* WITH_INNODB_DISALLOW_WRITES */
static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead, static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead,
PLUGIN_VAR_NOCMDARG, PLUGIN_VAR_NOCMDARG,
"Whether to use read ahead for random access within an extent.", "Whether to use read ahead for random access within an extent.",
@@ -19755,9 +19756,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(change_buffer_dump), MYSQL_SYSVAR(change_buffer_dump),
MYSQL_SYSVAR(change_buffering_debug), MYSQL_SYSVAR(change_buffering_debug),
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
#ifdef WITH_INNODB_DISALLOW_WRITES
MYSQL_SYSVAR(disallow_writes),
#endif /* WITH_INNODB_DISALLOW_WRITES */
MYSQL_SYSVAR(random_read_ahead), MYSQL_SYSVAR(random_read_ahead),
MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(read_only), MYSQL_SYSVAR(read_only),

View File

@@ -20,25 +20,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <atomic> #include <atomic>
#include "my_dbug.h" #include "my_dbug.h"
#if defined __linux__
/* futex(2): FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE */
#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__
/* system calls similar to Linux futex(2) */
#elif defined _WIN32
/* SRWLOCK as well as WaitOnAddress(), WakeByAddressSingle() */
#else
# define SUX_LOCK_GENERIC /* fall back to generic synchronization primitives */
#endif
#if !defined SUX_LOCK_GENERIC && 0 /* defined SAFE_MUTEX */
# define SUX_LOCK_GENERIC /* Use dummy implementation for debugging purposes */
#endif
#ifdef SUX_LOCK_GENERIC
/** Simple read-update-write lock based on std::atomic */
#else
/** Simple read-write lock based on std::atomic */ /** Simple read-write lock based on std::atomic */
#endif
class rw_lock class rw_lock
{ {
/** The lock word */ /** The lock word */
@@ -53,10 +35,6 @@ protected:
static constexpr uint32_t WRITER_WAITING= 1U << 30; static constexpr uint32_t WRITER_WAITING= 1U << 30;
/** Flag to indicate that write_lock() or write_lock_wait() is pending */ /** Flag to indicate that write_lock() or write_lock_wait() is pending */
static constexpr uint32_t WRITER_PENDING= WRITER | WRITER_WAITING; static constexpr uint32_t WRITER_PENDING= WRITER | WRITER_WAITING;
#ifdef SUX_LOCK_GENERIC
/** Flag to indicate that an update lock exists */
static constexpr uint32_t UPDATER= 1U << 29;
#endif /* SUX_LOCK_GENERIC */
/** Start waiting for an exclusive lock. */ /** Start waiting for an exclusive lock. */
void write_lock_wait_start() void write_lock_wait_start()
@@ -84,12 +62,8 @@ protected:
std::memory_order_relaxed); std::memory_order_relaxed);
} }
/** Try to acquire a shared lock. /** Try to acquire a shared lock.
@tparam prioritize_updater whether to ignore WRITER_WAITING for UPDATER
@param l the value of the lock word @param l the value of the lock word
@return whether the lock was acquired */ @return whether the lock was acquired */
#ifdef SUX_LOCK_GENERIC
template<bool prioritize_updater= false>
#endif /* SUX_LOCK_GENERIC */
bool read_trylock(uint32_t &l) bool read_trylock(uint32_t &l)
{ {
l= UNLOCKED; l= UNLOCKED;
@@ -97,66 +71,11 @@ protected:
std::memory_order_relaxed)) std::memory_order_relaxed))
{ {
DBUG_ASSERT(!(WRITER & l) || !(~WRITER_PENDING & l)); DBUG_ASSERT(!(WRITER & l) || !(~WRITER_PENDING & l));
#ifdef SUX_LOCK_GENERIC
DBUG_ASSERT((~(WRITER_PENDING | UPDATER) & l) < UPDATER);
if (prioritize_updater
? (WRITER & l) || ((WRITER_WAITING | UPDATER) & l) == WRITER_WAITING
: (WRITER_PENDING & l))
#else /* SUX_LOCK_GENERIC */
if (l & WRITER_PENDING) if (l & WRITER_PENDING)
#endif /* SUX_LOCK_GENERIC */
return false; return false;
} }
return true; return true;
} }
#ifdef SUX_LOCK_GENERIC
/** Try to acquire an update lock.
@param l the value of the lock word
@return whether the lock was acquired */
bool update_trylock(uint32_t &l)
{
l= UNLOCKED;
while (!lock.compare_exchange_strong(l, l | UPDATER,
std::memory_order_acquire,
std::memory_order_relaxed))
{
DBUG_ASSERT(!(WRITER & l) || !(~WRITER_PENDING & l));
DBUG_ASSERT((~(WRITER_PENDING | UPDATER) & l) < UPDATER);
if ((WRITER_PENDING | UPDATER) & l)
return false;
}
return true;
}
/** Try to upgrade an update lock to an exclusive lock.
@return whether the update lock was upgraded to exclusive */
bool upgrade_trylock()
{
auto l= UPDATER;
while (!lock.compare_exchange_strong(l, WRITER,
std::memory_order_acquire,
std::memory_order_relaxed))
{
/* Either conflicting (read) locks have been granted, or
the WRITER_WAITING flag was set by some thread that is waiting
to become WRITER. */
DBUG_ASSERT(((WRITER | UPDATER) & l) == UPDATER);
if (~(WRITER_WAITING | UPDATER) & l)
return false;
}
DBUG_ASSERT((l & ~WRITER_WAITING) == UPDATER);
/* Any thread that had set WRITER_WAITING will eventually be woken
up by ssux_lock_impl::x_unlock() or ssux_lock_impl::u_unlock()
(not ssux_lock_impl::wr_u_downgrade() to keep the code simple). */
return true;
}
/** Downgrade an exclusive lock to an update lock. */
void downgrade()
{
IF_DBUG_ASSERT(auto l=,)
lock.fetch_xor(WRITER | UPDATER, std::memory_order_relaxed);
DBUG_ASSERT((l & ~WRITER_WAITING) == WRITER);
}
#endif /* SUX_LOCK_GENERIC */
/** Wait for an exclusive lock. /** Wait for an exclusive lock.
@return whether the exclusive lock was acquired */ @return whether the exclusive lock was acquired */
@@ -183,24 +102,9 @@ public:
{ {
auto l= lock.fetch_sub(1, std::memory_order_release); auto l= lock.fetch_sub(1, std::memory_order_release);
DBUG_ASSERT(!(l & WRITER)); /* no write lock must have existed */ DBUG_ASSERT(!(l & WRITER)); /* no write lock must have existed */
#ifdef SUX_LOCK_GENERIC
DBUG_ASSERT(~(WRITER_PENDING | UPDATER) & l); /* at least one read lock */
return (~(WRITER_PENDING | UPDATER) & l) == 1;
#else /* SUX_LOCK_GENERIC */
DBUG_ASSERT(~(WRITER_PENDING) & l); /* at least one read lock */ DBUG_ASSERT(~(WRITER_PENDING) & l); /* at least one read lock */
return (~WRITER_PENDING & l) == 1; return (~WRITER_PENDING & l) == 1;
#endif /* SUX_LOCK_GENERIC */
} }
#ifdef SUX_LOCK_GENERIC
/** Release an update lock */
void update_unlock()
{
IF_DBUG_ASSERT(auto l=,)
lock.fetch_and(~UPDATER, std::memory_order_release);
/* the update lock must have existed */
DBUG_ASSERT((l & (WRITER | UPDATER)) == UPDATER);
}
#endif /* SUX_LOCK_GENERIC */
/** Release an exclusive lock */ /** Release an exclusive lock */
void write_unlock() void write_unlock()
{ {
@@ -211,11 +115,7 @@ public:
static_assert(WRITER == 1U << 31, "compatibility"); static_assert(WRITER == 1U << 31, "compatibility");
IF_DBUG_ASSERT(auto l=,) lock.fetch_sub(WRITER, std::memory_order_release); IF_DBUG_ASSERT(auto l=,) lock.fetch_sub(WRITER, std::memory_order_release);
/* the write lock must have existed */ /* the write lock must have existed */
#ifdef SUX_LOCK_GENERIC
DBUG_ASSERT((l & (WRITER | UPDATER)) == WRITER);
#else /* SUX_LOCK_GENERIC */
DBUG_ASSERT(l & WRITER); DBUG_ASSERT(l & WRITER);
#endif /* SUX_LOCK_GENERIC */
} }
/** Try to acquire a shared lock. /** Try to acquire a shared lock.
@return whether the lock was acquired */ @return whether the lock was acquired */
@@ -231,10 +131,6 @@ public:
/** @return whether an exclusive lock is being held by any thread */ /** @return whether an exclusive lock is being held by any thread */
bool is_write_locked() const { return !!(value() & WRITER); } bool is_write_locked() const { return !!(value() & WRITER); }
#ifdef SUX_LOCK_GENERIC
/** @return whether an update lock is being held by any thread */
bool is_update_locked() const { return !!(value() & UPDATER); }
#endif /* SUX_LOCK_GENERIC */
/** @return whether any lock is being held or waited for by any thread */ /** @return whether any lock is being held or waited for by any thread */
bool is_locked_or_waiting() const { return value() != 0; } bool is_locked_or_waiting() const { return value() != 0; }
/** @return whether any lock is being held by any thread */ /** @return whether any lock is being held by any thread */

View File

@@ -276,13 +276,6 @@ extern uint srv_flush_log_at_timeout;
extern my_bool srv_adaptive_flushing; extern my_bool srv_adaptive_flushing;
extern my_bool srv_flush_sync; extern my_bool srv_flush_sync;
#ifdef WITH_INNODB_DISALLOW_WRITES
extern my_bool innodb_disallow_writes;
void innodb_wait_allow_writes();
#else
# define innodb_wait_allow_writes() do {} while (0)
#endif /* WITH_INNODB_DISALLOW_WRITES */
/** Requested size in bytes */ /** Requested size in bytes */
extern ulint srv_buf_pool_size; extern ulint srv_buf_pool_size;
/** Requested buffer pool chunk size */ /** Requested buffer pool chunk size */

View File

@@ -20,27 +20,58 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "univ.i" #include "univ.i"
#include "rw_lock.h" #include "rw_lock.h"
#if defined __linux__
/* futex(2): FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE */
#elif defined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__
/* system calls similar to Linux futex(2) */
#elif defined _WIN32
/* SRWLOCK as well as WaitOnAddress(), WakeByAddressSingle() */
#else
# define SUX_LOCK_GENERIC /* fall back to generic synchronization primitives */
#endif
#if !defined SUX_LOCK_GENERIC && 0 /* defined SAFE_MUTEX */
# define SUX_LOCK_GENERIC /* Use dummy implementation for debugging purposes */
#endif
#ifdef SUX_LOCK_GENERIC #ifdef SUX_LOCK_GENERIC
/** An exclusive-only variant of srw_lock */ /** An exclusive-only variant of srw_lock */
template<bool spinloop> template<bool spinloop>
class srw_mutex_impl final class pthread_mutex_wrapper final
{ {
pthread_mutex_t lock; pthread_mutex_t lock;
public:
void init()
{
if (spinloop)
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
else
pthread_mutex_init(&lock, nullptr);
}
void destroy() { pthread_mutex_destroy(&lock); }
# ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void wr_lock() { pthread_mutex_lock(&lock); }
# else
private:
void wr_wait(); void wr_wait();
public: public:
void init() { pthread_mutex_init(&lock, nullptr); }
void destroy() { pthread_mutex_destroy(&lock); }
inline void wr_lock(); inline void wr_lock();
# endif
void wr_unlock() { pthread_mutex_unlock(&lock); } void wr_unlock() { pthread_mutex_unlock(&lock); }
bool wr_lock_try() { return !pthread_mutex_trylock(&lock); } bool wr_lock_try() { return !pthread_mutex_trylock(&lock); }
}; };
template<> void srw_mutex_impl<true>::wr_wait(); # ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
template<> void pthread_mutex_wrapper<true>::wr_wait();
template<> template<>
inline void srw_mutex_impl<false>::wr_lock() { pthread_mutex_lock(&lock); } inline void pthread_mutex_wrapper<false>::wr_lock()
{ pthread_mutex_lock(&lock); }
template<> template<>
inline void srw_mutex_impl<true>::wr_lock() { if (!wr_lock_try()) wr_wait(); } inline void pthread_mutex_wrapper<true>::wr_lock()
#else { if (!wr_lock_try()) wr_wait(); }
# endif
#endif
/** Futex-based mutex */ /** Futex-based mutex */
template<bool spinloop> template<bool spinloop>
class srw_mutex_impl final class srw_mutex_impl final
@@ -51,6 +82,15 @@ class srw_mutex_impl final
/** Identifies that the lock is being held */ /** Identifies that the lock is being held */
static constexpr uint32_t HOLDER= 1U << 31; static constexpr uint32_t HOLDER= 1U << 31;
#ifdef SUX_LOCK_GENERIC
public:
/** The mutex for the condition variables. */
pthread_mutex_t mutex;
private:
/** Condition variable for the lock word. Used with mutex. */
pthread_cond_t cond;
#endif
/** Wait until the mutex has been acquired */ /** Wait until the mutex has been acquired */
void wait_and_lock(); void wait_and_lock();
/** Wait for lock!=lk */ /** Wait for lock!=lk */
@@ -65,8 +105,22 @@ public:
bool is_locked() const bool is_locked() const
{ return (lock.load(std::memory_order_acquire) & HOLDER) != 0; } { return (lock.load(std::memory_order_acquire) & HOLDER) != 0; }
void init() { DBUG_ASSERT(!is_locked_or_waiting()); } void init()
void destroy() { DBUG_ASSERT(!is_locked_or_waiting()); } {
DBUG_ASSERT(!is_locked_or_waiting());
#ifdef SUX_LOCK_GENERIC
pthread_mutex_init(&mutex, nullptr);
pthread_cond_init(&cond, nullptr);
#endif
}
void destroy()
{
DBUG_ASSERT(!is_locked_or_waiting());
#ifdef SUX_LOCK_GENERIC
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
#endif
}
/** @return whether the mutex was acquired */ /** @return whether the mutex was acquired */
bool wr_lock_try() bool wr_lock_try()
@@ -88,19 +142,20 @@ public:
} }
} }
}; };
#endif
#ifdef SUX_LOCK_GENERIC
typedef pthread_mutex_wrapper<true> srw_spin_mutex;
typedef pthread_mutex_wrapper<false> srw_mutex;
#else
typedef srw_mutex_impl<true> srw_spin_mutex; typedef srw_mutex_impl<true> srw_spin_mutex;
typedef srw_mutex_impl<false> srw_mutex; typedef srw_mutex_impl<false> srw_mutex;
#endif
template<bool spinloop> class srw_lock_impl; template<bool spinloop> class srw_lock_impl;
/** Slim shared-update-exclusive lock with no recursion */ /** Slim shared-update-exclusive lock with no recursion */
template<bool spinloop> template<bool spinloop>
class ssux_lock_impl final class ssux_lock_impl final
#ifdef SUX_LOCK_GENERIC
: private rw_lock
#endif
{ {
#ifdef UNIV_PFS_RWLOCK #ifdef UNIV_PFS_RWLOCK
friend class ssux_lock; friend class ssux_lock;
@@ -110,50 +165,12 @@ class ssux_lock_impl final
friend srw_lock_impl<spinloop>; friend srw_lock_impl<spinloop>;
# endif # endif
#endif #endif
#ifdef SUX_LOCK_GENERIC
pthread_mutex_t mutex;
pthread_cond_t cond_shared;
pthread_cond_t cond_exclusive;
/** Wait for a read lock.
@param l lock word from a failed read_trylock() */
void read_lock(uint32_t l);
/** Wait for an update lock.
@param l lock word from a failed update_trylock() */
void update_lock(uint32_t l);
/** Wait for a write lock after a failed write_trylock() or upgrade_trylock()
@param holding_u whether we already hold u_lock() */
void write_lock(bool holding_u);
/** Wait for signal
@param l lock word from a failed acquisition */
inline void writer_wait(uint32_t l);
/** Wait for signal
@param l lock word from a failed acquisition */
inline void readers_wait(uint32_t l);
/** Wake waiters */
inline void wake();
public:
void init();
void destroy();
/** @return whether any writer is waiting */
bool is_waiting() const { return (value() & WRITER_WAITING) != 0; }
bool is_write_locked() const { return rw_lock::is_write_locked(); }
bool is_locked_or_waiting() const { return rw_lock::is_locked_or_waiting(); }
bool rd_lock_try() { uint32_t l; return read_trylock(l); }
bool wr_lock_try() { return write_trylock(); }
void rd_lock() { uint32_t l; if (!read_trylock(l)) read_lock(l); }
void u_lock() { uint32_t l; if (!update_trylock(l)) update_lock(l); }
bool u_lock_try() { uint32_t l; return update_trylock(l); }
void u_wr_upgrade() { if (!upgrade_trylock()) write_lock(true); }
void wr_u_downgrade() { downgrade(); }
void wr_lock() { if (!write_trylock()) write_lock(false); }
void rd_unlock();
void u_unlock();
void wr_unlock();
#else
/** mutex for synchronization; held by U or X lock holders */ /** mutex for synchronization; held by U or X lock holders */
srw_mutex_impl<spinloop> writer; srw_mutex_impl<spinloop> writer;
#ifdef SUX_LOCK_GENERIC
/** Condition variable for "readers"; used with writer.mutex. */
pthread_cond_t readers_cond;
#endif
/** S or U holders, and WRITER flag for X holder or waiter */ /** S or U holders, and WRITER flag for X holder or waiter */
std::atomic<uint32_t> readers; std::atomic<uint32_t> readers;
/** indicates an X request; readers=WRITER indicates granted X lock */ /** indicates an X request; readers=WRITER indicates granted X lock */
@@ -169,8 +186,22 @@ public:
/** Acquire a read lock */ /** Acquire a read lock */
void rd_wait(); void rd_wait();
public: public:
void init() { DBUG_ASSERT(is_vacant()); } void init()
void destroy() { DBUG_ASSERT(is_vacant()); } {
writer.init();
DBUG_ASSERT(is_vacant());
#ifdef SUX_LOCK_GENERIC
pthread_cond_init(&readers_cond, nullptr);
#endif
}
void destroy()
{
DBUG_ASSERT(is_vacant());
writer.destroy();
#ifdef SUX_LOCK_GENERIC
pthread_cond_destroy(&readers_cond);
#endif
}
/** @return whether any writer is waiting */ /** @return whether any writer is waiting */
bool is_waiting() const bool is_waiting() const
{ return (readers.load(std::memory_order_relaxed) & WRITER) != 0; } { return (readers.load(std::memory_order_relaxed) & WRITER) != 0; }
@@ -288,7 +319,6 @@ public:
void unlock_shared() { rd_unlock(); } void unlock_shared() { rd_unlock(); }
void lock() { wr_lock(); } void lock() { wr_lock(); }
void unlock() { wr_unlock(); } void unlock() { wr_unlock(); }
#endif
}; };
#if defined _WIN32 || defined SUX_LOCK_GENERIC #if defined _WIN32 || defined SUX_LOCK_GENERIC

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2017, 2021, MariaDB Corporation. # Copyright (c) 2017, 2022, MariaDB Corporation.
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -115,13 +115,6 @@ ENDIF()
CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF) CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF)
OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP})
IF (WITH_INNODB_DISALLOW_WRITES)
ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES)
ENDIF()
ADD_FEATURE_INFO(INNODB_DISALLOW_WRITES WITH_INNODB_DISALLOW_WRITES "Expose innodb_disallow_writes switch to stop innodb from writing to disk")
# Include directories under innobase # Include directories under innobase
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
${CMAKE_SOURCE_DIR}/storage/innobase/handler) ${CMAKE_SOURCE_DIR}/storage/innobase/handler)

View File

@@ -146,9 +146,6 @@ static ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
static ulint os_innodb_umask = 0; static ulint os_innodb_umask = 0;
#endif /* _WIN32 */ #endif /* _WIN32 */
#define WAIT_ALLOW_WRITES() innodb_wait_allow_writes()
Atomic_counter<ulint> os_n_file_reads; Atomic_counter<ulint> os_n_file_reads;
static ulint os_bytes_read_since_printout; static ulint os_bytes_read_since_printout;
Atomic_counter<size_t> os_n_file_writes; Atomic_counter<size_t> os_n_file_writes;
@@ -369,7 +366,6 @@ FILE*
os_file_create_tmpfile() os_file_create_tmpfile()
{ {
FILE* file = NULL; FILE* file = NULL;
WAIT_ALLOW_WRITES();
File fd = mysql_tmpfile("ib"); File fd = mysql_tmpfile("ib");
if (fd >= 0) { if (fd >= 0) {
@@ -969,7 +965,6 @@ os_file_flush_func(
{ {
int ret; int ret;
WAIT_ALLOW_WRITES();
ret = os_file_sync_posix(file); ret = os_file_sync_posix(file);
if (ret == 0) { if (ret == 0) {
@@ -1021,10 +1016,6 @@ os_file_create_simple_func(
int create_flag; int create_flag;
const char* mode_str = NULL; const char* mode_str = NULL;
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
WAIT_ALLOW_WRITES();
}
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT));
@@ -1145,7 +1136,6 @@ os_file_create_directory(
{ {
int rcode; int rcode;
WAIT_ALLOW_WRITES();
rcode = mkdir(pathname, 0770); rcode = mkdir(pathname, 0770);
if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) { if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) {
@@ -1412,10 +1402,6 @@ os_file_create_simple_no_error_handling_func(
os_file_t file; os_file_t file;
int create_flag; int create_flag;
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
WAIT_ALLOW_WRITES();
}
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT));
@@ -1490,7 +1476,6 @@ os_file_delete_if_exists_func(
} }
int ret; int ret;
WAIT_ALLOW_WRITES();
ret = unlink(name); ret = unlink(name);
@@ -1515,7 +1500,6 @@ os_file_delete_func(
const char* name) const char* name)
{ {
int ret; int ret;
WAIT_ALLOW_WRITES();
ret = unlink(name); ret = unlink(name);
@@ -1554,7 +1538,6 @@ os_file_rename_func(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
int ret; int ret;
WAIT_ALLOW_WRITES();
ret = rename(oldpath, newpath); ret = rename(oldpath, newpath);
@@ -1729,7 +1712,6 @@ bool
os_file_set_eof( os_file_set_eof(
FILE* file) /*!< in: file to be truncated */ FILE* file) /*!< in: file to be truncated */
{ {
WAIT_ALLOW_WRITES();
return(!ftruncate(fileno(file), ftell(file))); return(!ftruncate(fileno(file), ftell(file)));
} }
@@ -2174,10 +2156,6 @@ os_file_create_func(
? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
: FILE_SHARE_READ | FILE_SHARE_DELETE; : FILE_SHARE_READ | FILE_SHARE_DELETE;
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
WAIT_ALLOW_WRITES();
}
on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT
? true : false; ? true : false;
@@ -2901,8 +2879,6 @@ os_file_write_func(
ut_ad(n > 0); ut_ad(n > 0);
WAIT_ALLOW_WRITES();
ssize_t n_bytes = os_file_pwrite(type, file, (byte*)buf, n, offset, &err); ssize_t n_bytes = os_file_pwrite(type, file, (byte*)buf, n, offset, &err);
if ((ulint) n_bytes != n && !os_has_said_disk_full) { if ((ulint) n_bytes != n && !os_has_said_disk_full) {

View File

@@ -4349,7 +4349,6 @@ pfs_os_file_t
row_merge_file_create_low( row_merge_file_create_low(
const char* path) const char* path)
{ {
innodb_wait_allow_writes();
if (!path) { if (!path) {
path = mysql_tmpdir; path = mysql_tmpdir;
} }

View File

@@ -655,7 +655,6 @@ static void srv_init()
/* Initialize some INFORMATION SCHEMA internal structures */ /* Initialize some INFORMATION SCHEMA internal structures */
trx_i_s_cache_init(trx_i_s_cache); trx_i_s_cache_init(trx_i_s_cache);
} }
/*********************************************************************//** /*********************************************************************//**

View File

@@ -139,7 +139,8 @@ static inline void srw_pause(unsigned delay)
} }
#ifdef SUX_LOCK_GENERIC #ifdef SUX_LOCK_GENERIC
template<> void srw_mutex_impl<true>::wr_wait() # ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
template<> void pthread_mutex_wrapper<true>::wr_wait()
{ {
const unsigned delay= srw_pause_delay(); const unsigned delay= srw_pause_delay();
@@ -152,203 +153,46 @@ template<> void srw_mutex_impl<true>::wr_wait()
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
} }
# endif
template<bool spinloop>
void ssux_lock_impl<spinloop>::init()
{
DBUG_ASSERT(!is_locked_or_waiting());
pthread_mutex_init(&mutex, nullptr);
pthread_cond_init(&cond_shared, nullptr);
pthread_cond_init(&cond_exclusive, nullptr);
}
template<bool spinloop>
void ssux_lock_impl<spinloop>::destroy()
{
DBUG_ASSERT(!is_locked_or_waiting());
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_shared);
pthread_cond_destroy(&cond_exclusive);
}
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::writer_wait(uint32_t l)
{
pthread_mutex_lock(&mutex);
while (value() == l)
pthread_cond_wait(&cond_exclusive, &mutex);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::readers_wait(uint32_t l)
{
pthread_mutex_lock(&mutex);
while (value() == l)
pthread_cond_wait(&cond_shared, &mutex);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::wake()
{
pthread_mutex_lock(&mutex);
uint32_t l= value();
if (l & WRITER)
DBUG_ASSERT(!(l & ~WRITER_PENDING));
else
{
pthread_cond_broadcast(&cond_exclusive);
if (!(l & WRITER_PENDING))
pthread_cond_broadcast(&cond_shared);
}
pthread_mutex_unlock(&mutex);
}
/** Wait for a read lock.
@param lock word value from a failed read_trylock() */
template<bool spinloop>
void ssux_lock_impl<spinloop>::read_lock(uint32_t l)
{
do
{
if (l == WRITER_WAITING)
{
wake_writer:
pthread_mutex_lock(&mutex);
for (;;)
{
if (l == WRITER_WAITING)
pthread_cond_signal(&cond_exclusive);
l= value();
if (!(l & WRITER_PENDING))
break;
pthread_cond_wait(&cond_shared, &mutex);
}
pthread_mutex_unlock(&mutex);
continue;
}
else if (spinloop)
{
const unsigned delay= srw_pause_delay();
for (auto spin= srv_n_spin_wait_rounds; spin; spin--)
{
srw_pause(delay);
if (read_trylock<true>(l))
return;
else if (l == WRITER_WAITING)
goto wake_writer;
}
}
readers_wait(l);
}
while (!read_trylock<true>(l));
}
/** Wait for an update lock.
@param lock word value from a failed update_trylock() */
template<bool spinloop>
void ssux_lock_impl<spinloop>::update_lock(uint32_t l)
{
do
{
if ((l | UPDATER) == (UPDATER | WRITER_WAITING))
{
wake_writer:
pthread_mutex_lock(&mutex);
for (;;)
{
if ((l | UPDATER) == (UPDATER | WRITER_WAITING))
pthread_cond_signal(&cond_exclusive);
l= value();
if (!(l & WRITER_PENDING))
break;
pthread_cond_wait(&cond_shared, &mutex);
}
pthread_mutex_unlock(&mutex);
continue;
}
else if (spinloop)
{
const unsigned delay= srw_pause_delay();
for (auto spin= srv_n_spin_wait_rounds; spin; spin--)
{
srw_pause(delay);
if (update_trylock(l))
return;
else if ((l | UPDATER) == (UPDATER | WRITER_WAITING))
goto wake_writer;
}
}
readers_wait(l);
}
while (!update_trylock(l));
}
/** Wait for a write lock after a failed write_trylock() or upgrade_trylock()
@param holding_u whether we already hold u_lock() */
template<bool spinloop>
void ssux_lock_impl<spinloop>::write_lock(bool holding_u)
{
for (;;)
{
write_lock_wait_start();
const uint32_t e= holding_u ? WRITER_WAITING | UPDATER : WRITER_WAITING;
uint32_t l= e;
if (write_lock_wait_try(l))
return;
if (!(l & WRITER_WAITING))
{
switch (l) {
case UNLOCKED:
DBUG_ASSERT(!holding_u);
if (write_trylock())
return;
break;
case UPDATER:
if (holding_u && upgrade_trylock())
return;
}
for (l= write_lock_wait_start_read() | WRITER_WAITING;
(l | WRITER_WAITING) == e; )
if (write_lock_wait_try(l))
return;
}
else
DBUG_ASSERT(~WRITER_WAITING & l);
writer_wait(l);
}
}
template<bool spinloop>
void ssux_lock_impl<spinloop>::rd_unlock() { if (read_unlock()) wake(); }
template<bool spinloop>
void ssux_lock_impl<spinloop>::u_unlock() { update_unlock(); wake(); }
template<bool spinloop>
void ssux_lock_impl<spinloop>::wr_unlock() { write_unlock(); wake(); }
template void ssux_lock_impl<false>::init(); template void ssux_lock_impl<false>::init();
template void ssux_lock_impl<false>::destroy();
template void ssux_lock_impl<false>::rd_unlock();
template void ssux_lock_impl<false>::u_unlock();
template void ssux_lock_impl<false>::wr_unlock();
template void ssux_lock_impl<true>::init(); template void ssux_lock_impl<true>::init();
template void ssux_lock_impl<false>::destroy();
template void ssux_lock_impl<true>::destroy(); template void ssux_lock_impl<true>::destroy();
template void ssux_lock_impl<true>::read_lock(uint32_t);
template void ssux_lock_impl<true>::rd_unlock(); template<bool spinloop>
template void ssux_lock_impl<true>::u_unlock(); inline void srw_mutex_impl<spinloop>::wait(uint32_t lk)
template void ssux_lock_impl<true>::wr_unlock(); {
template void ssux_lock_impl<true>::write_lock(bool); pthread_mutex_lock(&mutex);
template void ssux_lock_impl<true>::update_lock(uint32_t); while (lock.load(std::memory_order_relaxed) == lk)
#else /* SUX_LOCK_GENERIC */ pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
{
pthread_mutex_lock(&writer.mutex);
while (readers.load(std::memory_order_relaxed) == lk)
pthread_cond_wait(&readers_cond, &writer.mutex);
pthread_mutex_unlock(&writer.mutex);
}
template<bool spinloop>
void srw_mutex_impl<spinloop>::wake()
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
void ssux_lock_impl<spinloop>::wake()
{
pthread_mutex_lock(&writer.mutex);
pthread_cond_signal(&readers_cond);
pthread_mutex_unlock(&writer.mutex);
}
#else
static_assert(4 == sizeof(rw_lock), "ABI"); static_assert(4 == sizeof(rw_lock), "ABI");
# ifdef _WIN32 # ifdef _WIN32
# include <synchapi.h> # include <synchapi.h>
@@ -401,7 +245,7 @@ inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
{ SRW_FUTEX(&readers, WAIT, lk); } { SRW_FUTEX(&readers, WAIT, lk); }
template<bool spinloop> template<bool spinloop>
void ssux_lock_impl<spinloop>::wake() { SRW_FUTEX(&readers, WAKE, 1); } void ssux_lock_impl<spinloop>::wake() { SRW_FUTEX(&readers, WAKE, 1); }
# endif
#endif #endif
template void srw_mutex_impl<false>::wake(); template void srw_mutex_impl<false>::wake();
@@ -425,6 +269,8 @@ assembler code or a Microsoft intrinsic function.
#if defined __clang_major__ && __clang_major__ < 10 #if defined __clang_major__ && __clang_major__ < 10
/* Only clang-10 introduced support for asm goto */ /* Only clang-10 introduced support for asm goto */
#elif defined __APPLE__
/* At least some versions of Apple Xcode do not support asm goto */
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
# define IF_FETCH_OR_GOTO(mem, bit, label) \ # define IF_FETCH_OR_GOTO(mem, bit, label) \
__asm__ goto("lock btsl $" #bit ", %0\n\t" \ __asm__ goto("lock btsl $" #bit ", %0\n\t" \
@@ -441,11 +287,13 @@ assembler code or a Microsoft intrinsic function.
goto label; goto label;
#endif #endif
template<> template<bool spinloop>
void srw_mutex_impl<true>::wait_and_lock() void srw_mutex_impl<spinloop>::wait_and_lock()
{ {
uint32_t lk= 1 + lock.fetch_add(1, std::memory_order_relaxed); uint32_t lk= 1 + lock.fetch_add(1, std::memory_order_relaxed);
if (spinloop)
{
const unsigned delay= srw_pause_delay(); const unsigned delay= srw_pause_delay();
for (auto spin= srv_n_spin_wait_rounds;;) for (auto spin= srv_n_spin_wait_rounds;;)
@@ -468,6 +316,7 @@ void srw_mutex_impl<true>::wait_and_lock()
if (!--spin) if (!--spin)
break; break;
} }
}
for (;;) for (;;)
{ {
@@ -497,35 +346,8 @@ acquired:
} }
} }
template<> template void srw_mutex_impl<false>::wait_and_lock();
void srw_mutex_impl<false>::wait_and_lock() template void srw_mutex_impl<true>::wait_and_lock();
{
for (uint32_t lk= 1 + lock.fetch_add(1, std::memory_order_relaxed);;)
{
DBUG_ASSERT(~HOLDER & lk);
if (lk & HOLDER)
{
wait(lk);
#ifdef IF_FETCH_OR_GOTO
reload:
#endif
lk= lock.load(std::memory_order_relaxed);
}
else
{
#ifdef IF_FETCH_OR_GOTO
static_assert(HOLDER == (1U << 31), "compatibility");
IF_FETCH_OR_GOTO(*this, 31, reload);
#else
if ((lk= lock.fetch_or(HOLDER, std::memory_order_relaxed)) & HOLDER)
continue;
DBUG_ASSERT(lk);
#endif
std::atomic_thread_fence(std::memory_order_acquire);
return;
}
}
}
template<bool spinloop> template<bool spinloop>
void ssux_lock_impl<spinloop>::wr_wait(uint32_t lk) void ssux_lock_impl<spinloop>::wr_wait(uint32_t lk)
@@ -577,7 +399,6 @@ void ssux_lock_impl<spinloop>::rd_wait()
template void ssux_lock_impl<true>::rd_wait(); template void ssux_lock_impl<true>::rd_wait();
template void ssux_lock_impl<false>::rd_wait(); template void ssux_lock_impl<false>::rd_wait();
#endif /* SUX_LOCK_GENERIC */
#if defined _WIN32 || defined SUX_LOCK_GENERIC #if defined _WIN32 || defined SUX_LOCK_GENERIC
template<> void srw_lock_<true>::rd_wait() template<> void srw_lock_<true>::rd_wait()
@@ -698,18 +519,6 @@ void ssux_lock::psi_wr_lock(const char *file, unsigned line)
void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line) void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line)
{ {
PSI_rwlock_locker_state state; PSI_rwlock_locker_state state;
# ifdef SUX_LOCK_GENERIC
const bool nowait= lock.upgrade_trylock();
if (PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)
(&state, pfs_psi,
nowait ? PSI_RWLOCK_TRYEXCLUSIVELOCK : PSI_RWLOCK_EXCLUSIVELOCK,
file, line))
{
if (!nowait)
lock.write_lock(true);
PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0);
}
# else /* SUX_LOCK_GENERIC */
DBUG_ASSERT(lock.writer.is_locked()); DBUG_ASSERT(lock.writer.is_locked());
uint32_t lk= 1; uint32_t lk= 1;
const bool nowait= const bool nowait=
@@ -725,18 +534,12 @@ void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line)
lock.u_wr_upgrade(); lock.u_wr_upgrade();
PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0); PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0);
} }
# endif /* SUX_LOCK_GENERIC */
else if (!nowait) else if (!nowait)
lock.u_wr_upgrade(); lock.u_wr_upgrade();
} }
#else /* UNIV_PFS_RWLOCK */ #else /* UNIV_PFS_RWLOCK */
template void ssux_lock_impl<false>::rd_lock(); template void ssux_lock_impl<false>::rd_lock();
# ifdef SUX_LOCK_GENERIC
template void ssux_lock_impl<false>::write_lock(bool);
template void ssux_lock_impl<false>::update_lock(uint32_t);
# else
template void ssux_lock_impl<false>::rd_unlock(); template void ssux_lock_impl<false>::rd_unlock();
template void ssux_lock_impl<false>::u_unlock(); template void ssux_lock_impl<false>::u_unlock();
template void ssux_lock_impl<false>::wr_unlock(); template void ssux_lock_impl<false>::wr_unlock();
# endif
#endif /* UNIV_PFS_RWLOCK */ #endif /* UNIV_PFS_RWLOCK */

View File

@@ -8935,21 +8935,24 @@ void translog_hard_group_commit(my_bool mode)
*/ */
void translog_sync() void translog_sync()
{
DBUG_ENTER("ma_translog_sync");
/* The following is only true if initalization of translog succeded */
if (log_descriptor.open_files.elements != 0)
{ {
uint32 max= get_current_logfile()->number; uint32 max= get_current_logfile()->number;
uint32 min; uint32 min;
DBUG_ENTER("ma_translog_sync");
min= soft_sync_min; min= soft_sync_min;
if (!min) if (!min)
min= max; min= max;
translog_sync_files(min, max, sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS); translog_sync_files(min, max, sync_log_dir >= TRANSLOG_SYNC_DIR_ALWAYS);
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/** /**
@brief set rate for group commit @brief set rate for group commit