mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 22:50:47 +02:00
MDEV-30164 System variable for default collations
This patch adds a way to override default collations (or "character set collations") for desired character sets. The SQL standard says: > Each collation known in an SQL-environment is applicable to one > or more character sets, and for each character set, one or more > collations are applicable to it, one of which is associated with > it as its character set collation. In MariaDB, character set collations has been hard-coded so far, e.g. utf8mb4_general_ci has been a hard-coded character set collation for utf8mb4. This patch allows to override (globally per server, or per session) character set collations, so for example, uca1400_ai_ci can be set as a character set collation for Unicode character sets (instead of compiled xxx_general_ci). The array of overridden character set collations is stored in a new (session and global) system variable @@character_set_collations and can be set as a comma separated list of charset=collation pairs, e.g.: SET @@character_set_collations='utf8mb3=uca1400_ai_ci,utf8mb4=uca1400_ai_ci'; The variable is empty by default, which mean use the hard-coded character set collations (e.g. utf8mb4_general_ci for utf8mb4). The variable can also be set globally by passing to the server startup command line, and/or in my.cnf.
This commit is contained in:
parent
584c2351de
commit
75f25e4ca7
59 changed files with 2228 additions and 111 deletions
client
libmysqld
mysql-test
main
ctype_collate_implicit.resultctype_collate_implicit.testctype_collate_implicit_def.optctype_collate_implicit_def.resultctype_collate_implicit_def.testctype_collate_implicit_utf32.resultctype_collate_implicit_utf32.testctype_utf8.resultctype_utf8mb4.resultctype_utf8mb4_heap.resultctype_utf8mb4_innodb.resultctype_utf8mb4_myisam.resultmysqlbinlog.resultmysqld--help.result
suite
sql
CMakeLists.txtcharset_collations.cccharset_collations.hfield.hhandler.hitem_func.hitem_strfunc.ccjson_table.cclex_charset.cclex_charset.hlog_event.cclog_event.hlog_event_client.cclog_event_server.ccmysqld.ccsimple_tokenizer.hsql_class.ccsql_class.hsql_connect.ccsql_lex.hsql_parse.ccsql_prepare.ccsql_show.ccsql_table.ccsql_type.ccsql_used.hsql_yacc.yystructs.hsys_vars.ccsys_vars.inl
|
@ -52,6 +52,7 @@
|
|||
#include "sql_string.h" // needed for Rpl_filter
|
||||
#include "sql_list.h" // needed for Rpl_filter
|
||||
#include "rpl_filter.h"
|
||||
#include "charset_collations.h"
|
||||
|
||||
#include "mysqld.h"
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||
../sql/sql_analyze_stmt.cc ../sql/sql_analyze_stmt.h
|
||||
../sql/compat56.cc
|
||||
../sql/sql_schema.cc
|
||||
../sql/lex_charset.cc
|
||||
../sql/lex_charset.cc ../sql/charset_collations.cc
|
||||
../sql/sql_type.cc ../sql/sql_type.h
|
||||
../sql/sql_mode.cc
|
||||
../sql/sql_type_string.cc
|
||||
|
|
291
mysql-test/main/ctype_collate_implicit.result
Normal file
291
mysql-test/main/ctype_collate_implicit.result
Normal file
|
@ -0,0 +1,291 @@
|
|||
#
|
||||
# MDEV-30164 System variable for default collations
|
||||
#
|
||||
SET @@character_set_collations= ' utf8mb3 = utf8mb3_bin , LATIN1 = LATIN1_BIN ';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_bin
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= ',,, utf8mb3 = utf8mb3_bin , , LATIN1 = LATIN1_BIN ,,';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_bin
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= 'utf8mb3 = utf8mb3_bin LATIN1 = LATIN1_BIN ';
|
||||
ERROR 42000: Variable 'character_set_collations' can't be set to the value of 'utf8mb3 = utf8mb3_bin LATIN1 = LATIN1_BIN '
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= ' 123 ';
|
||||
ERROR 42000: Variable 'character_set_collations' can't be set to the value of ' 123 '
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= ' utf8mb3 ';
|
||||
ERROR 42000: Variable 'character_set_collations' can't be set to the value of ' utf8mb3 '
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= ' utf8mb3 = ';
|
||||
ERROR 42000: Variable 'character_set_collations' can't be set to the value of ' utf8mb3 = '
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= ' utf8mb3 = 123 ';
|
||||
ERROR 42000: Variable 'character_set_collations' can't be set to the value of ' utf8mb3 = 123 '
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
utf8mb3=utf8mb3_bin
|
||||
SET @@character_set_collations='';
|
||||
SET @@character_set_collations='utf8mb3=utf8mb4_general_ci';
|
||||
ERROR 42000: COLLATION 'utf8mb4_general_ci' is not valid for CHARACTER SET 'utf8mb3'
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations='utf8mb4=utf8mb3_general_ci';
|
||||
ERROR 42000: COLLATION 'utf8mb3_general_ci' is not valid for CHARACTER SET 'utf8mb4'
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_general_ci';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
utf8mb3=utf8mb3_general_ci
|
||||
SET @@character_set_collations='utf8mb4=utf8mb4_general_ci,latin1=latin1_bin';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
latin1=latin1_bin,utf8mb4=utf8mb4_general_ci
|
||||
SET @@character_set_collations='utf8mb4=uca1400_ai_ci,latin1=uca1400_ai_ci';
|
||||
ERROR 42000: COLLATION 'uca1400_ai_ci' is not valid for CHARACTER SET 'latin1'
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
latin1=latin1_bin,utf8mb4=utf8mb4_general_ci
|
||||
SELECT @@character_set_collations RLIKE 'utf8mb4=utf8mb4_general_ci' AS expect_true;
|
||||
expect_true
|
||||
1
|
||||
SET @@character_set_collations='utf8mb4=uca1400_ai_ci';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
utf8mb4=utf8mb4_uca1400_ai_ci
|
||||
SET NAMES utf8mb4;
|
||||
SELECT @@collation_connection;
|
||||
@@collation_connection
|
||||
utf8mb4_uca1400_ai_ci
|
||||
SELECT collation('literal');
|
||||
collation('literal')
|
||||
utf8mb4_uca1400_ai_ci
|
||||
EXECUTE IMMEDIATE 'SELECT COLLATION(?)' USING 'literal';
|
||||
COLLATION(?)
|
||||
utf8mb4_uca1400_ai_ci
|
||||
CREATE VIEW v1 AS SELECT 'literal', collation('literal') as cl;
|
||||
SHOW CREATE VIEW v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'literal' AS `literal`,collation('literal') AS `cl` utf8mb4 utf8mb4_uca1400_ai_ci
|
||||
SELECT * FROM v1;
|
||||
literal cl
|
||||
literal utf8mb4_uca1400_ai_ci
|
||||
DROP VIEW v1;
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a TEXT COLLATE DEFAULT) CHARACTER SET utf8mb4;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a TEXT) CHARACTER SET utf8mb4;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
|
||||
DROP TABLE t1;
|
||||
CREATE DATABASE db1 CHARACTER SET utf8mb4;
|
||||
SHOW CREATE DATABASE db1;
|
||||
Database Create Database
|
||||
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci */
|
||||
DROP DATABASE db1;
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
SELECT
|
||||
@@collation_connection AS conn,
|
||||
COLLATION('a') AS lit,
|
||||
COLLATION(CONCAT(1)) AS num,
|
||||
COLLATION(CAST(123 AS CHAR)) AS casti,
|
||||
COLLATION(_utf8mb4'a') AS litu,
|
||||
COLLATION(_utf8mb4 0x62) AS lituh,
|
||||
COLLATION(_utf8mb4 X'63') AS lituhs,
|
||||
COLLATION(CAST(123 AS CHAR CHARACTER SET utf8mb4)) AS castic,
|
||||
COLLATION(CHAR(0x61 USING utf8mb4)) AS chr,
|
||||
COLLATION(CONVERT('a' USING utf8mb4)) AS conv;;
|
||||
conn utf8mb4_general_ci
|
||||
lit utf8mb4_general_ci
|
||||
num utf8mb4_general_ci
|
||||
casti utf8mb4_general_ci
|
||||
litu utf8mb4_uca1400_ai_ci
|
||||
lituh utf8mb4_uca1400_ai_ci
|
||||
lituhs utf8mb4_uca1400_ai_ci
|
||||
castic utf8mb4_uca1400_ai_ci
|
||||
chr utf8mb4_uca1400_ai_ci
|
||||
conv utf8mb4_uca1400_ai_ci
|
||||
SET NAMES utf8mb4;
|
||||
SELECT
|
||||
@@collation_connection AS conn,
|
||||
COLLATION('a') AS lit,
|
||||
COLLATION(CONCAT(1)) AS num,
|
||||
COLLATION(CAST(123 AS CHAR)) AS casti,
|
||||
COLLATION(_utf8mb4'a') AS litu,
|
||||
COLLATION(_utf8mb4 0x62) AS lituh,
|
||||
COLLATION(_utf8mb4 X'63') AS lituhs,
|
||||
COLLATION(CAST(123 AS CHAR CHARACTER SET utf8mb4)) AS castic,
|
||||
COLLATION(CHAR(0x61 USING utf8mb4)) AS chr,
|
||||
COLLATION(CONVERT('a' USING utf8mb4)) AS conv;;
|
||||
conn utf8mb4_uca1400_ai_ci
|
||||
lit utf8mb4_uca1400_ai_ci
|
||||
num utf8mb4_uca1400_ai_ci
|
||||
casti utf8mb4_uca1400_ai_ci
|
||||
litu utf8mb4_uca1400_ai_ci
|
||||
lituh utf8mb4_uca1400_ai_ci
|
||||
lituhs utf8mb4_uca1400_ai_ci
|
||||
castic utf8mb4_uca1400_ai_ci
|
||||
chr utf8mb4_uca1400_ai_ci
|
||||
conv utf8mb4_uca1400_ai_ci
|
||||
SET character_set_collations='latin1=latin1_bin,utf8mb4=uca1400_ai_ci';
|
||||
SHOW CHARACTER SET LIKE 'latin1';
|
||||
Charset Description Default collation Maxlen
|
||||
latin1 cp1252 West European latin1_bin 1
|
||||
SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS
|
||||
WHERE CHARACTER_SET_NAME='latin1';
|
||||
CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN
|
||||
latin1 latin1_bin cp1252 West European 1
|
||||
SHOW COLLATION LIKE 'latin1%';
|
||||
Collation Charset Id Default Compiled Sortlen
|
||||
latin1_german1_ci latin1 5 Yes 1
|
||||
latin1_swedish_ci latin1 8 Yes 1
|
||||
latin1_danish_ci latin1 15 Yes 1
|
||||
latin1_german2_ci latin1 31 Yes 2
|
||||
latin1_bin latin1 47 Yes Yes 1
|
||||
latin1_general_ci latin1 48 Yes 1
|
||||
latin1_general_cs latin1 49 Yes 1
|
||||
latin1_spanish_ci latin1 94 Yes 1
|
||||
latin1_swedish_nopad_ci latin1 1032 Yes 1
|
||||
latin1_nopad_bin latin1 1071 Yes 1
|
||||
SELECT COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATIONS
|
||||
WHERE CHARACTER_SET_NAME LIKE 'latin1%';
|
||||
COLLATION_NAME IS_DEFAULT
|
||||
latin1_german1_ci
|
||||
latin1_swedish_ci
|
||||
latin1_danish_ci
|
||||
latin1_german2_ci
|
||||
latin1_bin Yes
|
||||
latin1_general_ci
|
||||
latin1_general_cs
|
||||
latin1_spanish_ci
|
||||
latin1_swedish_nopad_ci
|
||||
latin1_nopad_bin
|
||||
SELECT COLLATION_NAME, FULL_COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
WHERE COLLATION_NAME LIKE 'latin1%';
|
||||
COLLATION_NAME FULL_COLLATION_NAME IS_DEFAULT
|
||||
latin1_german1_ci latin1_german1_ci
|
||||
latin1_swedish_ci latin1_swedish_ci
|
||||
latin1_danish_ci latin1_danish_ci
|
||||
latin1_german2_ci latin1_german2_ci
|
||||
latin1_bin latin1_bin Yes
|
||||
latin1_general_ci latin1_general_ci
|
||||
latin1_general_cs latin1_general_cs
|
||||
latin1_spanish_ci latin1_spanish_ci
|
||||
latin1_swedish_nopad_ci latin1_swedish_nopad_ci
|
||||
latin1_nopad_bin latin1_nopad_bin
|
||||
SHOW CHARACTER SET LIKE 'utf8mb4';
|
||||
Charset Description Default collation Maxlen
|
||||
utf8mb4 UTF-8 Unicode utf8mb4_uca1400_ai_ci 4
|
||||
SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS
|
||||
WHERE CHARACTER_SET_NAME='utf8mb4';
|
||||
CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN
|
||||
utf8mb4 utf8mb4_uca1400_ai_ci UTF-8 Unicode 4
|
||||
SHOW COLLATION LIKE '%uca1400_ai_ci%';
|
||||
Collation Charset Id Default Compiled Sortlen
|
||||
uca1400_ai_ci NULL NULL NULL Yes 8
|
||||
SELECT COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATIONS
|
||||
WHERE COLLATION_NAME LIKE '%uca1400_ai_ci%';
|
||||
COLLATION_NAME IS_DEFAULT
|
||||
uca1400_ai_ci NULL
|
||||
SELECT COLLATION_NAME, FULL_COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
WHERE COLLATION_NAME LIKE '%uca1400_ai_ci%';
|
||||
COLLATION_NAME FULL_COLLATION_NAME IS_DEFAULT
|
||||
uca1400_ai_ci utf8mb3_uca1400_ai_ci
|
||||
uca1400_ai_ci ucs2_uca1400_ai_ci
|
||||
uca1400_ai_ci utf8mb4_uca1400_ai_ci Yes
|
||||
uca1400_ai_ci utf16_uca1400_ai_ci
|
||||
uca1400_ai_ci utf32_uca1400_ai_ci
|
||||
SET @@character_set_collations='';
|
||||
PREPARE stmt FROM 'SELECT '
|
||||
'COLLATION(CAST("x" AS CHAR CHARACTER SET utf8mb3)) AS a, '
|
||||
'COLLATION(_utf8mb3"x") AS b';
|
||||
EXECUTE stmt;
|
||||
a b
|
||||
utf8mb3_general_ci utf8mb3_general_ci
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
EXECUTE stmt;
|
||||
a b
|
||||
utf8mb3_bin utf8mb3_bin
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
PREPARE stmt FROM 'SELECT '
|
||||
'COLLATION(CAST("x" AS CHAR CHARACTER SET utf8mb3)) AS a, '
|
||||
'COLLATION(_utf8mb3"x") AS b';
|
||||
EXECUTE stmt;
|
||||
a b
|
||||
utf8mb3_bin utf8mb3_bin
|
||||
SET @@character_set_collations=DEFAULT;
|
||||
EXECUTE stmt;
|
||||
a b
|
||||
utf8mb3_general_ci utf8mb3_general_ci
|
||||
SET NAMES utf8mb3;
|
||||
SET @@character_set_collations='';
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 '
|
||||
'(a TEXT CHARACTER SET utf8mb3 COLLATE DEFAULT COLLATE utf8mb3_general_ci)';
|
||||
EXECUTE stmt;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
EXECUTE stmt;
|
||||
ERROR HY000: Conflicting declarations: 'COLLATE utf8mb3_bin' and 'COLLATE utf8mb3_general_ci'
|
||||
SET @@character_set_collations='';
|
||||
EXECUTE stmt;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
237
mysql-test/main/ctype_collate_implicit.test
Normal file
237
mysql-test/main/ctype_collate_implicit.test
Normal file
|
@ -0,0 +1,237 @@
|
|||
--source include/have_utf8.inc
|
||||
--source include/have_utf8mb4.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30164 System variable for default collations
|
||||
--echo #
|
||||
|
||||
SET @@character_set_collations= ' utf8mb3 = utf8mb3_bin , LATIN1 = LATIN1_BIN ';
|
||||
SELECT @@character_set_collations;
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
# Relaxed redundant comma parsing
|
||||
SET @@character_set_collations= ',,, utf8mb3 = utf8mb3_bin , , LATIN1 = LATIN1_BIN ,,';
|
||||
SELECT @@character_set_collations;
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
# But at least one comma must be between pairs
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@character_set_collations= 'utf8mb3 = utf8mb3_bin LATIN1 = LATIN1_BIN ';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@character_set_collations= ' 123 ';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@character_set_collations= ' utf8mb3 ';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@character_set_collations= ' utf8mb3 = ';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@character_set_collations= ' utf8mb3 = 123 ';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
SELECT @@character_set_collations;
|
||||
SET @@character_set_collations='';
|
||||
|
||||
--error ER_COLLATION_CHARSET_MISMATCH
|
||||
SET @@character_set_collations='utf8mb3=utf8mb4_general_ci';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_COLLATION_CHARSET_MISMATCH
|
||||
SET @@character_set_collations='utf8mb4=utf8mb3_general_ci';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_general_ci';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
SET @@character_set_collations='utf8mb4=utf8mb4_general_ci,latin1=latin1_bin';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
--error ER_COLLATION_CHARSET_MISMATCH
|
||||
SET @@character_set_collations='utf8mb4=uca1400_ai_ci,latin1=uca1400_ai_ci';
|
||||
|
||||
# All or nothing is set. "Nothing" in this case because of the error on latin1.
|
||||
# The "uca1400_ai_ci FOR utf8mb4" part was ignored.
|
||||
SELECT @@character_set_collations;
|
||||
SELECT @@character_set_collations RLIKE 'utf8mb4=utf8mb4_general_ci' AS expect_true;
|
||||
|
||||
|
||||
SET @@character_set_collations='utf8mb4=uca1400_ai_ci';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SELECT @@collation_connection;
|
||||
|
||||
# We have to disable --view-protocol for the following statement.
|
||||
# 'mtr --view-protocol' creates a separate connection for these statements:
|
||||
# CREATE VIEW mysqltest_tmp_sp AS ...;
|
||||
# DROP VIEW mysqltest_tmp_sp;
|
||||
# The current @@character_set_collations does not affect this connection.
|
||||
# So --view-protocol would return the hard-coded character set collation here,
|
||||
# instead of utf8mb4_uca1400_ai_ci
|
||||
|
||||
--disable_view_protocol
|
||||
SELECT collation('literal');
|
||||
--enable_view_protocol
|
||||
EXECUTE IMMEDIATE 'SELECT COLLATION(?)' USING 'literal';
|
||||
|
||||
CREATE VIEW v1 AS SELECT 'literal', collation('literal') as cl;
|
||||
SHOW CREATE VIEW v1;
|
||||
SELECT * FROM v1;
|
||||
DROP VIEW v1;
|
||||
|
||||
|
||||
# Override @@collation_connection to utf8mb4_general_ci.
|
||||
# Make sure that CREATE statements does not use @@collation_connection.
|
||||
# to detect implicit collations.
|
||||
# Implicit collations are detected using @@character_set_collations!
|
||||
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a TEXT COLLATE DEFAULT) CHARACTER SET utf8mb4;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a TEXT) CHARACTER SET utf8mb4;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE DATABASE db1 CHARACTER SET utf8mb4;
|
||||
SHOW CREATE DATABASE db1;
|
||||
DROP DATABASE db1;
|
||||
|
||||
|
||||
# Test how @@character_set_collations affects various expressions
|
||||
# with implicit collations.
|
||||
|
||||
|
||||
let query=SELECT
|
||||
@@collation_connection AS conn,
|
||||
COLLATION('a') AS lit,
|
||||
COLLATION(CONCAT(1)) AS num,
|
||||
COLLATION(CAST(123 AS CHAR)) AS casti,
|
||||
COLLATION(_utf8mb4'a') AS litu,
|
||||
COLLATION(_utf8mb4 0x62) AS lituh,
|
||||
COLLATION(_utf8mb4 X'63') AS lituhs,
|
||||
COLLATION(CAST(123 AS CHAR CHARACTER SET utf8mb4)) AS castic,
|
||||
COLLATION(CHAR(0x61 USING utf8mb4)) AS chr,
|
||||
COLLATION(CONVERT('a' USING utf8mb4)) AS conv;
|
||||
|
||||
# The below SET NAMES sets @@collation_connection to utf8mb4_general_ci.
|
||||
# But @@character_set_collations still contains utf8mb4=uca1400_ai_ci.
|
||||
|
||||
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
# Columns expected to print utf8mb4_general_ci
|
||||
# because they use @@collation_connection:
|
||||
# - String literals without introducers
|
||||
# - Automatic number-to-string conversions
|
||||
# - CAST(AS CHAR) - without USING
|
||||
#
|
||||
# Columns expected to print utf8mb4_uca1400_ai_ci
|
||||
# because they use the current session default collation
|
||||
# for the character set (as specified in @@collation_connection)
|
||||
# - String literals with introducers
|
||||
# - CAST(AS CHAR USING cs)
|
||||
# - CHAR()
|
||||
# - CONVERT()
|
||||
|
||||
--vertical_results
|
||||
--eval $query;
|
||||
--horizontal_results
|
||||
|
||||
# This sets collation_connection to utf8mb4_uca1400_ai_ci
|
||||
# according to @@character_set_collations.
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
# Now all columns are expected to print utf8mb4_uca1400_ai_ci:
|
||||
# - Some columns because @@collation_connection says so
|
||||
# - Some columns because @@character_set_collations says so.
|
||||
|
||||
--vertical_results
|
||||
--eval $query;
|
||||
--horizontal_results
|
||||
|
||||
|
||||
#
|
||||
# INFORMATION_SCHEMA
|
||||
#
|
||||
|
||||
SET character_set_collations='latin1=latin1_bin,utf8mb4=uca1400_ai_ci';
|
||||
SHOW CHARACTER SET LIKE 'latin1';
|
||||
SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS
|
||||
WHERE CHARACTER_SET_NAME='latin1';
|
||||
|
||||
SHOW COLLATION LIKE 'latin1%';
|
||||
SELECT COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATIONS
|
||||
WHERE CHARACTER_SET_NAME LIKE 'latin1%';
|
||||
SELECT COLLATION_NAME, FULL_COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
WHERE COLLATION_NAME LIKE 'latin1%';
|
||||
|
||||
SHOW CHARACTER SET LIKE 'utf8mb4';
|
||||
SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS
|
||||
WHERE CHARACTER_SET_NAME='utf8mb4';
|
||||
|
||||
SHOW COLLATION LIKE '%uca1400_ai_ci%';
|
||||
SELECT COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATIONS
|
||||
WHERE COLLATION_NAME LIKE '%uca1400_ai_ci%';
|
||||
SELECT COLLATION_NAME, FULL_COLLATION_NAME, IS_DEFAULT
|
||||
FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
WHERE COLLATION_NAME LIKE '%uca1400_ai_ci%';
|
||||
|
||||
#
|
||||
# Prepared statements: reprepare on @@character_set_collations change.
|
||||
#
|
||||
|
||||
SET @@character_set_collations='';
|
||||
PREPARE stmt FROM 'SELECT '
|
||||
'COLLATION(CAST("x" AS CHAR CHARACTER SET utf8mb3)) AS a, '
|
||||
'COLLATION(_utf8mb3"x") AS b';
|
||||
EXECUTE stmt;
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
PREPARE stmt FROM 'SELECT '
|
||||
'COLLATION(CAST("x" AS CHAR CHARACTER SET utf8mb3)) AS a, '
|
||||
'COLLATION(_utf8mb3"x") AS b';
|
||||
EXECUTE stmt;
|
||||
SET @@character_set_collations=DEFAULT;
|
||||
EXECUTE stmt;
|
||||
|
||||
SET NAMES utf8mb3;
|
||||
SET @@character_set_collations='';
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 '
|
||||
'(a TEXT CHARACTER SET utf8mb3 COLLATE DEFAULT COLLATE utf8mb3_general_ci)';
|
||||
EXECUTE stmt;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
SET @@character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
--error ER_CONFLICTING_DECLARATIONS
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @@character_set_collations='';
|
||||
EXECUTE stmt;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
1
mysql-test/main/ctype_collate_implicit_def.opt
Normal file
1
mysql-test/main/ctype_collate_implicit_def.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--character-set-collations=utf8mb3=uca1400_ai_ci,latin1=latin1_bin
|
85
mysql-test/main/ctype_collate_implicit_def.result
Normal file
85
mysql-test/main/ctype_collate_implicit_def.result
Normal file
|
@ -0,0 +1,85 @@
|
|||
#
|
||||
# MDEV-30164 System variable for default collations
|
||||
#
|
||||
SELECT @@global.character_set_collations;
|
||||
@@global.character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_uca1400_ai_ci
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_uca1400_ai_ci
|
||||
SELECT COLLATION('literal');
|
||||
COLLATION('literal')
|
||||
latin1_bin
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
COLLATION_NAME
|
||||
latin1_bin
|
||||
DROP TABLE t1;
|
||||
SET NAMES utf8mb3;
|
||||
SELECT COLLATION('literal');
|
||||
COLLATION('literal')
|
||||
utf8mb3_uca1400_ai_ci
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
COLLATION_NAME
|
||||
utf8mb3_uca1400_ai_ci
|
||||
DROP TABLE t1;
|
||||
SET @@session.character_set_collations='latin1=latin1_german2_ci';
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
latin1=latin1_german2_ci
|
||||
SET @@session.character_set_collations=DEFAULT;
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_uca1400_ai_ci
|
||||
SET @@global.character_set_collations='utf8mb3=uca1400_as_ci,latin1=latin1_danish_ci';
|
||||
connect con1,localhost,root,,;
|
||||
connection con1;
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
latin1=latin1_danish_ci,utf8mb3=utf8mb3_uca1400_as_ci
|
||||
SELECT COLLATION('literal');
|
||||
COLLATION('literal')
|
||||
latin1_danish_ci
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
COLLATION_NAME
|
||||
latin1_danish_ci
|
||||
DROP TABLE t1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
SET @@global.character_set_collations=DEFAULT;
|
||||
SELECT @@global.character_set_collations;
|
||||
@@global.character_set_collations
|
||||
|
||||
connect con2,localhost,root,,;
|
||||
connection con2;
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
|
||||
SELECT COLLATION('literal');
|
||||
COLLATION('literal')
|
||||
latin1_swedish_ci
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
COLLATION_NAME
|
||||
latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
disconnect con2;
|
||||
connection default;
|
||||
SET @@global.character_set_collations='utf8mb3=uca1400_ai_ci,latin1=latin1_bin';
|
||||
connect con3,localhost,root,,;
|
||||
connection con3;
|
||||
SELECT @@session.character_set_collations;
|
||||
@@session.character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_uca1400_ai_ci
|
||||
SELECT COLLATION('literal');
|
||||
COLLATION('literal')
|
||||
latin1_bin
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
COLLATION_NAME
|
||||
latin1_bin
|
||||
DROP TABLE t1;
|
||||
disconnect con3;
|
||||
connection default;
|
73
mysql-test/main/ctype_collate_implicit_def.test
Normal file
73
mysql-test/main/ctype_collate_implicit_def.test
Normal file
|
@ -0,0 +1,73 @@
|
|||
--source include/have_utf8.inc
|
||||
--source include/have_utf8mb4.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30164 System variable for default collations
|
||||
--echo #
|
||||
|
||||
SELECT @@global.character_set_collations;
|
||||
SELECT @@session.character_set_collations;
|
||||
--disable_view_protocol
|
||||
SELECT COLLATION('literal');
|
||||
--enable_view_protocol
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
DROP TABLE t1;
|
||||
|
||||
SET NAMES utf8mb3;
|
||||
--disable_view_protocol
|
||||
SELECT COLLATION('literal');
|
||||
--enable_view_protocol
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
DROP TABLE t1;
|
||||
|
||||
SET @@session.character_set_collations='latin1=latin1_german2_ci';
|
||||
SELECT @@session.character_set_collations;
|
||||
|
||||
SET @@session.character_set_collations=DEFAULT;
|
||||
SELECT @@session.character_set_collations;
|
||||
|
||||
SET @@global.character_set_collations='utf8mb3=uca1400_as_ci,latin1=latin1_danish_ci';
|
||||
|
||||
--connect (con1,localhost,root,,)
|
||||
--connection con1
|
||||
SELECT @@session.character_set_collations;
|
||||
--disable_view_protocol
|
||||
SELECT COLLATION('literal');
|
||||
--enable_view_protocol
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
DROP TABLE t1;
|
||||
--disconnect con1
|
||||
--connection default
|
||||
|
||||
SET @@global.character_set_collations=DEFAULT;
|
||||
SELECT @@global.character_set_collations;
|
||||
|
||||
--connect (con2,localhost,root,,)
|
||||
--connection con2
|
||||
SELECT @@session.character_set_collations;
|
||||
--disable_view_protocol
|
||||
SELECT COLLATION('literal');
|
||||
--enable_view_protocol
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
DROP TABLE t1;
|
||||
--disconnect con2
|
||||
--connection default
|
||||
|
||||
# Set back to the command line value, to avoid mtr internal check failure.
|
||||
SET @@global.character_set_collations='utf8mb3=uca1400_ai_ci,latin1=latin1_bin';
|
||||
|
||||
--connect (con3,localhost,root,,)
|
||||
--connection con3
|
||||
SELECT @@session.character_set_collations;
|
||||
--disable_view_protocol
|
||||
SELECT COLLATION('literal');
|
||||
--enable_view_protocol
|
||||
CREATE TABLE t1 AS SELECT 'literal' AS c1;
|
||||
SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='t1';
|
||||
DROP TABLE t1;
|
||||
--disconnect con3
|
||||
--connection default
|
19
mysql-test/main/ctype_collate_implicit_utf32.result
Normal file
19
mysql-test/main/ctype_collate_implicit_utf32.result
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# MDEV-30164 System variable for default collations
|
||||
#
|
||||
SET @@character_set_collations= CONVERT('latin1=latin1_bin,utf8mb3=utf8mb3_bin' USING utf32);
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
latin1=latin1_bin,utf8mb3=utf8mb3_bin
|
||||
SET @@character_set_collations=_utf32'';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
||||
SET @@character_set_collations= CONVERT('utf32=utf32_bin' USING utf32);
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
utf32=utf32_bin
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
||||
@@character_set_collations
|
||||
|
16
mysql-test/main/ctype_collate_implicit_utf32.test
Normal file
16
mysql-test/main/ctype_collate_implicit_utf32.test
Normal file
|
@ -0,0 +1,16 @@
|
|||
--source include/have_utf8.inc
|
||||
--source include/have_utf32.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30164 System variable for default collations
|
||||
--echo #
|
||||
|
||||
SET @@character_set_collations= CONVERT('latin1=latin1_bin,utf8mb3=utf8mb3_bin' USING utf32);
|
||||
SELECT @@character_set_collations;
|
||||
SET @@character_set_collations=_utf32'';
|
||||
SELECT @@character_set_collations;
|
||||
|
||||
SET @@character_set_collations= CONVERT('utf32=utf32_bin' USING utf32);
|
||||
SELECT @@character_set_collations;
|
||||
SET @@character_set_collations='';
|
||||
SELECT @@character_set_collations;
|
|
@ -1819,6 +1819,7 @@ SET CHARACTER SET utf8;
|
|||
SHOW VARIABLES LIKE 'character\_set\_%';
|
||||
Variable_name Value
|
||||
character_set_client utf8mb3
|
||||
character_set_collations
|
||||
character_set_connection latin1
|
||||
character_set_database latin1
|
||||
character_set_filesystem binary
|
||||
|
|
|
@ -1844,6 +1844,7 @@ SET CHARACTER SET utf8mb4;
|
|||
SHOW VARIABLES LIKE 'character\_set\_%';
|
||||
Variable_name Value
|
||||
character_set_client utf8mb4
|
||||
character_set_collations
|
||||
character_set_connection latin1
|
||||
character_set_database latin1
|
||||
character_set_filesystem binary
|
||||
|
|
|
@ -1676,6 +1676,7 @@ SET CHARACTER SET utf8mb4;
|
|||
SHOW VARIABLES LIKE 'character\_set\_%';
|
||||
Variable_name Value
|
||||
character_set_client utf8mb4
|
||||
character_set_collations
|
||||
character_set_connection latin1
|
||||
character_set_database latin1
|
||||
character_set_filesystem binary
|
||||
|
|
|
@ -1802,6 +1802,7 @@ SET CHARACTER SET utf8mb4;
|
|||
SHOW VARIABLES LIKE 'character\_set\_%';
|
||||
Variable_name Value
|
||||
character_set_client utf8mb4
|
||||
character_set_collations
|
||||
character_set_connection latin1
|
||||
character_set_database latin1
|
||||
character_set_filesystem binary
|
||||
|
|
|
@ -1809,6 +1809,7 @@ SET CHARACTER SET utf8mb4;
|
|||
SHOW VARIABLES LIKE 'character\_set\_%';
|
||||
Variable_name Value
|
||||
character_set_client utf8mb4
|
||||
character_set_collations
|
||||
character_set_connection latin1
|
||||
character_set_database latin1
|
||||
character_set_filesystem binary
|
||||
|
|
|
@ -564,6 +564,7 @@ SET @@session.sql_mode=#/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=#/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
create table t1 (a varchar(64) character set utf8)
|
||||
|
|
|
@ -144,6 +144,8 @@ The following specify which files/extra groups are read (specified before remain
|
|||
Don't ignore client side character set value sent during
|
||||
handshake.
|
||||
(Defaults to on; use --skip-character-set-client-handshake to disable.)
|
||||
--character-set-collations=name
|
||||
Overrides for character set default collations.
|
||||
--character-set-filesystem=name
|
||||
Set the filesystem character set.
|
||||
-C, --character-set-server=name
|
||||
|
@ -1574,6 +1576,7 @@ binlog-row-metadata NO_LOG
|
|||
binlog-stmt-cache-size 32768
|
||||
bulk-insert-buffer-size 8388608
|
||||
character-set-client-handshake TRUE
|
||||
character-set-collations
|
||||
character-set-filesystem binary
|
||||
character-sets-dir MYSQL_CHARSETSDIR/
|
||||
chroot (No default value)
|
||||
|
|
|
@ -1934,7 +1934,6 @@ START TRANSACTION
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.time_zone='SYSTEM'/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2320,6 +2319,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c37 NATIONAL CHAR)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2378,6 +2378,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c38 NATIONAL CHAR(0))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2436,6 +2437,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c39 NATIONAL CHAR(1))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2494,6 +2496,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c40 NATIONAL CHAR(255))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2576,6 +2579,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c41 CHAR CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2634,6 +2638,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c42 CHAR(0) CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2692,6 +2697,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c43 CHAR(1) CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -2750,6 +2756,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c44 CHAR(255) CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3064,6 +3071,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c49 NATIONAL VARCHAR(0))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3122,6 +3130,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c50 NATIONAL VARCHAR(1))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3180,6 +3189,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c51 NATIONAL VARCHAR(255))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3262,6 +3272,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c52 NATIONAL VARCHAR(261))
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3344,6 +3355,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c53 VARCHAR(0) CHARACTER SET ucs2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3402,6 +3414,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c54 VARCHAR(1) CHARACTER SET ucs2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3460,6 +3473,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c55 VARCHAR(255) CHARACTER SET ucs2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -3518,6 +3532,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c56 VARCHAR(261) CHARACTER SET ucs2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -4656,6 +4671,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c67 TINYTEXT CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -4714,6 +4730,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c70 TEXT CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -4772,6 +4789,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c73 MEDIUMTEXT CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -4830,6 +4848,7 @@ DROP TABLE `t1` /* generated by server */
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t1 (c76 LONGTEXT CHARACTER SET UCS2)
|
||||
/*!*/;
|
||||
# at #
|
||||
|
|
|
@ -2275,6 +2275,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -5284,6 +5285,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -5684,6 +5686,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -5698,6 +5701,7 @@ c_1_n INT -- row number
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t2 (
|
||||
c_2_1 DATE,
|
||||
c_2_2 VARCHAR(255),
|
||||
|
@ -5710,6 +5714,7 @@ c_2_n INT -- row number
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t3 (
|
||||
c_3_1 DATE,
|
||||
c_3_2 VARCHAR(255),
|
||||
|
@ -6322,6 +6327,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
|
|
@ -2273,6 +2273,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -2547,7 +2548,6 @@ START TRANSACTION
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.time_zone='SYSTEM'/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -5305,6 +5305,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -5711,6 +5712,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -5725,6 +5727,7 @@ c_1_n INT -- row number
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t2 (
|
||||
c_2_1 DATE,
|
||||
c_2_2 VARCHAR(255),
|
||||
|
@ -5737,6 +5740,7 @@ c_2_n INT -- row number
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t3 (
|
||||
c_3_1 DATE,
|
||||
c_3_2 VARCHAR(255),
|
||||
|
@ -6359,6 +6363,7 @@ SET @@session.sql_mode=0/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=utf8mb3,@@session.collation_connection=33,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
|
|
@ -151,6 +151,7 @@ SET @@session.sql_mode=1411383296/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (
|
||||
|
@ -164,6 +165,7 @@ c2 VARCHAR(20)
|
|||
# at #
|
||||
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
CREATE TABLE t2 (
|
||||
c1 INT,
|
||||
c2 VARCHAR(20)
|
||||
|
|
|
@ -97,6 +97,7 @@ SET @@session.sql_mode=1411383296/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8)
|
||||
|
|
|
@ -99,6 +99,7 @@ SET @@session.sql_mode=1411383296/*!*/;
|
|||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C utf8mb3 *//*!*/;
|
||||
SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8)
|
||||
|
@ -126,6 +127,7 @@ START TRANSACTION
|
|||
# at #
|
||||
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=XXX/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
INSERT INTO t1 VALUES ('ä(i2)')
|
||||
/*!*/;
|
||||
# at #
|
||||
|
@ -171,6 +173,7 @@ START TRANSACTION
|
|||
# at #
|
||||
#YYMMDD HH:MM:SS server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid=<xid>
|
||||
SET TIMESTAMP=XXX/*!*/;
|
||||
SET @@session.character_set_collations=''/*!*/;
|
||||
INSERT INTO t1 VALUES ('ä(p2)')
|
||||
/*!*/;
|
||||
# at #
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
RESET MASTER;
|
||||
SET timestamp=1000000000;
|
||||
#
|
||||
# MDEV-30164 System variable for default collations
|
||||
#
|
||||
SET character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin';
|
||||
CREATE TABLE t1 (a VARCHAR(20));
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4);
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin);
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3);
|
||||
INSERT INTO t1 VALUES ('a00');
|
||||
INSERT INTO t1 VALUES (_utf8mb3'a01-utf8mb3');
|
||||
INSERT INTO t1 VALUES (_utf8mb4'a01-utf8mb4');
|
||||
PREPARE stmt FROM 'INSERT INTO t1 VALUES (?)';
|
||||
EXECUTE stmt USING _utf8mb3'a02-utf8mb3';
|
||||
EXECUTE stmt USING _utf8mb4'a02-utf8mb4';
|
||||
EXECUTE stmt USING CONVERT('a03-utf8mb3' USING utf8mb3);
|
||||
EXECUTE stmt USING CONVERT('a03-utf8mb4' USING utf8mb4);
|
||||
EXECUTE stmt USING IF(0,CONVERT('a04-utf8mb3' USING utf8mb3),CONVERT('a03-utf8mb4' USING utf8mb4));
|
||||
EXECUTE stmt USING IF(1,CONVERT('a04-utf8mb3' USING utf8mb3),CONVERT('a03-utf8mb4' USING utf8mb4));
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
EXECUTE IMMEDIATE 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)';
|
||||
DROP TABLE t1;
|
||||
EXECUTE IMMEDIATE 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)';
|
||||
DROP TABLE t1;
|
||||
FLUSH LOGS;
|
||||
|
||||
--- ---- ---
|
||||
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
|
||||
/*!40019 SET @@session.max_delayed_threads=0*/;
|
||||
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||
DELIMITER /*!*/;
|
||||
ROLLBACK/*!*/;
|
||||
use `test`/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.pseudo_thread_id=999999999/*!*/;
|
||||
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0, @@session.explicit_defaults_for_timestamp=1, @@session.system_versioning_insert_history=0/*!*/;
|
||||
SET @@session.sql_mode=#/*!*/;
|
||||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=#/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20))
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
INSERT INTO t1 VALUES ('a00')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES (_utf8mb3'a01-utf8mb3')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES (_utf8mb4'a01-utf8mb4')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a02-utf8mb3')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a02-utf8mb4')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a03-utf8mb3')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a03-utf8mb4')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a03-utf8mb4')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
INSERT INTO t1 VALUES ('a04-utf8mb3')
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin'/*!*/;
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE `t1` /* generated by server */
|
||||
/*!*/;
|
||||
DELIMITER ;
|
||||
# End of log file
|
||||
ROLLBACK /* added by mysqlbinlog */;
|
||||
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
||||
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
|
|
@ -0,0 +1,77 @@
|
|||
-- source include/have_utf8.inc
|
||||
-- source include/have_utf8mb4.inc
|
||||
-- source include/have_ucs2.inc
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
-- source include/have_log_bin.inc
|
||||
|
||||
--disable_query_log
|
||||
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||
--enable_query_log
|
||||
|
||||
RESET MASTER;
|
||||
SET timestamp=1000000000;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30164 System variable for default collations
|
||||
--echo #
|
||||
|
||||
SET character_set_collations='utf8mb3=utf8mb3_bin,ucs2=ucs2_bin';
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(20));
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4);
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin);
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3);
|
||||
|
||||
INSERT INTO t1 VALUES ('a00');
|
||||
INSERT INTO t1 VALUES (_utf8mb3'a01-utf8mb3');
|
||||
INSERT INTO t1 VALUES (_utf8mb4'a01-utf8mb4');
|
||||
|
||||
PREPARE stmt FROM 'INSERT INTO t1 VALUES (?)';
|
||||
EXECUTE stmt USING _utf8mb3'a02-utf8mb3';
|
||||
EXECUTE stmt USING _utf8mb4'a02-utf8mb4';
|
||||
|
||||
EXECUTE stmt USING CONVERT('a03-utf8mb3' USING utf8mb3);
|
||||
EXECUTE stmt USING CONVERT('a03-utf8mb4' USING utf8mb4);
|
||||
|
||||
EXECUTE stmt USING IF(0,CONVERT('a04-utf8mb3' USING utf8mb3),CONVERT('a03-utf8mb4' USING utf8mb4));
|
||||
EXECUTE stmt USING IF(1,CONVERT('a04-utf8mb3' USING utf8mb3),CONVERT('a03-utf8mb4' USING utf8mb4));
|
||||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
PREPARE stmt FROM 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
|
||||
EXECUTE IMMEDIATE 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb4)';
|
||||
DROP TABLE t1;
|
||||
|
||||
EXECUTE IMMEDIATE 'CREATE TABLE t1 (a VARCHAR(20) CHARACTER SET utf8mb3)';
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
### Starting master-bin.000002
|
||||
FLUSH LOGS;
|
||||
|
||||
--disable_query_log
|
||||
SELECT "--- ---- ---" as "";
|
||||
--enable_query_log
|
||||
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/
|
||||
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000001
|
83
mysql-test/suite/rpl/r/rpl_ctype_collate_implicit.result
Normal file
83
mysql-test/suite/rpl/r/rpl_ctype_collate_implicit.result
Normal file
|
@ -0,0 +1,83 @@
|
|||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-30164 System variable for default collations
|
||||
#
|
||||
connection master;
|
||||
SET @@character_set_collations='utf8mb3=uca1400_ai_ci,'
|
||||
'utf8mb4=uca1400_ai_ci,'
|
||||
'ucs2=uca1400_ai_ci,'
|
||||
'utf16=uca1400_ai_ci,'
|
||||
'utf32=uca1400_ai_ci';
|
||||
connection master;
|
||||
CREATE TABLE t1 AS SELECT CHAR(0x61 USING utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`CHAR(0x61 USING utf8mb4)` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection slave;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`CHAR(0x61 USING utf8mb4)` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
connection master;
|
||||
CREATE TABLE t1 AS SELECT CONVERT('a' USING utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`CONVERT('a' USING utf8mb4)` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection slave;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`CONVERT('a' USING utf8mb4)` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
connection master;
|
||||
CREATE TABLE t1 (
|
||||
c0 TEXT CHARACTER SET utf8mb3,
|
||||
c1 TEXT CHARACTER SET utf8mb4,
|
||||
c2 TEXT CHARACTER SET utf16,
|
||||
c3 TEXT CHARACTER SET utf32,
|
||||
c4 TEXT CHARACTER SET ucs2
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c0` text CHARACTER SET utf8mb3 COLLATE utf8mb3_uca1400_ai_ci DEFAULT NULL,
|
||||
`c1` text CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL,
|
||||
`c2` text CHARACTER SET utf16 COLLATE utf16_uca1400_ai_ci DEFAULT NULL,
|
||||
`c3` text CHARACTER SET utf32 COLLATE utf32_uca1400_ai_ci DEFAULT NULL,
|
||||
`c4` text CHARACTER SET ucs2 COLLATE ucs2_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection slave;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c0` text CHARACTER SET utf8mb3 COLLATE utf8mb3_uca1400_ai_ci DEFAULT NULL,
|
||||
`c1` text CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DEFAULT NULL,
|
||||
`c2` text CHARACTER SET utf16 COLLATE utf16_uca1400_ai_ci DEFAULT NULL,
|
||||
`c3` text CHARACTER SET utf32 COLLATE utf32_uca1400_ai_ci DEFAULT NULL,
|
||||
`c4` text CHARACTER SET ucs2 COLLATE ucs2_uca1400_ai_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
connection master;
|
||||
CREATE DATABASE db1 CHARACTER SET utf8mb4;
|
||||
connection slave;
|
||||
SHOW CREATE DATABASE db1;
|
||||
Database Create Database
|
||||
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci */
|
||||
connection master;
|
||||
DROP DATABASE db1;
|
||||
connection slave;
|
||||
include/rpl_end.inc
|
|
@ -52,7 +52,7 @@ SET TIMESTAMP=1293832861.123456/*!*/;
|
|||
SET @@session.time_zone='+03:00'/*!*/;
|
||||
insert t1 (b,c) values (now(6), now(6))
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1293832861.123456/*!*/;
|
||||
SET TIMESTAMP=1293832861/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
|
@ -68,7 +68,7 @@ START TRANSACTION
|
|||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
insert t1 (b,c) values (now(), now())
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
SET TIMESTAMP=1643756522/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
|
@ -76,7 +76,7 @@ START TRANSACTION
|
|||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
insert t1 (b,c) values (0,0)
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
SET TIMESTAMP=1643756522/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
START TRANSACTION
|
||||
|
@ -84,7 +84,7 @@ START TRANSACTION
|
|||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
insert t1 (a,b,c) values (0,0,now(6))
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1643756522.654321/*!*/;
|
||||
SET TIMESTAMP=1643756522/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
SET TIMESTAMP=1643756522/*!*/;
|
||||
|
|
60
mysql-test/suite/rpl/t/rpl_ctype_collate_implicit.test
Normal file
60
mysql-test/suite/rpl/t/rpl_ctype_collate_implicit.test
Normal file
|
@ -0,0 +1,60 @@
|
|||
--source include/have_binlog_format_row.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30164 System variable for default collations
|
||||
--echo #
|
||||
|
||||
--connection master
|
||||
SET @@character_set_collations='utf8mb3=uca1400_ai_ci,'
|
||||
'utf8mb4=uca1400_ai_ci,'
|
||||
'ucs2=uca1400_ai_ci,'
|
||||
'utf16=uca1400_ai_ci,'
|
||||
'utf32=uca1400_ai_ci';
|
||||
|
||||
--connection master
|
||||
CREATE TABLE t1 AS SELECT CHAR(0x61 USING utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
--sync_slave_with_master
|
||||
SHOW CREATE TABLE t1;
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--connection master
|
||||
CREATE TABLE t1 AS SELECT CONVERT('a' USING utf8mb4);
|
||||
SHOW CREATE TABLE t1;
|
||||
--sync_slave_with_master
|
||||
SHOW CREATE TABLE t1;
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--connection master
|
||||
CREATE TABLE t1 (
|
||||
c0 TEXT CHARACTER SET utf8mb3,
|
||||
c1 TEXT CHARACTER SET utf8mb4,
|
||||
c2 TEXT CHARACTER SET utf16,
|
||||
c3 TEXT CHARACTER SET utf32,
|
||||
c4 TEXT CHARACTER SET ucs2
|
||||
);
|
||||
SHOW CREATE TABLE t1;
|
||||
--sync_slave_with_master
|
||||
SHOW CREATE TABLE t1;
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--connection master
|
||||
CREATE DATABASE db1 CHARACTER SET utf8mb4;
|
||||
--sync_slave_with_master
|
||||
SHOW CREATE DATABASE db1;
|
||||
--connection master
|
||||
DROP DATABASE db1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--source include/rpl_end.inc
|
|
@ -502,6 +502,16 @@ NUMERIC_BLOCK_SIZE NULL
|
|||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT NULL
|
||||
VARIABLE_NAME CHARACTER_SET_COLLATIONS
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE VARCHAR
|
||||
VARIABLE_COMMENT Overrides for character set default collations
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT NULL
|
||||
VARIABLE_NAME CHARACTER_SET_CONNECTION
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE ENUM
|
||||
|
|
|
@ -542,6 +542,16 @@ NUMERIC_BLOCK_SIZE NULL
|
|||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT NULL
|
||||
VARIABLE_NAME CHARACTER_SET_COLLATIONS
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE VARCHAR
|
||||
VARIABLE_COMMENT Overrides for character set default collations
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT NULL
|
||||
VARIABLE_NAME CHARACTER_SET_CONNECTION
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE ENUM
|
||||
|
|
|
@ -166,7 +166,7 @@ SET (SQL_SOURCE
|
|||
semisync.cc semisync_master.cc semisync_slave.cc
|
||||
semisync_master_ack_receiver.cc
|
||||
sql_schema.cc
|
||||
lex_charset.cc
|
||||
lex_charset.cc charset_collations.cc
|
||||
sql_type.cc sql_mode.cc sql_type_json.cc
|
||||
sql_type_string.cc
|
||||
sql_type_geom.cc
|
||||
|
|
117
sql/charset_collations.cc
Normal file
117
sql/charset_collations.cc
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* Copyright (c) 2023, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
|
||||
#include "my_global.h"
|
||||
#include "my_sys.h"
|
||||
#include "lex_charset.h"
|
||||
#include "mysqld_error.h"
|
||||
#include "charset_collations.h"
|
||||
#include "simple_tokenizer.h"
|
||||
|
||||
bool Charset_collation_map_st::insert_or_replace(
|
||||
const Lex_exact_charset &charset,
|
||||
const Lex_extended_collation &collation,
|
||||
bool error_on_conflicting_duplicate)
|
||||
{
|
||||
Lex_exact_charset_opt_extended_collate res(charset);
|
||||
Sql_used used;
|
||||
if (res.merge_collation_override(&used, *this, collation))
|
||||
return true;
|
||||
|
||||
if (error_on_conflicting_duplicate)
|
||||
{
|
||||
const Elem_st *dup;
|
||||
if ((dup= find_elem_by_charset_id(charset.charset_info()->number)) &&
|
||||
dup->to() != res.collation().charset_info())
|
||||
{
|
||||
my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
|
||||
"", dup->to()->coll_name.str,
|
||||
"", res.collation().charset_info()->coll_name.str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return insert_or_replace(Elem(charset.charset_info(),
|
||||
res.collation().charset_info()));
|
||||
}
|
||||
|
||||
|
||||
bool Charset_collation_map_st::insert_or_replace(
|
||||
const LEX_CSTRING &cs_name,
|
||||
const LEX_CSTRING &cl_name,
|
||||
bool error_on_conflicting_duplicate,
|
||||
myf utf8_flag)
|
||||
{
|
||||
char charset_name_c[MY_CS_CHARACTER_SET_NAME_SIZE + 1/*for '\0'*/];
|
||||
strmake(charset_name_c, cs_name.str, cs_name.length);
|
||||
CHARSET_INFO *cs= get_charset_by_csname(charset_name_c,
|
||||
MY_CS_PRIMARY, utf8_flag);
|
||||
if (!cs)
|
||||
{
|
||||
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), charset_name_c);
|
||||
return true;
|
||||
}
|
||||
|
||||
char collation_name_c[MY_CS_COLLATION_NAME_SIZE + 1/*for '\0'*/];
|
||||
strmake(collation_name_c, cl_name.str, cl_name.length);
|
||||
|
||||
Lex_exact_collation tmpec(&my_charset_bin);
|
||||
Lex_extended_collation tmp(tmpec);
|
||||
if (tmp.set_by_name(collation_name_c, utf8_flag))
|
||||
return true;
|
||||
|
||||
return insert_or_replace(Lex_exact_charset(cs), tmp,
|
||||
error_on_conflicting_duplicate);
|
||||
}
|
||||
|
||||
|
||||
bool Charset_collation_map_st::from_text(const LEX_CSTRING &str, myf utf8_flag)
|
||||
{
|
||||
init();
|
||||
Simple_tokenizer stream(str.str, str.length);
|
||||
|
||||
/*
|
||||
Allow relaxed comma parsing:
|
||||
SET @@character_set_collations=
|
||||
',,,utf8mb3 = utf8mb3_bin,,latin1 = latin1_bin,,,';
|
||||
It makes it easier for the user to edit the value
|
||||
using SQL functions CONCAT or REGEXP_REPLACE.
|
||||
*/
|
||||
for ( ; ; )
|
||||
{
|
||||
LEX_CSTRING charset_name= stream.get_ident();
|
||||
if (charset_name.length)
|
||||
{
|
||||
if (stream.get_char('='))
|
||||
return true;
|
||||
LEX_CSTRING collation_name= stream.get_ident();
|
||||
if (!collation_name.length)
|
||||
return true;
|
||||
/*
|
||||
Don't allow duplicate conflicting declarations within the same string:
|
||||
SET @@var='utf8mb3=utf8mb3_general_ci,utf8mb3=utf8mb3_bin';
|
||||
*/
|
||||
if (insert_or_replace(charset_name, collation_name,
|
||||
true/*err on dup*/, utf8_flag))
|
||||
return true;
|
||||
}
|
||||
if (!stream.get_char(','))
|
||||
continue;
|
||||
if (stream.eof())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
247
sql/charset_collations.h
Normal file
247
sql/charset_collations.h
Normal file
|
@ -0,0 +1,247 @@
|
|||
/* Copyright (c) 2023, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#ifndef LEX_CHARSET_COLLATIONS_INCLUDED
|
||||
#define LEX_CHARSET_COLLATIONS_INCLUDED
|
||||
|
||||
#include "sql_used.h"
|
||||
|
||||
struct Charset_collation_map_st
|
||||
{
|
||||
public:
|
||||
|
||||
struct Elem_st
|
||||
{
|
||||
protected:
|
||||
CHARSET_INFO *m_from; // From a character set
|
||||
CHARSET_INFO *m_to; // To a collation
|
||||
static size_t print_lex_string(char *dst, const LEX_CSTRING &str)
|
||||
{
|
||||
memcpy(dst, str.str, str.length);
|
||||
return str.length;
|
||||
}
|
||||
public:
|
||||
/*
|
||||
Size in text format: 'utf8mb4=utf8mb4_unicode_ai_ci'
|
||||
*/
|
||||
static constexpr size_t text_size_max()
|
||||
{
|
||||
return MY_CS_CHARACTER_SET_NAME_SIZE + 1 +
|
||||
MY_CS_COLLATION_NAME_SIZE;
|
||||
}
|
||||
CHARSET_INFO *from() const
|
||||
{
|
||||
return m_from;
|
||||
}
|
||||
CHARSET_INFO *to() const
|
||||
{
|
||||
return m_to;
|
||||
}
|
||||
void set_to(CHARSET_INFO *cl)
|
||||
{
|
||||
m_to= cl;
|
||||
}
|
||||
size_t print(char *dst) const
|
||||
{
|
||||
const char *dst0= dst;
|
||||
dst+= print_lex_string(dst, m_from->cs_name);
|
||||
*dst++= '=';
|
||||
dst+= print_lex_string(dst, m_to->coll_name);
|
||||
return (size_t) (dst - dst0);
|
||||
}
|
||||
int cmp_by_charset_id(const Elem_st &rhs) const
|
||||
{
|
||||
return m_from->number < rhs.m_from->number ? -1 :
|
||||
m_from->number > rhs.m_from->number ? +1 : 0;
|
||||
}
|
||||
};
|
||||
class Elem: public Elem_st
|
||||
{
|
||||
public:
|
||||
Elem(CHARSET_INFO *from, CHARSET_INFO *to)
|
||||
{
|
||||
m_from= from;
|
||||
m_to= to;
|
||||
}
|
||||
};
|
||||
protected:
|
||||
Elem_st m_element[8]; // Should be enough for now
|
||||
uint m_count;
|
||||
uint m_version;
|
||||
|
||||
static int cmp_by_charset_id(const void *a, const void *b)
|
||||
{
|
||||
return static_cast<const Elem_st*>(a)->
|
||||
cmp_by_charset_id(*static_cast<const Elem_st*>(b));
|
||||
}
|
||||
|
||||
void sort()
|
||||
{
|
||||
qsort(m_element, m_count, sizeof(Elem_st), cmp_by_charset_id);
|
||||
}
|
||||
|
||||
const Elem_st *find_elem_by_charset_id(uint id) const
|
||||
{
|
||||
if (!m_count)
|
||||
return NULL;
|
||||
int first= 0, last= ((int) m_count) - 1;
|
||||
for ( ; first <= last; )
|
||||
{
|
||||
const int middle= (first + last) / 2;
|
||||
DBUG_ASSERT(middle >= 0);
|
||||
DBUG_ASSERT(middle < (int) m_count);
|
||||
const uint middle_id= m_element[middle].from()->number;
|
||||
if (middle_id == id)
|
||||
return &m_element[middle];
|
||||
if (middle_id < id)
|
||||
first= middle + 1;
|
||||
else
|
||||
last= middle - 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool insert(const Elem_st &elem)
|
||||
{
|
||||
DBUG_ASSERT(elem.from()->state & MY_CS_PRIMARY);
|
||||
if (m_count >= array_elements(m_element))
|
||||
return true;
|
||||
m_element[m_count]= elem;
|
||||
m_count++;
|
||||
sort();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool insert_or_replace(const Elem_st &elem)
|
||||
{
|
||||
DBUG_ASSERT(elem.from()->state & MY_CS_PRIMARY);
|
||||
const Elem_st *found= find_elem_by_charset_id(elem.from()->number);
|
||||
if (found)
|
||||
{
|
||||
const_cast<Elem_st*>(found)->set_to(elem.to());
|
||||
return false;
|
||||
}
|
||||
return insert(elem);
|
||||
}
|
||||
|
||||
public:
|
||||
void init()
|
||||
{
|
||||
m_count= 0;
|
||||
m_version= 0;
|
||||
}
|
||||
uint count() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
uint version() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
void set(const Charset_collation_map_st &rhs, uint version_increment)
|
||||
{
|
||||
uint version= m_version;
|
||||
*this= rhs;
|
||||
m_version= version + version_increment;
|
||||
}
|
||||
const Elem_st & operator[](uint pos) const
|
||||
{
|
||||
DBUG_ASSERT(pos < m_count);
|
||||
return m_element[pos];
|
||||
}
|
||||
bool insert_or_replace(const class Lex_exact_charset &cs,
|
||||
const class Lex_extended_collation &cl,
|
||||
bool error_on_conflicting_duplicate);
|
||||
bool insert_or_replace(const LEX_CSTRING &cs,
|
||||
const LEX_CSTRING &cl,
|
||||
bool error_on_conflicting_duplicate,
|
||||
myf utf8_flag);
|
||||
CHARSET_INFO *get_collation_for_charset(Sql_used *used,
|
||||
CHARSET_INFO *cs) const
|
||||
{
|
||||
DBUG_ASSERT(cs->state & MY_CS_PRIMARY);
|
||||
const Elem_st *elem= find_elem_by_charset_id(cs->number);
|
||||
used->used|= Sql_used::CHARACTER_SET_COLLATIONS_USED;
|
||||
if (elem)
|
||||
return elem->to();
|
||||
return cs;
|
||||
}
|
||||
size_t text_format_nbytes_needed() const
|
||||
{
|
||||
return (Elem_st::text_size_max() + 1/* for ',' */) * m_count;
|
||||
}
|
||||
size_t print(char *dst, size_t nbytes_available) const
|
||||
{
|
||||
const char *dst0= dst;
|
||||
const char *end= dst + nbytes_available;
|
||||
for (uint i= 0; i < m_count; i++)
|
||||
{
|
||||
if (Elem_st::text_size_max() + 1/* for ',' */ > (size_t) (end - dst))
|
||||
break;
|
||||
if (i > 0)
|
||||
*dst++= ',';
|
||||
dst+= m_element[i].print(dst);
|
||||
}
|
||||
return dst - dst0;
|
||||
}
|
||||
static constexpr size_t binary_size_max()
|
||||
{
|
||||
return 1/*count*/ + 4 * array_elements(m_element);
|
||||
}
|
||||
size_t to_binary(char *dst) const
|
||||
{
|
||||
const char *dst0= dst;
|
||||
*dst++= (char) (uchar) m_count;
|
||||
for (uint i= 0; i < m_count; i++)
|
||||
{
|
||||
int2store(dst, (uint16) m_element[i].from()->number);
|
||||
dst+= 2;
|
||||
int2store(dst, (uint16) m_element[i].to()->number);
|
||||
dst+= 2;
|
||||
}
|
||||
return (size_t) (dst - dst0);
|
||||
}
|
||||
size_t from_binary(const char *src, size_t srclen)
|
||||
{
|
||||
const char *src0= src;
|
||||
init();
|
||||
if (!srclen)
|
||||
return 0; // Empty
|
||||
uint count= (uchar) *src++;
|
||||
if (srclen < 1 + 4 * count)
|
||||
return 0;
|
||||
for (uint i= 0; i < count; i++, src+= 4)
|
||||
{
|
||||
CHARSET_INFO *cs, *cl;
|
||||
if (!(cs= get_charset(uint2korr(src), MYF(0))) ||
|
||||
!(cl= get_charset(uint2korr(src + 2), MYF(0))))
|
||||
{
|
||||
/*
|
||||
Unpacking from binary format happens on the slave side.
|
||||
If for some reasons the slave does not know about a
|
||||
character set or a collation, just skip the pair here.
|
||||
This pair might not even be needed.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
insert_or_replace(Elem(cs, cl));
|
||||
}
|
||||
return src - src0;
|
||||
}
|
||||
bool from_text(const LEX_CSTRING &str, myf utf8_flag);
|
||||
};
|
||||
|
||||
|
||||
#endif // LEX_CHARSET_COLLATIONS_INCLUDED
|
|
@ -5340,7 +5340,9 @@ public:
|
|||
- find a _bin collation if the BINARY comparison style was specified, e.g.:
|
||||
CREATE TABLE t1 (a VARCHAR(10) BINARY) CHARSET utf8;
|
||||
*/
|
||||
bool prepare_charset_for_string(const Column_derived_attributes *dattr);
|
||||
bool prepare_charset_for_string(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Column_derived_attributes *dattr);
|
||||
|
||||
/**
|
||||
Prepare a SET/ENUM field.
|
||||
|
@ -5495,10 +5497,11 @@ public:
|
|||
|
||||
bool check_vcol_for_key(THD *thd) const;
|
||||
|
||||
void set_charset_collation_attrs(const
|
||||
void set_charset_collation_attrs(Sql_used *used,
|
||||
const Charset_collation_map_st &map, const
|
||||
Lex_column_charset_collation_attrs_st &lc)
|
||||
{
|
||||
charset= lc.charset_info();
|
||||
charset= lc.charset_info(used, map);
|
||||
if (lc.is_contextually_typed_collation())
|
||||
flags|= CONTEXT_COLLATION_FLAG;
|
||||
else
|
||||
|
|
|
@ -2366,32 +2366,42 @@ struct Table_specification_st: public HA_CREATE_INFO,
|
|||
convert_charset_collation.init();
|
||||
}
|
||||
|
||||
bool add_table_option_convert_charset(CHARSET_INFO *cs)
|
||||
bool add_table_option_convert_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
// cs can be NULL, e.g.: ALTER TABLE t1 CONVERT TO CHARACTER SET DEFAULT;
|
||||
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
|
||||
return cs ?
|
||||
convert_charset_collation.merge_exact_charset(Lex_exact_charset(cs)) :
|
||||
convert_charset_collation.merge_exact_charset(used, map,
|
||||
Lex_exact_charset(cs)) :
|
||||
convert_charset_collation.merge_charset_default();
|
||||
}
|
||||
bool add_table_option_convert_collation(const Lex_extended_collation_st &cl)
|
||||
bool add_table_option_convert_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
|
||||
return convert_charset_collation.merge_collation(cl);
|
||||
return convert_charset_collation.merge_collation(used, map, cl);
|
||||
}
|
||||
|
||||
bool add_table_option_default_charset(CHARSET_INFO *cs)
|
||||
bool add_table_option_default_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
// cs can be NULL, e.g.: CREATE TABLE t1 (..) CHARACTER SET DEFAULT;
|
||||
used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
||||
return cs ?
|
||||
default_charset_collation.merge_exact_charset(Lex_exact_charset(cs)) :
|
||||
default_charset_collation.merge_exact_charset(used, map,
|
||||
Lex_exact_charset(cs)) :
|
||||
default_charset_collation.merge_charset_default();
|
||||
}
|
||||
bool add_table_option_default_collation(const Lex_extended_collation_st &cl)
|
||||
bool add_table_option_default_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
||||
return default_charset_collation.merge_collation(cl);
|
||||
return default_charset_collation.merge_collation(used, map, cl);
|
||||
}
|
||||
|
||||
bool resolve_to_charset_collation_context(THD *thd,
|
||||
|
|
|
@ -3785,10 +3785,12 @@ public:
|
|||
}
|
||||
bool set(const Type_handler *handler,
|
||||
const Lex_length_and_dec_st & length_and_dec,
|
||||
Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_column_charset_collation_attrs_st &cscl,
|
||||
CHARSET_INFO *defcs)
|
||||
{
|
||||
CHARSET_INFO *tmp= cscl.resolved_to_character_set(defcs);
|
||||
CHARSET_INFO *tmp= cscl.resolved_to_character_set(used, map, defcs);
|
||||
if (!tmp)
|
||||
return true;
|
||||
set(handler, length_and_dec, tmp);
|
||||
|
|
|
@ -3830,7 +3830,9 @@ bool Item_func_set_collation::fix_length_and_dec(THD *thd)
|
|||
if (agg_arg_charsets_for_string_result(collation, args, 1))
|
||||
return true;
|
||||
Lex_exact_charset_opt_extended_collate cl(collation.collation, true);
|
||||
if (cl.merge_collation_override(m_set_collation))
|
||||
if (cl.merge_collation_override(thd,
|
||||
thd->variables.character_set_collations,
|
||||
m_set_collation))
|
||||
return true;
|
||||
collation.set(cl.collation().charset_info(), DERIVATION_EXPLICIT,
|
||||
args[0]->collation.repertoire);
|
||||
|
|
|
@ -925,7 +925,10 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
|
|||
return set(thd, ctype, path, nullptr);
|
||||
|
||||
CHARSET_INFO *tmp;
|
||||
if (!(tmp= cl.resolved_to_character_set(&my_charset_utf8mb4_general_ci)))
|
||||
if (!(tmp= cl.resolved_to_character_set(
|
||||
thd,
|
||||
thd->variables.character_set_collations,
|
||||
&my_charset_utf8mb4_general_ci)))
|
||||
return 1;
|
||||
return set(thd, ctype, path, tmp);
|
||||
}
|
||||
|
|
|
@ -197,7 +197,9 @@ Lex_context_collation::raise_if_not_equal(const Lex_context_collation &cl) const
|
|||
CREATE DATABASE db1 COLLATE DEFAULT CHARACTER SET latin1;
|
||||
*/
|
||||
bool Lex_exact_charset_opt_extended_collate::
|
||||
merge_context_collation_override(const Lex_context_collation &cl)
|
||||
merge_context_collation_override(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl)
|
||||
{
|
||||
DBUG_ASSERT(m_ci);
|
||||
|
||||
|
@ -215,7 +217,7 @@ bool Lex_exact_charset_opt_extended_collate::
|
|||
// COLLATE DEFAULT
|
||||
if (cl.is_contextually_typed_collate_default())
|
||||
{
|
||||
CHARSET_INFO *ci= find_default_collation();
|
||||
CHARSET_INFO *ci= find_mapped_default_collation(used, map);
|
||||
DBUG_ASSERT(ci);
|
||||
if (!ci)
|
||||
return true;
|
||||
|
@ -238,7 +240,9 @@ bool Lex_exact_charset_opt_extended_collate::
|
|||
}
|
||||
|
||||
|
||||
bool Lex_extended_collation_st::merge_exact_charset(const Lex_exact_charset &cs)
|
||||
bool Lex_extended_collation_st::merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs)
|
||||
{
|
||||
switch (m_type) {
|
||||
case TYPE_EXACT:
|
||||
|
@ -250,7 +254,7 @@ bool Lex_extended_collation_st::merge_exact_charset(const Lex_exact_charset &cs)
|
|||
{
|
||||
// COLLATE DEFAULT .. CHARACTER SET latin1
|
||||
Lex_exact_charset_opt_extended_collate tmp(cs);
|
||||
if (tmp.merge_context_collation(Lex_context_collation(m_ci)))
|
||||
if (tmp.merge_context_collation(used, map, Lex_context_collation(m_ci)))
|
||||
return true;
|
||||
*this= Lex_extended_collation(tmp.collation());
|
||||
return false;
|
||||
|
@ -419,7 +423,7 @@ CHARSET_INFO *Lex_exact_charset_opt_extended_collate::find_bin_collation() const
|
|||
|
||||
|
||||
CHARSET_INFO *
|
||||
Lex_exact_charset_opt_extended_collate::find_default_collation() const
|
||||
Lex_exact_charset_opt_extended_collate::find_compiled_default_collation() const
|
||||
{
|
||||
// See comments in find_bin_collation()
|
||||
DBUG_ASSERT(m_ci->cs_name.length !=4 || memcmp(m_ci->cs_name.str, "utf8", 4));
|
||||
|
@ -447,6 +451,17 @@ Lex_exact_charset_opt_extended_collate::find_default_collation() const
|
|||
}
|
||||
|
||||
|
||||
CHARSET_INFO *
|
||||
Lex_exact_charset_opt_extended_collate::
|
||||
find_mapped_default_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map) const
|
||||
{
|
||||
CHARSET_INFO *cs= find_compiled_default_collation();
|
||||
if (!cs)
|
||||
return nullptr;
|
||||
return map.get_collation_for_charset(used, cs);
|
||||
}
|
||||
|
||||
/*
|
||||
Resolve an empty or a contextually typed collation according to the
|
||||
upper level default character set (and optionally a collation), e.g.:
|
||||
|
@ -459,7 +474,9 @@ Lex_exact_charset_opt_extended_collate::find_default_collation() const
|
|||
"def" is the upper level CHARACTER SET clause (e.g. of a table)
|
||||
*/
|
||||
CHARSET_INFO *Lex_exact_charset_extended_collation_attrs_st::
|
||||
resolved_to_character_set(CHARSET_INFO *def) const
|
||||
resolved_to_character_set(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *def) const
|
||||
{
|
||||
DBUG_ASSERT(def);
|
||||
|
||||
|
@ -467,6 +484,10 @@ CHARSET_INFO *Lex_exact_charset_extended_collation_attrs_st::
|
|||
case TYPE_EMPTY:
|
||||
return def;
|
||||
case TYPE_CHARACTER_SET:
|
||||
{
|
||||
DBUG_ASSERT(m_ci);
|
||||
return map.get_collation_for_charset(used, m_ci);
|
||||
}
|
||||
case TYPE_CHARACTER_SET_COLLATE_EXACT:
|
||||
case TYPE_COLLATE_EXACT:
|
||||
DBUG_ASSERT(m_ci);
|
||||
|
@ -474,7 +495,7 @@ CHARSET_INFO *Lex_exact_charset_extended_collation_attrs_st::
|
|||
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||
{
|
||||
Lex_exact_charset_opt_extended_collate tmp(def, true);
|
||||
if (tmp.merge_context_collation_override(Lex_context_collation(m_ci)))
|
||||
if (tmp.merge_context_collation_override(used, map, Lex_context_collation(m_ci)))
|
||||
return NULL;
|
||||
return tmp.collation().charset_info();
|
||||
}
|
||||
|
@ -526,7 +547,9 @@ bool Lex_exact_charset_extended_collation_attrs_st::
|
|||
|
||||
|
||||
bool Lex_exact_charset_extended_collation_attrs_st::
|
||||
merge_context_collation(const Lex_context_collation &cl)
|
||||
merge_context_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl)
|
||||
{
|
||||
switch (m_type) {
|
||||
case TYPE_EMPTY:
|
||||
|
@ -540,7 +563,7 @@ bool Lex_exact_charset_extended_collation_attrs_st::
|
|||
{
|
||||
// CHARACTER SET latin1 .. COLLATE DEFAULT
|
||||
Lex_exact_charset_opt_extended_collate tmp(m_ci, false);
|
||||
if (tmp.merge_context_collation(cl))
|
||||
if (tmp.merge_context_collation(used, map, cl))
|
||||
return true;
|
||||
*this= Lex_exact_charset_extended_collation_attrs(tmp);
|
||||
return false;
|
||||
|
@ -582,24 +605,29 @@ bool Lex_exact_charset_opt_extended_collate::
|
|||
|
||||
|
||||
bool Lex_exact_charset_opt_extended_collate::
|
||||
merge_context_collation(const Lex_context_collation &cl)
|
||||
merge_context_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl)
|
||||
{
|
||||
// CHARACTER SET latin1 [COLLATE latin1_bin] .. COLLATE DEFAULT
|
||||
if (m_with_collate)
|
||||
return Lex_exact_collation(m_ci).
|
||||
raise_if_conflicts_with_context_collation(cl, false);
|
||||
return merge_context_collation_override(cl);
|
||||
return merge_context_collation_override(used, map, cl);
|
||||
}
|
||||
|
||||
|
||||
bool Lex_exact_charset_extended_collation_attrs_st::
|
||||
merge_collation(const Lex_extended_collation_st &cl)
|
||||
merge_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
switch (cl.type()) {
|
||||
case Lex_extended_collation_st::TYPE_EXACT:
|
||||
return merge_exact_collation(Lex_exact_collation(cl.charset_info()));
|
||||
case Lex_extended_collation_st::TYPE_CONTEXTUALLY_TYPED:
|
||||
return merge_context_collation(Lex_context_collation(cl.charset_info()));
|
||||
return merge_context_collation(used, map,
|
||||
Lex_context_collation(cl.charset_info()));
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
return false;
|
||||
|
@ -613,7 +641,9 @@ bool Lex_exact_charset_extended_collation_attrs_st::
|
|||
@param cs - The "CHARACTER SET exact_charset_name".
|
||||
*/
|
||||
bool Lex_exact_charset_extended_collation_attrs_st::
|
||||
merge_exact_charset(const Lex_exact_charset &cs)
|
||||
merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs)
|
||||
{
|
||||
DBUG_ASSERT(cs.charset_info());
|
||||
|
||||
|
@ -643,7 +673,7 @@ bool Lex_exact_charset_extended_collation_attrs_st::
|
|||
// COLLATE DEFAULT .. CHARACTER SET cs
|
||||
{
|
||||
Lex_exact_charset_opt_extended_collate tmp(cs);
|
||||
if (tmp.merge_context_collation(Lex_context_collation(m_ci)))
|
||||
if (tmp.merge_context_collation(used, map, Lex_context_collation(m_ci)))
|
||||
return true;
|
||||
*this= Lex_exact_charset_extended_collation_attrs(tmp);
|
||||
return false;
|
||||
|
@ -664,11 +694,14 @@ bool Lex_extended_charset_extended_collation_attrs_st::merge_charset_default()
|
|||
|
||||
|
||||
bool Lex_extended_charset_extended_collation_attrs_st::
|
||||
merge_exact_charset(const Lex_exact_charset &cs)
|
||||
merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs)
|
||||
{
|
||||
if (m_charset_order == CHARSET_TYPE_EMPTY)
|
||||
m_charset_order= CHARSET_TYPE_EXACT;
|
||||
return Lex_exact_charset_extended_collation_attrs_st::merge_exact_charset(cs);
|
||||
return Lex_exact_charset_extended_collation_attrs_st::
|
||||
merge_exact_charset(used, map, cs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -691,13 +724,16 @@ bool Lex_extended_charset_extended_collation_attrs_st::
|
|||
|
||||
CHARSET_INFO *
|
||||
Lex_extended_charset_extended_collation_attrs_st::
|
||||
resolved_to_context(const Charset_collation_context &ctx) const
|
||||
resolved_to_context(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Charset_collation_context &ctx) const
|
||||
{
|
||||
if (Lex_opt_context_charset_st::is_empty())
|
||||
{
|
||||
// Without CHARACTER SET DEFAULT
|
||||
return Lex_exact_charset_extended_collation_attrs_st::
|
||||
resolved_to_character_set(ctx.collate_default().charset_info());
|
||||
resolved_to_character_set(used, map,
|
||||
ctx.collate_default().charset_info());
|
||||
}
|
||||
|
||||
// With CHARACTER SET DEFAULT
|
||||
|
@ -767,8 +803,9 @@ Lex_extended_charset_extended_collation_attrs_st::
|
|||
ALTER DATABASE db1 COLLATE DEFAULT CHARACTER SET DEFAULT;
|
||||
*/
|
||||
return Lex_exact_charset_extended_collation_attrs_st::
|
||||
resolved_to_character_set(ctx.charset_default().
|
||||
collation().charset_info());
|
||||
resolved_to_character_set(used, map,
|
||||
ctx.charset_default().
|
||||
collation().charset_info());
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
return NULL;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef LEX_CHARSET_INCLUDED
|
||||
#define LEX_CHARSET_INCLUDED
|
||||
|
||||
#include "charset_collations.h"
|
||||
|
||||
/*
|
||||
An extention for Charset_loader_mysys,
|
||||
|
@ -296,7 +297,9 @@ public:
|
|||
bool set_by_name(const char *name, myf my_flags); // e.g. MY_UTF8_IS_UTF8MB3
|
||||
bool raise_if_conflicts_with_context_collation(const Lex_context_collation &)
|
||||
const;
|
||||
bool merge_exact_charset(const Lex_exact_charset &rhs);
|
||||
bool merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &rhs);
|
||||
bool merge_exact_collation(const Lex_exact_collation &rhs);
|
||||
bool merge(const Lex_extended_collation_st &rhs);
|
||||
};
|
||||
|
@ -347,7 +350,10 @@ public:
|
|||
}
|
||||
bool with_collate() const { return m_with_collate; }
|
||||
CHARSET_INFO *find_bin_collation() const;
|
||||
CHARSET_INFO *find_default_collation() const;
|
||||
CHARSET_INFO *find_compiled_default_collation() const;
|
||||
CHARSET_INFO *find_mapped_default_collation(
|
||||
Sql_used *used,
|
||||
const Charset_collation_map_st &map) const;
|
||||
bool raise_if_charsets_differ(const Lex_exact_charset &cs) const;
|
||||
bool raise_if_not_applicable(const Lex_exact_collation &cl) const;
|
||||
/*
|
||||
|
@ -355,18 +361,23 @@ public:
|
|||
So the full syntax looks like:
|
||||
CHARACTER SET cs [COLLATE cl] ... COLLATE cl2
|
||||
*/
|
||||
bool merge_collation(const Lex_extended_collation_st &cl)
|
||||
bool merge_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
switch (cl.type()) {
|
||||
case Lex_extended_collation_st::TYPE_EXACT:
|
||||
return merge_exact_collation(Lex_exact_collation(cl.charset_info()));
|
||||
case Lex_extended_collation_st::TYPE_CONTEXTUALLY_TYPED:
|
||||
return merge_context_collation(Lex_context_collation(cl.charset_info()));
|
||||
return merge_context_collation(used, map,
|
||||
Lex_context_collation(cl.charset_info()));
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
bool merge_collation_override(const Lex_extended_collation_st &cl)
|
||||
bool merge_collation_override(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
switch (cl.type()) {
|
||||
case Lex_extended_collation_st::TYPE_EXACT:
|
||||
|
@ -374,7 +385,7 @@ public:
|
|||
Lex_exact_collation(cl.charset_info()));
|
||||
case Lex_extended_collation_st::TYPE_CONTEXTUALLY_TYPED:
|
||||
return merge_context_collation_override(
|
||||
Lex_context_collation(cl.charset_info()));
|
||||
used, map, Lex_context_collation(cl.charset_info()));
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
return false;
|
||||
|
@ -383,8 +394,12 @@ public:
|
|||
Add a context collation:
|
||||
CHARACTER SET cs [COLLATE cl] ... COLLATE DEFAULT
|
||||
*/
|
||||
bool merge_context_collation(const Lex_context_collation &cl);
|
||||
bool merge_context_collation_override(const Lex_context_collation &cl);
|
||||
bool merge_context_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl);
|
||||
bool merge_context_collation_override(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl);
|
||||
/*
|
||||
Add an exact collation:
|
||||
CHARACTER SET cs [COLLATE cl] ... COLLATE latin1_bin
|
||||
|
@ -399,7 +414,7 @@ public:
|
|||
{
|
||||
if ((m_ci->state & MY_CS_PRIMARY))
|
||||
return Lex_exact_charset(m_ci);
|
||||
return Lex_exact_charset(find_default_collation());
|
||||
return Lex_exact_charset(find_compiled_default_collation());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -507,11 +522,13 @@ public:
|
|||
m_ci= cs.charset_info();
|
||||
m_type= TYPE_CHARACTER_SET;
|
||||
}
|
||||
bool set_charset_collate_default(const Lex_exact_charset &cs)
|
||||
bool set_charset_collate_default(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs)
|
||||
{
|
||||
CHARSET_INFO *ci;
|
||||
if (!(ci= Lex_exact_charset_opt_extended_collate(cs).
|
||||
find_default_collation()))
|
||||
find_mapped_default_collation(used, map)))
|
||||
return true;
|
||||
m_ci= ci;
|
||||
m_type= TYPE_CHARACTER_SET_COLLATE_EXACT;
|
||||
|
@ -544,6 +561,21 @@ public:
|
|||
{
|
||||
return m_ci;
|
||||
}
|
||||
CHARSET_INFO *charset_info(Sql_used *used,
|
||||
const Charset_collation_map_st &map) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case TYPE_CHARACTER_SET:
|
||||
return map.get_collation_for_charset(used, m_ci);
|
||||
case TYPE_EMPTY:
|
||||
case TYPE_CHARACTER_SET_COLLATE_EXACT:
|
||||
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||
case TYPE_COLLATE_EXACT:
|
||||
break;
|
||||
}
|
||||
return m_ci;
|
||||
}
|
||||
Type type() const
|
||||
{
|
||||
return m_type;
|
||||
|
@ -552,7 +584,9 @@ public:
|
|||
{
|
||||
return m_type == TYPE_COLLATE_CONTEXTUALLY_TYPED;
|
||||
}
|
||||
CHARSET_INFO *resolved_to_character_set(CHARSET_INFO *cs) const;
|
||||
CHARSET_INFO *resolved_to_character_set(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *cs) const;
|
||||
/*
|
||||
Merge the column CHARACTER SET clause to:
|
||||
- an exact collation name
|
||||
|
@ -561,15 +595,17 @@ public:
|
|||
"cl" corresponds to the COLLATE clause
|
||||
*/
|
||||
bool merge_column_charset_clause_and_collate_clause(
|
||||
Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset_extended_collation_attrs_st &cl)
|
||||
{
|
||||
switch (cl.type()) {
|
||||
case TYPE_EMPTY:
|
||||
return false;
|
||||
case TYPE_COLLATE_EXACT:
|
||||
return merge_exact_collation(Lex_exact_collation(cl.charset_info()));
|
||||
return merge_exact_collation(Lex_exact_collation(cl.m_ci));
|
||||
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||
return merge_context_collation(Lex_context_collation(cl.charset_info()));
|
||||
return merge_context_collation(used, map, Lex_context_collation(cl.m_ci));
|
||||
case TYPE_CHARACTER_SET:
|
||||
case TYPE_CHARACTER_SET_COLLATE_EXACT:
|
||||
break;
|
||||
|
@ -584,6 +620,8 @@ public:
|
|||
in an independent COLLATE clause in a column attribute.
|
||||
*/
|
||||
bool merge_column_collate_clause_and_collate_clause(
|
||||
Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset_extended_collation_attrs_st &cl)
|
||||
{
|
||||
DBUG_ASSERT(m_type != TYPE_CHARACTER_SET);
|
||||
|
@ -591,9 +629,9 @@ public:
|
|||
case TYPE_EMPTY:
|
||||
return false;
|
||||
case TYPE_COLLATE_EXACT:
|
||||
return merge_exact_collation(Lex_exact_collation(cl.charset_info()));
|
||||
return merge_exact_collation(Lex_exact_collation(cl.m_ci));
|
||||
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||
return merge_context_collation(Lex_context_collation(cl.charset_info()));
|
||||
return merge_context_collation(used, map, Lex_context_collation(cl.m_ci));
|
||||
case TYPE_CHARACTER_SET:
|
||||
case TYPE_CHARACTER_SET_COLLATE_EXACT:
|
||||
break;
|
||||
|
@ -601,10 +639,16 @@ public:
|
|||
DBUG_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
bool merge_exact_charset(const Lex_exact_charset &cs);
|
||||
bool merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs);
|
||||
bool merge_exact_collation(const Lex_exact_collation &cl);
|
||||
bool merge_context_collation(const Lex_context_collation &cl);
|
||||
bool merge_collation(const Lex_extended_collation_st &cl);
|
||||
bool merge_context_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_context_collation &cl);
|
||||
bool merge_collation(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_extended_collation_st &cl);
|
||||
};
|
||||
|
||||
|
||||
|
@ -713,9 +757,13 @@ public:
|
|||
}
|
||||
bool raise_if_charset_conflicts_with_default(
|
||||
const Lex_exact_charset_opt_extended_collate &def) const;
|
||||
CHARSET_INFO *resolved_to_context(const Charset_collation_context &ctx) const;
|
||||
CHARSET_INFO *resolved_to_context(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Charset_collation_context &ctx) const;
|
||||
bool merge_charset_default();
|
||||
bool merge_exact_charset(const Lex_exact_charset &cs);
|
||||
bool merge_exact_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_exact_charset &cs);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1330,6 +1330,7 @@ code_name(int code)
|
|||
case Q_HRNOW: return "Q_HRNOW";
|
||||
case Q_XID: return "XID";
|
||||
case Q_GTID_FLAGS3: return "Q_GTID_FLAGS3";
|
||||
case Q_CHARACTER_SET_COLLATIONS: return "Q_CHARACTER_SET_COLLATIONS";
|
||||
}
|
||||
sprintf(buf, "CODE#%d", code);
|
||||
return buf;
|
||||
|
@ -1375,7 +1376,8 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len,
|
|||
Log_event_type event_type)
|
||||
:Log_event(buf, description_event), data_buf(0), query(NullS),
|
||||
db(NullS), catalog_len(0), status_vars_len(0),
|
||||
flags2_inited(0), sql_mode_inited(0), charset_inited(0), flags2(0),
|
||||
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
|
||||
character_set_collations({0,0}), flags2(0),
|
||||
auto_increment_increment(1), auto_increment_offset(1),
|
||||
time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
|
||||
table_map_for_update(0), xid(0), gtid_flags_extra(0),
|
||||
|
@ -1480,6 +1482,17 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len,
|
|||
pos+= 6;
|
||||
break;
|
||||
}
|
||||
case Q_CHARACTER_SET_COLLATIONS:
|
||||
{
|
||||
const uchar *pos0= pos;
|
||||
CHECK_SPACE(pos, end, 1);
|
||||
uint16 count= *pos++;
|
||||
CHECK_SPACE(pos, end, count * 4);
|
||||
pos+= count * 4;
|
||||
character_set_collations= Lex_cstring((const char *) pos0,
|
||||
(const char *) pos);
|
||||
break;
|
||||
}
|
||||
case Q_TIME_ZONE_CODE:
|
||||
{
|
||||
if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <lex_charset.h>
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
#include "sql_const.h"
|
||||
|
@ -225,7 +226,8 @@ class String;
|
|||
packet (i.e. a query) sent from client to master;
|
||||
First, an auxiliary log_event status vars estimation:
|
||||
*/
|
||||
#define MAX_SIZE_LOG_EVENT_STATUS (1 + 4 /* type, flags2 */ + \
|
||||
#define MAX_SIZE_LOG_EVENT_STATUS (uint) \
|
||||
(1 + 4 /* type, flags2 */ + \
|
||||
1 + 8 /* type, sql_mode */ + \
|
||||
1 + 1 + 255 /* type, length, catalog */ + \
|
||||
1 + 4 /* type, auto_increment */ + \
|
||||
|
@ -237,7 +239,10 @@ class String;
|
|||
1 + 4 /* type, master_data_written */ + \
|
||||
1 + 3 /* type, sec_part of NOW() */ + \
|
||||
1 + 16 + 1 + 60/* type, user_len, user, host_len, host */ + \
|
||||
1 + 2 + 8 /* type, flags3, seq_no */)
|
||||
1 + 2 + 8 /* type, flags3, seq_no */ + \
|
||||
1 + Charset_collation_map_st::binary_size_max() \
|
||||
/* type, map */ \
|
||||
)
|
||||
#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
|
||||
LOG_EVENT_HEADER_LEN + /* write_header */ \
|
||||
QUERY_HEADER_LEN + /* write_data */ \
|
||||
|
@ -319,6 +324,8 @@ class String;
|
|||
#define Q_XID 129
|
||||
|
||||
#define Q_GTID_FLAGS3 130
|
||||
|
||||
#define Q_CHARACTER_SET_COLLATIONS 131
|
||||
/* Intvar event post-header */
|
||||
|
||||
/* Intvar event data */
|
||||
|
@ -2131,6 +2138,8 @@ public:
|
|||
bool sql_mode_inited;
|
||||
bool charset_inited;
|
||||
|
||||
LEX_CSTRING character_set_collations;
|
||||
|
||||
uint32 flags2;
|
||||
sql_mode_t sql_mode;
|
||||
ulong auto_increment_increment, auto_increment_offset;
|
||||
|
|
|
@ -1982,6 +1982,38 @@ bool Query_log_event::print_query_header(IO_CACHE* file,
|
|||
memcpy(print_event_info->charset, charset, 6);
|
||||
print_event_info->charset_inited= 1;
|
||||
}
|
||||
|
||||
if (character_set_collations.length)
|
||||
{
|
||||
Charset_collation_map_st map;
|
||||
size_t length= map.from_binary(character_set_collations.str,
|
||||
character_set_collations.length);
|
||||
if (length == character_set_collations.length)
|
||||
{
|
||||
Binary_string str;
|
||||
size_t nbytes= map.text_format_nbytes_needed();
|
||||
if (str.alloc(nbytes))
|
||||
goto err;
|
||||
size_t text_length= map.print((char*) str.ptr(), nbytes);
|
||||
str.length(text_length);
|
||||
/*
|
||||
my_b_printf() does not seem to support '%.*s'
|
||||
so append a \0 terminator.
|
||||
*/
|
||||
str.append_char('\0');
|
||||
if (my_b_printf(file, "SET @@session.character_set_collations='%s'%s\n",
|
||||
str.ptr(), print_event_info->delimiter))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_b_printf(file,
|
||||
"/* SET @@session.character_set_collations='%s' */\n",
|
||||
"<format not recognized>"))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (time_zone_len)
|
||||
{
|
||||
if (memcmp(print_event_info->time_zone_str,
|
||||
|
|
|
@ -1164,6 +1164,14 @@ bool Query_log_event::write()
|
|||
int2store(start+2, auto_increment_offset);
|
||||
start+= 4;
|
||||
}
|
||||
|
||||
if (thd && (thd->used & THD::CHARACTER_SET_COLLATIONS_USED))
|
||||
{
|
||||
*start++= Q_CHARACTER_SET_COLLATIONS;
|
||||
size_t len= thd->variables.character_set_collations.to_binary((char*)start);
|
||||
start+= len;
|
||||
}
|
||||
|
||||
if (charset_inited)
|
||||
{
|
||||
*start++= Q_CHARSET_CODE;
|
||||
|
@ -1946,6 +1954,17 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
|
|||
thd->variables.sql_mode=
|
||||
(sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
|
||||
(sql_mode & ~(sql_mode_t) MODE_NO_DIR_IN_CREATE));
|
||||
|
||||
size_t cslen= thd->variables.character_set_collations.from_binary(
|
||||
character_set_collations.str,
|
||||
character_set_collations.length);
|
||||
if (cslen != character_set_collations.length)
|
||||
{
|
||||
// Fatal: either a broken even, or an unknown collation ID
|
||||
thd->variables.character_set_collations.init();
|
||||
goto compare_errors; // QQ: report an error here?
|
||||
}
|
||||
|
||||
if (charset_inited)
|
||||
{
|
||||
rpl_sql_thread_info *sql_info= thd->system_thread_info.rpl_sql_info;
|
||||
|
|
|
@ -351,6 +351,7 @@ char *enforced_storage_engine=NULL;
|
|||
char *gtid_pos_auto_engines;
|
||||
plugin_ref *opt_gtid_pos_auto_plugins;
|
||||
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
|
||||
static const char *character_set_collations_str= "";
|
||||
Thread_cache thread_cache;
|
||||
static bool binlog_format_used= false;
|
||||
LEX_STRING opt_init_connect, opt_init_slave;
|
||||
|
@ -4288,6 +4289,18 @@ static int init_common_variables()
|
|||
*/
|
||||
myf utf8_flag= global_system_variables.old_behavior &
|
||||
OLD_MODE_UTF8_IS_UTF8MB3 ? MY_UTF8_IS_UTF8MB3 : 0;
|
||||
|
||||
if (character_set_collations_str[0])
|
||||
{
|
||||
Lex_cstring_strlen str(character_set_collations_str);
|
||||
if (global_system_variables.character_set_collations.
|
||||
from_text(str, utf8_flag))
|
||||
{
|
||||
sql_print_error(ER_DEFAULT(ER_WRONG_VALUE_FOR_VAR),
|
||||
"character_set_collations", character_set_collations_str);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *next_character_set_name= strchr(default_character_set_name, ',');
|
||||
|
@ -4306,7 +4319,13 @@ static int init_common_variables()
|
|||
return 1; // Eof of the list
|
||||
}
|
||||
else
|
||||
{
|
||||
Sql_used used;
|
||||
default_charset_info= global_system_variables.character_set_collations.
|
||||
get_collation_for_charset(&used,
|
||||
default_charset_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (default_collation_name)
|
||||
|
@ -6520,6 +6539,9 @@ struct my_option my_long_options[]=
|
|||
{"collation-server", 0, "Set the default collation.",
|
||||
&default_collation_name, &default_collation_name,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{"character-set-collations", 0, "Overrides for character set default collations.",
|
||||
&character_set_collations_str, &character_set_collations_str,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
|
||||
&opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
|
||||
0, 0, 0},
|
||||
|
|
85
sql/simple_tokenizer.h
Normal file
85
sql/simple_tokenizer.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* Copyright (c) 2023, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#ifndef SIMPLE_TOKENIZER_INCLUDED
|
||||
#define SIMPLE_TOKENIZER_INCLUDED
|
||||
|
||||
|
||||
class Simple_tokenizer
|
||||
{
|
||||
const char *m_ptr;
|
||||
const char *m_end;
|
||||
public:
|
||||
Simple_tokenizer(const char *str, size_t length)
|
||||
:m_ptr(str), m_end(str + length)
|
||||
{ }
|
||||
const char *ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
bool eof() const
|
||||
{
|
||||
return m_ptr >= m_end;
|
||||
}
|
||||
void get_spaces()
|
||||
{
|
||||
for ( ; !eof(); m_ptr++)
|
||||
{
|
||||
if (m_ptr[0] != ' ')
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool is_ident_start(char ch) const
|
||||
{
|
||||
return (ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
ch == '_';
|
||||
}
|
||||
bool is_ident_body(char ch) const
|
||||
{
|
||||
return is_ident_start(ch) ||
|
||||
(ch >= '0' && ch <= '9');
|
||||
}
|
||||
bool is_ident_start() const
|
||||
{
|
||||
return !eof() && is_ident_start(*m_ptr);
|
||||
}
|
||||
bool is_ident_body() const
|
||||
{
|
||||
return !eof() && is_ident_body(*m_ptr);
|
||||
}
|
||||
LEX_CSTRING get_ident()
|
||||
{
|
||||
get_spaces();
|
||||
if (!is_ident_start())
|
||||
return {m_ptr,0};
|
||||
const char *start= m_ptr++;
|
||||
for ( ; is_ident_body(); m_ptr++)
|
||||
{ }
|
||||
LEX_CSTRING res= {start, (size_t) (m_ptr - start)};
|
||||
return res;
|
||||
}
|
||||
bool get_char(char ch)
|
||||
{
|
||||
get_spaces();
|
||||
if (eof() || *m_ptr != ch)
|
||||
return true;
|
||||
m_ptr++;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // SIMPLE_TOKENIZER_INCLUDED
|
|
@ -637,7 +637,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
|||
protocol_text(this), protocol_binary(this), initial_status_var(0),
|
||||
m_current_stage_key(0), m_psi(0),
|
||||
in_sub_stmt(0), log_all_errors(0),
|
||||
binlog_unsafe_warning_flags(0), used(0),
|
||||
binlog_unsafe_warning_flags(0),
|
||||
current_stmt_binlog_format(BINLOG_FORMAT_MIXED),
|
||||
bulk_param(0),
|
||||
table_map_for_update(0),
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "dur_prop.h"
|
||||
#include <waiting_threads.h>
|
||||
#include "sql_const.h"
|
||||
#include "sql_used.h"
|
||||
#include <mysql/plugin_audit.h>
|
||||
#include "log.h"
|
||||
#include "rpl_tblmap.h"
|
||||
|
@ -886,6 +887,8 @@ typedef struct system_variables
|
|||
|
||||
vers_asof_timestamp_t vers_asof_timestamp;
|
||||
my_bool binlog_alter_two_phase;
|
||||
|
||||
Charset_collation_map_st character_set_collations;
|
||||
} SV;
|
||||
|
||||
/**
|
||||
|
@ -2603,6 +2606,7 @@ struct thd_async_state
|
|||
*/
|
||||
|
||||
class THD: public THD_count, /* this must be first */
|
||||
public Sql_used,
|
||||
public Statement,
|
||||
/*
|
||||
This is to track items changed during execution of a prepared
|
||||
|
@ -2925,12 +2929,6 @@ public:
|
|||
*/
|
||||
uint32 binlog_unsafe_warning_flags;
|
||||
|
||||
typedef uint used_t;
|
||||
enum { RAND_USED=1, TIME_ZONE_USED=2, QUERY_START_SEC_PART_USED=4,
|
||||
THREAD_SPECIFIC_USED=8 };
|
||||
|
||||
used_t used;
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
binlog_cache_mngr * binlog_setup_trx_data();
|
||||
/*
|
||||
|
|
|
@ -801,6 +801,9 @@ bool thd_init_client_charset(THD *thd, uint cs_number)
|
|||
cs->cs_name.str);
|
||||
return true;
|
||||
}
|
||||
Sql_used used;
|
||||
cs= global_system_variables.character_set_collations.
|
||||
get_collation_for_charset(&used, cs);
|
||||
thd->org_charset= cs;
|
||||
thd->update_charset(cs,cs,cs);
|
||||
}
|
||||
|
|
|
@ -4465,19 +4465,23 @@ public:
|
|||
bool add_alter_list(LEX_CSTRING par_name, Virtual_column_info *expr,
|
||||
bool par_exists);
|
||||
bool add_alter_list(LEX_CSTRING name, LEX_CSTRING new_name, bool exists);
|
||||
bool add_alter_list_item_convert_to_charset(CHARSET_INFO *cs)
|
||||
bool add_alter_list_item_convert_to_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
if (create_info.add_table_option_convert_charset(cs))
|
||||
if (create_info.add_table_option_convert_charset(used, map, cs))
|
||||
return true;
|
||||
alter_info.flags|= ALTER_CONVERT_TO;
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
add_alter_list_item_convert_to_charset(CHARSET_INFO *cs,
|
||||
add_alter_list_item_convert_to_charset(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
CHARSET_INFO *cs,
|
||||
const Lex_extended_collation_st &cl)
|
||||
{
|
||||
if (create_info.add_table_option_convert_charset(cs) ||
|
||||
create_info.add_table_option_convert_collation(cl))
|
||||
if (create_info.add_table_option_convert_charset(used, map, cs) ||
|
||||
create_info.add_table_option_convert_collation(used, map, cl))
|
||||
return true;
|
||||
alter_info.flags|= ALTER_CONVERT_TO;
|
||||
return false;
|
||||
|
|
|
@ -5812,6 +5812,32 @@ finish:
|
|||
}
|
||||
thd->reset_kill_query();
|
||||
}
|
||||
|
||||
/*
|
||||
Binary logging is now done. Unset the "used" flags to avoid
|
||||
flags leaking to the next event (and to the COMMIT statement
|
||||
in the end of the current event).
|
||||
|
||||
Example:
|
||||
|
||||
Suppose a non-default collation (in @@character_set_collations)
|
||||
was used during the statement, the mysqlbinlog output for
|
||||
the current statement will contain a sequence like this:
|
||||
|
||||
SET character_set_collations='utf8mb3=utf8mb3_bin';
|
||||
INSERT INTO t1 VALUES (_utf8mb3'test');
|
||||
COMMIT;
|
||||
|
||||
The statment (INSERT in this example) is already in binlog at this point, and the
|
||||
and the "SET character_set_collations" is written inside a
|
||||
Q_CHARACTER_SET_COLLATIONS chunk in its log entry header.
|
||||
The flag CHARACTER_SET_COLLATIONS_USED is not needed any more.
|
||||
The COMMIT can be printed without "SET character_set_collations".
|
||||
|
||||
The same logic applies to the other _USED flags.
|
||||
*/
|
||||
thd->used= 0;
|
||||
|
||||
if (unlikely(thd->is_error()) ||
|
||||
(thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
|
||||
{
|
||||
|
|
|
@ -226,6 +226,20 @@ private:
|
|||
*/
|
||||
MEM_ROOT main_mem_root;
|
||||
sql_mode_t m_sql_mode;
|
||||
THD::used_t m_prepare_time_thd_used_flags;
|
||||
uint m_prepare_time_charset_collation_map_version;
|
||||
bool check_charset_collation_map_version(THD *thd,
|
||||
Reprepare_observer *observer)
|
||||
{
|
||||
if ((m_prepare_time_thd_used_flags & THD::CHARACTER_SET_COLLATIONS_USED) &&
|
||||
m_prepare_time_charset_collation_map_version !=
|
||||
thd->variables.character_set_collations.version())
|
||||
{
|
||||
observer->report_error(thd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
bool set_db(const LEX_CSTRING *db);
|
||||
bool set_parameters(String *expanded_query,
|
||||
|
@ -3891,7 +3905,9 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
|
|||
iterations(0),
|
||||
start_param(0),
|
||||
read_types(0),
|
||||
m_sql_mode(thd->variables.sql_mode)
|
||||
m_sql_mode(thd->variables.sql_mode),
|
||||
m_prepare_time_thd_used_flags(0),
|
||||
m_prepare_time_charset_collation_map_version(0)
|
||||
{
|
||||
init_sql_alloc(key_memory_prepared_statement_main_mem_root,
|
||||
&main_mem_root, thd_arg->variables.query_alloc_block_size,
|
||||
|
@ -4274,6 +4290,9 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
}
|
||||
// The same format as for triggers to compare
|
||||
hr_prepare_time= my_hrtime();
|
||||
m_prepare_time_thd_used_flags= thd->used;
|
||||
m_prepare_time_charset_collation_map_version=
|
||||
thd->variables.character_set_collations.version();
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
@ -4829,6 +4848,13 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
|
|||
/* Ditto */
|
||||
swap_variables(LEX_CSTRING, db, copy->db);
|
||||
|
||||
swap_variables(uint,
|
||||
m_prepare_time_charset_collation_map_version,
|
||||
copy->m_prepare_time_charset_collation_map_version);
|
||||
swap_variables(THD::used_t,
|
||||
m_prepare_time_thd_used_flags,
|
||||
copy->m_prepare_time_thd_used_flags);
|
||||
|
||||
DBUG_ASSERT(param_count == copy->param_count);
|
||||
DBUG_ASSERT(thd == copy->thd);
|
||||
last_error[0]= '\0';
|
||||
|
@ -4872,6 +4898,9 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
|
||||
LEX_CSTRING stmt_db_name= db;
|
||||
|
||||
if (check_charset_collation_map_version(thd, thd->m_reprepare_observer))
|
||||
return true;
|
||||
|
||||
status_var_increment(thd->status_var.com_stmt_execute);
|
||||
|
||||
if (flags & (uint) IS_IN_USE)
|
||||
|
@ -4989,6 +5018,15 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||
MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, thd->get_db(),
|
||||
&thd->security_ctx->priv_user[0],
|
||||
(char *) thd->security_ctx->host_or_ip, 1);
|
||||
/*
|
||||
Some thd->used flags are set only during PREPARE.
|
||||
For example CHARACTER_SET_COLLATIONS_USED is in most cases
|
||||
set during parsing only.
|
||||
Mix PREPARE time thd->used flags to EXECUTE time thd->used flags,
|
||||
e.g. to have the log event header write an optional chunk with
|
||||
the @@character_set_collations map.
|
||||
*/
|
||||
thd->used|= m_prepare_time_thd_used_flags;
|
||||
error= mysql_execute_command(thd, true);
|
||||
MYSQL_QUERY_EXEC_DONE(error);
|
||||
thd->update_server_status();
|
||||
|
|
|
@ -6257,7 +6257,9 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
const char *comment;
|
||||
restore_record(table, s->default_values);
|
||||
table->field[0]->store(&tmp_cs->cs_name, scs);
|
||||
table->field[1]->store(&tmp_cs->coll_name, scs);
|
||||
CHARSET_INFO *def_cl= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, tmp_cs);
|
||||
table->field[1]->store(&def_cl->coll_name, scs);
|
||||
comment= tmp_cs->comment ? tmp_cs->comment : "";
|
||||
table->field[2]->store(comment, strlen(comment), scs);
|
||||
table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
|
||||
|
@ -6360,6 +6362,8 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
(tmp_cs->state & MY_CS_HIDDEN) ||
|
||||
!(tmp_cs->state & MY_CS_PRIMARY))
|
||||
continue;
|
||||
CHARSET_INFO *def_cl= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, tmp_cs);
|
||||
for (cl= all_charsets;
|
||||
cl < all_charsets + array_elements(all_charsets) ;
|
||||
cl ++)
|
||||
|
@ -6400,7 +6404,7 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
table->field[2]->store((longlong) tmp_cl->number, TRUE);
|
||||
table->field[3]->set_notnull(); // IS_DEFAULT
|
||||
table->field[3]->store(
|
||||
Show::Yes_or_empty::value(tmp_cl->default_flag()), scs);
|
||||
Show::Yes_or_empty::value(def_cl == tmp_cl), scs);
|
||||
}
|
||||
table->field[4]->store(
|
||||
Show::Yes_or_empty::value(tmp_cl->compiled_flag()), scs);
|
||||
|
@ -6428,6 +6432,8 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
|
||||
!(tmp_cs->state & MY_CS_PRIMARY))
|
||||
continue;
|
||||
CHARSET_INFO *def_cl= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, tmp_cs);
|
||||
for (cl= all_charsets;
|
||||
cl < all_charsets + array_elements(all_charsets) ;
|
||||
cl ++)
|
||||
|
@ -6447,7 +6453,7 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
table->field[2]->store(full_collation_name, scs);
|
||||
table->field[3]->store(tmp_cl->number);
|
||||
table->field[4]->store(
|
||||
Show::Yes_or_empty::value(tmp_cl->default_flag()), scs);
|
||||
Show::Yes_or_empty::value(def_cl == tmp_cl), scs);
|
||||
if (schema_table_store_record(thd, table))
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2201,10 +2201,12 @@ bool check_duplicates_in_interval(const char *set_or_name,
|
|||
Generates an error to the diagnostics area in case of a failure.
|
||||
*/
|
||||
bool Column_definition::
|
||||
prepare_charset_for_string(const Column_derived_attributes *dattr)
|
||||
prepare_charset_for_string(Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Column_derived_attributes *dattr)
|
||||
{
|
||||
CHARSET_INFO *tmp= charset_collation_attrs().
|
||||
resolved_to_character_set(dattr->charset());
|
||||
resolved_to_character_set(used, map, dattr->charset());
|
||||
if (!tmp)
|
||||
return true;
|
||||
charset= tmp;
|
||||
|
@ -12535,7 +12537,8 @@ bool HA_CREATE_INFO::
|
|||
// Make sure we don't do double resolution in direct SQL execution
|
||||
DBUG_ASSERT(!default_table_charset || thd->stmt_arena->is_stmt_execute());
|
||||
if (!(default_table_charset=
|
||||
default_cscl.resolved_to_context(ctx)))
|
||||
default_cscl.resolved_to_context(thd,
|
||||
thd->variables.character_set_collations, ctx)))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12547,7 +12550,8 @@ bool HA_CREATE_INFO::
|
|||
DBUG_ASSERT(!alter_table_convert_to_charset ||
|
||||
thd->stmt_arena->is_stmt_execute());
|
||||
if (!(alter_table_convert_to_charset=
|
||||
convert_cscl.resolved_to_context(ctx)))
|
||||
convert_cscl.resolved_to_context(thd,
|
||||
thd->variables.character_set_collations, ctx)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -2718,7 +2718,9 @@ Type_handler::Column_definition_set_attributes(THD *thd,
|
|||
column_definition_type_t type)
|
||||
const
|
||||
{
|
||||
def->set_charset_collation_attrs(attr.charset_collation_attrs());
|
||||
def->set_charset_collation_attrs(thd,
|
||||
thd->variables.character_set_collations,
|
||||
attr.charset_collation_attrs());
|
||||
def->set_length_and_dec(attr);
|
||||
return false;
|
||||
}
|
||||
|
@ -3026,7 +3028,9 @@ bool Type_handler_null::
|
|||
*derived_attr)
|
||||
const
|
||||
{
|
||||
def->prepare_charset_for_string(derived_attr);
|
||||
def->prepare_charset_for_string(thd,
|
||||
thd->variables.character_set_collations,
|
||||
derived_attr);
|
||||
def->create_length_to_internal_length_null();
|
||||
return false;
|
||||
}
|
||||
|
@ -3108,7 +3112,10 @@ bool Type_handler_typelib::
|
|||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
return def->prepare_charset_for_string(thd,
|
||||
thd->variables.
|
||||
character_set_collations,
|
||||
derived_attr) ||
|
||||
def->prepare_stage1_typelib(thd, mem_root, type);
|
||||
}
|
||||
|
||||
|
@ -3122,7 +3129,10 @@ bool Type_handler_string_result::
|
|||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
return def->prepare_charset_for_string(thd,
|
||||
thd->variables.
|
||||
character_set_collations,
|
||||
derived_attr) ||
|
||||
def->prepare_stage1_string(thd, mem_root);
|
||||
}
|
||||
|
||||
|
|
33
sql/sql_used.h
Normal file
33
sql/sql_used.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* Copyright (c) 2023, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#ifndef SQL_USED_INCLUDED
|
||||
#define SQL_USED_INCLUDED
|
||||
|
||||
class Sql_used
|
||||
{
|
||||
public:
|
||||
typedef uint used_t;
|
||||
enum { RAND_USED=1, TIME_ZONE_USED=2, QUERY_START_SEC_PART_USED=4,
|
||||
THREAD_SPECIFIC_USED=8,
|
||||
CHARACTER_SET_COLLATIONS_USED= 16
|
||||
};
|
||||
used_t used;
|
||||
Sql_used()
|
||||
:used(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif // SQL_USED_INCLUDED
|
|
@ -5565,7 +5565,8 @@ versioning_option:
|
|||
default_charset:
|
||||
opt_default charset opt_equal charset_name_or_default
|
||||
{
|
||||
if (unlikely(Lex->create_info.add_table_option_default_charset($4)))
|
||||
if (unlikely(Lex->create_info.add_table_option_default_charset(
|
||||
thd, thd->variables.character_set_collations, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
@ -5574,7 +5575,8 @@ default_collation:
|
|||
opt_default COLLATE_SYM opt_equal collation_name_or_default
|
||||
{
|
||||
Table_specification_st *cinfo= &Lex->create_info;
|
||||
if (unlikely(cinfo->add_table_option_default_collation($4)))
|
||||
if (unlikely(cinfo->add_table_option_default_collation(
|
||||
thd, thd->variables.character_set_collations, $4)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
@ -5827,9 +5829,12 @@ field_type_or_serial:
|
|||
field_def
|
||||
{
|
||||
auto tmp= $1.charset_collation_attrs();
|
||||
if (tmp.merge_column_charset_clause_and_collate_clause($3))
|
||||
if (tmp.merge_column_charset_clause_and_collate_clause(
|
||||
thd, thd->variables.character_set_collations, $3))
|
||||
MYSQL_YYABORT;
|
||||
Lex->last_field->set_charset_collation_attrs(tmp);
|
||||
Lex->last_field->set_charset_collation_attrs(
|
||||
thd, thd->variables.character_set_collations,
|
||||
tmp);
|
||||
}
|
||||
| SERIAL_SYM
|
||||
{
|
||||
|
@ -5867,7 +5872,8 @@ field_def:
|
|||
| attribute_list compressed_deprecated_column_attribute { $$= $1; }
|
||||
| attribute_list compressed_deprecated_column_attribute attribute_list
|
||||
{
|
||||
if (($$= $1).merge_column_collate_clause_and_collate_clause($3))
|
||||
if (($$= $1).merge_column_collate_clause_and_collate_clause(
|
||||
thd, thd->variables.character_set_collations, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| opt_generated_always AS virtual_column_func
|
||||
|
@ -6347,8 +6353,9 @@ opt_precision:
|
|||
attribute_list:
|
||||
attribute_list attribute
|
||||
{
|
||||
if (($$= $1).merge_column_collate_clause_and_collate_clause($2))
|
||||
MYSQL_YYABORT;
|
||||
if (($$= $1).merge_column_collate_clause_and_collate_clause(
|
||||
thd, thd->variables.character_set_collations, $2))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| attribute
|
||||
;
|
||||
|
@ -6575,11 +6582,17 @@ binary:
|
|||
}
|
||||
| charset_or_alias COLLATE_SYM DEFAULT
|
||||
{
|
||||
$$.set_charset_collate_default(Lex_exact_charset($1));
|
||||
$$.set_charset_collate_default(
|
||||
thd,
|
||||
thd->variables.character_set_collations,
|
||||
Lex_exact_charset($1));
|
||||
}
|
||||
| charset_or_alias COLLATE_SYM collation_name
|
||||
{
|
||||
if ($3.merge_exact_charset(Lex_exact_charset($1)))
|
||||
if ($3.merge_exact_charset(
|
||||
thd,
|
||||
thd->variables.character_set_collations,
|
||||
Lex_exact_charset($1)))
|
||||
MYSQL_YYABORT;
|
||||
$$= Lex_exact_charset_extended_collation_attrs($3);
|
||||
}
|
||||
|
@ -7660,13 +7673,15 @@ alter_list_item:
|
|||
}
|
||||
| CONVERT_SYM TO_SYM charset charset_name_or_default
|
||||
{
|
||||
if (Lex->add_alter_list_item_convert_to_charset($4))
|
||||
if (Lex->add_alter_list_item_convert_to_charset(
|
||||
thd, thd->variables.character_set_collations, $4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| CONVERT_SYM TO_SYM charset charset_name_or_default
|
||||
COLLATE_SYM collation_name_or_default
|
||||
{
|
||||
if (Lex->add_alter_list_item_convert_to_charset($4, $6))
|
||||
if (Lex->add_alter_list_item_convert_to_charset(
|
||||
thd, thd->variables.character_set_collations, $4, $6))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| create_table_options_space_separated
|
||||
|
@ -9542,7 +9557,9 @@ temporal_dyncol_type:
|
|||
string_dyncol_type:
|
||||
char opt_binary
|
||||
{
|
||||
if ($$.set(DYN_COL_STRING, $2, thd->variables.collation_connection))
|
||||
if ($$.set(DYN_COL_STRING, thd,
|
||||
thd->variables.character_set_collations,
|
||||
$2, thd->variables.collation_connection))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| nchar
|
||||
|
@ -9721,6 +9738,8 @@ column_default_non_parenthesized_expr:
|
|||
}
|
||||
| CONVERT_SYM '(' expr USING charset_name ')'
|
||||
{
|
||||
$5= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, $5);
|
||||
$$= new (thd->mem_root) Item_func_conv_charset(thd, $3, $5);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
|
@ -9873,6 +9892,8 @@ function_call_keyword:
|
|||
}
|
||||
| CHAR_SYM '(' expr_list USING charset_name ')'
|
||||
{
|
||||
$5= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, $5);
|
||||
$$= new (thd->mem_root) Item_func_char(thd, *$3, $5);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
|
@ -11174,19 +11195,22 @@ cast_type:
|
|||
{ $$.set(&type_handler_long_blob, $2, &my_charset_bin); }
|
||||
| CHAR_SYM opt_field_length opt_binary
|
||||
{
|
||||
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||
if ($$.set(&type_handler_long_blob,
|
||||
$2, thd, thd->variables.character_set_collations, $3,
|
||||
thd->variables.collation_connection))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| VARCHAR field_length opt_binary
|
||||
{
|
||||
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||
if ($$.set(&type_handler_long_blob,
|
||||
$2, thd, thd->variables.character_set_collations, $3,
|
||||
thd->variables.collation_connection))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| VARCHAR2_ORACLE_SYM field_length opt_binary
|
||||
{
|
||||
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||
if ($$.set(&type_handler_long_blob,
|
||||
$2, thd, thd->variables.character_set_collations, $3,
|
||||
thd->variables.collation_connection))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
@ -14839,6 +14863,8 @@ text_literal:
|
|||
}
|
||||
| UNDERSCORE_CHARSET TEXT_STRING
|
||||
{
|
||||
$1= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, $1);
|
||||
if (unlikely(!($$= thd->make_string_literal_charset($2, $1))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
@ -14978,6 +15004,8 @@ literal:
|
|||
Item_string_with_introducer *item_str;
|
||||
LEX_CSTRING tmp;
|
||||
$2->get_value(&tmp);
|
||||
$1= thd->variables.character_set_collations.
|
||||
get_collation_for_charset(thd, $1);
|
||||
/*
|
||||
Pass NULL as name. Name will be set in the "select_item" rule and
|
||||
will include the introducer and the original hex/bin notation.
|
||||
|
@ -16694,7 +16722,11 @@ option_value_no_option_type:
|
|||
{
|
||||
CHARSET_INFO *def= global_system_variables.character_set_client;
|
||||
Lex_exact_charset_opt_extended_collate tmp($2 ? $2 : def, false);
|
||||
if (Lex->set_names($1.pos(), tmp, yychar == YYEMPTY))
|
||||
Lex_extended_collation_st cl;
|
||||
cl.set_collate_default();
|
||||
if (tmp.merge_collation(thd, thd->variables.
|
||||
character_set_collations, cl) ||
|
||||
Lex->set_names($1.pos(), tmp, yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| NAMES_SYM charset_name_or_default
|
||||
|
@ -16702,7 +16734,8 @@ option_value_no_option_type:
|
|||
{
|
||||
CHARSET_INFO *def= global_system_variables.character_set_client;
|
||||
Lex_exact_charset_opt_extended_collate tmp($2 ? $2 : def, false);
|
||||
if (tmp.merge_collation($4) ||
|
||||
if (tmp.merge_collation(thd, thd->variables.
|
||||
character_set_collations, $4) ||
|
||||
Lex->set_names($1.pos(), tmp, yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
|
|
@ -773,10 +773,13 @@ public:
|
|||
m_ci= cs;
|
||||
Lex_length_and_dec_st::reset();
|
||||
}
|
||||
bool set(int type, const Lex_column_charset_collation_attrs_st &collation,
|
||||
bool set(int type,
|
||||
Sql_used *used,
|
||||
const Charset_collation_map_st &map,
|
||||
const Lex_column_charset_collation_attrs_st &collation,
|
||||
CHARSET_INFO *charset)
|
||||
{
|
||||
CHARSET_INFO *tmp= collation.resolved_to_character_set(charset);
|
||||
CHARSET_INFO *tmp= collation.resolved_to_character_set(used, map, charset);
|
||||
if (!tmp)
|
||||
return true;
|
||||
set(type, tmp);
|
||||
|
|
|
@ -438,6 +438,14 @@ static bool update_auto_increment_increment (sys_var *self, THD *thd, enum_var_t
|
|||
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
|
||||
static Sys_var_charset_collation_map Sys_character_set_collations(
|
||||
"character_set_collations",
|
||||
"Overrides for character set default collations",
|
||||
SESSION_VAR(character_set_collations),
|
||||
NO_CMD_LINE, NOT_IN_BINLOG);
|
||||
|
||||
|
||||
static Sys_var_double Sys_analyze_sample_percentage(
|
||||
"analyze_sample_percentage",
|
||||
"Percentage of rows from the table ANALYZE TABLE will sample "
|
||||
|
@ -819,7 +827,7 @@ static bool check_charset(sys_var *self, THD *thd, set_var *var)
|
|||
((thd->variables.pseudo_slave_mode || thd->slave_thread) &&
|
||||
(var->save_result.ptr=
|
||||
Lex_exact_charset_opt_extended_collate(cs, true).
|
||||
find_default_collation())))
|
||||
find_compiled_default_collation())))
|
||||
return false;
|
||||
}
|
||||
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
|
||||
|
|
101
sql/sys_vars.inl
101
sql/sys_vars.inl
|
@ -2994,3 +2994,104 @@ public:
|
|||
virtual const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const
|
||||
{ return value_ptr(thd, global_var(vers_asof_timestamp_t)); }
|
||||
};
|
||||
|
||||
|
||||
class Sys_var_charset_collation_map: public sys_var
|
||||
{
|
||||
public:
|
||||
Sys_var_charset_collation_map(const char *name_arg, const char *comment,
|
||||
int flag_args, ptrdiff_t off, size_t size,
|
||||
CMD_LINE getopt,
|
||||
enum binlog_status_enum binlog_status_arg)
|
||||
:sys_var(&all_sys_vars, name_arg, comment,
|
||||
flag_args, off, getopt.id, getopt.arg_type,
|
||||
SHOW_CHAR,
|
||||
DEFAULT(0), nullptr, binlog_status_arg,
|
||||
nullptr, nullptr, nullptr)
|
||||
{
|
||||
option.var_type|= GET_STR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static bool charset_collation_map_from_item(Charset_collation_map_st *map,
|
||||
Item *item,
|
||||
myf utf8_flag)
|
||||
{
|
||||
String *value, buffer;
|
||||
if (!(value= item->val_str_ascii(&buffer)))
|
||||
return true;
|
||||
return map->from_text(value->to_lex_cstring(), utf8_flag);
|
||||
}
|
||||
|
||||
static const uchar *make_value_ptr(THD *thd,
|
||||
const Charset_collation_map_st &map)
|
||||
{
|
||||
size_t nbytes= map.text_format_nbytes_needed();
|
||||
char *buf= (char *) thd->alloc(nbytes + 1);
|
||||
size_t length= map.print(buf, nbytes);
|
||||
buf[length]= '\0';
|
||||
return (uchar *) buf;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool do_check(THD *thd, set_var *var) override
|
||||
{
|
||||
Charset_collation_map_st *map= (Charset_collation_map_st*)
|
||||
thd->alloc(sizeof(Charset_collation_map_st));
|
||||
if (!map || charset_collation_map_from_item(map, var->value,
|
||||
thd->get_utf8_flag()))
|
||||
return true;
|
||||
var->save_result.ptr= map;
|
||||
return false;
|
||||
}
|
||||
|
||||
void session_save_default(THD *thd, set_var *var) override
|
||||
{
|
||||
thd->variables.character_set_collations.set(
|
||||
global_system_variables.character_set_collations, 1);
|
||||
}
|
||||
|
||||
void global_save_default(THD *thd, set_var *var) override
|
||||
{
|
||||
global_system_variables.character_set_collations.init();
|
||||
}
|
||||
|
||||
bool session_update(THD *thd, set_var *var) override
|
||||
{
|
||||
if (!var->value)
|
||||
{
|
||||
session_save_default(thd, var);
|
||||
return false;
|
||||
}
|
||||
thd->variables.character_set_collations.
|
||||
set(*(Charset_collation_map_st*) var->save_result.ptr, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool global_update(THD *thd, set_var *var) override
|
||||
{
|
||||
if (!var->value)
|
||||
{
|
||||
global_save_default(thd, var);
|
||||
return false;
|
||||
}
|
||||
global_system_variables.character_set_collations=
|
||||
*(Charset_collation_map_st*) var->save_result.ptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
const uchar *
|
||||
session_value_ptr(THD *thd, const LEX_CSTRING *base) const override
|
||||
{
|
||||
return make_value_ptr(thd, thd->variables.character_set_collations);
|
||||
}
|
||||
|
||||
const uchar *
|
||||
global_value_ptr(THD *thd, const LEX_CSTRING *base) const override
|
||||
{
|
||||
return make_value_ptr(thd, global_system_variables.
|
||||
character_set_collations);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue