Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä 2020-05-26 11:54:55 +03:00
commit ca38b6e427
47 changed files with 1104 additions and 347 deletions

View File

@ -787,6 +787,7 @@ static ha_checksum checksum_format_specifier(const char* msg)
case 'x': case 'x':
case 's': case 's':
case 'M': case 'M':
case 'T':
chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start)); chksum= my_checksum(chksum, (uchar*) start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */ start= 0; /* Not in format specifier anymore */
break; break;

View File

@ -55,7 +55,8 @@
Supported formats are 's' (null pointer is accepted, printed as Supported formats are 's' (null pointer is accepted, printed as
"(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o', "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o',
'X', 'p' (works as 0x%x), 'f', 'g', 'M' (extension, see below). 'X', 'p' (works as 0x%x), 'f', 'g', 'M' (extension, see below),
'T' (extension, see below).
Standard syntax for positional arguments $n is supported. Standard syntax for positional arguments $n is supported.
@ -69,6 +70,9 @@
Format 'M': takes one integer, prints this integer, space, double quote Format 'M': takes one integer, prints this integer, space, double quote
error message, double quote. In other words error message, double quote. In other words
printf("%M", n) === printf("%d \"%s\"", n, strerror(n)) printf("%M", n) === printf("%d \"%s\"", n, strerror(n))
Format 'T': takes string and print it like s but if the strints should be
truncated puts "..." at the end.
*/ */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -3172,5 +3172,147 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and weight_string(`test`.`t1`.`a`,0,0,1) = 'a' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and weight_string(`test`.`t1`.`a`,0,0,1) = 'a'
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
#
CREATE TABLE t1(a ENUM(0x6100,0x6200,0x6300) CHARACTER SET 'Binary');
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a\0','b\0','c\0') CHARACTER SET binary DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1),(2),(3);
SELECT HEX(a) FROM t1 ORDER BY a;
HEX(a)
6100
6200
6300
DROP TABLE t1;
0x00 in the middle or in the end of a value
CREATE TABLE t1 (a ENUM(0x6100));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a\0') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1);
SELECT HEX(a) FROM t1;
HEX(a)
6100
DROP TABLE t1;
CREATE TABLE t1 (a ENUM(0x610062));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a\0b') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1);
SELECT HEX(a) FROM t1;
HEX(a)
610062
DROP TABLE t1;
0x00 in the beginning of the first value:
CREATE TABLE t1 (a ENUM(0x0061));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('\0a') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(1);
SELECT HEX(a) FROM t1;
HEX(a)
0061
DROP TABLE t1;
CREATE TABLE t1 (a ENUM(0x0061), b ENUM('b'));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('\0a') DEFAULT NULL,
`b` enum('b') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1,1);
SELECT HEX(a), HEX(b) FROM t1;
HEX(a) HEX(b)
0061 62
DROP TABLE t1;
# 0x00 in the beginning of the second (and following) value of the *last* ENUM/SET in the table:
CREATE TABLE t1 (a ENUM('a',0x0061));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a','\0a') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1),(2);
SELECT HEX(a) FROM t1 ORDER BY a;
HEX(a)
61
0061
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a'), b ENUM('b',0x0061));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('a') DEFAULT NULL,
`b` enum('b','\0a') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,2);
SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
HEX(a) HEX(b)
61 62
61 0061
DROP TABLE t1;
0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b'));
ERROR HY000: Incorrect information in file: 'DIR/t1.frm'
#
# End of 10.1 tests # End of 10.1 tests
# #
#
# Start of 10.2 tests
#
#
# MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
# 10.2 tests
#
SET NAMES latin1;
CREATE TABLE t1(c ENUM(0x0061) CHARACTER SET 'Binary', d JSON);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a') CHARACTER SET binary DEFAULT NULL,
`d` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`d`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
HEX(c)
0061
DROP TABLE t1;
CREATE TABLE t1(
c ENUM(0x0061) CHARACTER SET 'Binary',
d INT DEFAULT NULL CHECK (d>0)
);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a') CHARACTER SET binary DEFAULT NULL,
`d` int(11) DEFAULT NULL CHECK (`d` > 0)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1,1);
SELECT HEX(c), d FROM t1;
HEX(c) d
0061 1
DROP TABLE t1;
CREATE TABLE t1(c ENUM(0x0061) CHARACTER SET 'Binary' CHECK (c>0));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a') CHARACTER SET binary DEFAULT NULL CHECK (`c` > 0)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1);
SELECT HEX(c) FROM t1;
HEX(c)
0061
DROP TABLE t1;
#
# End of 10.2 tests
#

View File

@ -74,6 +74,107 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a';
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
--echo #
CREATE TABLE t1(a ENUM(0x6100,0x6200,0x6300) CHARACTER SET 'Binary');
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1),(2),(3);
SELECT HEX(a) FROM t1 ORDER BY a;
DROP TABLE t1;
--echo 0x00 in the middle or in the end of a value
CREATE TABLE t1 (a ENUM(0x6100));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1);
SELECT HEX(a) FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM(0x610062));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1);
SELECT HEX(a) FROM t1;
DROP TABLE t1;
--echo 0x00 in the beginning of the first value:
CREATE TABLE t1 (a ENUM(0x0061));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES(1);
SELECT HEX(a) FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM(0x0061), b ENUM('b'));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,1);
SELECT HEX(a), HEX(b) FROM t1;
DROP TABLE t1;
--echo # 0x00 in the beginning of the second (and following) value of the *last* ENUM/SET in the table:
CREATE TABLE t1 (a ENUM('a',0x0061));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1),(2);
SELECT HEX(a) FROM t1 ORDER BY a;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a'), b ENUM('b',0x0061));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,2);
SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
DROP TABLE t1;
--echo 0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
--replace_regex /'.*t1.frm'/'DIR\/t1.frm'/
--error ER_NOT_FORM_FILE
CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b'));
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
--echo #
--echo # Start of 10.2 tests
--echo #
--echo #
--echo # MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
--echo # 10.2 tests
--echo #
SET NAMES latin1;
CREATE TABLE t1(c ENUM(0x0061) CHARACTER SET 'Binary', d JSON);
SHOW CREATE TABLE t1;
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
DROP TABLE t1;
CREATE TABLE t1(
c ENUM(0x0061) CHARACTER SET 'Binary',
d INT DEFAULT NULL CHECK (d>0)
);
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1,1);
SELECT HEX(c), d FROM t1;
DROP TABLE t1;
CREATE TABLE t1(c ENUM(0x0061) CHARACTER SET 'Binary' CHECK (c>0));
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1);
SELECT HEX(c) FROM t1;
DROP TABLE t1;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -7899,5 +7899,46 @@ a b
DROP TABLE t1; DROP TABLE t1;
SET NAMES utf8; SET NAMES utf8;
# #
# MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
# 10.2 tests
#
SET NAMES utf8, COLLATION_CONNECTION=utf16_hungarian_ci;
CREATE TABLE t1(c ENUM('aaaaaaaa') CHARACTER SET 'Binary',d JSON);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a\0a\0a\0a\0a\0a\0a\0a') CHARACTER SET binary DEFAULT NULL,
`d` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`d`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
HEX(c)
00610061006100610061006100610061
DROP TABLE t1;
CREATE OR REPLACE TABLE t1(c ENUM('aaaaaaaaa') CHARACTER SET 'Binary',d JSON);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a\0a\0a\0a\0a\0a\0a\0a\0a') CHARACTER SET binary DEFAULT NULL,
`d` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`d`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
HEX(c)
006100610061006100610061006100610061
DROP TABLE t1;
CREATE OR REPLACE TABLE t1(c ENUM('aaaaaaaaaa') CHARACTER SET 'Binary',d JSON);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` enum('\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a') CHARACTER SET binary DEFAULT NULL,
`d` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`d`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
HEX(c)
0061006100610061006100610061006100610061
DROP TABLE t1;
#
# End of 10.2 tests # End of 10.2 tests
# #

View File

@ -243,6 +243,31 @@ SET NAMES utf8, collation_connection=utf16_unicode_520_nopad_ci;
SET NAMES utf8; SET NAMES utf8;
--echo #
--echo # MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
--echo # 10.2 tests
--echo #
SET NAMES utf8, COLLATION_CONNECTION=utf16_hungarian_ci;
CREATE TABLE t1(c ENUM('aaaaaaaa') CHARACTER SET 'Binary',d JSON); # ERROR 1064 (42000): You have an error in your SQL syntax
SHOW CREATE TABLE t1;
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
DROP TABLE t1;
CREATE OR REPLACE TABLE t1(c ENUM('aaaaaaaaa') CHARACTER SET 'Binary',d JSON); # ERROR 1033 (HY000): Incorrect information in file: './test/t.frm'
SHOW CREATE TABLE t1;
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
DROP TABLE t1;
CREATE OR REPLACE TABLE t1(c ENUM('aaaaaaaaaa') CHARACTER SET 'Binary',d JSON); # Sig 11
SHOW CREATE TABLE t1;
INSERT INTO t1 (c) VALUES (1);
SELECT HEX(c) FROM t1;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #

View File

@ -2868,5 +2868,25 @@ DROP TABLE t1;
# #
SET STORAGE_ENGINE=Default; SET STORAGE_ENGINE=Default;
# #
# MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
# 10.2 tests
#
SET NAMES utf8, COLLATION_CONNECTION=utf32_bin;
CREATE TABLE t1(c1 ENUM('a','b','ac') CHARACTER SET 'Binary',c2 JSON,c3 INT);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` enum('\0\0\0a','\0\0\0b','\0\0\0a\0\0\0c') CHARACTER SET binary DEFAULT NULL,
`c2` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`c2`)),
`c3` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (c1) VALUES (1),(2),(3);
SELECT HEX(c1) FROM t1 ORDER BY c1;
HEX(c1)
00000061
00000062
0000006100000063
DROP TABLE t1;
#
# End of 10.2 tests # End of 10.2 tests
# #

View File

@ -1035,6 +1035,19 @@ let $coll='utf32_nopad_bin';
let $coll_pad='utf32_bin'; let $coll_pad='utf32_bin';
--source include/ctype_pad_all_engines.inc --source include/ctype_pad_all_engines.inc
--echo #
--echo # MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
--echo # 10.2 tests
--echo #
SET NAMES utf8, COLLATION_CONNECTION=utf32_bin;
CREATE TABLE t1(c1 ENUM('a','b','ac') CHARACTER SET 'Binary',c2 JSON,c3 INT);
SHOW CREATE TABLE t1;
INSERT INTO t1 (c1) VALUES (1),(2),(3);
SELECT HEX(c1) FROM t1 ORDER BY c1;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #

View File

@ -506,3 +506,17 @@ disconnect con1;
connection default; connection default;
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# MDEV-21398 Deadlock (server hang) or assertion failure in
# Diagnostics_area::set_error_status upon ALTER under lock
#
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 WRITE, t1 AS t1a READ;
ALTER TABLE t1 CHANGE COLUMN IF EXISTS x xx INT;
Warnings:
Note 1054 Unknown column 'x' in 't1'
UNLOCK TABLES;
DROP TABLE t1;
#
# End of 10.2 tests
#

View File

@ -619,3 +619,17 @@ UNLOCK TABLES;
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1, t2; DROP TABLE t1, t2;
--echo #
--echo # MDEV-21398 Deadlock (server hang) or assertion failure in
--echo # Diagnostics_area::set_error_status upon ALTER under lock
--echo #
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 WRITE, t1 AS t1a READ;
ALTER TABLE t1 CHANGE COLUMN IF EXISTS x xx INT;
UNLOCK TABLES;
DROP TABLE t1;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@ -3760,7 +3760,7 @@ DROP TABLE t1;
# #
CREATE TABLE t1(a int); CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2); INSERT INTO t1 VALUES (1), (2);
mysqldump: Input filename too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... mysqldump: Input filename too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t2 (a INT) ENGINE=MyISAM; CREATE TABLE t2 (a INT) ENGINE=MyISAM;
CREATE TABLE t3 (a INT) ENGINE=MyISAM; CREATE TABLE t3 (a INT) ENGINE=MyISAM;

View File

@ -2,6 +2,6 @@ MariaDB error code 150: Foreign key constraint is incorrectly formed
Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.
OS error code 23: Too many open files in system OS error code 23: Too many open files in system
Win32 error code 23: Data error (cyclic redundancy check). Win32 error code 23: Data error (cyclic redundancy check).
MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192s' for key %d MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192T' for key %d
Win32 error code 1062: The service has not been started. Win32 error code 1062: The service has not been started.
Illegal error code: 30000 Illegal error code: 30000

View File

@ -1,5 +1,5 @@
Illegal error code: 10000 Illegal error code: 10000
MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192s' for key %d MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192T' for key %d
MariaDB error code 1408 (ER_STARTUP): %s: ready for connections. MariaDB error code 1408 (ER_STARTUP): %s: ready for connections.
Version: '%s' socket: '%s' port: %d %s Version: '%s' socket: '%s' port: %d %s
MariaDB error code 1459 (ER_TABLE_NEEDS_UPGRADE): Upgrade required. Please do "REPAIR %s %`s" or dump/reload to fix it! MariaDB error code 1459 (ER_TABLE_NEEDS_UPGRADE): Upgrade required. Please do "REPAIR %s %`s" or dump/reload to fix it!

View File

@ -3724,6 +3724,25 @@ MAX(1) OVER () COUNT(a) abs(a)
1 0 NULL 1 0 NULL
drop table t1; drop table t1;
# #
# MDEV-22461: JOIN::make_aggr_tables_info(): Assertion `select_options & (1ULL << 17)' failed.
#
CREATE TEMPORARY TABLE t0 (a INT PRIMARY KEY ) ;
INSERT INTO t0 VALUES (1),(2),(3);
SELECT a FROM t0
WHERE a < 8
GROUP BY 1.5
WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
a
1
SELECT a, ROW_NUMBER() OVER v2
FROM t0
WHERE a < 8
GROUP BY 1.5
WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
a ROW_NUMBER() OVER v2
1 1
drop table t0;
#
# End of 10.2 tests # End of 10.2 tests
# #
# #

View File

@ -2426,6 +2426,26 @@ SELECT MAX(1) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE;
drop table t1; drop table t1;
--echo #
--echo # MDEV-22461: JOIN::make_aggr_tables_info(): Assertion `select_options & (1ULL << 17)' failed.
--echo #
CREATE TEMPORARY TABLE t0 (a INT PRIMARY KEY ) ;
INSERT INTO t0 VALUES (1),(2),(3);
SELECT a FROM t0
WHERE a < 8
GROUP BY 1.5
WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
SELECT a, ROW_NUMBER() OVER v2
FROM t0
WHERE a < 8
GROUP BY 1.5
WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
drop table t0;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #

View File

@ -345,3 +345,16 @@ connection default;
XA END 'xid1'; XA END 'xid1';
XA ROLLBACK 'xid1'; XA ROLLBACK 'xid1';
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
XA BEGIN 'xid';
CREATE TEMPORARY SEQUENCE s;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
XA END 'xid';
XA ROLLBACK 'xid';
XA BEGIN 'xid';
CREATE SEQUENCE s;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
XA END 'xid';
XA ROLLBACK 'xid';
#
# End of 10.3 tests
#

View File

@ -478,3 +478,29 @@ DROP TABLE t1, t2, t3;
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
#
# MDEV-22002 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())'
# failed upon CREATE TEMPORARY SEQUENCE under XA
#
XA BEGIN 'xid';
--error ER_XAER_RMFAIL
CREATE TEMPORARY SEQUENCE s;
XA END 'xid';
XA ROLLBACK 'xid';
XA BEGIN 'xid';
--error ER_XAER_RMFAIL
CREATE SEQUENCE s;
XA END 'xid';
XA ROLLBACK 'xid';
--echo #
--echo # End of 10.3 tests
--echo #

View File

@ -106,7 +106,7 @@ RAISE dup_val_on_index;
END; END;
$$ $$
CALL p1(); CALL p1();
ERROR 23000: Duplicate entry '%-.192s' for key %d ERROR 23000: Duplicate entry '%-.192T' for key %d
DROP PROCEDURE p1; DROP PROCEDURE p1;
CREATE PROCEDURE p1 CREATE PROCEDURE p1
AS AS

View File

@ -152,3 +152,41 @@ SELECT * FROM t1;
a b d a b d
1 NULL NULL 1 NULL NULL
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-22637 Rollback of insert fails when column reorder happens
#
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_TRANS_TABLES', '');
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_ALL_TABLES', '');
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100), f4 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "This is column2", "This is column3",
"This is column4");
set DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
ALTER TABLE t1 ADD COLUMN f6 int after f3, add primary key(f6, f4(3), f3(3));
connect con1,localhost,root,,;
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
BEGIN;
INSERT INTO t1(f1, f2) VALUES(2, "This is column2 value");
ROLLBACK;
set DEBUG_SYNC = 'now SIGNAL insert_done';
connection default;
Warnings:
Warning 1265 Data truncated for column 'f3' at row 3
Warning 1265 Data truncated for column 'f4' at row 3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` char(100) DEFAULT NULL,
`f3` char(100) NOT NULL,
`f6` int(11) NOT NULL,
`f4` char(100) NOT NULL,
PRIMARY KEY (`f6`,`f4`(3),`f3`(3))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
SELECT COUNT(*) FROM t1;
COUNT(*)
1
disconnect con1;
DROP TABLE t1;
SET DEBUG_SYNC = 'RESET';
SET SQL_MODE=DEFAULT;

View File

@ -196,3 +196,30 @@ SHOW CREATE TABLE t1;
UPDATE t1 SET d=NULL; UPDATE t1 SET d=NULL;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-22637 Rollback of insert fails when column reorder happens
--echo #
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_TRANS_TABLES', '');
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_ALL_TABLES', '');
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100), f4 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "This is column2", "This is column3",
"This is column4");
set DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
--send ALTER TABLE t1 ADD COLUMN f6 int after f3, add primary key(f6, f4(3), f3(3))
connect(con1,localhost,root,,);
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
BEGIN;
INSERT INTO t1(f1, f2) VALUES(2, "This is column2 value");
ROLLBACK;
set DEBUG_SYNC = 'now SIGNAL insert_done';
connection default;
reap;
SHOW CREATE TABLE t1;
SELECT COUNT(*) FROM t1;
disconnect con1;
DROP TABLE t1;
SET DEBUG_SYNC = 'RESET';
SET SQL_MODE=DEFAULT;

View File

@ -11,7 +11,7 @@ drop table t1;
connection slave; connection slave;
include/wait_for_slave_sql_to_stop.inc include/wait_for_slave_sql_to_stop.inc
call mtr.add_suppression("Slave SQL.*Query caused different errors on master and slave.*Error on master:.* error code=1062.*Error on slave:.* error.* 0"); call mtr.add_suppression("Slave SQL.*Query caused different errors on master and slave.*Error on master:.* error code=1062.*Error on slave:.* error.* 0");
Error: "Query caused different errors on master and slave. Error on master: message (format)='Duplicate entry '%-.192s' for key %d' error code=1062 ; Error on slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave) Error: "Query caused different errors on master and slave. Error on master: message (format)='Duplicate entry '%-.192T' for key %d' error code=1062 ; Error on slave: actual message='no error', error code=0. Default database: 'test'. Query: 'insert into t1 values(1),(2)'" (expected different error codes on master and slave)
Errno: "0" (expected 0) Errno: "0" (expected 0)
drop table t1; drop table t1;
include/stop_slave.inc include/stop_slave.inc

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2017, Aliyun and/or its affiliates. Copyright (c) 2017, Aliyun and/or its affiliates.
Copyright (c) 2017, MariaDB corporation Copyright (c) 2017, 2020, 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,7 +115,7 @@ int ha_sequence::open(const char *name, int mode, uint flags)
file->ha_close(); file->ha_close();
} }
else if (!table->s->tmp_table) else if (!table->s->tmp_table)
table->m_needs_reopen= true; table->internal_set_needs_reopen(true);
/* /*
The following is needed to fix comparison of rows in The following is needed to fix comparison of rows in

View File

@ -6846,8 +6846,8 @@ Item_float::Item_float(THD *thd, const char *str_arg, size_t length):
&error); &error);
if (unlikely(error)) if (unlikely(error))
{ {
char tmp[NAME_LEN + 1]; char tmp[NAME_LEN + 2];
my_snprintf(tmp, sizeof(tmp), "%.*s", (int)length, str_arg); my_snprintf(tmp, sizeof(tmp), "%.*s", static_cast<int>(length), str_arg);
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp);
} }
presentation= name.str= str_arg; presentation= name.str= str_arg;

View File

@ -1017,11 +1017,16 @@ static Item *create_comparator(MY_XPATH *xpath,
b->fixed_type_handler() == &type_handler_xpath_nodeset) b->fixed_type_handler() == &type_handler_xpath_nodeset)
{ {
uint len= (uint)(xpath->query.end - context->beg); uint len= (uint)(xpath->query.end - context->beg);
set_if_smaller(len, 32); if (len <= 32)
my_printf_error(ER_UNKNOWN_ERROR, my_printf_error(ER_UNKNOWN_ERROR,
"XPATH error: " "XPATH error: "
"comparison of two nodesets is not supported: '%.*s'", "comparison of two nodesets is not supported: '%.*s'",
MYF(0), len, context->beg); MYF(0), len, context->beg);
else
my_printf_error(ER_UNKNOWN_ERROR,
"XPATH error: "
"comparison of two nodesets is not supported: '%.32T'",
MYF(0), context->beg);
return 0; // TODO: Comparison of two nodesets return 0; // TODO: Comparison of two nodesets
} }
@ -2674,9 +2679,12 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath)
xpath->item= NULL; xpath->item= NULL;
DBUG_ASSERT(xpath->query.end > dollar_pos); DBUG_ASSERT(xpath->query.end > dollar_pos);
uint len= (uint)(xpath->query.end - dollar_pos); uint len= (uint)(xpath->query.end - dollar_pos);
set_if_smaller(len, 32); if (len <= 32)
my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.*s'", my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.*s'",
MYF(0), len, dollar_pos); MYF(0), len, dollar_pos);
else
my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.32T'",
MYF(0), dollar_pos);
} }
} }
return xpath->item ? 1 : 0; return xpath->item ? 1 : 0;
@ -2807,9 +2815,13 @@ bool Item_xml_str_func::fix_fields(THD *thd, Item **ref)
if (!rc) if (!rc)
{ {
uint clen= (uint)(xpath.query.end - xpath.lasttok.beg); uint clen= (uint)(xpath.query.end - xpath.lasttok.beg);
set_if_smaller(clen, 32); if (clen <= 32)
my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%.*s'", my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%.*s'",
MYF(0), clen, xpath.lasttok.beg); MYF(0), clen, xpath.lasttok.beg);
else
my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%.32T'",
MYF(0), xpath.lasttok.beg);
return true; return true;
} }

View File

@ -1197,30 +1197,30 @@ ER_TABLE_EXISTS_ERROR 42S01
swe "Tabellen '%-.192s' finns redan" swe "Tabellen '%-.192s' finns redan"
ukr "Таблиця '%-.192s' вже існує" ukr "Таблиця '%-.192s' вже існує"
ER_BAD_TABLE_ERROR 42S02 ER_BAD_TABLE_ERROR 42S02
cze "Neznámá tabulka '%-.100s'" cze "Neznámá tabulka '%-.100T'"
dan "Ukendt tabel '%-.100s'" dan "Ukendt tabel '%-.100T'"
nla "Onbekende tabel '%-.100s'" nla "Onbekende tabel '%-.100T'"
eng "Unknown table '%-.100s'" eng "Unknown table '%-.100T'"
est "Tundmatu tabel '%-.100s'" est "Tundmatu tabel '%-.100T'"
fre "Table '%-.100s' inconnue" fre "Table '%-.100T' inconnue"
ger "Unbekannte Tabelle '%-.100s'" ger "Unbekannte Tabelle '%-.100T'"
greek "Αγνωστος πίνακας '%-.100s'" greek "Αγνωστος πίνακας '%-.100T'"
hindi "अज्ञात टेबल '%-.100s'" hindi "अज्ञात टेबल '%-.100T'"
hun "Ervenytelen tabla: '%-.100s'" hun "Ervenytelen tabla: '%-.100T'"
ita "Tabella '%-.100s' sconosciuta" ita "Tabella '%-.100T' sconosciuta"
jpn "'%-.100s' は不明な表です。" jpn "'%-.100T' は不明な表です。"
kor "테이블 '%-.100s'는 알수 없음" kor "테이블 '%-.100T'는 알수 없음"
nor "Ukjent tabell '%-.100s'" nor "Ukjent tabell '%-.100T'"
norwegian-ny "Ukjent tabell '%-.100s'" norwegian-ny "Ukjent tabell '%-.100T'"
pol "Nieznana tabela '%-.100s'" pol "Nieznana tabela '%-.100T'"
por "Tabela '%-.100s' desconhecida" por "Tabela '%-.100T' desconhecida"
rum "Tabela '%-.100s' este invalida" rum "Tabela '%-.100T' este invalida"
rus "Неизвестная таблица '%-.100s'" rus "Неизвестная таблица '%-.100T'"
serbian "Nepoznata tabela '%-.100s'" serbian "Nepoznata tabela '%-.100T'"
slo "Neznáma tabuľka '%-.100s'" slo "Neznáma tabuľka '%-.100T'"
spa "Tabla '%-.100s' desconocida" spa "Tabla '%-.100T' desconocida"
swe "Okänd tabell '%-.100s'" swe "Okänd tabell '%-.100T'"
ukr "Невідома таблиця '%-.100s'" ukr "Невідома таблиця '%-.100T'"
ER_NON_UNIQ_ERROR 23000 ER_NON_UNIQ_ERROR 23000
cze "Sloupec '%-.192s' v %-.192s není zcela jasný" cze "Sloupec '%-.192s' v %-.192s není zcela jasný"
dan "Felt: '%-.192s' i tabel %-.192s er ikke entydigt" dan "Felt: '%-.192s' i tabel %-.192s er ikke entydigt"
@ -1394,30 +1394,30 @@ ER_WRONG_VALUE_COUNT 21S01
swe "Antalet kolumner motsvarar inte antalet värden" swe "Antalet kolumner motsvarar inte antalet värden"
ukr "Кількість стовбців не співпадає з кількістю значень" ukr "Кількість стовбців не співпадає з кількістю значень"
ER_TOO_LONG_IDENT 42000 S1009 ER_TOO_LONG_IDENT 42000 S1009
cze "Jméno identifikátoru '%-.100s' je příliš dlouhé" cze "Jméno identifikátoru '%-.100T' je příliš dlouhé"
dan "Navnet '%-.100s' er for langt" dan "Navnet '%-.100T' er for langt"
nla "Naam voor herkenning '%-.100s' is te lang" nla "Naam voor herkenning '%-.100T' is te lang"
eng "Identifier name '%-.100s' is too long" eng "Identifier name '%-.100T' is too long"
est "Identifikaatori '%-.100s' nimi on liiga pikk" est "Identifikaatori '%-.100T' nimi on liiga pikk"
fre "Le nom de l'identificateur '%-.100s' est trop long" fre "Le nom de l'identificateur '%-.100T' est trop long"
ger "Name des Bezeichners '%-.100s' ist zu lang" ger "Name des Bezeichners '%-.100T' ist zu lang"
greek "Το identifier name '%-.100s' είναι πολύ μεγάλο" greek "Το identifier name '%-.100T' είναι πολύ μεγάλο"
hindi "पहचानकर्ता का नाम '%-.100s' बहुत लंबा है" hindi "पहचानकर्ता का नाम '%-.100T' बहुत लंबा है"
hun "A(z) '%-.100s' azonositonev tul hosszu" hun "A(z) '%-.100T' azonositonev tul hosszu"
ita "Il nome dell'identificatore '%-.100s' e` troppo lungo" ita "Il nome dell'identificatore '%-.100T' e` troppo lungo"
jpn "識別子名 '%-.100s' は長すぎます。" jpn "識別子名 '%-.100T' は長すぎます。"
kor "Identifier '%-.100s'는 너무 길군요." kor "Identifier '%-.100T'는 너무 길군요."
nor "Identifikator '%-.100s' er for lang" nor "Identifikator '%-.100T' er for lang"
norwegian-ny "Identifikator '%-.100s' er for lang" norwegian-ny "Identifikator '%-.100T' er for lang"
pol "Nazwa identyfikatora '%-.100s' jest zbyt długa" pol "Nazwa identyfikatora '%-.100T' jest zbyt długa"
por "Nome identificador '%-.100s' é longo demais" por "Nome identificador '%-.100T' é longo demais"
rum "Numele indentificatorului '%-.100s' este prea lung" rum "Numele indentificatorului '%-.100T' este prea lung"
rus "Слишком длинный идентификатор '%-.100s'" rus "Слишком длинный идентификатор '%-.100T'"
serbian "Ime '%-.100s' je predugačko" serbian "Ime '%-.100T' je predugačko"
slo "Meno identifikátora '%-.100s' je príliš dlhé" slo "Meno identifikátora '%-.100T' je príliš dlhé"
spa "El nombre del identificador '%-.100s' es demasiado grande" spa "El nombre del identificador '%-.100T' es demasiado grande"
swe "Kolumnnamn '%-.100s' är för långt" swe "Kolumnnamn '%-.100T' är för långt"
ukr "Ім'я ідентифікатора '%-.100s' задовге" ukr "Ім'я ідентифікатора '%-.100T' задовге"
ER_DUP_FIELDNAME 42S21 S1009 ER_DUP_FIELDNAME 42S21 S1009
cze "Zdvojené jméno sloupce '%-.192s'" cze "Zdvojené jméno sloupce '%-.192s'"
dan "Feltnavnet '%-.192s' findes allerede" dan "Feltnavnet '%-.192s' findes allerede"
@ -1471,30 +1471,30 @@ ER_DUP_KEYNAME 42000 S1009
# When using this error code, please use ER(ER_DUP_ENTRY_WITH_KEY_NAME) # When using this error code, please use ER(ER_DUP_ENTRY_WITH_KEY_NAME)
# for the message string. See, for example, code in handler.cc. # for the message string. See, for example, code in handler.cc.
ER_DUP_ENTRY 23000 S1009 ER_DUP_ENTRY 23000 S1009
cze "Zdvojený klíč '%-.192s' (číslo klíče %d)" cze "Zdvojený klíč '%-.192T' (číslo klíče %d)"
dan "Ens værdier '%-.192s' for indeks %d" dan "Ens værdier '%-.192T' for indeks %d"
nla "Dubbele ingang '%-.192s' voor zoeksleutel %d" nla "Dubbele ingang '%-.192T' voor zoeksleutel %d"
eng "Duplicate entry '%-.192s' for key %d" eng "Duplicate entry '%-.192T' for key %d"
est "Kattuv väärtus '%-.192s' võtmele %d" est "Kattuv väärtus '%-.192T' võtmele %d"
fre "Duplicata du champ '%-.192s' pour la clef %d" fre "Duplicata du champ '%-.192T' pour la clef %d"
ger "Doppelter Eintrag '%-.192s' für Schlüssel %d" ger "Doppelter Eintrag '%-.192T' für Schlüssel %d"
greek "Διπλή εγγραφή '%-.192s' για το κλειδί %d" greek "Διπλή εγγραφή '%-.192T' για το κλειδί %d"
hindi "सामान प्रवेश '%-.192s' KEY %d के लिए" hindi "सामान प्रवेश '%-.192T' KEY %d के लिए"
hun "Duplikalt bejegyzes '%-.192s' a %d kulcs szerint" hun "Duplikalt bejegyzes '%-.192T' a %d kulcs szerint"
ita "Valore duplicato '%-.192s' per la chiave %d" ita "Valore duplicato '%-.192T' per la chiave %d"
jpn "'%-.192s' は索引 %d で重複しています。" jpn "'%-.192T' は索引 %d で重複しています。"
kor "중복된 입력 값 '%-.192s': key %d" kor "중복된 입력 값 '%-.192T': key %d"
nor "Like verdier '%-.192s' for nøkkel %d" nor "Like verdier '%-.192T' for nøkkel %d"
norwegian-ny "Like verdiar '%-.192s' for nykkel %d" norwegian-ny "Like verdiar '%-.192T' for nykkel %d"
pol "Powtórzone wystąpienie '%-.192s' dla klucza %d" pol "Powtórzone wystąpienie '%-.192T' dla klucza %d"
por "Entrada '%-.192s' duplicada para a chave %d" por "Entrada '%-.192T' duplicada para a chave %d"
rum "Cimpul '%-.192s' e duplicat pentru cheia %d" rum "Cimpul '%-.192T' e duplicat pentru cheia %d"
rus "Дублирующаяся запись '%-.192s' по ключу %d" rus "Дублирующаяся запись '%-.192T' по ключу %d"
serbian "Dupliran unos '%-.192s' za ključ '%d'" serbian "Dupliran unos '%-.192T' za ključ '%d'"
slo "Opakovaný kľúč '%-.192s' (číslo kľúča %d)" slo "Opakovaný kľúč '%-.192T' (číslo kľúča %d)"
spa "Entrada duplicada '%-.192s' para la clave %d" spa "Entrada duplicada '%-.192T' para la clave %d"
swe "Dublett '%-.192s' för nyckel %d" swe "Dublett '%-.192T' för nyckel %d"
ukr "Дублюючий запис '%-.192s' для ключа %d" ukr "Дублюючий запис '%-.192T' для ключа %d"
ER_WRONG_FIELD_SPEC 42000 S1009 ER_WRONG_FIELD_SPEC 42000 S1009
cze "Chybná specifikace sloupce '%-.192s'" cze "Chybná specifikace sloupce '%-.192s'"
dan "Forkert kolonnespecifikaton for felt '%-.192s'" dan "Forkert kolonnespecifikaton for felt '%-.192s'"
@ -1521,30 +1521,30 @@ ER_WRONG_FIELD_SPEC 42000 S1009
swe "Felaktigt kolumntyp för kolumn '%-.192s'" swe "Felaktigt kolumntyp för kolumn '%-.192s'"
ukr "Невірний специфікатор стовбця '%-.192s'" ukr "Невірний специфікатор стовбця '%-.192s'"
ER_PARSE_ERROR 42000 s1009 ER_PARSE_ERROR 42000 s1009
cze "%s blízko '%-.80s' na řádku %d" cze "%s blízko '%-.80T' na řádku %d"
dan "%s nær '%-.80s' på linje %d" dan "%s nær '%-.80T' på linje %d"
nla "%s bij '%-.80s' in regel %d" nla "%s bij '%-.80T' in regel %d"
eng "%s near '%-.80s' at line %d" eng "%s near '%-.80T' at line %d"
est "%s '%-.80s' ligidal real %d" est "%s '%-.80T' ligidal real %d"
fre "%s près de '%-.80s' à la ligne %d" fre "%s près de '%-.80T' à la ligne %d"
ger "%s bei '%-.80s' in Zeile %d" ger "%s bei '%-.80T' in Zeile %d"
greek "%s πλησίον '%-.80s' στη γραμμή %d" greek "%s πλησίον '%-.80T' στη γραμμή %d"
hindi "%s के पास '%-.80s' लाइन %d में" hindi "%s के पास '%-.80T' लाइन %d में"
hun "A %s a '%-.80s'-hez kozeli a %d sorban" hun "A %s a '%-.80T'-hez kozeli a %d sorban"
ita "%s vicino a '%-.80s' linea %d" ita "%s vicino a '%-.80T' linea %d"
jpn "%s : '%-.80s' 付近 %d 行目" jpn "%s : '%-.80T' 付近 %d 行目"
kor "'%s' 에러 같읍니다. ('%-.80s' 명령어 라인 %d)" kor "'%s' 에러 같읍니다. ('%-.80T' 명령어 라인 %d)"
nor "%s nær '%-.80s' på linje %d" nor "%s nær '%-.80T' på linje %d"
norwegian-ny "%s attmed '%-.80s' på line %d" norwegian-ny "%s attmed '%-.80T' på line %d"
pol "%s obok '%-.80s' w linii %d" pol "%s obok '%-.80T' w linii %d"
por "%s próximo a '%-.80s' na linha %d" por "%s próximo a '%-.80T' na linha %d"
rum "%s linga '%-.80s' pe linia %d" rum "%s linga '%-.80T' pe linia %d"
rus "%s около '%-.80s' на строке %d" rus "%s около '%-.80T' на строке %d"
serbian "'%s' u iskazu '%-.80s' na liniji %d" serbian "'%s' u iskazu '%-.80T' na liniji %d"
slo "%s blízko '%-.80s' na riadku %d" slo "%s blízko '%-.80T' na riadku %d"
spa "%s cerca '%-.80s' en la linea %d" spa "%s cerca '%-.80T' en la linea %d"
swe "%s nära '%-.80s' på rad %d" swe "%s nära '%-.80T' på rad %d"
ukr "%s біля '%-.80s' в строці %d" ukr "%s біля '%-.80T' в строці %d"
ER_EMPTY_QUERY 42000 ER_EMPTY_QUERY 42000
cze "Výsledek dotazu je prázdný" cze "Výsledek dotazu je prázdný"
dan "Forespørgsel var tom" dan "Forespørgsel var tom"
@ -2380,30 +2380,30 @@ ER_TABLE_NOT_LOCKED
ER_UNUSED_17 ER_UNUSED_17
eng "You should never see it" eng "You should never see it"
ER_WRONG_DB_NAME 42000 ER_WRONG_DB_NAME 42000
cze "Nepřípustné jméno databáze '%-.100s'" cze "Nepřípustné jméno databáze '%-.100T'"
dan "Ugyldigt database navn '%-.100s'" dan "Ugyldigt database navn '%-.100T'"
nla "Databasenaam '%-.100s' is niet getoegestaan" nla "Databasenaam '%-.100T' is niet getoegestaan"
eng "Incorrect database name '%-.100s'" eng "Incorrect database name '%-.100T'"
est "Vigane andmebaasi nimi '%-.100s'" est "Vigane andmebaasi nimi '%-.100T'"
fre "Nom de base de donnée illégal: '%-.100s'" fre "Nom de base de donnée illégal: '%-.100T'"
ger "Unerlaubter Datenbankname '%-.100s'" ger "Unerlaubter Datenbankname '%-.100T'"
greek "Λάθος όνομα βάσης δεδομένων '%-.100s'" greek "Λάθος όνομα βάσης δεδομένων '%-.100T'"
hindi "डेटाबेस नाम '%-.100s' गलत है" hindi "डेटाबेस नाम '%-.100T' गलत है"
hun "Hibas adatbazisnev: '%-.100s'" hun "Hibas adatbazisnev: '%-.100T'"
ita "Nome database errato '%-.100s'" ita "Nome database errato '%-.100T'"
jpn "データベース名 '%-.100s' は不正です。" jpn "データベース名 '%-.100T' は不正です。"
kor "'%-.100s' 데이타베이스의 이름이 부정확합니다." kor "'%-.100T' 데이타베이스의 이름이 부정확합니다."
nor "Ugyldig database navn '%-.100s'" nor "Ugyldig database navn '%-.100T'"
norwegian-ny "Ugyldig database namn '%-.100s'" norwegian-ny "Ugyldig database namn '%-.100T'"
pol "Niedozwolona nazwa bazy danych '%-.100s'" pol "Niedozwolona nazwa bazy danych '%-.100T'"
por "Nome de banco de dados '%-.100s' incorreto" por "Nome de banco de dados '%-.100T' incorreto"
rum "Numele bazei de date este incorect '%-.100s'" rum "Numele bazei de date este incorect '%-.100T'"
rus "Некорректное имя базы данных '%-.100s'" rus "Некорректное имя базы данных '%-.100T'"
serbian "Pogrešno ime baze '%-.100s'" serbian "Pogrešno ime baze '%-.100T'"
slo "Neprípustné meno databázy '%-.100s'" slo "Neprípustné meno databázy '%-.100T'"
spa "Nombre de base de datos ilegal '%-.100s'" spa "Nombre de base de datos ilegal '%-.100T'"
swe "Felaktigt databasnamn '%-.100s'" swe "Felaktigt databasnamn '%-.100T'"
ukr "Невірне ім'я бази данних '%-.100s'" ukr "Невірне ім'я бази данних '%-.100T'"
ER_WRONG_TABLE_NAME 42000 ER_WRONG_TABLE_NAME 42000
cze "Nepřípustné jméno tabulky '%-.100s'" cze "Nepřípustné jméno tabulky '%-.100s'"
dan "Ugyldigt tabel navn '%-.100s'" dan "Ugyldigt tabel navn '%-.100s'"
@ -4688,15 +4688,15 @@ ER_NO_DEFAULT 42000
spa "Variable '%-.64s' no tiene un valor patrón" spa "Variable '%-.64s' no tiene un valor patrón"
swe "Variabel '%-.64s' har inte ett DEFAULT-värde" swe "Variabel '%-.64s' har inte ett DEFAULT-värde"
ER_WRONG_VALUE_FOR_VAR 42000 ER_WRONG_VALUE_FOR_VAR 42000
nla "Variabele '%-.64s' kan niet worden gewijzigd naar de waarde '%-.200s'" nla "Variabele '%-.64s' kan niet worden gewijzigd naar de waarde '%-.200T'"
eng "Variable '%-.64s' can't be set to the value of '%-.200s'" eng "Variable '%-.64s' can't be set to the value of '%-.200T'"
ger "Variable '%-.64s' kann nicht auf '%-.200s' gesetzt werden" ger "Variable '%-.64s' kann nicht auf '%-.200T' gesetzt werden"
ita "Alla variabile '%-.64s' non puo' essere assegato il valore '%-.200s'" ita "Alla variabile '%-.64s' non puo' essere assegato il valore '%-.200T'"
jpn "変数 '%-.64s' に値 '%-.200s' を設定できません。" jpn "変数 '%-.64s' に値 '%-.200T' を設定できません。"
por "Variável '%-.64s' não pode ser configurada para o valor de '%-.200s'" por "Variável '%-.64s' não pode ser configurada para o valor de '%-.200T'"
rus "Переменная '%-.64s' не может быть установлена в значение '%-.200s'" rus "Переменная '%-.64s' не может быть установлена в значение '%-.200T'"
spa "Variable '%-.64s' no puede ser configurada para el valor de '%-.200s'" spa "Variable '%-.64s' no puede ser configurada para el valor de '%-.200T'"
swe "Variabel '%-.64s' kan inte sättas till '%-.200s'" swe "Variabel '%-.64s' kan inte sättas till '%-.200T'"
ER_WRONG_TYPE_FOR_VAR 42000 ER_WRONG_TYPE_FOR_VAR 42000
nla "Foutief argumenttype voor variabele '%-.64s'" nla "Foutief argumenttype voor variabele '%-.64s'"
eng "Incorrect argument type to variable '%-.64s'" eng "Incorrect argument type to variable '%-.64s'"
@ -5140,11 +5140,11 @@ ER_DUPLICATED_VALUE_IN_TYPE
por "Coluna '%-.100s' tem valor duplicado '%-.64s' em %s" por "Coluna '%-.100s' tem valor duplicado '%-.64s' em %s"
spa "Columna '%-.100s' tiene valor doblado '%-.64s' en %s" spa "Columna '%-.100s' tiene valor doblado '%-.64s' en %s"
ER_TRUNCATED_WRONG_VALUE 22007 ER_TRUNCATED_WRONG_VALUE 22007
eng "Truncated incorrect %-.32s value: '%-.128s'" eng "Truncated incorrect %-.32T value: '%-.128T'"
ger "Falscher %-.32s-Wert gekürzt: '%-.128s'" ger "Falscher %-.32T-Wert gekürzt: '%-.128T'"
jpn "不正な %-.32s の値が切り捨てられました。: '%-.128s'" jpn "不正な %-.32T の値が切り捨てられました。: '%-.128T'"
por "Truncado errado %-.32s valor: '%-.128s'" por "Truncado errado %-.32T valor: '%-.128T'"
spa "Equivocado truncado %-.32s valor: '%-.128s'" spa "Equivocado truncado %-.32T valor: '%-.128T'"
ER_TOO_MUCH_AUTO_TIMESTAMP_COLS ER_TOO_MUCH_AUTO_TIMESTAMP_COLS
eng "Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause" eng "Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
ger "Fehlerhafte Tabellendefinition. Es kann nur eine einzige TIMESTAMP-Spalte mit CURRENT_TIMESTAMP als DEFAULT oder in einer ON-UPDATE-Klausel geben" ger "Fehlerhafte Tabellendefinition. Es kann nur eine einzige TIMESTAMP-Spalte mit CURRENT_TIMESTAMP als DEFAULT oder in einer ON-UPDATE-Klausel geben"
@ -5181,8 +5181,8 @@ ER_WARN_INVALID_TIMESTAMP
eng "Invalid TIMESTAMP value in column '%s' at row %lu" eng "Invalid TIMESTAMP value in column '%s' at row %lu"
ger "Ungültiger TIMESTAMP-Wert in Feld '%s', Zeile %lu" ger "Ungültiger TIMESTAMP-Wert in Feld '%s', Zeile %lu"
ER_INVALID_CHARACTER_STRING ER_INVALID_CHARACTER_STRING
eng "Invalid %s character string: '%.64s'" eng "Invalid %s character string: '%.64T'"
ger "Ungültiger %s-Zeichen-String: '%.64s'" ger "Ungültiger %s-Zeichen-String: '%.64T'"
ER_WARN_ALLOWED_PACKET_OVERFLOWED ER_WARN_ALLOWED_PACKET_OVERFLOWED
eng "Result of %s() was larger than max_allowed_packet (%ld) - truncated" eng "Result of %s() was larger than max_allowed_packet (%ld) - truncated"
ger "Ergebnis von %s() war größer als max_allowed_packet (%ld) Bytes und wurde deshalb gekürzt" ger "Ergebnis von %s() war größer als max_allowed_packet (%ld) Bytes und wurde deshalb gekürzt"
@ -5426,11 +5426,11 @@ ER_DIVISION_BY_ZERO 22012
ger "Division durch 0" ger "Division durch 0"
hindi "0 से विभाजन" hindi "0 से विभाजन"
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD 22007 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD 22007
eng "Incorrect %-.32s value: '%-.128s' for column `%.192s`.`%.192s`.`%.192s` at row %lu" eng "Incorrect %-.32s value: '%-.128T' for column `%.192s`.`%.192s`.`%.192s` at row %lu"
ger "Falscher %-.32s-Wert: '%-.128s' für Feld '`%.192s`.`%.192s`.`%.192s` in Zeile %lu" ger "Falscher %-.32s-Wert: '%-.128T' für Feld '`%.192s`.`%.192s`.`%.192s` in Zeile %lu"
ER_ILLEGAL_VALUE_FOR_TYPE 22007 ER_ILLEGAL_VALUE_FOR_TYPE 22007
eng "Illegal %s '%-.192s' value found during parsing" eng "Illegal %s '%-.192T' value found during parsing"
ger "Nicht zulässiger %s-Wert '%-.192s' beim Parsen gefunden" ger "Nicht zulässiger %s-Wert '%-.192T' beim Parsen gefunden"
ER_VIEW_NONUPD_CHECK ER_VIEW_NONUPD_CHECK
eng "CHECK OPTION on non-updatable view %`-.192s.%`-.192s" eng "CHECK OPTION on non-updatable view %`-.192s.%`-.192s"
ger "CHECK OPTION auf nicht-aktualisierbarem View %`-.192s.%`-.192s" ger "CHECK OPTION auf nicht-aktualisierbarem View %`-.192s.%`-.192s"
@ -5576,8 +5576,8 @@ ER_CANT_CREATE_USER_WITH_GRANT 42000
eng "You are not allowed to create a user with GRANT" eng "You are not allowed to create a user with GRANT"
ger "Sie dürfen keinen Benutzer mit GRANT anlegen" ger "Sie dürfen keinen Benutzer mit GRANT anlegen"
ER_WRONG_VALUE_FOR_TYPE ER_WRONG_VALUE_FOR_TYPE
eng "Incorrect %-.32s value: '%-.128s' for function %-.32s" eng "Incorrect %-.32s value: '%-.128T' for function %-.32s"
ger "Falscher %-.32s-Wert: '%-.128s' für Funktion %-.32s" ger "Falscher %-.32s-Wert: '%-.128T' für Funktion %-.32s"
ER_TABLE_DEF_CHANGED ER_TABLE_DEF_CHANGED
eng "Table definition has changed, please retry transaction" eng "Table definition has changed, please retry transaction"
ger "Tabellendefinition wurde geändert, bitte starten Sie die Transaktion neu" ger "Tabellendefinition wurde geändert, bitte starten Sie die Transaktion neu"
@ -5756,8 +5756,8 @@ ER_HOSTNAME
ger "Hostname" ger "Hostname"
hindi "होस्ट का नाम" hindi "होस्ट का नाम"
ER_WRONG_STRING_LENGTH ER_WRONG_STRING_LENGTH
eng "String '%-.70s' is too long for %s (should be no longer than %d)" eng "String '%-.70T' is too long for %s (should be no longer than %d)"
ger "String '%-.70s' ist zu lang für %s (sollte nicht länger sein als %d)" ger "String '%-.70T' ist zu lang für %s (sollte nicht länger sein als %d)"
ER_NON_INSERTABLE_TABLE ER_NON_INSERTABLE_TABLE
eng "The target table %-.100s of the %s is not insertable-into" eng "The target table %-.100s of the %s is not insertable-into"
ger "Die Zieltabelle %-.100s von %s ist nicht einfügbar" ger "Die Zieltabelle %-.100s von %s ist nicht einfügbar"
@ -5964,8 +5964,8 @@ ER_PLUGIN_IS_NOT_LOADED
eng "Plugin '%-.192s' is not loaded" eng "Plugin '%-.192s' is not loaded"
ger "Plugin '%-.192s' ist nicht geladen" ger "Plugin '%-.192s' ist nicht geladen"
ER_WRONG_VALUE ER_WRONG_VALUE
eng "Incorrect %-.32s value: '%-.128s'" eng "Incorrect %-.32s value: '%-.128T'"
ger "Falscher %-.32s-Wert: '%-.128s'" ger "Falscher %-.32s-Wert: '%-.128T'"
ER_NO_PARTITION_FOR_GIVEN_VALUE ER_NO_PARTITION_FOR_GIVEN_VALUE
eng "Table has no partition for value %-.64s" eng "Table has no partition for value %-.64s"
ger "Tabelle hat für den Wert %-.64s keine Partition" ger "Tabelle hat für den Wert %-.64s keine Partition"
@ -6108,8 +6108,8 @@ ER_WRONG_PARTITION_NAME
ER_CANT_CHANGE_TX_CHARACTERISTICS 25001 ER_CANT_CHANGE_TX_CHARACTERISTICS 25001
eng "Transaction characteristics can't be changed while a transaction is in progress" eng "Transaction characteristics can't be changed while a transaction is in progress"
ER_DUP_ENTRY_AUTOINCREMENT_CASE ER_DUP_ENTRY_AUTOINCREMENT_CASE
eng "ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '%-.192s' for key '%-.192s'" eng "ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '%-.192T' for key '%-.192s'"
ger "ALTER TABLE führt zur Neusequenzierung von auto_increment, wodurch der doppelte Eintrag '%-.192s' für Schlüssel '%-.192s' auftritt" ger "ALTER TABLE führt zur Neusequenzierung von auto_increment, wodurch der doppelte Eintrag '%-.192T' für Schlüssel '%-.192s' auftritt"
ER_EVENT_MODIFY_QUEUE_ERROR ER_EVENT_MODIFY_QUEUE_ERROR
eng "Internal scheduler error %d" eng "Internal scheduler error %d"
ger "Interner Scheduler-Fehler %d" ger "Interner Scheduler-Fehler %d"
@ -6164,29 +6164,29 @@ ER_NATIVE_FCT_NAME_COLLISION
# When using this error message, use the ER_DUP_ENTRY error code. See, for # When using this error message, use the ER_DUP_ENTRY error code. See, for
# example, code in handler.cc. # example, code in handler.cc.
ER_DUP_ENTRY_WITH_KEY_NAME 23000 S1009 ER_DUP_ENTRY_WITH_KEY_NAME 23000 S1009
cze "Zvojený klíč '%-.64s' (číslo klíče '%-.192s')" cze "Zvojený klíč '%-.64T' (číslo klíče '%-.192s')"
dan "Ens værdier '%-.64s' for indeks '%-.192s'" dan "Ens værdier '%-.64T' for indeks '%-.192s'"
nla "Dubbele ingang '%-.64s' voor zoeksleutel '%-.192s'" nla "Dubbele ingang '%-.64T' voor zoeksleutel '%-.192s'"
eng "Duplicate entry '%-.64s' for key '%-.192s'" eng "Duplicate entry '%-.64T' for key '%-.192s'"
est "Kattuv väärtus '%-.64s' võtmele '%-.192s'" est "Kattuv väärtus '%-.64T' võtmele '%-.192s'"
fre "Duplicata du champ '%-.64s' pour la clef '%-.192s'" fre "Duplicata du champ '%-.64T' pour la clef '%-.192s'"
ger "Doppelter Eintrag '%-.64s' für Schlüssel '%-.192s'" ger "Doppelter Eintrag '%-.64T' für Schlüssel '%-.192s'"
greek "Διπλή εγγραφή '%-.64s' για το κλειδί '%-.192s'" greek "Διπλή εγγραφή '%-.64T' για το κλειδί '%-.192s'"
hun "Duplikalt bejegyzes '%-.64s' a '%-.192s' kulcs szerint" hun "Duplikalt bejegyzes '%-.64T' a '%-.192s' kulcs szerint"
ita "Valore duplicato '%-.64s' per la chiave '%-.192s'" ita "Valore duplicato '%-.64T' per la chiave '%-.192s'"
jpn "'%-.64s' は索引 '%-.192s' で重複しています。" jpn "'%-.64T' は索引 '%-.192s' で重複しています。"
kor "중복된 입력 값 '%-.64s': key '%-.192s'" kor "중복된 입력 값 '%-.64T': key '%-.192s'"
nor "Like verdier '%-.64s' for nøkkel '%-.192s'" nor "Like verdier '%-.64T' for nøkkel '%-.192s'"
norwegian-ny "Like verdiar '%-.64s' for nykkel '%-.192s'" norwegian-ny "Like verdiar '%-.64T' for nykkel '%-.192s'"
pol "Powtórzone wystąpienie '%-.64s' dla klucza '%-.192s'" pol "Powtórzone wystąpienie '%-.64T' dla klucza '%-.192s'"
por "Entrada '%-.64s' duplicada para a chave '%-.192s'" por "Entrada '%-.64T' duplicada para a chave '%-.192s'"
rum "Cimpul '%-.64s' e duplicat pentru cheia '%-.192s'" rum "Cimpul '%-.64T' e duplicat pentru cheia '%-.192s'"
rus "Дублирующаяся запись '%-.64s' по ключу '%-.192s'" rus "Дублирующаяся запись '%-.64T' по ключу '%-.192s'"
serbian "Dupliran unos '%-.64s' za ključ '%-.192s'" serbian "Dupliran unos '%-.64T' za ključ '%-.192s'"
slo "Opakovaný kľúč '%-.64s' (číslo kľúča '%-.192s')" slo "Opakovaný kľúč '%-.64T' (číslo kľúča '%-.192s')"
spa "Entrada duplicada '%-.64s' para la clave '%-.192s'" spa "Entrada duplicada '%-.64T' para la clave '%-.192s'"
swe "Dublett '%-.64s' för nyckel '%-.192s'" swe "Dublett '%-.64T' för nyckel '%-.192s'"
ukr "Дублюючий запис '%-.64s' для ключа '%-.192s'" ukr "Дублюючий запис '%-.64T' для ключа '%-.192s'"
ER_BINLOG_PURGE_EMFILE ER_BINLOG_PURGE_EMFILE
eng "Too many files opened, please execute the command again" eng "Too many files opened, please execute the command again"
ger "Zu viele offene Dateien, bitte führen Sie den Befehl noch einmal aus" ger "Zu viele offene Dateien, bitte führen Sie den Befehl noch einmal aus"
@ -6467,8 +6467,8 @@ ER_SLAVE_CANT_CREATE_CONVERSION
ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
eng "Cannot modify @@session.binlog_format inside a transaction" eng "Cannot modify @@session.binlog_format inside a transaction"
ER_PATH_LENGTH ER_PATH_LENGTH
eng "The path specified for %.64s is too long" eng "The path specified for %.64T is too long"
hindi "%.64s के लिए निर्दिष्ट पथ बहुत लंबा है" hindi "%.64T के लिए निर्दिष्ट पथ बहुत लंबा है"
ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT
eng "'%s' is deprecated and will be removed in a future release" eng "'%s' is deprecated and will be removed in a future release"
ger "'%s' ist veraltet und wird in einer zukünftigen Version entfernt werden" ger "'%s' ist veraltet und wird in einer zukünftigen Version entfernt werden"
@ -7168,8 +7168,8 @@ ER_UNKNOWN_OPTION
eng "Unknown option '%-.64s'" eng "Unknown option '%-.64s'"
hindi "अज्ञात विकल्प '%-.64s'" hindi "अज्ञात विकल्प '%-.64s'"
ER_BAD_OPTION_VALUE ER_BAD_OPTION_VALUE
eng "Incorrect value '%-.64s' for option '%-.64s'" eng "Incorrect value '%-.64T' for option '%-.64s'"
hindi "गलत मान '%-.64s' विकल्प '%-.64s' के लिए" hindi "गलत मान '%-.64T' विकल्प '%-.64s' के लिए"
ER_UNUSED_6 ER_UNUSED_6
eng "You should never see it" eng "You should never see it"
ER_UNUSED_7 ER_UNUSED_7
@ -7326,8 +7326,8 @@ ER_ROLE_DROP_EXISTS
ER_CANNOT_CONVERT_CHARACTER ER_CANNOT_CONVERT_CHARACTER
eng "Cannot convert '%s' character 0x%-.64s to '%s'" eng "Cannot convert '%s' character 0x%-.64s to '%s'"
ER_INVALID_DEFAULT_VALUE_FOR_FIELD 22007 ER_INVALID_DEFAULT_VALUE_FOR_FIELD 22007
eng "Incorrect default value '%-.128s' for column '%.192s'" eng "Incorrect default value '%-.128T' for column '%.192s'"
hindi "गलत डिफ़ॉल्ट मान '%-.128s' कॉलम '%.192s' के लिए" hindi "गलत डिफ़ॉल्ट मान '%-.128T' कॉलम '%.192s' के लिए"
ER_KILL_QUERY_DENIED_ERROR ER_KILL_QUERY_DENIED_ERROR
eng "You are not owner of query %lu" eng "You are not owner of query %lu"
ger "Sie sind nicht Eigentümer von Abfrage %lu" ger "Sie sind nicht Eigentümer von Abfrage %lu"

View File

@ -1090,7 +1090,7 @@ send_result_message:
} }
/* Make sure this table instance is not reused after the operation. */ /* Make sure this table instance is not reused after the operation. */
if (table->table) if (table->table)
table->table->m_needs_reopen= true; table->table->mark_table_for_reopen();
} }
result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK; result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
table->next_local= save_next_local; table->next_local= save_next_local;
@ -1215,7 +1215,7 @@ err:
trans_rollback(thd); trans_rollback(thd);
if (table && table->table) if (table && table->table)
{ {
table->table->m_needs_reopen= true; table->table->mark_table_for_reopen();
table->table= 0; table->table= 0;
} }
close_thread_tables(thd); // Shouldn't be needed close_thread_tables(thd); // Shouldn't be needed

View File

@ -2398,9 +2398,9 @@ Locked_tables_list::init_locked_tables(THD *thd)
in reopen_tables(). reopen_tables() is a critical in reopen_tables(). reopen_tables() is a critical
path and we don't want to complicate it with extra allocations. path and we don't want to complicate it with extra allocations.
*/ */
m_reopen_array= (TABLE**)alloc_root(&m_locked_tables_root, m_reopen_array= (TABLE_LIST**)alloc_root(&m_locked_tables_root,
sizeof(TABLE*) * sizeof(TABLE_LIST*) *
(m_locked_tables_count+1)); (m_locked_tables_count+1));
if (m_reopen_array == NULL) if (m_reopen_array == NULL)
{ {
reset(); reset();
@ -2510,6 +2510,7 @@ void Locked_tables_list::reset()
m_locked_tables_last= &m_locked_tables; m_locked_tables_last= &m_locked_tables;
m_reopen_array= NULL; m_reopen_array= NULL;
m_locked_tables_count= 0; m_locked_tables_count= 0;
some_table_marked_for_reopen= 0;
} }
@ -2605,7 +2606,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
in reopen_tables() always links the opened table in reopen_tables() always links the opened table
to the beginning of the open_tables list. to the beginning of the open_tables list.
*/ */
DBUG_ASSERT(thd->open_tables == m_reopen_array[reopen_count]); DBUG_ASSERT(thd->open_tables == m_reopen_array[reopen_count]->table);
thd->open_tables->pos_in_locked_tables->table= NULL; thd->open_tables->pos_in_locked_tables->table= NULL;
thd->open_tables->pos_in_locked_tables= NULL; thd->open_tables->pos_in_locked_tables= NULL;
@ -2635,10 +2636,36 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
} }
/*
Mark all instances of the table to be reopened
This is only needed when LOCK TABLES is active
*/
void Locked_tables_list::mark_table_for_reopen(THD *thd, TABLE *table)
{
TABLE_SHARE *share= table->s;
for (TABLE_LIST *table_list= m_locked_tables;
table_list; table_list= table_list->next_global)
{
if (table_list->table->s == share)
table_list->table->internal_set_needs_reopen(true);
}
/* This is needed in the case where lock tables where not used */
table->internal_set_needs_reopen(true);
some_table_marked_for_reopen= 1;
}
/** /**
Reopen the tables locked with LOCK TABLES and temporarily closed Reopen the tables locked with LOCK TABLES and temporarily closed
by a DDL statement or FLUSH TABLES. by a DDL statement or FLUSH TABLES.
@param need_reopen If set, reopen open tables that are marked with
for reopen.
If not set, reopen tables that where closed.
@note This function is a no-op if we're not under LOCK TABLES. @note This function is a no-op if we're not under LOCK TABLES.
@return TRUE if an error reopening the tables. May happen in @return TRUE if an error reopening the tables. May happen in
@ -2656,6 +2683,12 @@ Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
MYSQL_LOCK *merged_lock; MYSQL_LOCK *merged_lock;
DBUG_ENTER("Locked_tables_list::reopen_tables"); DBUG_ENTER("Locked_tables_list::reopen_tables");
DBUG_ASSERT(some_table_marked_for_reopen || !need_reopen);
/* Reset flag that some table was marked for reopen */
some_table_marked_for_reopen= 0;
for (TABLE_LIST *table_list= m_locked_tables; for (TABLE_LIST *table_list= m_locked_tables;
table_list; table_list= table_list->next_global) table_list; table_list= table_list->next_global)
{ {
@ -2679,24 +2712,32 @@ Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
else else
{ {
if (table_list->table) /* The table was not closed */ if (table_list->table) /* The table was not closed */
continue; continue;
} }
/* Links into thd->open_tables upon success */
if (open_table(thd, table_list, &ot_ctx))
{
unlink_all_closed_tables(thd, 0, reopen_count);
DBUG_RETURN(TRUE);
}
table_list->table->pos_in_locked_tables= table_list;
/* See also the comment on lock type in init_locked_tables(). */
table_list->table->reginfo.lock_type= table_list->lock_type;
DBUG_ASSERT(reopen_count < m_locked_tables_count); DBUG_ASSERT(reopen_count < m_locked_tables_count);
m_reopen_array[reopen_count++]= table_list->table; m_reopen_array[reopen_count++]= table_list;
} }
if (reopen_count) if (reopen_count)
{ {
TABLE **tables= (TABLE**) my_alloca(reopen_count * sizeof(TABLE*));
for (uint i= 0 ; i < reopen_count ; i++)
{
TABLE_LIST *table_list= m_reopen_array[i];
/* Links into thd->open_tables upon success */
if (open_table(thd, table_list, &ot_ctx))
{
unlink_all_closed_tables(thd, 0, i);
my_afree((void*) tables);
DBUG_RETURN(TRUE);
}
tables[i]= table_list->table;
table_list->table->pos_in_locked_tables= table_list;
/* See also the comment on lock type in init_locked_tables(). */
table_list->table->reginfo.lock_type= table_list->lock_type;
}
thd->in_lock_tables= 1; thd->in_lock_tables= 1;
/* /*
We re-lock all tables with mysql_lock_tables() at once rather We re-lock all tables with mysql_lock_tables() at once rather
@ -2709,7 +2750,7 @@ Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
works fine. Patching legacy code of thr_lock.c is risking to works fine. Patching legacy code of thr_lock.c is risking to
break something else. break something else.
*/ */
lock= mysql_lock_tables(thd, m_reopen_array, reopen_count, lock= mysql_lock_tables(thd, tables, reopen_count,
MYSQL_OPEN_REOPEN | MYSQL_LOCK_USE_MALLOC); MYSQL_OPEN_REOPEN | MYSQL_LOCK_USE_MALLOC);
thd->in_lock_tables= 0; thd->in_lock_tables= 0;
if (lock == NULL || (merged_lock= if (lock == NULL || (merged_lock=
@ -2718,9 +2759,11 @@ Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
unlink_all_closed_tables(thd, lock, reopen_count); unlink_all_closed_tables(thd, lock, reopen_count);
if (! thd->killed) if (! thd->killed)
my_error(ER_LOCK_DEADLOCK, MYF(0)); my_error(ER_LOCK_DEADLOCK, MYF(0));
my_afree((void*) tables);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
thd->lock= merged_lock; thd->lock= merged_lock;
my_afree((void*) tables);
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }

View File

@ -1871,20 +1871,23 @@ private:
TABLE_LIST *m_locked_tables; TABLE_LIST *m_locked_tables;
TABLE_LIST **m_locked_tables_last; TABLE_LIST **m_locked_tables_last;
/** An auxiliary array used only in reopen_tables(). */ /** An auxiliary array used only in reopen_tables(). */
TABLE **m_reopen_array; TABLE_LIST **m_reopen_array;
/** /**
Count the number of tables in m_locked_tables list. We can't Count the number of tables in m_locked_tables list. We can't
rely on thd->lock->table_count because it excludes rely on thd->lock->table_count because it excludes
non-transactional temporary tables. We need to know non-transactional temporary tables. We need to know
an exact number of TABLE objects. an exact number of TABLE objects.
*/ */
size_t m_locked_tables_count; uint m_locked_tables_count;
public: public:
bool some_table_marked_for_reopen;
Locked_tables_list() Locked_tables_list()
:m_locked_tables(NULL), :m_locked_tables(NULL),
m_locked_tables_last(&m_locked_tables), m_locked_tables_last(&m_locked_tables),
m_reopen_array(NULL), m_reopen_array(NULL),
m_locked_tables_count(0) m_locked_tables_count(0),
some_table_marked_for_reopen(0)
{ {
init_sql_alloc(&m_locked_tables_root, "Locked_tables_list", init_sql_alloc(&m_locked_tables_root, "Locked_tables_list",
MEM_ROOT_BLOCK_SIZE, 0, MEM_ROOT_BLOCK_SIZE, 0,
@ -1908,6 +1911,7 @@ public:
bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table, bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table,
MYSQL_LOCK *lock); MYSQL_LOCK *lock);
void add_back_last_deleted_lock(TABLE_LIST *dst_table_list); void add_back_last_deleted_lock(TABLE_LIST *dst_table_list);
void mark_table_for_reopen(THD *thd, TABLE *table);
}; };

View File

@ -6128,7 +6128,8 @@ finish:
lex->unit.cleanup(); lex->unit.cleanup();
/* close/reopen tables that were marked to need reopen under LOCK TABLES */ /* close/reopen tables that were marked to need reopen under LOCK TABLES */
if (! thd->lex->requires_prelocking()) if (unlikely(thd->locked_tables_list.some_table_marked_for_reopen) &&
!thd->lex->requires_prelocking())
thd->locked_tables_list.reopen_tables(thd, true); thd->locked_tables_list.reopen_tables(thd, true);
if (! thd->in_sub_stmt) if (! thd->in_sub_stmt)

View File

@ -5033,7 +5033,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
{ {
*fast_alter_table= true; *fast_alter_table= true;
/* Force table re-open for consistency with the main case. */ /* Force table re-open for consistency with the main case. */
table->m_needs_reopen= true; table->mark_table_for_reopen();
} }
else else
{ {
@ -5081,7 +5081,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
must be reopened. must be reopened.
*/ */
*fast_alter_table= true; *fast_alter_table= true;
table->m_needs_reopen= true; table->mark_table_for_reopen();
} }
else else
{ {
@ -6930,7 +6930,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
THD *thd= lpt->thd; THD *thd= lpt->thd;
TABLE *table= lpt->table; TABLE *table= lpt->table;
DBUG_ENTER("handle_alter_part_error"); DBUG_ENTER("handle_alter_part_error");
DBUG_ASSERT(table->m_needs_reopen); DBUG_ASSERT(table->needs_reopen());
if (close_table) if (close_table)
{ {
@ -7151,7 +7151,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
bool frm_install= FALSE; bool frm_install= FALSE;
MDL_ticket *mdl_ticket= table->mdl_ticket; MDL_ticket *mdl_ticket= table->mdl_ticket;
DBUG_ENTER("fast_alter_partition_table"); DBUG_ENTER("fast_alter_partition_table");
DBUG_ASSERT(table->m_needs_reopen); DBUG_ASSERT(table->needs_reopen());
part_info= table->part_info; part_info= table->part_info;
lpt->thd= thd; lpt->thd= thd;

View File

@ -1864,7 +1864,7 @@ static void plugin_load(MEM_ROOT *tmp_root)
sql_print_error(ER_THD(new_thd, ER_GET_ERRNO), my_errno, sql_print_error(ER_THD(new_thd, ER_GET_ERRNO), my_errno,
table->file->table_type()); table->file->table_type());
end_read_record(&read_record_info); end_read_record(&read_record_info);
table->m_needs_reopen= TRUE; // Force close to free memory table->mark_table_for_reopen();
close_mysql_tables(new_thd); close_mysql_tables(new_thd);
end: end:
new_thd->db= null_clex_str; // Avoid free on thd->db new_thd->db= null_clex_str; // Avoid free on thd->db

View File

@ -2761,11 +2761,16 @@ int JOIN::optimize_stage2()
} }
need_tmp= test_if_need_tmp_table(); need_tmp= test_if_need_tmp_table();
//TODO this could probably go in test_if_need_tmp_table.
if (this->select_lex->window_specs.elements > 0) { /*
need_tmp= TRUE; If window functions are present then we can't have simple_order set to
TRUE as the window function needs a temp table for computation.
ORDER BY is computed after the window function computation is done, so
the sort will be done on the temp table.
*/
if (select_lex->have_window_funcs())
simple_order= FALSE; simple_order= FALSE;
}
/* /*
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table

View File

@ -1747,6 +1747,7 @@ public:
- We are using an ORDER BY or GROUP BY on fields not in the first table - We are using an ORDER BY or GROUP BY on fields not in the first table
- We are using different ORDER BY and GROUP BY orders - We are using different ORDER BY and GROUP BY orders
- The user wants us to buffer the result. - The user wants us to buffer the result.
- We are using WINDOW functions.
When the WITH ROLLUP modifier is present, we cannot skip temporary table When the WITH ROLLUP modifier is present, we cannot skip temporary table
creation for the DISTINCT clause just because there are only const tables. creation for the DISTINCT clause just because there are only const tables.
*/ */
@ -1756,7 +1757,8 @@ public:
((select_distinct || !simple_order || !simple_group) || ((select_distinct || !simple_order || !simple_group) ||
(group_list && order) || (group_list && order) ||
MY_TEST(select_options & OPTION_BUFFER_RESULT))) || MY_TEST(select_options & OPTION_BUFFER_RESULT))) ||
(rollup.state != ROLLUP::STATE_NONE && select_distinct)); (rollup.state != ROLLUP::STATE_NONE && select_distinct) ||
select_lex->have_window_funcs());
} }
bool choose_subquery_plan(table_map join_tables); bool choose_subquery_plan(table_map join_tables);
void get_partial_cost_and_fanout(int end_tab_idx, void get_partial_cost_and_fanout(int end_tab_idx,

View File

@ -355,8 +355,10 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *org_table_list)
seq->reserved_until= seq->start; seq->reserved_until= seq->start;
error= seq->write_initial_sequence(table); error= seq->write_initial_sequence(table);
trans_commit_stmt(thd); if (trans_commit_stmt(thd))
trans_commit_implicit(thd); error= 1;
if (trans_commit_implicit(thd))
error= 1;
if (!temporary_table) if (!temporary_table)
{ {

View File

@ -8130,7 +8130,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (field->default_value) if (field->default_value)
field->default_value->expr->walk(&Item::rename_fields_processor, 1, field->default_value->expr->walk(&Item::rename_fields_processor, 1,
&column_rename_param); &column_rename_param);
table->m_needs_reopen= 1; // because new column name is on thd->mem_root // Force reopen because new column name is on thd->mem_root
table->mark_table_for_reopen();
} }
/* Check if field is changed */ /* Check if field is changed */
@ -8682,7 +8683,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{ {
check->expr->walk(&Item::rename_fields_processor, 1, check->expr->walk(&Item::rename_fields_processor, 1,
&column_rename_param); &column_rename_param);
table->m_needs_reopen= 1; // because new column name is on thd->mem_root // Force reopen because new column name is on thd->mem_root
table->mark_table_for_reopen();
} }
new_constraint_list.push_back(check, thd->mem_root); new_constraint_list.push_back(check, thd->mem_root);
} }

View File

@ -257,7 +257,9 @@ void udf_init()
if (unlikely(error > 0)) if (unlikely(error > 0))
sql_print_error("Got unknown error: %d", my_errno); sql_print_error("Got unknown error: %d", my_errno);
end_read_record(&read_record_info); end_read_record(&read_record_info);
table->m_needs_reopen= TRUE; // Force close to free memory
// Force close to free memory
table->mark_table_for_reopen();
end: end:
close_mysql_tables(new_thd); close_mysql_tables(new_thd);

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, 2019, MariaDB Copyright (c) 2008, 2020, 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
@ -96,8 +96,11 @@ static std::atomic<ulong> last_table_id;
/* Functions defined in this file */ /* Functions defined in this file */
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, static bool fix_type_pointers(const char ***typelib_value_names,
uint types, char **names); uint **typelib_value_lengths,
TYPELIB *point_to_type, uint types,
char *names, size_t names_length);
static uint find_field(Field **fields, uchar *record, uint start, uint length); static uint find_field(Field **fields, uchar *record, uint start, uint length);
inline bool is_system_table_name(const char *name, size_t length); inline bool is_system_table_name(const char *name, size_t length);
@ -723,7 +726,8 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
uint keys, KEY *keyinfo, uint keys, KEY *keyinfo,
uint new_frm_ver, uint *ext_key_parts, uint new_frm_ver, uint *ext_key_parts,
TABLE_SHARE *share, uint len, TABLE_SHARE *share, uint len,
KEY *first_keyinfo, char** keynames) KEY *first_keyinfo,
LEX_STRING *keynames)
{ {
uint i, j, n_length; uint i, j, n_length;
KEY_PART_INFO *key_part= NULL; KEY_PART_INFO *key_part= NULL;
@ -875,10 +879,13 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
share->ext_key_parts++; share->ext_key_parts++;
share->ext_key_parts+= keyinfo->ext_key_parts; share->ext_key_parts+= keyinfo->ext_key_parts;
} }
*keynames=(char*) key_part; keynames->str= (char*) key_part;
strpos+= strnmov(*keynames, (char *) strpos, frm_image_end - strpos) - *keynames; keynames->length= strnmov(keynames->str, (char *) strpos,
frm_image_end - strpos) - keynames->str;
strpos+= keynames->length;
if (*strpos++) // key names are \0-terminated if (*strpos++) // key names are \0-terminated
return 1; return 1;
keynames->length++; // Include '\0', to make fix_type_pointers() happy.
//reading index comments //reading index comments
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++) for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
@ -1571,11 +1578,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
TABLE_SHARE *share= this; TABLE_SHARE *share= this;
uint new_frm_ver, field_pack_length, new_field_pack_flag; uint new_frm_ver, field_pack_length, new_field_pack_flag;
uint interval_count, interval_parts, read_length, int_length; uint interval_count, interval_parts, read_length, int_length;
uint total_typelib_value_count;
uint db_create_options, keys, key_parts, n_length; uint db_create_options, keys, key_parts, n_length;
uint com_length, null_bit_pos, UNINIT_VAR(mysql57_vcol_null_bit_pos), bitmap_count; uint com_length, null_bit_pos, UNINIT_VAR(mysql57_vcol_null_bit_pos), bitmap_count;
uint i, hash_fields= 0; uint i, hash_fields= 0;
bool use_hash, mysql57_null_bits= 0; bool use_hash, mysql57_null_bits= 0;
char *keynames, *names, *comment_pos; LEX_STRING keynames= {NULL, 0};
char *names, *comment_pos;
const uchar *forminfo; const uchar *forminfo;
const uchar *frm_image_end = frm_image + frm_length; const uchar *frm_image_end = frm_image + frm_length;
uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos); uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos);
@ -1587,6 +1596,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
KEY_PART_INFO *key_part= NULL; KEY_PART_INFO *key_part= NULL;
Field **field_ptr, *reg_field; Field **field_ptr, *reg_field;
const char **interval_array; const char **interval_array;
uint *typelib_value_lengths= NULL;
enum legacy_db_type legacy_db_type; enum legacy_db_type legacy_db_type;
my_bitmap_map *bitmaps; my_bitmap_map *bitmaps;
bool null_bits_are_used; bool null_bits_are_used;
@ -1986,11 +1996,34 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length)); DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length));
/*
We load the following things into TYPELIBs:
- One TYPELIB for field names
- interval_count TYPELIBs for ENUM/SET values
- One TYPELIB for key names
Every TYPELIB requires one extra value with a NULL pointer and zero length,
which is the end-of-values marker.
TODO-10.5+:
Note, we should eventually reuse this total_typelib_value_count
to allocate interval_array. The below code reserves less space
than total_typelib_value_count pointers. So it seems `interval_array`
and `names` overlap in the memory. Too dangerous to fix in 10.1.
*/
total_typelib_value_count=
(share->fields + 1/*end-of-values marker*/) +
(interval_parts + interval_count/*end-of-values markers*/) +
(keys + 1/*end-of-values marker*/);
if (!multi_alloc_root(&share->mem_root, if (!multi_alloc_root(&share->mem_root,
&share->field, (uint)(share->fields+1)*sizeof(Field*), &share->field, (uint)(share->fields+1)*sizeof(Field*),
&share->intervals, (uint)interval_count*sizeof(TYPELIB), &share->intervals, (uint)interval_count*sizeof(TYPELIB),
&share->check_constraints, (uint) share->table_check_constraints * sizeof(Virtual_column_info*), &share->check_constraints, (uint) share->table_check_constraints * sizeof(Virtual_column_info*),
/*
This looks wrong: shouldn't it be (+2+interval_count)
instread of (+3) ?
*/
&interval_array, (uint) (share->fields+interval_parts+ keys+3)*sizeof(char *), &interval_array, (uint) (share->fields+interval_parts+ keys+3)*sizeof(char *),
&typelib_value_lengths, total_typelib_value_count * sizeof(uint *),
&names, (uint) (n_length+int_length), &names, (uint) (n_length+int_length),
&comment_pos, (uint) com_length, &comment_pos, (uint) com_length,
&vcol_screen_pos, vcol_screen_length, &vcol_screen_pos, vcol_screen_length,
@ -2017,33 +2050,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length,
vcol_screen_length); vcol_screen_length);
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names); if (fix_type_pointers(&interval_array, &typelib_value_lengths,
if (share->fieldnames.count != share->fields) &share->fieldnames, 1, names, n_length) ||
share->fieldnames.count != share->fields)
goto err; goto err;
fix_type_pointers(&interval_array, share->intervals, interval_count, &names);
{ if (fix_type_pointers(&interval_array, &typelib_value_lengths,
/* Set ENUM and SET lengths */ share->intervals, interval_count,
TYPELIB *interval; names + n_length, int_length))
for (interval= share->intervals; goto err;
interval < share->intervals + interval_count;
interval++)
{
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
count)))
goto err;
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
interval->type_lengths[count]= (uint)strlen(val);
}
interval->type_lengths[count]= 0;
}
}
if (keynames) if (keynames.length &&
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames); (fix_type_pointers(&interval_array, &typelib_value_lengths,
&share->keynames, 1, keynames.str, keynames.length) ||
share->keynames.count != keys))
goto err;
/* Allocate handler */ /* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root, if (!(handler_file= get_new_handler(share, thd->mem_root,
@ -4185,37 +4206,81 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
** with a '\0' ** with a '\0'
*/ */
static void static bool
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, fix_type_pointers(const char ***typelib_value_names,
char **names) uint **typelib_value_lengths,
TYPELIB *point_to_type, uint types,
char *ptr, size_t length)
{ {
char *type_name, *ptr; const char *end= ptr + length;
char chr;
ptr= *names;
while (types--) while (types--)
{ {
char sep;
point_to_type->name=0; point_to_type->name=0;
point_to_type->type_names= *array; point_to_type->type_names= *typelib_value_names;
point_to_type->type_lengths= *typelib_value_lengths;
if ((chr= *ptr)) /* Test if empty type */ /*
Typelib can be encoded as:
1) 0x00 - empty typelib
2) 0xFF 0x00 - empty typelib (index names)
3) sep (value sep)... 0x00 - non-empty typelib (where sep is a separator)
*/
if (length == 2 && ptr[0] == (char) 0xFF && ptr[1] == '\0')
{ {
while ((type_name=strchr(ptr+1,chr)) != NullS) /*
{ This is a special case #2.
*((*array)++) = ptr+1; If there are no indexes at all, index names can be encoded
*type_name= '\0'; /* End string */ as a two byte sequence: 0xFF 0x00
ptr=type_name; TODO: Check if it's a bug in the FRM packing routine.
} It should probably write just 0x00 instead of 0xFF00.
ptr+=2; /* Skip end mark and last 0 */ */
ptr+= 2;
} }
else else if ((sep= *ptr++)) // A non-empty typelib
ptr++; {
point_to_type->count= (uint) (*array - point_to_type->type_names); for ( ; ptr < end; )
{
// Now scan the next value+sep pair
char *vend= (char*) memchr(ptr, sep, end - ptr);
if (!vend)
return true; // Bad format
*((*typelib_value_names)++)= ptr;
*((*typelib_value_lengths)++)= (uint) (vend - ptr);
*vend= '\0'; // Change sep to '\0'
ptr= vend + 1; // Shift from sep to the next byte
/*
Now we can have either:
- the end-of-typelib marker (0x00)
- more value+sep pairs
*/
if (!*ptr)
{
/*
We have an ambiguity here. 0x00 can be an end-of-typelib marker,
but it can also be a part of the next value:
CREATE TABLE t1 (a ENUM(0x61, 0x0062) CHARACTER SET BINARY);
If this is the last ENUM/SET in the table and there is still more
packed data left after 0x00, then we know for sure that 0x00
is a part of the next value.
TODO-10.5+: we should eventually introduce a new unambiguous
typelib encoding for FRM.
*/
if (!types && ptr + 1 < end)
continue; // A binary value starting with 0x00
ptr++; // Consume the end-of-typelib marker
break; // End of the current typelib
}
}
}
point_to_type->count= (uint) (*typelib_value_names -
point_to_type->type_names);
point_to_type++; point_to_type++;
*((*array)++)= NullS; /* End of type */ *((*typelib_value_names)++)= NullS; /* End of type */
*((*typelib_value_lengths)++)= 0; /* End of type */
} }
*names=ptr; /* Update end */ return ptr != end;
return;
} /* fix_type_pointers */ } /* fix_type_pointers */
@ -9640,3 +9705,14 @@ void TABLE::initialize_quick_structures()
bzero(quick_costs, sizeof(quick_costs)); bzero(quick_costs, sizeof(quick_costs));
bzero(quick_n_ranges, sizeof(quick_n_ranges)); bzero(quick_n_ranges, sizeof(quick_n_ranges));
} }
/*
Mark table to be reopened after query
*/
void TABLE::mark_table_for_reopen()
{
THD *thd= in_use;
DBUG_ASSERT(thd);
thd->locked_tables_list.mark_table_for_reopen(thd, this);
}

View File

@ -1373,8 +1373,8 @@ public:
bool insert_or_update; /* Can be used by the handler */ bool insert_or_update; /* Can be used by the handler */
bool alias_name_used; /* true if table_name is alias */ bool alias_name_used; /* true if table_name is alias */
bool get_fields_in_item_tree; /* Signal to fix_field */ bool get_fields_in_item_tree; /* Signal to fix_field */
bool m_needs_reopen;
private: private:
bool m_needs_reopen;
bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/ bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/
public: public:
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
@ -1478,6 +1478,16 @@ public:
/** Should this instance of the table be reopened? */ /** Should this instance of the table be reopened? */
inline bool needs_reopen() inline bool needs_reopen()
{ return !db_stat || m_needs_reopen; } { return !db_stat || m_needs_reopen; }
/*
Mark that all current connection instances of the table should be
reopen at end of statement
*/
void mark_table_for_reopen();
/* Should only be called from Locked_tables_list::mark_table_for_reopen() */
void internal_set_needs_reopen(bool value)
{
m_needs_reopen= value;
}
bool alloc_keys(uint key_count); bool alloc_keys(uint key_count);
bool check_tmp_key(uint key, uint key_parts, bool check_tmp_key(uint key, uint key_parts,

View File

@ -1067,7 +1067,7 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length,
case TMP_TABLE_ANY: found= true; break; case TMP_TABLE_ANY: found= true; break;
} }
} }
if (table && unlikely(table->m_needs_reopen)) if (table && unlikely(table->needs_reopen()))
{ {
share->all_tmp_tables.remove(table); share->all_tmp_tables.remove(table);
free_temporary_table(table); free_temporary_table(table);

View File

@ -1689,7 +1689,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
{ {
tl->table->use_all_columns(); tl->table->use_all_columns();
/* Force close at the end of the function to free memory. */ /* Force close at the end of the function to free memory. */
tl->table->m_needs_reopen= TRUE; tl->table->mark_table_for_reopen();
} }
/* /*

View File

@ -672,6 +672,18 @@ static bool pack_vcols(String *buf, List<Create_field> &create_fields,
} }
static uint typelib_values_packed_length(const TYPELIB *t)
{
uint length= 0;
for (uint i= 0; t->type_names[i]; i++)
{
length+= t->type_lengths[i];
length++; /* Separator */
}
return length;
}
/* Make formheader */ /* Make formheader */
static bool pack_header(THD *thd, uchar *forminfo, static bool pack_header(THD *thd, uchar *forminfo,
@ -765,9 +777,8 @@ static bool pack_header(THD *thd, uchar *forminfo,
field->interval_id=get_interval_id(&int_count,create_fields,field); field->interval_id=get_interval_id(&int_count,create_fields,field);
if (old_int_count != int_count) if (old_int_count != int_count)
{ {
for (const char **pos=field->interval->type_names ; *pos ; pos++) int_length+= typelib_values_packed_length(field->interval);
int_length+=(uint) strlen(*pos)+1; // field + suffix prefix int_parts+= field->interval->count + 1;
int_parts+=field->interval->count+1;
} }
} }
if (f_maybe_null(field->pack_flag)) if (f_maybe_null(field->pack_flag))
@ -856,11 +867,7 @@ static size_t packed_fields_length(List<Create_field> &create_fields)
{ {
int_count= field->interval_id; int_count= field->interval_id;
length++; length++;
for (int i=0; field->interval->type_names[i]; i++) length+= typelib_values_packed_length(field->interval);
{
length+= field->interval->type_lengths[i];
length++;
}
length++; length++;
} }

View File

@ -3395,7 +3395,7 @@ ha_innobase::reset_template(void)
/* Force table to be freed in close_thread_table(). */ /* Force table to be freed in close_thread_table(). */
DBUG_EXECUTE_IF("free_table_in_fts_query", DBUG_EXECUTE_IF("free_table_in_fts_query",
if (m_prebuilt->in_fts_query) { if (m_prebuilt->in_fts_query) {
table->m_needs_reopen = true; table->mark_table_for_reopen();
} }
); );
@ -5093,9 +5093,8 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
{ {
DBUG_ENTER("innobase_kill_query"); DBUG_ENTER("innobase_kill_query");
if (trx_t *trx= thd_to_trx(thd)) if (trx_t* trx= thd_to_trx(thd))
{ {
ut_ad(trx->mysql_thd == thd);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) if (trx->is_wsrep() && wsrep_thd_is_aborting(thd))
/* if victim has been signaled by BF thread and/or aborting is already /* if victim has been signaled by BF thread and/or aborting is already
@ -5103,8 +5102,29 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
Also, BF thread should own trx mutex for the victim. */ Also, BF thread should own trx mutex for the victim. */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
/* Cancel a pending lock request if there are any */ lock_mutex_enter();
lock_trx_handle_wait(trx); mutex_enter(&trx_sys.mutex);
trx_mutex_enter(trx);
/* It is possible that innobase_close_connection() is concurrently
being executed on our victim. Even if the trx object is later
reused for another client connection or a background transaction,
its trx->mysql_thd will differ from our thd.
trx_t::state changes are protected by trx_t::mutex, and
trx_sys.trx_list is protected by trx_sys.mutex, in
both trx_create() and trx_free().
At this point, trx may have been reallocated for another client
connection, or for a background operation. In that case, either
trx_t::state or trx_t::mysql_thd should not match our expectations. */
bool cancel= trx->mysql_thd == thd && trx->state == TRX_STATE_ACTIVE &&
!trx->lock.was_chosen_as_deadlock_victim;
mutex_exit(&trx_sys.mutex);
if (!cancel);
else if (lock_t *lock= trx->lock.wait_lock)
lock_cancel_waiting_and_release(lock);
lock_mutex_exit();
trx_mutex_exit(trx);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2020, 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
@ -86,11 +87,15 @@ struct Pool {
for (Element* elem = m_start; elem != m_last; ++elem) { for (Element* elem = m_start; elem != m_last; ++elem) {
ut_ad(elem->m_pool == this); ut_ad(elem->m_pool == this);
#ifdef __SANITIZE_ADDRESS__
/* Unpoison the memory for AddressSanitizer */ /* Unpoison the memory for AddressSanitizer */
MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
#endif
#ifdef HAVE_valgrind
/* Declare the contents as initialized for Valgrind; /* Declare the contents as initialized for Valgrind;
we checked this in mem_free(). */ we checked this in mem_free(). */
UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type); UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
#endif
Factory::destroy(&elem->m_type); Factory::destroy(&elem->m_type);
} }
@ -127,13 +132,18 @@ struct Pool {
#if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__ #if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__
if (elem) { if (elem) {
# ifdef __SANITIZE_ADDRESS__
/* Unpoison the memory for AddressSanitizer */ /* Unpoison the memory for AddressSanitizer */
MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
# endif
# ifdef HAVE_valgrind
/* Declare the memory initialized for Valgrind. /* Declare the memory initialized for Valgrind.
The trx_t that are released to the pool are The trx_t that are released to the pool are
actually initialized; we checked that by actually initialized; we checked that by
UNIV_MEM_ASSERT_RW() in mem_free() below. */ UNIV_MEM_ASSERT_RW() in mem_free() below. */
UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type); UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
# endif
} }
#endif #endif

View File

@ -1177,19 +1177,15 @@ row_log_table_get_pk_col(
return(DB_INVALID_NULL); return(DB_INVALID_NULL);
} }
ulint new_i = dict_col_get_clust_pos(ifield->col, index); unsigned col_no= ifield->col->ind;
ut_ad(col_no < log->defaults->n_fields);
if (UNIV_UNLIKELY(new_i >= log->defaults->n_fields)) {
ut_ad(0);
return DB_INVALID_NULL;
}
field = static_cast<const byte*>( field = static_cast<const byte*>(
log->defaults->fields[new_i].data); log->defaults->fields[col_no].data);
if (!field) { if (!field) {
return(DB_INVALID_NULL); return(DB_INVALID_NULL);
} }
len = log->defaults->fields[new_i].len; len = log->defaults->fields[col_no].len;
} }
if (rec_offs_nth_extern(offsets, i)) { if (rec_offs_nth_extern(offsets, i)) {
@ -1671,10 +1667,12 @@ blob_done:
const dfield_t& default_field const dfield_t& default_field
= log->defaults->fields[col_no]; = log->defaults->fields[col_no];
Field* field = log->old_table->field[col_no];
Field* field = log->old_table->field[col->ind];
field->set_warning(Sql_condition::WARN_LEVEL_WARN, field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1, ulong(log->n_rows)); WARN_DATA_TRUNCATED, 1,
ulong(log->n_rows));
if (!log->allow_not_null) { if (!log->allow_not_null) {
/* We got a NULL value for a NOT NULL column. */ /* We got a NULL value for a NOT NULL column. */

View File

@ -455,12 +455,30 @@ void trx_free(trx_t*& trx)
ut_ad(trx->will_lock == 0); ut_ad(trx->will_lock == 0);
trx_pools->mem_free(trx); trx_pools->mem_free(trx);
#ifdef __SANITIZE_ADDRESS__
/* Unpoison the memory for innodb_monitor_set_option; /* Unpoison the memory for innodb_monitor_set_option;
it is operating also on the freed transaction objects. */ it is operating also on the freed transaction objects. */
MEM_UNDEFINED(&trx->mutex, sizeof trx->mutex); MEM_UNDEFINED(&trx->mutex, sizeof trx->mutex);
/* Declare the contents as initialized for Valgrind; /* For innobase_kill_connection() */
we checked that it was initialized in trx_pools->mem_free(trx). */ # ifdef WITH_WSREP
MEM_UNDEFINED(&trx->wsrep, sizeof trx->wsrep);
# endif
MEM_UNDEFINED(&trx->state, sizeof trx->state);
MEM_UNDEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
#ifdef HAVE_valgrind
/* Unpoison the memory for innodb_monitor_set_option;
it is operating also on the freed transaction objects.
We checked that these were initialized in
trx_pools->mem_free(trx). */
UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex); UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex);
/* For innobase_kill_connection() */
# ifdef WITH_WSREP
UNIV_MEM_VALID(&trx->wsrep, sizeof trx->wsrep);
# endif
UNIV_MEM_VALID(&trx->state, sizeof trx->state);
UNIV_MEM_VALID(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
trx = NULL; trx = NULL;
} }

View File

@ -224,7 +224,8 @@ err:
*/ */
static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end, static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
size_t width, char *par, uint print_type) size_t width, char *par, uint print_type,
my_bool nice_cut)
{ {
int well_formed_error; int well_formed_error;
uint dots= 0; uint dots= 0;
@ -232,24 +233,34 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
if (!par) if (!par)
par = (char*) "(null)"; par = (char*) "(null)";
plen= slen= strnlen(par, width + 1); if (nice_cut)
if (plen > width)
plen= width;
if (left_len <= plen)
plen = left_len - 1;
if ((slen > plen))
{ {
if (plen < 3) plen= slen= strnlen(par, width + 1);
if (plen > width)
plen= width;
if (left_len <= plen)
plen = left_len - 1;
if ((slen > plen))
{ {
dots= (uint) plen; if (plen < 3)
plen= 0; {
} dots= (uint) plen;
else plen= 0;
{ }
dots= 3; else
plen-= 3; {
dots= 3;
plen-= 3;
}
} }
} }
else
{
plen= slen= strnlen(par, width);
dots= 0;
if (left_len <= plen)
plen = left_len - 1;
}
plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error); plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error);
if (print_type & ESCAPED_ARG) if (print_type & ESCAPED_ARG)
@ -446,6 +457,7 @@ start:
switch (args_arr[i].arg_type) { switch (args_arr[i].arg_type) {
case 's': case 's':
case 'b': case 'b':
case 'T':
args_arr[i].str_arg= va_arg(ap, char *); args_arr[i].str_arg= va_arg(ap, char *);
break; break;
case 'f': case 'f':
@ -480,12 +492,14 @@ start:
size_t width= 0, length= 0; size_t width= 0, length= 0;
switch (print_arr[i].arg_type) { switch (print_arr[i].arg_type) {
case 's': case 's':
case 'T':
{ {
char *par= args_arr[print_arr[i].arg_idx].str_arg; char *par= args_arr[print_arr[i].arg_idx].str_arg;
width= (print_arr[i].flags & WIDTH_ARG) width= (print_arr[i].flags & WIDTH_ARG)
? (size_t)args_arr[print_arr[i].width].longlong_arg ? (size_t)args_arr[print_arr[i].width].longlong_arg
: print_arr[i].width; : print_arr[i].width;
to= process_str_arg(cs, to, end, width, par, print_arr[i].flags); to= process_str_arg(cs, to, end, width, par, print_arr[i].flags,
(print_arr[i].arg_type == 'T'));
break; break;
} }
case 'b': case 'b':
@ -552,7 +566,7 @@ start:
*to++= '"'; *to++= '"';
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg); my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
to= process_str_arg(cs, to, real_end, width, errmsg_buff, to= process_str_arg(cs, to, real_end, width, errmsg_buff,
print_arr[i].flags); print_arr[i].flags, 1);
if (real_end > to) *to++= '"'; if (real_end > to) *to++= '"';
} }
break; break;
@ -676,10 +690,10 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
fmt= check_longlong(fmt, &have_longlong); fmt= check_longlong(fmt, &have_longlong);
if (*fmt == 's') /* String parameter */ if (*fmt == 's' || *fmt == 'T') /* String parameter */
{ {
reg2 char *par= va_arg(ap, char *); reg2 char *par= va_arg(ap, char *);
to= process_str_arg(cs, to, end, width, par, print_type); to= process_str_arg(cs, to, end, width, par, print_type, (*fmt == 'T'));
continue; continue;
} }
else if (*fmt == 'b') /* Buffer parameter */ else if (*fmt == 'b') /* Buffer parameter */
@ -731,7 +745,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
*to++= ' '; *to++= ' ';
*to++= '"'; *to++= '"';
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg); my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
to= process_str_arg(cs, to, real_end, width, errmsg_buff, print_type); to= process_str_arg(cs, to, real_end, width, errmsg_buff,
print_type, 1);
if (real_end > to) *to++= '"'; if (real_end > to) *to++= '"';
} }
continue; continue;

View File

@ -61,7 +61,7 @@ static void test_many(const char **res, const char *fmt, ...)
int main(void) int main(void)
{ {
plan(43); plan(47);
test1("Constant string", test1("Constant string",
"Constant string"); "Constant string");
@ -99,27 +99,33 @@ int main(void)
test1("Width is ignored for strings <x> <y>", test1("Width is ignored for strings <x> <y>",
"Width is ignored for strings <%04s> <%5s>", "x", "y"); "Width is ignored for strings <%04s> <%5s>", "x", "y");
test1("Precision works for strings <ab...>", test1("Precision works for strings <abcde>",
"Precision works for strings <%.5s>", "abcdef!"); "Precision works for strings <%.5s>", "abcdef!");
test1("Precision works for strings <ab...>",
"Precision works for strings <%.5T>", "abcdef!");
test1("Flag '`' (backtick) works: `abcd` `op``q` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.4s (mysql extension)",
"abcd", "op`qrst");
test1("Flag '`' (backtick) works: `abcd` `op``q...` (mysql extension)", test1("Flag '`' (backtick) works: `abcd` `op``q...` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.7s (mysql extension)", "Flag '`' (backtick) works: %`T %`.7T (mysql extension)",
"abcd", "op`qrstuuuuuuuuu"); "abcd", "op`qrstuuuuuuuuu");
test1("Flag '`' (backtick) works: `abcd` `.` (mysql extension)", test1("Flag '`' (backtick) works: `abcd` `.` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.1s (mysql extension)", "Flag '`' (backtick) works: %`T %`.1T (mysql extension)",
"abcd", "op`qrstuuuuuuuuu"); "abcd", "op`qrstuuuuuuuuu");
test1("Flag '`' (backtick) works: `abcd` `...` (mysql extension)", test1("Flag '`' (backtick) works: `abcd` `...` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.3s (mysql extension)", "Flag '`' (backtick) works: %`T %`.3T (mysql extension)",
"abcd", "op`qrstuuuuuuuuu"); "abcd", "op`qrstuuuuuuuuu");
test1("Flag '`' (backtick) works: `abcd` `op...` (mysql extension)", test1("Flag '`' (backtick) works: `abcd` `op...` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.5s (mysql extension)", "Flag '`' (backtick) works: %`T %`.5T (mysql extension)",
"abcd", "op`qrstuuuuuuuuu"); "abcd", "op`qrstuuuuuuuuu");
test1("Flag '`' (backtick) works: `abcd` `op``...` (mysql extension)", test1("Flag '`' (backtick) works: `abcd` `op``...` (mysql extension)",
"Flag '`' (backtick) works: %`s %`.6s (mysql extension)", "Flag '`' (backtick) works: %`T %`.6T (mysql extension)",
"abcd", "op`qrstuuuuuuuuu"); "abcd", "op`qrstuuuuuuuuu");
test1("Length modifiers work: 1 * -1 * 2 * 3", test1("Length modifiers work: 1 * -1 * 2 * 3",
@ -141,15 +147,21 @@ int main(void)
test1("Asterisk '*' as a width works: < 4>", test1("Asterisk '*' as a width works: < 4>",
"Asterisk '*' as a width works: <%*d>", 5, 4); "Asterisk '*' as a width works: <%*d>", 5, 4);
test1("Asterisk '*' as a precision works: <qwe...>", test1("Asterisk '*' as a precision works: <qwerty>",
"Asterisk '*' as a precision works: <%.*s>", 6, "qwertyuiop"); "Asterisk '*' as a precision works: <%.*s>", 6, "qwertyuiop");
test1("Asterisk '*' as a precision works: <qwe...>",
"Asterisk '*' as a precision works: <%.*T>", 6, "qwertyuiop");
test1("Positional arguments for a width: < 4>", test1("Positional arguments for a width: < 4>",
"Positional arguments for a width: <%1$*2$d>", 4, 5); "Positional arguments for a width: <%1$*2$d>", 4, 5);
test1("Positional arguments for a precision: <qwe...>", test1("Positional arguments for a precision: <qwerty>",
"Positional arguments for a precision: <%1$.*2$s>", "qwertyuiop", 6); "Positional arguments for a precision: <%1$.*2$s>", "qwertyuiop", 6);
test1("Positional arguments for a precision: <qwe...>",
"Positional arguments for a precision: <%1$.*2$T>", "qwertyuiop", 6);
test1("Positional arguments and a width: <0000ab>", test1("Positional arguments and a width: <0000ab>",
"Positional arguments and a width: <%1$06x>", 0xab); "Positional arguments and a width: <%1$06x>", 0xab);