mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-27743 Remove Lex::charset
This patch also fixes: MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition MDEV-27853 Wrong data type on column `COLLATE DEFAULT` and table `COLLATE some_non_default_collation` MDEV-28067 Multiple conflicting column COLLATE clauses are not rejected MDEV-28118 Wrong collation of `CAST(.. AS CHAR COLLATE DEFAULT)` MDEV-28119 Wrong column collation on MODIFY + CONVERT
This commit is contained in:
@@ -3693,7 +3693,10 @@ static char *fieldflags2str(uint f) {
|
|||||||
ff2s_check_flag(NUM);
|
ff2s_check_flag(NUM);
|
||||||
ff2s_check_flag(PART_KEY);
|
ff2s_check_flag(PART_KEY);
|
||||||
ff2s_check_flag(GROUP);
|
ff2s_check_flag(GROUP);
|
||||||
ff2s_check_flag(BINCMP);
|
/*
|
||||||
|
CONTEXT_COLLATION_FLAG (former BINCMP_FLAG) is used at parse
|
||||||
|
time only and should never show up on the client side. Don't test it.
|
||||||
|
*/
|
||||||
ff2s_check_flag(ON_UPDATE_NOW);
|
ff2s_check_flag(ON_UPDATE_NOW);
|
||||||
#undef ff2s_check_flag
|
#undef ff2s_check_flag
|
||||||
if (f)
|
if (f)
|
||||||
|
@@ -1269,6 +1269,15 @@ extern struct charset_info_st my_charset_utf8mb4_general_nopad_ci;
|
|||||||
extern struct charset_info_st my_charset_utf8mb4_unicode_ci;
|
extern struct charset_info_st my_charset_utf8mb4_unicode_ci;
|
||||||
extern struct charset_info_st my_charset_utf8mb4_unicode_nopad_ci;
|
extern struct charset_info_st my_charset_utf8mb4_unicode_nopad_ci;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Contextually typed collations, e.g.:
|
||||||
|
CHAR(10) COLLATE DEFAULT
|
||||||
|
CHAR(10) BINARY
|
||||||
|
*/
|
||||||
|
extern struct charset_info_st my_collation_contextually_typed_default;
|
||||||
|
extern struct charset_info_st my_collation_contextually_typed_binary;
|
||||||
|
|
||||||
|
|
||||||
#define MY_UTF8MB3 "utf8mb3"
|
#define MY_UTF8MB3 "utf8mb3"
|
||||||
#define MY_UTF8MB4 "utf8mb4"
|
#define MY_UTF8MB4 "utf8mb4"
|
||||||
|
|
||||||
|
@@ -180,7 +180,7 @@ enum enum_indicator_type
|
|||||||
#define NUM_FLAG 32768U /* Field is num (for clients) */
|
#define NUM_FLAG 32768U /* Field is num (for clients) */
|
||||||
#define PART_KEY_FLAG 16384U /* Intern; Part of some key */
|
#define PART_KEY_FLAG 16384U /* Intern; Part of some key */
|
||||||
#define GROUP_FLAG 32768U /* Intern: Group field */
|
#define GROUP_FLAG 32768U /* Intern: Group field */
|
||||||
#define BINCMP_FLAG 131072U /* Intern: Used by sql_yacc */
|
#define CONTEXT_COLLATION_FLAG 131072U /* Intern: Used by sql_yacc */
|
||||||
#define GET_FIXED_FIELDS_FLAG (1U << 18) /* Used to get fields in item tree */
|
#define GET_FIXED_FIELDS_FLAG (1U << 18) /* Used to get fields in item tree */
|
||||||
#define FIELD_IN_PART_FUNC_FLAG (1U << 19)/* Field part of partition func */
|
#define FIELD_IN_PART_FUNC_FLAG (1U << 19)/* Field part of partition func */
|
||||||
#define PART_INDIRECT_KEY_FLAG (1U << 20)
|
#define PART_INDIRECT_KEY_FLAG (1U << 20)
|
||||||
|
@@ -118,6 +118,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||||||
../sql/sql_analyze_stmt.cc ../sql/sql_analyze_stmt.h
|
../sql/sql_analyze_stmt.cc ../sql/sql_analyze_stmt.h
|
||||||
../sql/compat56.cc
|
../sql/compat56.cc
|
||||||
../sql/sql_schema.cc
|
../sql/sql_schema.cc
|
||||||
|
../sql/lex_charset.cc
|
||||||
../sql/sql_type.cc ../sql/sql_type.h
|
../sql/sql_type.cc ../sql/sql_type.h
|
||||||
../sql/sql_mode.cc
|
../sql/sql_mode.cc
|
||||||
../sql/sql_type_string.cc
|
../sql/sql_type_string.cc
|
||||||
|
11816
mysql-test/main/ctype_collate_column.result
Normal file
11816
mysql-test/main/ctype_collate_column.result
Normal file
File diff suppressed because it is too large
Load Diff
627
mysql-test/main/ctype_collate_column.test
Normal file
627
mysql-test/main/ctype_collate_column.test
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
--source include/have_utf8mb4.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.9 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27853 Wrong data type on column `COLLATE DEFAULT` and table `COLLATE some_non_default_collation`
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a CHAR(10) COLLATE DEFAULT
|
||||||
|
) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28067 Multiple conflicting column COLLATE clauses are not rejected
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--error ER_CONFLICTING_DECLARATIONS
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE latin1_swedish_ci NOT NULL COLLATE latin1_bin);
|
||||||
|
|
||||||
|
--error ER_CONFLICTING_DECLARATIONS
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT NOT NULL COLLATE latin1_bin);
|
||||||
|
|
||||||
|
--error ER_CONFLICTING_DECLARATIONS
|
||||||
|
CREATE TABLE t1 (a CHAR(10) BINARY NOT NULL COLLATE latin1_swedish_ci);
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT NOT NULL COLLATE latin1_swedish_ci);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(10) BINARY NOT NULL COLLATE latin1_bin);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27743 Remove Lex::charset
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# Iterate through all possible combinations of this grammar:
|
||||||
|
#
|
||||||
|
# CREATE TABLE t1 (
|
||||||
|
# a CHAR(10) [ CHARACTER SET cs ] [ COLLATE cl0 | BINARY ]
|
||||||
|
# NOT NULL [COLLATE cl1]
|
||||||
|
# DEFAULT '' [COLLATE cl2]
|
||||||
|
# ) [CHARACTER SET tcs [COLLATE tcl]];
|
||||||
|
#
|
||||||
|
# and check that:
|
||||||
|
# - either the column gets the expected character set and collation
|
||||||
|
# - or the expected error is returned
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE cs (cs VARCHAR(64) NOT NULL);
|
||||||
|
INSERT INTO cs (cs) VALUES
|
||||||
|
(''),
|
||||||
|
('CHARACTER SET latin1'),
|
||||||
|
('CHARACTER SET utf8mb4');
|
||||||
|
|
||||||
|
CREATE TABLE cl0 (cl0 VARCHAR(64) NOT NULL);
|
||||||
|
INSERT INTO cl0 (cl0) VALUES
|
||||||
|
(''),
|
||||||
|
('BINARY'),
|
||||||
|
('COLLATE DEFAULT'),
|
||||||
|
('COLLATE latin1_bin'),
|
||||||
|
('COLLATE latin1_swedish_ci'),
|
||||||
|
('COLLATE utf8mb4_bin'),
|
||||||
|
('COLLATE utf8mb4_general_ci');
|
||||||
|
|
||||||
|
CREATE TABLE cl1 (cl1 VARCHAR(64) NOT NULL);
|
||||||
|
INSERT INTO cl1 (cl1) VALUES
|
||||||
|
(''),
|
||||||
|
('COLLATE DEFAULT'),
|
||||||
|
('COLLATE latin1_bin'),
|
||||||
|
('COLLATE latin1_swedish_ci'),
|
||||||
|
('COLLATE utf8mb4_bin'),
|
||||||
|
('COLLATE utf8mb4_general_ci');
|
||||||
|
|
||||||
|
CREATE TABLE tcs (tcs VARCHAR(64) NOT NULL);
|
||||||
|
INSERT INTO tcs (tcs) VALUES
|
||||||
|
(''),
|
||||||
|
('CHARACTER SET latin1'),
|
||||||
|
('CHARACTER SET latin1 COLLATE latin1_bin'),
|
||||||
|
('CHARACTER SET utf8mb4'),
|
||||||
|
('CHARACTER SET utf8mb4 COLLATE utf8mb4_bin');
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION is_collate_clause_with_explicit_default_collation(cl VARCHAR(64))
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
RETURN cl IN
|
||||||
|
('COLLATE latin1_swedish_ci',
|
||||||
|
'COLLATE utf8mb4_general_ci'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE FUNCTION is_collate_clause_with_explicit_collation(cl VARCHAR(64))
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
RETURN cl IN
|
||||||
|
('COLLATE latin1_swedish_ci',
|
||||||
|
'COLLATE latin1_bin',
|
||||||
|
'COLLATE utf8mb4_general_ci',
|
||||||
|
'COLLATE utf8mb4_bin'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION is_conflicting_collate_explicit2(result TEXT,
|
||||||
|
a VARCHAR(64),
|
||||||
|
b VARCHAR(64))
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
RETURN a<>b
|
||||||
|
AND is_collate_clause_with_explicit_collation(a)
|
||||||
|
AND is_collate_clause_with_explicit_collation(b)
|
||||||
|
AND result LIKE 'ERROR%HY000%Conflicting declarations%';
|
||||||
|
|
||||||
|
CREATE FUNCTION is_conflicting_collate_default_collate_explicit(result TEXT,
|
||||||
|
b VARCHAR(64))
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
RETURN is_collate_clause_with_explicit_collation(b)
|
||||||
|
AND NOT is_collate_clause_with_explicit_default_collation(b)
|
||||||
|
AND result LIKE 'ERROR%HY000%Conflicting declarations%';
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION
|
||||||
|
is_conflicting_charset_explicit_collate_explicit(result TEXT,
|
||||||
|
cs_clause VARCHAR(64),
|
||||||
|
cl_clause VARCHAR(64))
|
||||||
|
RETURNS BOOLEAN
|
||||||
|
RETURN cs_clause LIKE 'CHARACTER SET%'
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl_clause)
|
||||||
|
AND REGEXP_SUBSTR(cs_clause,'[0-9a-z_]*$') <>
|
||||||
|
REGEXP_SUBSTR(cl_clause,'(?<=COLLATE )[0-9a-z_]*')
|
||||||
|
AND result LIKE 'ERROR%42000%COLLATION%is not valid for CHARACTER SET%';
|
||||||
|
|
||||||
|
CREATE FUNCTION collate_cs_default_collation(cs_name VARCHAR(64))
|
||||||
|
RETURNS VARCHAR(64)
|
||||||
|
RETURN
|
||||||
|
(SELECT CONCAT('COLLATE ',COLLATION_NAME)
|
||||||
|
FROM INFORMATION_SCHEMA.COLLATIONS
|
||||||
|
WHERE IS_DEFAULT='Yes' AND CHARACTER_SET_NAME = cs_name);
|
||||||
|
|
||||||
|
CREATE TABLE results
|
||||||
|
(
|
||||||
|
dt VARCHAR(64),
|
||||||
|
cs VARCHAR(64),
|
||||||
|
cl0 VARCHAR(64),
|
||||||
|
cl1 VARCHAR(64),
|
||||||
|
cl2 VARCHAR(64),
|
||||||
|
tcs VARCHAR(64),
|
||||||
|
query VARCHAR(1024),
|
||||||
|
result VARCHAR(1024),
|
||||||
|
|
||||||
|
cs_name VARCHAR(64) GENERATED ALWAYS AS
|
||||||
|
(CASE WHEN cs LIKE 'CHARACTER SET%' THEN REGEXP_SUBSTR(cs,'[0-9a-z_]*$')
|
||||||
|
ELSE NULL
|
||||||
|
END
|
||||||
|
),
|
||||||
|
|
||||||
|
collate_cs_bin VARCHAR(64) GENERATED ALWAYS AS
|
||||||
|
(
|
||||||
|
CONCAT('COLLATE ', cs_name, '_bin')
|
||||||
|
),
|
||||||
|
|
||||||
|
tcs_character_set_name VARCHAR(64) GENERATED ALWAYS AS
|
||||||
|
(CASE WHEN tcs LIKE 'CHARACTER SET%' THEN REGEXP_SUBSTR(tcs,'(?<=CHARACTER SET )[0-9a-z]*')
|
||||||
|
ELSE NULL
|
||||||
|
END
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE p1(dt TEXT, cs TEXT, cl0 TEXT, cl1 TEXT, cl2 TEXT, tcs TEXT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE errstate TEXT DEFAULT NULL;
|
||||||
|
DECLARE errno INT DEFAULT NULL;
|
||||||
|
DECLARE errmsg TEXT DEFAULT NULL;
|
||||||
|
DECLARE query TEXT;
|
||||||
|
DECLARE result TEXT;
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
GET DIAGNOSTICS CONDITION 1 errstate = RETURNED_SQLSTATE,
|
||||||
|
errno = MYSQL_ERRNO, errmsg = MESSAGE_TEXT;
|
||||||
|
END;
|
||||||
|
SET query= CONCAT('CREATE TABLE t1 (a ', dt, ' ', cs, ' ', cl0,
|
||||||
|
' NOT NULL ',cl1,
|
||||||
|
' DEFAULT '''' ', cl2,
|
||||||
|
') ', tcs, ' ENGINE=Memory');
|
||||||
|
EXECUTE IMMEDIATE query;
|
||||||
|
IF errmsg IS NOT NULL
|
||||||
|
THEN
|
||||||
|
SET result=CONCAT('ERROR: ',
|
||||||
|
COALESCE(errstate,'<NULL>'), ' ',
|
||||||
|
COALESCE(errno,'<NULL>'), ' ',
|
||||||
|
COALESCE(errmsg,'<NULL>'));
|
||||||
|
INSERT INTO results (dt,cs,cl0,cl1,cl2,tcs,query,result)
|
||||||
|
VALUES (dt,cs,cl0,cl1,cl2,tcs,query,result);
|
||||||
|
ELSE
|
||||||
|
FOR row IN (SELECT CONCAT(COLUMN_TYPE,
|
||||||
|
' CHARACTER SET ', CHARACTER_SET_NAME,
|
||||||
|
' COLLATE ', COLLATION_NAME) AS result
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1')
|
||||||
|
DO
|
||||||
|
INSERT INTO results (dt,cs,cl0,cl1,cl2,tcs,query,result)
|
||||||
|
VALUES (dt,cs,cl0,cl1,cl2,tcs,query,row.result);
|
||||||
|
END FOR;
|
||||||
|
DROP TABLE t1;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE p3(dt TEXT)
|
||||||
|
BEGIN
|
||||||
|
FOR row IN (
|
||||||
|
SELECT cs, cl0, cl1.cl1 AS cl1, cl2.cl1 AS cl2, tcs
|
||||||
|
FROM cs, cl0, cl1, cl1 AS cl2, tcs
|
||||||
|
ORDER BY cs, cl0, cl1, cl2, tcs
|
||||||
|
)
|
||||||
|
DO
|
||||||
|
CALL p1(dt, row.cs, row.cl0, row.cl1, row.cl2, row.tcs);
|
||||||
|
END FOR;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
--disable_column_names
|
||||||
|
CALL p3('char(10)');
|
||||||
|
--enable_column_names
|
||||||
|
|
||||||
|
|
||||||
|
--vertical_results
|
||||||
|
SELECT query, result, '' AS `` FROM results
|
||||||
|
ORDER BY dt, cs, cl0, cl1, cl2, tcs;
|
||||||
|
--horizontal_results
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP PROCEDURE p3;
|
||||||
|
|
||||||
|
DROP TABLE cs, cl0, cl1, tcs;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Statements with errors
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHARACTER SET cs2 COLLATE cs2_xxx
|
||||||
|
# CHARACTER SET cs1 NOT NULL COLLATE cs2_xxx DEFAULT '' [COLLATE cs2_xxx]
|
||||||
|
# CHARACTER SET cs1 NOT NULL DEFAULT '' COLLATE cs2_xxx
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE is_conflicting_charset_explicit_collate_explicit(result, cs, cl0);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cl0=''
|
||||||
|
AND cl2=''
|
||||||
|
AND is_conflicting_charset_explicit_collate_explicit(result, cs, cl1);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cl0=''
|
||||||
|
AND (cl1='' OR cl1=cl2)
|
||||||
|
AND is_conflicting_charset_explicit_collate_explicit(result, cs, cl2);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
# CHARACTER SET cs COLLATE DEFAULT
|
||||||
|
# NOT NULL [COLLATE cs_non_default]
|
||||||
|
# DEFAULT '' [COLLATE cs_non_default]
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%'
|
||||||
|
AND cl0='COLLATE DEFAULT'
|
||||||
|
AND cl2=''
|
||||||
|
AND is_conflicting_collate_explicit2(result, collate_cs_default_collation(cs_name), cl1);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%'
|
||||||
|
AND cl0='COLLATE DEFAULT'
|
||||||
|
AND (cl1=''||cl2=cl1)
|
||||||
|
AND is_conflicting_collate_explicit2(result, collate_cs_default_collation(cs_name), cl2);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# `COLLATE DEFAULT` is not supported in cl1 and cl2
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE (cl1='COLLATE DEFAULT' OR cl2='COLLATE DEFAULT')
|
||||||
|
AND result LIKE 'ERROR%42000%syntax%near%DEFAULT%';
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# Conflicting COLLATE with explicit collation name
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results WHERE is_conflicting_collate_explicit2(result, cl1, cl2);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cl2='' AND is_conflicting_collate_explicit2(result, cl0, cl1);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE (cl1='' OR cl1=cl2) AND is_conflicting_collate_explicit2(result, cl0, cl2);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) COLLATE DEFAULT .. COLLATE cs_non_default
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0='COLLATE DEFAULT'
|
||||||
|
AND
|
||||||
|
((cl1='' AND is_conflicting_collate_default_collate_explicit(result, cl2)) OR
|
||||||
|
(cl2='' AND is_conflicting_collate_default_collate_explicit(result, cl1)) OR
|
||||||
|
(cl2=cl1 AND is_conflicting_collate_default_collate_explicit(result, cl1)));
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) BINARY .. COLLATE xxx_ci
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cl0 LIKE 'BINARY' AND
|
||||||
|
((cl1='' AND cl2 NOT LIKE '%_bin' AND is_collate_clause_with_explicit_collation(cl2)) OR
|
||||||
|
(cl2='' AND cl1 NOT LIKE '%_bin' AND is_collate_clause_with_explicit_collation(cl1)) OR
|
||||||
|
(cl1=cl2 AND cl1 NOT LIKE '%_bin' AND is_collate_clause_with_explicit_collation(cl1)))
|
||||||
|
AND result LIKE 'ERROR%HY000%Conflicting declarations%';
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) CHARACTER SET cs1 BINARY .. COLLATE cs2_..
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%' AND cl0='BINARY'
|
||||||
|
AND cl1=''
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl2)
|
||||||
|
AND cl2 NOT LIKE CONCAT(cs_name, '%')
|
||||||
|
AND result LIKE 'ERROR%HY000%Conflicting declarations%';
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%' AND cl0='BINARY'
|
||||||
|
AND (cl2='' || cl2=cl1)
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl1)
|
||||||
|
AND cl1 NOT LIKE CONCAT(cs_name, '%')
|
||||||
|
AND result LIKE 'ERROR%HY000%Conflicting declarations%';
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Statements without errors
|
||||||
|
# where the character set and the collation are determined from
|
||||||
|
# the database level.
|
||||||
|
#
|
||||||
|
|
||||||
|
# CREATE TABLE t1 (a CHAR(10) [COLLATE DEFAULT] NOT NULL DEFAULT '');
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0 IN ('','COLLATE DEFAULT')
|
||||||
|
AND cl1='' AND cl2='' AND tcs=''
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE
|
||||||
|
(SELECT CONCAT('CHARACTER SET ', DEFAULT_CHARACTER_SET_NAME, ' ',
|
||||||
|
'COLLATE ', DEFAULT_COLLATION_NAME)
|
||||||
|
FROM INFORMATION_SCHEMA.SCHEMATA
|
||||||
|
WHERE SCHEMA_NAME=database()
|
||||||
|
);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
# CREATE TABLE t1 (a CHAR(10) BINARY NOT NULL DEFAULT '');
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0='BINARY' AND cl1='' AND cl2='' AND tcs=''
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE
|
||||||
|
(SELECT CONCAT('CHARACTER SET ', DEFAULT_CHARACTER_SET_NAME, ' ',
|
||||||
|
'COLLATE ', DEFAULT_CHARACTER_SET_NAME, '_bin')
|
||||||
|
FROM INFORMATION_SCHEMA.SCHEMATA
|
||||||
|
WHERE SCHEMA_NAME=database()
|
||||||
|
);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Statements without errors
|
||||||
|
# where the character set and the collation are determined from
|
||||||
|
# the table level.
|
||||||
|
#
|
||||||
|
|
||||||
|
# CREATE TABLE t1 (a char(10) NOT NULL DEFAULT '') CHARACTER SET cs
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs=''
|
||||||
|
AND cl0=''
|
||||||
|
AND cl1=''
|
||||||
|
AND cl2=''
|
||||||
|
AND tcs LIKE 'CHARACTER SET%'
|
||||||
|
AND tcs NOT LIKE '%COLLATE%'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE tcs
|
||||||
|
AND result RLIKE collate_cs_default_collation(tcs_character_set_name);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CREATE TABLE t1 (a CHAR(10) NOT NULL DEFAULT '') CHARACTER SET cs COLLATE cs_xxx
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0='' AND cl1='' AND cl2=''
|
||||||
|
AND tcs LIKE 'CHARACTER SET%COLLATE%'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE tcs;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT) CHARACTER SET cs ..
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs=''
|
||||||
|
AND cl0='COLLATE DEFAULT'
|
||||||
|
AND cl1=''
|
||||||
|
AND cl2=''
|
||||||
|
AND tcs LIKE 'CHARACTER SET%'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE collate_cs_default_collation(tcs_character_set_name);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
# CREATE TABLE t1
|
||||||
|
# (
|
||||||
|
# a CHAR(10) BINARY NOT NULL DEFAULT ''
|
||||||
|
# ) CHARACTER SET cs COLLATE cs_bin;
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs=''
|
||||||
|
AND cl0='BINARY'
|
||||||
|
AND cl1=''
|
||||||
|
AND cl2=''
|
||||||
|
AND tcs LIKE 'CHARACTER SET%'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE CONCAT('COLLATE ', tcs_character_set_name, '_bin');
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Statements without errors
|
||||||
|
# where the character set and the collation are determined from
|
||||||
|
# the column level.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) COLLATE cs_xxx .. [COLLATE cs_xxx] .. [COLLATE cs_xxx]
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND is_collate_clause_with_explicit_collation(cl0)
|
||||||
|
AND (cl1='' OR cl1=cl0)
|
||||||
|
AND (cl2='' OR cl2=cl0)
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl0;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHARACTER SET cs [COLLATE DEFAULT|COLLATE cs_def]
|
||||||
|
# NOT NULL [COLLATE cs_def]
|
||||||
|
# DEFAULT '' [COLLATE cs_def]
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET %'
|
||||||
|
AND cl0 IN ('','COLLATE DEFAULT',collate_cs_default_collation(cs_name))
|
||||||
|
AND cl1 IN ('',collate_cs_default_collation(cs_name))
|
||||||
|
AND cl2 IN ('',collate_cs_default_collation(cs_name))
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE collate_cs_default_collation(cs_name);
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) COLLATE DEFAULT .. COLLATE cs_def .. [COLLATE cs_def]
|
||||||
|
#
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs=''
|
||||||
|
AND cl0='COLLATE DEFAULT'
|
||||||
|
AND is_collate_clause_with_explicit_default_collation(cl1)
|
||||||
|
AND cl2=''
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl1;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) COLLATE DEFAULT .. COLLATE cs_def .. [COLLATE cs_def]
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs=''
|
||||||
|
AND cl0='COLLATE DEFAULT'
|
||||||
|
AND is_collate_clause_with_explicit_default_collation(cl2)
|
||||||
|
AND (cl1='' OR cl2=cl1)
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHARACTER SET cs [BINARY|COLLATE cs_bin]
|
||||||
|
# NOT NULL [COLLATE cs_bin]
|
||||||
|
# DEFAULT '' [COLLATE cs_bin]
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET %'
|
||||||
|
AND (cl0='BINARY' OR cl0=collate_cs_bin)
|
||||||
|
AND (cl1='' OR cl1=collate_cs_bin)
|
||||||
|
AND (cl2='' OR cl2=collate_cs_bin)
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE collate_cs_bin;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHARACTER SET cs NOT NULL DEFAULT '' COLLATE cs_def
|
||||||
|
# CHARACTER SET cs NOT NULL COLLATE cs_def DEFAULT '' [COLLATE cs_def]
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%' AND cl0=''
|
||||||
|
AND (cl2='' OR cl2=cl1)
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl1)
|
||||||
|
AND cl1 RLIKE CONCAT('COLLATE ',cs_name,'_')
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl1;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs LIKE 'CHARACTER SET%' AND cl0=''
|
||||||
|
AND cl1=''
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl2)
|
||||||
|
AND cl2 RLIKE CONCAT('COLLATE ',cs_name,'_')
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) BINARY NOT NULL DEFAULT '' COLLATE cs_bin
|
||||||
|
# CHAR(10) BINARY NOT NULL COLLATE cs_bin DEFAULT '' [COLLATE cs_bin]
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0='BINARY'
|
||||||
|
AND (cl2='' OR cl2=cl1)
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl1)
|
||||||
|
AND cl1 RLIKE '_bin$'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl1;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0='BINARY'
|
||||||
|
AND cl1=''
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl2)
|
||||||
|
AND cl2 RLIKE '_bin$'
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHAR(10) NOT NULL DEFAULT '' COLLATE cs_xxx
|
||||||
|
# CHAR(10) NOT NULL COLLATE cs_xxx DEFAULT '' [COLLATE cs_xxx]
|
||||||
|
#
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0=''
|
||||||
|
AND cl1=''
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl2)
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl2;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
DELETE FROM results
|
||||||
|
WHERE cs='' AND cl0=''
|
||||||
|
AND (cl2='' OR cl2=cl1)
|
||||||
|
AND is_collate_clause_with_explicit_collation(cl1)
|
||||||
|
AND result NOT LIKE 'ERROR%'
|
||||||
|
AND result RLIKE cl1;
|
||||||
|
SELECT ROW_COUNT();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--vertical_results
|
||||||
|
--echo # Expect empty set
|
||||||
|
SELECT *, '---' AS `---` FROM results WHERE result LIKE 'ERROR%';
|
||||||
|
--echo # Expect empty set
|
||||||
|
SELECT *, '---' AS `---` FROM results WHERE result NOT LIKE 'ERROR%';
|
||||||
|
--horizontal_results
|
||||||
|
|
||||||
|
DROP TABLE results;
|
||||||
|
|
||||||
|
|
||||||
|
DROP FUNCTION is_collate_clause_with_explicit_default_collation;
|
||||||
|
DROP FUNCTION is_collate_clause_with_explicit_collation;
|
||||||
|
DROP FUNCTION is_conflicting_charset_explicit_collate_explicit;
|
||||||
|
DROP FUNCTION is_conflicting_collate_explicit2;
|
||||||
|
DROP FUNCTION is_conflicting_collate_default_collate_explicit;
|
||||||
|
DROP FUNCTION collate_cs_default_collation;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.9 tests
|
||||||
|
--echo #
|
@@ -8889,6 +8889,38 @@ a b
|
|||||||
111 111
|
111 111
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT);
|
||||||
|
CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT)
|
||||||
|
a
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` varchar(10) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
c1
|
||||||
|
string
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` longtext DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -8950,3 +8982,31 @@ Warning 1292 Truncated incorrect INTEGER value: 'a
|
|||||||
#
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.6 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
#
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET latin1 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
name
|
||||||
|
Jeans
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET latin1 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`name` varchar(10) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.6 tests
|
||||||
|
#
|
||||||
|
@@ -438,6 +438,28 @@ let $coll_pad='latin1_bin';
|
|||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
--source include/ctype_like_range_mdev14350.inc
|
--source include/ctype_like_range_mdev14350.inc
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT);
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
@@ -475,3 +497,29 @@ SELECT CAST(_latin1 0x61FF62 AS INT);
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.6 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET latin1 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET latin1 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.6 tests
|
||||||
|
--echo #
|
||||||
|
@@ -11476,3 +11476,46 @@ Warning 1292 Truncated incorrect INTEGER value: 'яяя'
|
|||||||
#
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.9 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-28118 Wrong collation of `CAST(.. AS CHAR COLLATE DEFAULT)`
|
||||||
|
#
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_bin;
|
||||||
|
SELECT COLLATION(CAST('a' AS CHAR COLLATE DEFAULT));
|
||||||
|
COLLATION(CAST('a' AS CHAR COLLATE DEFAULT))
|
||||||
|
utf8mb3_general_ci
|
||||||
|
CREATE TABLE t1 AS SELECT CAST('a' AS CHAR COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` varchar(1) CHARACTER SET utf8mb3 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-28119 Wrong column collation on MODIFY + CONVERT
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a CHAR);
|
||||||
|
ALTER TABLE t1
|
||||||
|
MODIFY a CHAR COLLATE DEFAULT,
|
||||||
|
CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(1) CHARACTER SET utf8mb3 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a CHAR);
|
||||||
|
ALTER TABLE t1
|
||||||
|
MODIFY a CHAR BINARY,
|
||||||
|
CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.9 tests
|
||||||
|
#
|
||||||
|
@@ -2357,3 +2357,41 @@ SELECT CAST(_utf8 'яяя' AS INT);
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.9 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28118 Wrong collation of `CAST(.. AS CHAR COLLATE DEFAULT)`
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_bin;
|
||||||
|
SELECT COLLATION(CAST('a' AS CHAR COLLATE DEFAULT));
|
||||||
|
CREATE TABLE t1 AS SELECT CAST('a' AS CHAR COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28119 Wrong column collation on MODIFY + CONVERT
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR);
|
||||||
|
ALTER TABLE t1
|
||||||
|
MODIFY a CHAR COLLATE DEFAULT,
|
||||||
|
CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_bin;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR);
|
||||||
|
ALTER TABLE t1
|
||||||
|
MODIFY a CHAR BINARY,
|
||||||
|
CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.9 tests
|
||||||
|
--echo #
|
||||||
|
@@ -4147,6 +4147,38 @@ EXECUTE IMMEDIATE 'SELECT ''😎'' AS c';
|
|||||||
c
|
c
|
||||||
😎
|
😎
|
||||||
#
|
#
|
||||||
|
# MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(10) CHARACTER SET utf8mb4 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||||
|
CAST('a' AS CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT)
|
||||||
|
a
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` varchar(10) CHARACTER SET utf8mb4 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
c1
|
||||||
|
string
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` longtext CHARACTER SET utf8mb4 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -4167,3 +4199,31 @@ ERROR 42000: COLLATION 'latin1_swedish_ci' is not valid for CHARACTER SET 'utf8m
|
|||||||
#
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.6 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
#
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
name
|
||||||
|
Jeans
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`name` varchar(10) CHARACTER SET utf8mb4 DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of 10.6 tests
|
||||||
|
#
|
||||||
|
@@ -2040,6 +2040,27 @@ PREPARE stmt FROM 'SELECT ''😎'' AS c';
|
|||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
EXECUTE IMMEDIATE 'SELECT ''😎'' AS c';
|
EXECUTE IMMEDIATE 'SELECT ''😎'' AS c';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT);
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT CAST('a' AS CHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET utf8mb4 COLLATE DEFAULT) AS c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
@@ -2062,3 +2083,30 @@ SELECT 1 COLLATE latin1_swedish_ci;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.6 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
CREATE TABLE t1 AS
|
||||||
|
SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) CHARACTER SET utf8mb4 COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.6 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
@@ -987,3 +987,78 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
|
|||||||
#
|
#
|
||||||
# End of 10.6 tests
|
# End of 10.6 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.9 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-27743 Remove Lex::charset
|
||||||
|
#
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_general_ci
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_general_ci
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) BINARY PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_bin
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
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 `jt`.`name` AS `name` from JSON_TABLE('[{"name":"Jeans"}]', '$[*]' COLUMNS (`name` varchar(10) PATH '$.name')) `jt` latin1 latin1_swedish_ci
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_general_ci
|
||||||
|
DROP VIEW v1;
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
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 `jt`.`name` AS `name` from JSON_TABLE('[{"name":"Jeans"}]', '$[*]' COLUMNS (`name` varchar(10) PATH '$.name')) `jt` latin1 latin1_swedish_ci
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_general_ci
|
||||||
|
DROP VIEW v1;
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) BINARY PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
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 `jt`.`name` AS `name` from JSON_TABLE('[{"name":"Jeans"}]', '$[*]' COLUMNS (`name` varchar(10) CHARSET utf8mb4 COLLATE utf8mb4_bin PATH '$.name')) `jt` latin1 latin1_swedish_ci
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
collation(name)
|
||||||
|
utf8mb4_bin
|
||||||
|
DROP VIEW v1;
|
||||||
|
#
|
||||||
|
# End of 10.9 tests
|
||||||
|
#
|
||||||
|
@@ -845,3 +845,70 @@ SELECT * FROM json_table('[{"name":"str"}]', '$[*]'
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.6 tests
|
--echo # End of 10.6 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.9 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27743 Remove Lex::charset
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
|
||||||
|
SELECT collation(name)
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) BINARY PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) COLLATE DEFAULT PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT *
|
||||||
|
FROM json_table('[{"name":"Jeans"}]', '$[*]'
|
||||||
|
COLUMNS(
|
||||||
|
name VARCHAR(10) BINARY PATH '$.name'
|
||||||
|
)
|
||||||
|
) AS jt;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT collation(name) FROM v1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.9 tests
|
||||||
|
--echo #
|
||||||
|
@@ -18,7 +18,7 @@ grant test_role to test_user@localhost;
|
|||||||
set default role test_role for root@localhost;
|
set default role test_role for root@localhost;
|
||||||
drop role test_role;
|
drop role test_role;
|
||||||
drop user test_user@localhost;
|
drop user test_user@localhost;
|
||||||
alter table user add column default_role char(80) binary default '' not null
|
alter table user add column default_role char(80) default '' not null
|
||||||
COLLATE utf8_general_ci
|
COLLATE utf8_general_ci
|
||||||
after is_role;
|
after is_role;
|
||||||
alter table user add max_statement_time decimal(12,6) default 0 not null
|
alter table user add max_statement_time decimal(12,6) default 0 not null
|
||||||
|
@@ -36,7 +36,7 @@ set default role test_role for root@localhost;
|
|||||||
drop role test_role;
|
drop role test_role;
|
||||||
drop user test_user@localhost;
|
drop user test_user@localhost;
|
||||||
|
|
||||||
alter table user add column default_role char(80) binary default '' not null
|
alter table user add column default_role char(80) default '' not null
|
||||||
COLLATE utf8_general_ci
|
COLLATE utf8_general_ci
|
||||||
after is_role;
|
after is_role;
|
||||||
alter table user add max_statement_time decimal(12,6) default 0 not null
|
alter table user add max_statement_time decimal(12,6) default 0 not null
|
||||||
|
@@ -162,6 +162,7 @@ SET (SQL_SOURCE
|
|||||||
semisync.cc semisync_master.cc semisync_slave.cc
|
semisync.cc semisync_master.cc semisync_slave.cc
|
||||||
semisync_master_ack_receiver.cc
|
semisync_master_ack_receiver.cc
|
||||||
sql_schema.cc
|
sql_schema.cc
|
||||||
|
lex_charset.cc
|
||||||
sql_type.cc sql_mode.cc sql_type_json.cc
|
sql_type.cc sql_mode.cc sql_type_json.cc
|
||||||
sql_type_string.cc
|
sql_type_string.cc
|
||||||
sql_type_geom.cc
|
sql_type_geom.cc
|
||||||
|
@@ -10410,17 +10410,15 @@ bool Column_definition::prepare_interval_field(MEM_ROOT *mem_root,
|
|||||||
|
|
||||||
bool Column_definition::set_attributes(THD *thd,
|
bool Column_definition::set_attributes(THD *thd,
|
||||||
const Lex_field_type_st &def,
|
const Lex_field_type_st &def,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(type_handler() == &type_handler_null);
|
DBUG_ASSERT(type_handler() == &type_handler_null);
|
||||||
DBUG_ASSERT(charset == &my_charset_bin || charset == NULL);
|
|
||||||
DBUG_ASSERT(length == 0);
|
DBUG_ASSERT(length == 0);
|
||||||
DBUG_ASSERT(decimals == 0);
|
DBUG_ASSERT(decimals == 0);
|
||||||
|
|
||||||
set_handler(def.type_handler());
|
set_handler(def.type_handler());
|
||||||
return type_handler()->Column_definition_set_attributes(thd, this,
|
return type_handler()->Column_definition_set_attributes(thd, this,
|
||||||
def, cs, type);
|
def, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
19
sql/field.h
19
sql/field.h
@@ -5299,7 +5299,6 @@ public:
|
|||||||
Column_definition(THD *thd, Field *field, Field *orig_field);
|
Column_definition(THD *thd, Field *field, Field *orig_field);
|
||||||
bool set_attributes(THD *thd,
|
bool set_attributes(THD *thd,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type);
|
column_definition_type_t type);
|
||||||
void create_length_to_internal_length_null()
|
void create_length_to_internal_length_null()
|
||||||
{
|
{
|
||||||
@@ -5493,6 +5492,24 @@ public:
|
|||||||
{ return compression_method_ptr; }
|
{ return compression_method_ptr; }
|
||||||
|
|
||||||
bool check_vcol_for_key(THD *thd) const;
|
bool check_vcol_for_key(THD *thd) const;
|
||||||
|
|
||||||
|
void set_lex_charset_collation(const Lex_charset_collation_st &lc)
|
||||||
|
{
|
||||||
|
charset= lc.charset_collation();
|
||||||
|
if (lc.is_contextually_typed_collation())
|
||||||
|
flags|= CONTEXT_COLLATION_FLAG;
|
||||||
|
else
|
||||||
|
flags&= ~CONTEXT_COLLATION_FLAG;
|
||||||
|
}
|
||||||
|
Lex_charset_collation lex_charset_collation() const
|
||||||
|
{
|
||||||
|
return Lex_charset_collation(
|
||||||
|
charset,
|
||||||
|
!charset ? Lex_charset_collation_st::TYPE_EMPTY :
|
||||||
|
flags & CONTEXT_COLLATION_FLAG ?
|
||||||
|
Lex_charset_collation_st::TYPE_COLLATE_CONTEXTUALLY_TYPED :
|
||||||
|
Lex_charset_collation_st::TYPE_CHARACTER_SET);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3761,26 +3761,41 @@ struct Lex_cast_type_st: public Lex_length_and_dec_st
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const Type_handler *m_type_handler;
|
const Type_handler *m_type_handler;
|
||||||
|
CHARSET_INFO *m_charset;
|
||||||
public:
|
public:
|
||||||
void set(const Type_handler *handler, Lex_length_and_dec_st length_and_dec)
|
void set(const Type_handler *handler,
|
||||||
|
Lex_length_and_dec_st length_and_dec,
|
||||||
|
CHARSET_INFO *cs= NULL)
|
||||||
{
|
{
|
||||||
m_type_handler= handler;
|
m_type_handler= handler;
|
||||||
|
m_charset= cs;
|
||||||
Lex_length_and_dec_st::operator=(length_and_dec);
|
Lex_length_and_dec_st::operator=(length_and_dec);
|
||||||
}
|
}
|
||||||
|
bool set(const Type_handler *handler,
|
||||||
|
const Lex_length_and_dec_st & length_and_dec,
|
||||||
|
const Lex_charset_collation_st &cscl,
|
||||||
|
CHARSET_INFO *defcs)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *tmp= cscl.resolved_to_character_set(defcs);
|
||||||
|
if (!tmp)
|
||||||
|
return true;
|
||||||
|
set(handler, length_and_dec, tmp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void set(const Type_handler *handler)
|
void set(const Type_handler *handler)
|
||||||
{
|
{
|
||||||
m_type_handler= handler;
|
m_type_handler= handler;
|
||||||
|
m_charset= NULL;
|
||||||
Lex_length_and_dec_st::reset();
|
Lex_length_and_dec_st::reset();
|
||||||
}
|
}
|
||||||
const Type_handler *type_handler() const { return m_type_handler; }
|
const Type_handler *type_handler() const { return m_type_handler; }
|
||||||
Item *create_typecast_item(THD *thd, Item *item,
|
CHARSET_INFO *charset() const { return m_charset; }
|
||||||
CHARSET_INFO *cs= NULL) const
|
Item *create_typecast_item(THD *thd, Item *item) const
|
||||||
{
|
{
|
||||||
return m_type_handler->
|
return m_type_handler->
|
||||||
create_typecast_item(thd, item, Type_cast_attributes(*this, cs));
|
create_typecast_item(thd, item, Type_cast_attributes(*this, m_charset));
|
||||||
}
|
}
|
||||||
Item *create_typecast_item_or_error(THD *thd, Item *item,
|
Item *create_typecast_item_or_error(THD *thd, Item *item) const;
|
||||||
CHARSET_INFO *cs= NULL) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -716,7 +716,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table,
|
|||||||
uint fieldnr= 0;
|
uint fieldnr= 0;
|
||||||
MEM_ROOT *mem_root_save= thd->mem_root;
|
MEM_ROOT *mem_root_save= thd->mem_root;
|
||||||
List_iterator_fast<Json_table_column> jc_i(jt->m_columns);
|
List_iterator_fast<Json_table_column> jc_i(jt->m_columns);
|
||||||
Column_derived_attributes da(NULL);
|
Column_derived_attributes da(&my_charset_utf8mb4_general_ci);
|
||||||
DBUG_ENTER("add_json_table_fields");
|
DBUG_ENTER("add_json_table_fields");
|
||||||
|
|
||||||
thd->mem_root= &table->mem_root;
|
thd->mem_root= &table->mem_root;
|
||||||
@@ -733,8 +733,6 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table,
|
|||||||
executing a prepared statement for the second time.
|
executing a prepared statement for the second time.
|
||||||
*/
|
*/
|
||||||
sql_f->length= sql_f->char_length;
|
sql_f->length= sql_f->char_length;
|
||||||
if (!sql_f->charset)
|
|
||||||
sql_f->charset= &my_charset_utf8mb4_general_ci;
|
|
||||||
|
|
||||||
if (sql_f->prepare_stage1(thd, thd->mem_root, table->file,
|
if (sql_f->prepare_stage1(thd, thd->mem_root, table->file,
|
||||||
table->file->ha_table_flags(), &da))
|
table->file->ha_table_flags(), &da))
|
||||||
@@ -873,6 +871,19 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
|
||||||
|
const Lex_charset_collation_st &cl)
|
||||||
|
{
|
||||||
|
if (cl.is_empty() || cl.is_contextually_typed_collate_default())
|
||||||
|
return set(thd, ctype, path, nullptr);
|
||||||
|
|
||||||
|
CHARSET_INFO *tmp;
|
||||||
|
if (!(tmp= cl.resolved_to_character_set(&my_charset_utf8mb4_general_ci)))
|
||||||
|
return 1;
|
||||||
|
return set(thd, ctype, path, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int print_path(String *str, const json_path_t *p)
|
static int print_path(String *str, const json_path_t *p)
|
||||||
{
|
{
|
||||||
return str->append('\'') ||
|
return str->append('\'') ||
|
||||||
@@ -915,7 +926,10 @@ int Json_table_column::print(THD *thd, Field **f, String *str)
|
|||||||
if (str->append(column_type) ||
|
if (str->append(column_type) ||
|
||||||
((*f)->has_charset() && m_explicit_cs &&
|
((*f)->has_charset() && m_explicit_cs &&
|
||||||
(str->append(STRING_WITH_LEN(" CHARSET ")) ||
|
(str->append(STRING_WITH_LEN(" CHARSET ")) ||
|
||||||
str->append(&m_explicit_cs->cs_name))) ||
|
str->append(&m_explicit_cs->cs_name) ||
|
||||||
|
(!(m_explicit_cs->state & MY_CS_PRIMARY) &&
|
||||||
|
(str->append(STRING_WITH_LEN(" COLLATE ")) ||
|
||||||
|
str->append(&m_explicit_cs->coll_name))))) ||
|
||||||
str->append(m_column_type == PATH ? &path : &exists_path) ||
|
str->append(m_column_type == PATH ? &path : &exists_path) ||
|
||||||
print_path(str, &m_path))
|
print_path(str, &m_path))
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -160,6 +160,8 @@ public:
|
|||||||
m_column_type= ctype;
|
m_column_type= ctype;
|
||||||
}
|
}
|
||||||
int set(THD *thd, enum_type ctype, const LEX_CSTRING &path, CHARSET_INFO *cs);
|
int set(THD *thd, enum_type ctype, const LEX_CSTRING &path, CHARSET_INFO *cs);
|
||||||
|
int set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
|
||||||
|
const Lex_charset_collation_st &cl);
|
||||||
Json_table_column(Create_field *f, Json_table_nested_path *nest) :
|
Json_table_column(Create_field *f, Json_table_nested_path *nest) :
|
||||||
m_field(f), m_nest(nest), m_explicit_cs(NULL)
|
m_field(f), m_nest(nest), m_explicit_cs(NULL)
|
||||||
{
|
{
|
||||||
|
339
sql/lex_charset.cc
Normal file
339
sql/lex_charset.cc
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
/* Copyright (c) 2021, 2022, 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 "m_ctype.h"
|
||||||
|
#include "lex_charset.h"
|
||||||
|
#include "mysqld_error.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** find a collation with binary comparison rules
|
||||||
|
*/
|
||||||
|
CHARSET_INFO *Lex_charset_collation_st::find_bin_collation(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We don't need to handle old_mode=UTF8_IS_UTF8MB3 here,
|
||||||
|
because "cs" points to a real character set name.
|
||||||
|
It can be either "utf8mb3" or "utf8mb4". It cannot be "utf8".
|
||||||
|
No thd->get_utf8_flag() flag passed to get_charset_by_csname().
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(cs->cs_name.length !=4 || memcmp(cs->cs_name.str, "utf8", 4));
|
||||||
|
/*
|
||||||
|
CREATE TABLE t1 (a CHAR(10) BINARY)
|
||||||
|
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||||
|
Nothing to do, we have the binary collation already.
|
||||||
|
*/
|
||||||
|
if (cs->state & MY_CS_BINSORT)
|
||||||
|
return cs;
|
||||||
|
|
||||||
|
// CREATE TABLE t1 (a CHAR(10) BINARY) CHARACTER SET utf8mb4;
|
||||||
|
if (!(cs= get_charset_by_csname(cs->cs_name.str, MY_CS_BINSORT, MYF(0))))
|
||||||
|
{
|
||||||
|
char tmp[65];
|
||||||
|
strxnmov(tmp, sizeof(tmp)-1, cs->cs_name.str, "_bin", NULL);
|
||||||
|
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CHARSET_INFO *Lex_charset_collation_st::find_default_collation(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
// See comments in find_bin_collation()
|
||||||
|
DBUG_ASSERT(cs->cs_name.length !=4 || memcmp(cs->cs_name.str, "utf8", 4));
|
||||||
|
/*
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT) CHARACTER SET utf8mb4;
|
||||||
|
Nothing to do, we have the default collation already.
|
||||||
|
*/
|
||||||
|
if (cs->state & MY_CS_PRIMARY)
|
||||||
|
return cs;
|
||||||
|
/*
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT)
|
||||||
|
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||||
|
|
||||||
|
Don't need to handle old_mode=UTF8_IS_UTF8MB3 here.
|
||||||
|
See comments in find_bin_collation.
|
||||||
|
*/
|
||||||
|
cs= get_charset_by_csname(cs->cs_name.str, MY_CS_PRIMARY, MYF(MY_WME));
|
||||||
|
/*
|
||||||
|
The above should never fail, as we have default collations for
|
||||||
|
all character sets.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(cs);
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Lex_charset_collation_st::set_charset_collate_exact(CHARSET_INFO *cs,
|
||||||
|
CHARSET_INFO *cl)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cs != nullptr && cl != nullptr);
|
||||||
|
if (!my_charset_same(cl, cs))
|
||||||
|
{
|
||||||
|
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
||||||
|
cl->coll_name.str, cs->cs_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
set_collate_exact(cl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Resolve an empty or a contextually typed collation according to the
|
||||||
|
upper level default character set (and optionally a collation), e.g.:
|
||||||
|
CREATE TABLE t1 (a CHAR(10)) CHARACTER SET latin1;
|
||||||
|
CREATE TABLE t1 (a CHAR(10) BINARY) CHARACTER SET latin1;
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE DEFAULT)
|
||||||
|
CHARACTER SET latin1 COLLATE latin1_bin;
|
||||||
|
|
||||||
|
"this" is the COLLATE clause (e.g. of a column)
|
||||||
|
"def" is the upper level CHARACTER SET clause (e.g. of a table)
|
||||||
|
*/
|
||||||
|
CHARSET_INFO *
|
||||||
|
Lex_charset_collation_st::resolved_to_character_set(CHARSET_INFO *def) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(def);
|
||||||
|
|
||||||
|
switch (m_type) {
|
||||||
|
case TYPE_EMPTY:
|
||||||
|
return def;
|
||||||
|
case TYPE_CHARACTER_SET:
|
||||||
|
DBUG_ASSERT(m_ci);
|
||||||
|
return m_ci;
|
||||||
|
case TYPE_COLLATE_EXACT:
|
||||||
|
DBUG_ASSERT(m_ci);
|
||||||
|
return m_ci;
|
||||||
|
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contextually typed
|
||||||
|
DBUG_ASSERT(m_ci);
|
||||||
|
|
||||||
|
if (is_contextually_typed_binary_style()) // CHAR(10) BINARY
|
||||||
|
return find_bin_collation(def);
|
||||||
|
|
||||||
|
if (is_contextually_typed_collate_default()) // CHAR(10) COLLATE DEFAULT
|
||||||
|
return find_default_collation(def);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Non-binary and non-default contextually typed collation.
|
||||||
|
We don't have such yet - the parser cannot produce this.
|
||||||
|
But will have soon, e.g. "uca1400_as_ci".
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Merge the CHARACTER SET clause to:
|
||||||
|
- an empty COLLATE clause
|
||||||
|
- an explicitly typed collation name
|
||||||
|
- a contextually typed collation
|
||||||
|
|
||||||
|
"this" corresponds to `CHARACTER SET xxx [BINARY]`
|
||||||
|
"cl" corresponds to the COLLATE clause
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Lex_charset_collation_st::
|
||||||
|
merge_charset_clause_and_collate_clause(const Lex_charset_collation_st &cl)
|
||||||
|
{
|
||||||
|
if (cl.is_empty()) // No COLLATE clause
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (m_type) {
|
||||||
|
case TYPE_EMPTY:
|
||||||
|
/*
|
||||||
|
No CHARACTER SET clause
|
||||||
|
CHAR(10) NOT NULL COLLATE latin1_bin
|
||||||
|
CHAR(10) NOT NULL COLLATE DEFAULT
|
||||||
|
*/
|
||||||
|
*this= cl;
|
||||||
|
return false;
|
||||||
|
case TYPE_CHARACTER_SET:
|
||||||
|
case TYPE_COLLATE_EXACT:
|
||||||
|
{
|
||||||
|
Lex_explicit_charset_opt_collate ecs(m_ci, m_type == TYPE_COLLATE_EXACT);
|
||||||
|
if (ecs.merge_collate_or_error(cl))
|
||||||
|
return true;
|
||||||
|
set_collate_exact(ecs.charset_and_collation());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_contextually_typed_collation())
|
||||||
|
{
|
||||||
|
if (cl.is_contextually_typed_collation())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
CONTEXT + CONTEXT:
|
||||||
|
CHAR(10) BINARY .. COLLATE DEFAULT - not supported by the parser
|
||||||
|
CHAR(10) BINARY .. COLLATE uca1400_as_ci - not supported yet
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(0); // Not possible yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CONTEXT + EXPLICIT
|
||||||
|
CHAR(10) COLLATE DEFAULT .. COLLATE latin1_swedish_ci
|
||||||
|
CHAR(10) BINARY .. COLLATE latin1_bin
|
||||||
|
CHAR(10) COLLATE uca1400_as_ci .. COLLATE latin1_bin
|
||||||
|
*/
|
||||||
|
if (is_contextually_typed_collate_default() &&
|
||||||
|
!(cl.charset_collation()->state & MY_CS_PRIMARY))
|
||||||
|
{
|
||||||
|
my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
|
||||||
|
"COLLATE ", "DEFAULT", "COLLATE ",
|
||||||
|
cl.charset_collation()->coll_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_contextually_typed_binary_style() &&
|
||||||
|
!(cl.charset_collation()->state & MY_CS_BINSORT))
|
||||||
|
{
|
||||||
|
my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
|
||||||
|
"", "BINARY", "COLLATE ", cl.charset_collation()->coll_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*this= cl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Lex_explicit_charset_opt_collate::
|
||||||
|
merge_collate_or_error(const Lex_charset_collation_st &cl)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cl.type() != Lex_charset_collation_st::TYPE_CHARACTER_SET);
|
||||||
|
|
||||||
|
switch (cl.type()) {
|
||||||
|
case Lex_charset_collation_st::TYPE_EMPTY:
|
||||||
|
return false;
|
||||||
|
case Lex_charset_collation_st::TYPE_CHARACTER_SET:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
case Lex_charset_collation_st::TYPE_COLLATE_EXACT:
|
||||||
|
/*
|
||||||
|
EXPLICIT + EXPLICIT
|
||||||
|
CHAR(10) CHARACTER SET latin1 .. COLLATE latin1_bin
|
||||||
|
CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin .. COLLATE latin1_bin
|
||||||
|
CHAR(10) COLLATE latin1_bin .. COLLATE latin1_bin
|
||||||
|
CHAR(10) COLLATE latin1_bin .. COLLATE latin1_bin
|
||||||
|
CHAR(10) CHARACTER SET latin1 BINARY .. COLLATE latin1_bin
|
||||||
|
*/
|
||||||
|
if (m_with_collate && m_ci != cl.charset_collation())
|
||||||
|
{
|
||||||
|
my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
|
||||||
|
"COLLATE ", m_ci->coll_name.str,
|
||||||
|
"COLLATE ", cl.charset_collation()->coll_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!my_charset_same(m_ci, cl.charset_collation()))
|
||||||
|
{
|
||||||
|
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
||||||
|
cl.charset_collation()->coll_name.str, m_ci->cs_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
m_ci= cl.charset_collation();
|
||||||
|
m_with_collate= true;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case Lex_charset_collation_st::TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||||
|
if (cl.is_contextually_typed_collate_default())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
SET NAMES latin1 COLLATE DEFAULT;
|
||||||
|
ALTER TABLE t1 CONVERT TO CHARACTER SET latin1 COLLATE DEFAULT;
|
||||||
|
*/
|
||||||
|
CHARSET_INFO *tmp= Lex_charset_collation_st::find_default_collation(m_ci);
|
||||||
|
if (!tmp)
|
||||||
|
return true;
|
||||||
|
m_ci= tmp;
|
||||||
|
m_with_collate= true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
EXPLICIT + CONTEXT
|
||||||
|
CHAR(10) COLLATE latin1_bin .. COLLATE DEFAULT not possible yet
|
||||||
|
CHAR(10) COLLATE latin1_bin .. COLLATE uca1400_as_ci
|
||||||
|
*/
|
||||||
|
|
||||||
|
DBUG_ASSERT(0); // Not possible yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is used in the "attribute_list" rule to merge two independent
|
||||||
|
COLLATE clauses (not belonging to a CHARACTER SET clause).
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Lex_charset_collation_st::
|
||||||
|
merge_collate_clause_and_collate_clause(const Lex_charset_collation_st &cl)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
"BINARY" and "COLLATE DEFAULT" are not possible
|
||||||
|
in an independent COLLATE clause in a column attribute.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(!is_contextually_typed_collation());
|
||||||
|
DBUG_ASSERT(!cl.is_contextually_typed_collation());
|
||||||
|
|
||||||
|
if (cl.is_empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (m_type) {
|
||||||
|
case TYPE_EMPTY:
|
||||||
|
*this= cl;
|
||||||
|
return false;
|
||||||
|
case TYPE_CHARACTER_SET:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
case TYPE_COLLATE_EXACT:
|
||||||
|
case TYPE_COLLATE_CONTEXTUALLY_TYPED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Two independent explicit collations:
|
||||||
|
CHAR(10) NOT NULL COLLATE latin1_bin DEFAULT 'a' COLLATE latin1_bin
|
||||||
|
Note, we should perhaps eventually disallow double COLLATE clauses.
|
||||||
|
But for now let's just disallow only conflicting ones.
|
||||||
|
*/
|
||||||
|
if (charset_collation() != cl.charset_collation())
|
||||||
|
{
|
||||||
|
my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
|
||||||
|
"COLLATE ", charset_collation()->coll_name.str,
|
||||||
|
"COLLATE ", cl.charset_collation()->coll_name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
199
sql/lex_charset.h
Normal file
199
sql/lex_charset.h
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/* Copyright (c) 2021, 2022, 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_INCLUDED
|
||||||
|
#define LEX_CHARSET_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse time character set and collation.
|
||||||
|
|
||||||
|
Can be:
|
||||||
|
|
||||||
|
1. Empty (not specified on the column level):
|
||||||
|
CREATE TABLE t1 (a CHAR(10)) CHARACTER SET latin2; -- (1a)
|
||||||
|
CREATE TABLE t1 (a CHAR(10)); -- (1b)
|
||||||
|
|
||||||
|
2. Precisely typed:
|
||||||
|
CREATE TABLE t1 (a CHAR(10) COLLATE latin1_bin); -- (2a)
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin); -- (2b)
|
||||||
|
|
||||||
|
3. Contextually typed:
|
||||||
|
CREATE TABLE t2 (a CHAR(10) BINARY) CHARACTER SET latin2; -- (3a)
|
||||||
|
CREATE TABLE t2 (a CHAR(10) BINARY); -- (3b)
|
||||||
|
CREATE TABLE t2 (a CHAR(10) COLLATE DEFAULT)
|
||||||
|
CHARACER SET latin2 COLLATE latin2_bin; -- (3c)
|
||||||
|
|
||||||
|
In case of an empty or a contextually typed collation,
|
||||||
|
it is a subject to later resolution, when the context
|
||||||
|
character set becomes known in the end of the CREATE statement:
|
||||||
|
- either after the explicit table level CHARACTER SET, like in (1a,3a,3c)
|
||||||
|
- or by the inhereted database level CHARACTER SET, like in (1b,3b)
|
||||||
|
|
||||||
|
Resolution happens in Type_handler::Column_definition_prepare_stage1().
|
||||||
|
*/
|
||||||
|
struct Lex_charset_collation_st
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
TYPE_EMPTY= 0,
|
||||||
|
TYPE_CHARACTER_SET= 1,
|
||||||
|
TYPE_COLLATE_EXACT= 2,
|
||||||
|
TYPE_COLLATE_CONTEXTUALLY_TYPED= 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// Number of bits required to store enum Type values
|
||||||
|
|
||||||
|
#define LEX_CHARSET_COLLATION_TYPE_BITS 2
|
||||||
|
static_assert(((1<<LEX_CHARSET_COLLATION_TYPE_BITS)-1) >=
|
||||||
|
TYPE_COLLATE_CONTEXTUALLY_TYPED,
|
||||||
|
"Lex_charset_collation_st::Type bits check");
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CHARSET_INFO *m_ci;
|
||||||
|
Type m_type;
|
||||||
|
public:
|
||||||
|
static CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs);
|
||||||
|
static CHARSET_INFO *find_default_collation(CHARSET_INFO *cs);
|
||||||
|
public:
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
m_ci= NULL;
|
||||||
|
m_type= TYPE_EMPTY;
|
||||||
|
}
|
||||||
|
bool is_empty() const
|
||||||
|
{
|
||||||
|
return m_type == TYPE_EMPTY;
|
||||||
|
}
|
||||||
|
void set_charset(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cs);
|
||||||
|
m_ci= cs;
|
||||||
|
m_type= TYPE_CHARACTER_SET;
|
||||||
|
}
|
||||||
|
void set_charset_collate_default(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cs);
|
||||||
|
m_ci= cs;
|
||||||
|
m_type= TYPE_COLLATE_EXACT;
|
||||||
|
}
|
||||||
|
bool set_charset_collate_binary(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cs);
|
||||||
|
if (!(cs= find_bin_collation(cs)))
|
||||||
|
return true;
|
||||||
|
m_ci= cs;
|
||||||
|
m_type= TYPE_COLLATE_EXACT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool set_charset_collate_exact(CHARSET_INFO *cs,
|
||||||
|
CHARSET_INFO *cl);
|
||||||
|
void set_collate_default()
|
||||||
|
{
|
||||||
|
m_ci= &my_collation_contextually_typed_default;
|
||||||
|
m_type= TYPE_COLLATE_CONTEXTUALLY_TYPED;
|
||||||
|
}
|
||||||
|
void set_contextually_typed_binary_style()
|
||||||
|
{
|
||||||
|
m_ci= &my_collation_contextually_typed_binary;
|
||||||
|
m_type= TYPE_COLLATE_CONTEXTUALLY_TYPED;
|
||||||
|
}
|
||||||
|
bool is_contextually_typed_collate_default() const
|
||||||
|
{
|
||||||
|
return m_ci == &my_collation_contextually_typed_default;
|
||||||
|
}
|
||||||
|
bool is_contextually_typed_binary_style() const
|
||||||
|
{
|
||||||
|
return m_ci == &my_collation_contextually_typed_binary;
|
||||||
|
}
|
||||||
|
void set_collate_exact(CHARSET_INFO *cl)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(cl);
|
||||||
|
m_ci= cl;
|
||||||
|
m_type= TYPE_COLLATE_EXACT;
|
||||||
|
}
|
||||||
|
CHARSET_INFO *charset_collation() const
|
||||||
|
{
|
||||||
|
return m_ci;
|
||||||
|
}
|
||||||
|
Type type() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
bool is_contextually_typed_collation() const
|
||||||
|
{
|
||||||
|
return m_type == TYPE_COLLATE_CONTEXTUALLY_TYPED;
|
||||||
|
}
|
||||||
|
CHARSET_INFO *resolved_to_character_set(CHARSET_INFO *cs) const;
|
||||||
|
bool merge_charset_clause_and_collate_clause(const Lex_charset_collation_st &cl);
|
||||||
|
bool merge_collate_clause_and_collate_clause(const Lex_charset_collation_st &cl);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
CHARACTER SET cs [COLLATE cl]
|
||||||
|
*/
|
||||||
|
class Lex_explicit_charset_opt_collate
|
||||||
|
{
|
||||||
|
CHARSET_INFO *m_ci;
|
||||||
|
bool m_with_collate;
|
||||||
|
public:
|
||||||
|
Lex_explicit_charset_opt_collate(CHARSET_INFO *ci, bool with_collate)
|
||||||
|
:m_ci(ci), m_with_collate(with_collate)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_ci);
|
||||||
|
// Item_func_set_collation uses non-default collations in "ci"
|
||||||
|
//DBUG_ASSERT(m_ci->default_flag() || m_with_collate);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Merge to another COLLATE clause. So the full syntax looks like:
|
||||||
|
CHARACTER SET cs [COLLATE cl] ... COLLATE cl2
|
||||||
|
*/
|
||||||
|
bool merge_collate_or_error(const Lex_charset_collation_st &cl);
|
||||||
|
bool merge_opt_collate_or_error(const Lex_charset_collation_st &cl)
|
||||||
|
{
|
||||||
|
if (cl.is_empty())
|
||||||
|
return false;
|
||||||
|
return merge_collate_or_error(cl);
|
||||||
|
}
|
||||||
|
CHARSET_INFO *charset_and_collation() const { return m_ci; }
|
||||||
|
bool with_collate() const { return m_with_collate; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Lex_charset_collation: public Lex_charset_collation_st
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Lex_charset_collation()
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
Lex_charset_collation(CHARSET_INFO *collation, Type type)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(collation || type == TYPE_EMPTY);
|
||||||
|
m_ci= collation;
|
||||||
|
m_type= type;
|
||||||
|
}
|
||||||
|
static Lex_charset_collation national(bool bin_mod)
|
||||||
|
{
|
||||||
|
return bin_mod ?
|
||||||
|
Lex_charset_collation(&my_charset_utf8mb3_bin, TYPE_COLLATE_EXACT) :
|
||||||
|
Lex_charset_collation(&my_charset_utf8mb3_general_ci, TYPE_CHARACTER_SET);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LEX_CHARSET_INCLUDED
|
@@ -543,36 +543,10 @@ bool LEX::add_alter_list(LEX_CSTRING name, LEX_CSTRING new_name, bool exists)
|
|||||||
|
|
||||||
|
|
||||||
void LEX::init_last_field(Column_definition *field,
|
void LEX::init_last_field(Column_definition *field,
|
||||||
const LEX_CSTRING *field_name,
|
const LEX_CSTRING *field_name)
|
||||||
const CHARSET_INFO *cs)
|
|
||||||
{
|
{
|
||||||
last_field= field;
|
last_field= field;
|
||||||
|
|
||||||
field->field_name= *field_name;
|
field->field_name= *field_name;
|
||||||
|
|
||||||
/* reset LEX fields that are used in Create_field::set_and_check() */
|
|
||||||
charset= cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if charset is NULL - we're parsing a field declaration.
|
|
||||||
we cannot call find_bin_collation for a field here, because actual
|
|
||||||
field charset is determined in get_sql_field_charset() much later.
|
|
||||||
so we only set a flag.
|
|
||||||
*/
|
|
||||||
if (!charset)
|
|
||||||
{
|
|
||||||
charset= cs;
|
|
||||||
last_field->flags|= bin ? BINCMP_FLAG : 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
charset= bin ? find_bin_collation(cs ? cs : charset)
|
|
||||||
: cs ? cs : charset;
|
|
||||||
return charset == NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6392,8 +6366,7 @@ sp_variable *LEX::sp_param_init(LEX_CSTRING *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sp_variable *spvar= spcont->add_variable(thd, name);
|
sp_variable *spvar= spcont->add_variable(thd, name);
|
||||||
init_last_field(&spvar->field_def, name,
|
init_last_field(&spvar->field_def, name);
|
||||||
thd->variables.collation_database);
|
|
||||||
return spvar;
|
return spvar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6402,8 +6375,7 @@ bool LEX::sp_param_fill_definition(sp_variable *spvar,
|
|||||||
const Lex_field_type_st &def)
|
const Lex_field_type_st &def)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
last_field->set_attributes(thd, def, charset,
|
last_field->set_attributes(thd, def, COLUMN_DEFINITION_ROUTINE_PARAM) ||
|
||||||
COLUMN_DEFINITION_ROUTINE_PARAM) ||
|
|
||||||
sphead->fill_spvar_definition(thd, last_field, &spvar->name);
|
sphead->fill_spvar_definition(thd, last_field, &spvar->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6411,8 +6383,7 @@ bool LEX::sp_param_fill_definition(sp_variable *spvar,
|
|||||||
bool LEX::sf_return_fill_definition(const Lex_field_type_st &def)
|
bool LEX::sf_return_fill_definition(const Lex_field_type_st &def)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
last_field->set_attributes(thd, def, charset,
|
last_field->set_attributes(thd, def, COLUMN_DEFINITION_FUNCTION_RETURN) ||
|
||||||
COLUMN_DEFINITION_FUNCTION_RETURN) ||
|
|
||||||
sphead->fill_field_definition(thd, last_field);
|
sphead->fill_field_definition(thd, last_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6492,8 +6463,7 @@ void LEX::sp_variable_declarations_init(THD *thd, int nvars)
|
|||||||
|
|
||||||
sphead->reset_lex(thd);
|
sphead->reset_lex(thd);
|
||||||
spcont->declare_var_boundary(nvars);
|
spcont->declare_var_boundary(nvars);
|
||||||
thd->lex->init_last_field(&spvar->field_def, &spvar->name,
|
thd->lex->init_last_field(&spvar->field_def, &spvar->name);
|
||||||
thd->variables.collation_database);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -11465,16 +11435,15 @@ Spvar_definition *LEX::row_field_name(THD *thd, const Lex_ident_sys_st &name)
|
|||||||
}
|
}
|
||||||
if (unlikely(!(res= new (thd->mem_root) Spvar_definition())))
|
if (unlikely(!(res= new (thd->mem_root) Spvar_definition())))
|
||||||
return NULL;
|
return NULL;
|
||||||
init_last_field(res, &name, thd->variables.collation_database);
|
init_last_field(res, &name);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *
|
Item *
|
||||||
Lex_cast_type_st::create_typecast_item_or_error(THD *thd, Item *item,
|
Lex_cast_type_st::create_typecast_item_or_error(THD *thd, Item *item) const
|
||||||
CHARSET_INFO *cs) const
|
|
||||||
{
|
{
|
||||||
Item *tmp= create_typecast_item(thd, item, cs);
|
Item *tmp= create_typecast_item(thd, item);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
Name name= m_type_handler->name();
|
Name name= m_type_handler->name();
|
||||||
@@ -11534,8 +11503,7 @@ bool LEX::set_field_type_udt(Lex_field_type_st *type,
|
|||||||
const Type_handler *h;
|
const Type_handler *h;
|
||||||
if (!(h= Type_handler::handler_by_name_or_error(thd, name)))
|
if (!(h= Type_handler::handler_by_name_or_error(thd, name)))
|
||||||
return true;
|
return true;
|
||||||
type->set(h, attr);
|
type->set(h, attr, &my_charset_bin);
|
||||||
charset= &my_charset_bin;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11547,7 +11515,6 @@ bool LEX::set_cast_type_udt(Lex_cast_type_st *type,
|
|||||||
if (!(h= Type_handler::handler_by_name_or_error(thd, name)))
|
if (!(h= Type_handler::handler_by_name_or_error(thd, name)))
|
||||||
return true;
|
return true;
|
||||||
type->set(h);
|
type->set(h);
|
||||||
charset= NULL;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3192,8 +3192,6 @@ public:
|
|||||||
/* Query Plan Footprint of a currently running select */
|
/* Query Plan Footprint of a currently running select */
|
||||||
Explain_query *explain;
|
Explain_query *explain;
|
||||||
|
|
||||||
// type information
|
|
||||||
CHARSET_INFO *charset;
|
|
||||||
/*
|
/*
|
||||||
LEX which represents current statement (conventional, SP or PS)
|
LEX which represents current statement (conventional, SP or PS)
|
||||||
|
|
||||||
@@ -3800,14 +3798,12 @@ public:
|
|||||||
bool is_analyze, bool *printed_anything);
|
bool is_analyze, bool *printed_anything);
|
||||||
bool restore_set_statement_var();
|
bool restore_set_statement_var();
|
||||||
|
|
||||||
void init_last_field(Column_definition *field, const LEX_CSTRING *name,
|
void init_last_field(Column_definition *field, const LEX_CSTRING *name);
|
||||||
const CHARSET_INFO *cs);
|
|
||||||
bool last_field_generated_always_as_row_start_or_end(Lex_ident *p,
|
bool last_field_generated_always_as_row_start_or_end(Lex_ident *p,
|
||||||
const char *type,
|
const char *type,
|
||||||
uint flags);
|
uint flags);
|
||||||
bool last_field_generated_always_as_row_start();
|
bool last_field_generated_always_as_row_start();
|
||||||
bool last_field_generated_always_as_row_end();
|
bool last_field_generated_always_as_row_end();
|
||||||
bool set_bincmp(CHARSET_INFO *cs, bool bin);
|
|
||||||
|
|
||||||
bool new_sp_instr_stmt(THD *, const LEX_CSTRING &prefix,
|
bool new_sp_instr_stmt(THD *, const LEX_CSTRING &prefix,
|
||||||
const LEX_CSTRING &suffix);
|
const LEX_CSTRING &suffix);
|
||||||
|
@@ -10463,24 +10463,6 @@ merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl)
|
|||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** find a collation with binary comparison rules
|
|
||||||
*/
|
|
||||||
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs)
|
|
||||||
{
|
|
||||||
const char *csname= cs->cs_name.str;
|
|
||||||
THD *thd= current_thd;
|
|
||||||
myf utf8_flag= thd->get_utf8_flag();
|
|
||||||
|
|
||||||
cs= get_charset_by_csname(csname, MY_CS_BINSORT, MYF(utf8_flag));
|
|
||||||
if (!cs)
|
|
||||||
{
|
|
||||||
char tmp[65];
|
|
||||||
strxnmov(tmp, sizeof(tmp)-1, csname, "_bin", NULL);
|
|
||||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
|
|
||||||
}
|
|
||||||
return cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LEX::mark_first_table_as_inserting()
|
void LEX::mark_first_table_as_inserting()
|
||||||
{
|
{
|
||||||
TABLE_LIST *t= first_select_lex()->table_list.first;
|
TABLE_LIST *t= first_select_lex()->table_list.first;
|
||||||
|
@@ -79,7 +79,6 @@ bool check_string_char_length(const LEX_CSTRING *str, uint err_msg,
|
|||||||
bool no_error);
|
bool no_error);
|
||||||
bool check_ident_length(const LEX_CSTRING *ident);
|
bool check_ident_length(const LEX_CSTRING *ident);
|
||||||
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
|
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
|
||||||
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs);
|
|
||||||
bool check_host_name(LEX_CSTRING *str);
|
bool check_host_name(LEX_CSTRING *str);
|
||||||
bool check_identifier_name(LEX_CSTRING *str, uint max_char_length,
|
bool check_identifier_name(LEX_CSTRING *str, uint max_char_length,
|
||||||
uint err_code, const char *param_for_err_msg);
|
uint err_code, const char *param_for_err_msg);
|
||||||
|
@@ -2190,12 +2190,27 @@ bool check_duplicates_in_interval(const char *set_or_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Resolves the column collation if:
|
||||||
|
- it was not typed at all, or
|
||||||
|
- it was contextually typed
|
||||||
|
according to the table level character set.
|
||||||
|
Generates an error to the diagnostics area in case of a failure.
|
||||||
|
*/
|
||||||
bool Column_definition::
|
bool Column_definition::
|
||||||
prepare_charset_for_string(const Column_derived_attributes *dattr)
|
prepare_charset_for_string(const Column_derived_attributes *dattr)
|
||||||
{
|
{
|
||||||
if (!charset)
|
CHARSET_INFO *tmp= lex_charset_collation().
|
||||||
charset= dattr->charset();
|
resolved_to_character_set(dattr->charset());
|
||||||
return (flags & BINCMP_FLAG) && !(charset= find_bin_collation(charset));
|
if (!tmp)
|
||||||
|
return true;
|
||||||
|
charset= tmp;
|
||||||
|
/*
|
||||||
|
Remove the "is contextually typed collation" indicator on success,
|
||||||
|
for safety.
|
||||||
|
*/
|
||||||
|
flags&= ~CONTEXT_COLLATION_FLAG;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3959,8 +3974,7 @@ bool Column_definition::prepare_blob_field(THD *thd)
|
|||||||
|
|
||||||
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
|
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(charset);
|
const Column_derived_attributes dattr(thd->variables.collation_database);
|
||||||
const Column_derived_attributes dattr(&my_charset_bin);
|
|
||||||
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY, &dattr) ||
|
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY, &dattr) ||
|
||||||
prepare_stage2(NULL, HA_CAN_GEOMETRY);
|
prepare_stage2(NULL, HA_CAN_GEOMETRY);
|
||||||
}
|
}
|
||||||
|
@@ -2713,11 +2713,10 @@ bool
|
|||||||
Type_handler::Column_definition_set_attributes(THD *thd,
|
Type_handler::Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
def->charset= cs;
|
def->set_lex_charset_collation(attr.lex_charset_collation());
|
||||||
def->set_length_and_dec(attr);
|
def->set_length_and_dec(attr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2746,11 +2745,10 @@ Type_handler_string::Column_definition_set_attributes(
|
|||||||
THD *thd,
|
THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
Type_handler::Column_definition_set_attributes(thd, def, attr, cs, type);
|
Type_handler::Column_definition_set_attributes(thd, def, attr, type);
|
||||||
if (attr.has_explicit_length())
|
if (attr.has_explicit_length())
|
||||||
return false;
|
return false;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -2778,11 +2776,10 @@ Type_handler_varchar::Column_definition_set_attributes(
|
|||||||
THD *thd,
|
THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
Type_handler::Column_definition_set_attributes(thd, def, attr, cs, type);
|
Type_handler::Column_definition_set_attributes(thd, def, attr, type);
|
||||||
if (attr.has_explicit_length())
|
if (attr.has_explicit_length())
|
||||||
return false;
|
return false;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -3156,7 +3153,7 @@ bool Type_handler_general_purpose_string::
|
|||||||
Change character sets for all varchar/char/text columns,
|
Change character sets for all varchar/char/text columns,
|
||||||
but do not touch varbinary/binary/blob columns.
|
but do not touch varbinary/binary/blob columns.
|
||||||
*/
|
*/
|
||||||
if (defcs != &my_charset_bin)
|
if (!(def->flags & CONTEXT_COLLATION_FLAG) && defcs != &my_charset_bin)
|
||||||
def->charset= bulk_alter_attr->alter_table_convert_to_charset();
|
def->charset= bulk_alter_attr->alter_table_convert_to_charset();
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -4267,10 +4264,9 @@ Type_handler_timestamp_common::
|
|||||||
Column_definition_set_attributes(THD *thd,
|
Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type) const
|
column_definition_type_t type) const
|
||||||
{
|
{
|
||||||
Type_handler::Column_definition_set_attributes(thd, def, attr, cs, type);
|
Type_handler::Column_definition_set_attributes(thd, def, attr, type);
|
||||||
if (!opt_explicit_defaults_for_timestamp)
|
if (!opt_explicit_defaults_for_timestamp)
|
||||||
def->flags|= NOT_NULL_FLAG;
|
def->flags|= NOT_NULL_FLAG;
|
||||||
return false;
|
return false;
|
||||||
|
@@ -3924,7 +3924,6 @@ public:
|
|||||||
virtual bool Column_definition_set_attributes(THD *thd,
|
virtual bool Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const;
|
const;
|
||||||
// Fix attributes after the parser
|
// Fix attributes after the parser
|
||||||
@@ -6659,7 +6658,6 @@ public:
|
|||||||
bool Column_definition_set_attributes(THD *thd,
|
bool Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const override;
|
const override;
|
||||||
};
|
};
|
||||||
@@ -6912,7 +6910,6 @@ public:
|
|||||||
bool Column_definition_set_attributes(THD *thd,
|
bool Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const override;
|
const override;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
||||||
@@ -7009,7 +7006,6 @@ public:
|
|||||||
bool Column_definition_set_attributes(THD *thd,
|
bool Column_definition_set_attributes(THD *thd,
|
||||||
Column_definition *def,
|
Column_definition *def,
|
||||||
const Lex_field_type_st &attr,
|
const Lex_field_type_st &attr,
|
||||||
CHARSET_INFO *cs,
|
|
||||||
column_definition_type_t type)
|
column_definition_type_t type)
|
||||||
const override;
|
const override;
|
||||||
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
||||||
|
281
sql/sql_yacc.yy
281
sql/sql_yacc.yy
@@ -193,14 +193,6 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define bincmp_collation(X,Y) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (unlikely(Lex->set_bincmp(X,Y))) \
|
|
||||||
MYSQL_YYABORT; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
%union {
|
%union {
|
||||||
int num;
|
int num;
|
||||||
@@ -221,6 +213,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
|
|||||||
Lex_length_and_dec_st Lex_length_and_dec;
|
Lex_length_and_dec_st Lex_length_and_dec;
|
||||||
Lex_cast_type_st Lex_cast_type;
|
Lex_cast_type_st Lex_cast_type;
|
||||||
Lex_field_type_st Lex_field_type;
|
Lex_field_type_st Lex_field_type;
|
||||||
|
Lex_charset_collation_st Lex_charset_collation;
|
||||||
Lex_dyncol_type_st Lex_dyncol_type;
|
Lex_dyncol_type_st Lex_dyncol_type;
|
||||||
Lex_for_loop_st for_loop;
|
Lex_for_loop_st for_loop;
|
||||||
Lex_for_loop_bounds_st for_loop_bounds;
|
Lex_for_loop_bounds_st for_loop_bounds;
|
||||||
@@ -1386,6 +1379,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
field_type_misc
|
field_type_misc
|
||||||
json_table_field_type
|
json_table_field_type
|
||||||
|
|
||||||
|
%type <Lex_charset_collation>
|
||||||
|
binary
|
||||||
|
opt_binary
|
||||||
|
opt_binary_and_compression
|
||||||
|
attribute
|
||||||
|
attribute_list
|
||||||
|
field_def
|
||||||
|
|
||||||
|
|
||||||
%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
|
%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
|
||||||
numeric_dyncol_type temporal_dyncol_type string_dyncol_type
|
numeric_dyncol_type temporal_dyncol_type string_dyncol_type
|
||||||
|
|
||||||
@@ -1575,8 +1577,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
text_or_password
|
text_or_password
|
||||||
|
|
||||||
%type <charset>
|
%type <charset>
|
||||||
opt_collate
|
opt_collate_or_default
|
||||||
collate
|
|
||||||
charset_name
|
charset_name
|
||||||
charset_or_alias
|
charset_or_alias
|
||||||
charset_name_or_default
|
charset_name_or_default
|
||||||
@@ -1658,14 +1659,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
delete_limit_clause fields opt_values values
|
delete_limit_clause fields opt_values values
|
||||||
no_braces_with_names opt_values_with_names values_with_names
|
no_braces_with_names opt_values_with_names values_with_names
|
||||||
procedure_list procedure_list2 procedure_item
|
procedure_list procedure_list2 procedure_item
|
||||||
field_def handler opt_generated_always
|
handler opt_generated_always
|
||||||
opt_ignore opt_column opt_restrict
|
opt_ignore opt_column opt_restrict
|
||||||
grant revoke set lock unlock string_list
|
grant revoke set lock unlock string_list
|
||||||
opt_binary table_lock_list table_lock
|
table_lock_list table_lock
|
||||||
ref_list opt_match_clause opt_on_update_delete use
|
ref_list opt_match_clause opt_on_update_delete use
|
||||||
opt_delete_options opt_delete_option varchar nchar nvarchar
|
opt_delete_options opt_delete_option varchar nchar nvarchar
|
||||||
opt_outer table_list table_name table_alias_ref_list table_alias_ref
|
opt_outer table_list table_name table_alias_ref_list table_alias_ref
|
||||||
attribute attribute_list
|
|
||||||
compressed_deprecated_data_type_attribute
|
compressed_deprecated_data_type_attribute
|
||||||
compressed_deprecated_column_attribute
|
compressed_deprecated_column_attribute
|
||||||
grant_list
|
grant_list
|
||||||
@@ -3124,7 +3124,7 @@ optionally_qualified_column_ident:
|
|||||||
row_field_definition:
|
row_field_definition:
|
||||||
row_field_name field_type
|
row_field_name field_type
|
||||||
{
|
{
|
||||||
Lex->last_field->set_attributes(thd, $2, Lex->charset,
|
Lex->last_field->set_attributes(thd, $2,
|
||||||
COLUMN_DEFINITION_ROUTINE_LOCAL);
|
COLUMN_DEFINITION_ROUTINE_LOCAL);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -3157,7 +3157,7 @@ sp_decl_variable_list:
|
|||||||
sp_decl_idents_init_vars
|
sp_decl_idents_init_vars
|
||||||
field_type
|
field_type
|
||||||
{
|
{
|
||||||
Lex->last_field->set_attributes(thd, $2, Lex->charset,
|
Lex->last_field->set_attributes(thd, $2,
|
||||||
COLUMN_DEFINITION_ROUTINE_LOCAL);
|
COLUMN_DEFINITION_ROUTINE_LOCAL);
|
||||||
}
|
}
|
||||||
sp_opt_default
|
sp_opt_default
|
||||||
@@ -5723,7 +5723,7 @@ field_spec:
|
|||||||
if (unlikely(!f))
|
if (unlikely(!f))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->init_last_field(f, &$1, NULL);
|
lex->init_last_field(f, &$1);
|
||||||
$<create_field>$= f;
|
$<create_field>$= f;
|
||||||
lex->parsing_options.lookup_keywords_after_qualifier= true;
|
lex->parsing_options.lookup_keywords_after_qualifier= true;
|
||||||
}
|
}
|
||||||
@@ -5751,10 +5751,16 @@ field_spec:
|
|||||||
field_type_or_serial:
|
field_type_or_serial:
|
||||||
qualified_field_type
|
qualified_field_type
|
||||||
{
|
{
|
||||||
Lex->last_field->set_attributes(thd, $1, Lex->charset,
|
Lex->last_field->set_attributes(thd, $1,
|
||||||
COLUMN_DEFINITION_TABLE_FIELD);
|
COLUMN_DEFINITION_TABLE_FIELD);
|
||||||
}
|
}
|
||||||
field_def
|
field_def
|
||||||
|
{
|
||||||
|
Lex_charset_collation tmp= $1.lex_charset_collation();
|
||||||
|
if (tmp.merge_charset_clause_and_collate_clause($3))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
Lex->last_field->set_lex_charset_collation(tmp);
|
||||||
|
}
|
||||||
| SERIAL_SYM
|
| SERIAL_SYM
|
||||||
{
|
{
|
||||||
Lex->last_field->set_handler(&type_handler_ulonglong);
|
Lex->last_field->set_handler(&type_handler_ulonglong);
|
||||||
@@ -5786,25 +5792,34 @@ opt_asrow_attribute_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
field_def:
|
field_def:
|
||||||
/* empty */ { }
|
/* empty */ { $$.init(); }
|
||||||
| attribute_list
|
| attribute_list
|
||||||
| attribute_list compressed_deprecated_column_attribute
|
| attribute_list compressed_deprecated_column_attribute { $$= $1; }
|
||||||
| attribute_list compressed_deprecated_column_attribute attribute_list
|
| attribute_list compressed_deprecated_column_attribute attribute_list
|
||||||
|
{
|
||||||
|
if (($$= $1).merge_collate_clause_and_collate_clause($3))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| opt_generated_always AS virtual_column_func
|
| opt_generated_always AS virtual_column_func
|
||||||
{
|
{
|
||||||
Lex->last_field->vcol_info= $3;
|
Lex->last_field->vcol_info= $3;
|
||||||
Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps
|
Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps
|
||||||
}
|
}
|
||||||
vcol_opt_specifier vcol_opt_attribute
|
vcol_opt_specifier vcol_opt_attribute
|
||||||
|
{
|
||||||
|
$$.init();
|
||||||
|
}
|
||||||
| opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute
|
| opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute
|
||||||
{
|
{
|
||||||
if (Lex->last_field_generated_always_as_row_start())
|
if (Lex->last_field_generated_always_as_row_start())
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
$$.init();
|
||||||
}
|
}
|
||||||
| opt_generated_always AS ROW_SYM END opt_asrow_attribute
|
| opt_generated_always AS ROW_SYM END opt_asrow_attribute
|
||||||
{
|
{
|
||||||
if (Lex->last_field_generated_always_as_row_end())
|
if (Lex->last_field_generated_always_as_row_end())
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
$$.init();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -6017,49 +6032,46 @@ field_type_numeric:
|
|||||||
|
|
||||||
|
|
||||||
opt_binary_and_compression:
|
opt_binary_and_compression:
|
||||||
/* empty */
|
/* empty */ { $$.init(); }
|
||||||
| binary
|
| binary { $$= $1; }
|
||||||
| binary compressed_deprecated_data_type_attribute
|
| binary compressed_deprecated_data_type_attribute { $$= $1; }
|
||||||
| compressed opt_binary
|
| compressed opt_binary { $$= $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
field_type_string:
|
field_type_string:
|
||||||
char opt_field_length opt_binary
|
char opt_field_length opt_binary
|
||||||
{
|
{
|
||||||
$$.set(&type_handler_string, $2);
|
$$.set(&type_handler_string, $2, $3);
|
||||||
}
|
}
|
||||||
| nchar opt_field_length opt_bin_mod
|
| nchar opt_field_length opt_bin_mod
|
||||||
{
|
{
|
||||||
$$.set(&type_handler_string, $2);
|
$$.set(&type_handler_string, $2,
|
||||||
bincmp_collation(national_charset_info, $3);
|
Lex_charset_collation::national($3));
|
||||||
}
|
}
|
||||||
| BINARY opt_field_length
|
| BINARY opt_field_length
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_string, $2, &my_charset_bin);
|
||||||
$$.set(&type_handler_string, $2);
|
|
||||||
}
|
}
|
||||||
| varchar opt_field_length opt_binary_and_compression
|
| varchar opt_field_length opt_binary_and_compression
|
||||||
{
|
{
|
||||||
$$.set(&type_handler_varchar, $2);
|
$$.set(&type_handler_varchar, $2, $3);
|
||||||
}
|
}
|
||||||
| VARCHAR2_ORACLE_SYM opt_field_length opt_binary_and_compression
|
| VARCHAR2_ORACLE_SYM opt_field_length opt_binary_and_compression
|
||||||
{
|
{
|
||||||
$$.set(&type_handler_varchar, $2);
|
$$.set(&type_handler_varchar, $2, $3);
|
||||||
}
|
}
|
||||||
| nvarchar opt_field_length opt_compressed opt_bin_mod
|
| nvarchar opt_field_length opt_compressed opt_bin_mod
|
||||||
{
|
{
|
||||||
$$.set(&type_handler_varchar, $2);
|
$$.set(&type_handler_varchar, $2,
|
||||||
bincmp_collation(national_charset_info, $4);
|
Lex_charset_collation::national($4));
|
||||||
}
|
}
|
||||||
| VARBINARY opt_field_length opt_compressed
|
| VARBINARY opt_field_length opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_varchar, $2, &my_charset_bin);
|
||||||
$$.set(&type_handler_varchar, $2);
|
|
||||||
}
|
}
|
||||||
| RAW_ORACLE_SYM opt_field_length opt_compressed
|
| RAW_ORACLE_SYM opt_field_length opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset= &my_charset_bin;
|
$$.set(&type_handler_varchar, $2, &my_charset_bin);
|
||||||
$$.set(&type_handler_varchar, $2);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -6105,65 +6117,57 @@ field_type_temporal:
|
|||||||
field_type_lob:
|
field_type_lob:
|
||||||
TINYBLOB opt_compressed
|
TINYBLOB opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_tiny_blob, &my_charset_bin);
|
||||||
$$.set(&type_handler_tiny_blob);
|
|
||||||
}
|
}
|
||||||
| BLOB_MARIADB_SYM opt_field_length opt_compressed
|
| BLOB_MARIADB_SYM opt_field_length opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_blob, $2, &my_charset_bin);
|
||||||
$$.set(&type_handler_blob, $2);
|
|
||||||
}
|
}
|
||||||
| BLOB_ORACLE_SYM field_length opt_compressed
|
| BLOB_ORACLE_SYM field_length opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_blob, $2, &my_charset_bin);
|
||||||
$$.set(&type_handler_blob, $2);
|
|
||||||
}
|
}
|
||||||
| BLOB_ORACLE_SYM opt_compressed
|
| BLOB_ORACLE_SYM opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_long_blob, &my_charset_bin);
|
||||||
$$.set(&type_handler_long_blob);
|
|
||||||
}
|
}
|
||||||
| MEDIUMBLOB opt_compressed
|
| MEDIUMBLOB opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_medium_blob, &my_charset_bin);
|
||||||
$$.set(&type_handler_medium_blob);
|
|
||||||
}
|
}
|
||||||
| LONGBLOB opt_compressed
|
| LONGBLOB opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_long_blob, &my_charset_bin);
|
||||||
$$.set(&type_handler_long_blob);
|
|
||||||
}
|
}
|
||||||
| LONG_SYM VARBINARY opt_compressed
|
| LONG_SYM VARBINARY opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset=&my_charset_bin;
|
$$.set(&type_handler_medium_blob, &my_charset_bin);
|
||||||
$$.set(&type_handler_medium_blob);
|
|
||||||
}
|
}
|
||||||
| LONG_SYM varchar opt_binary_and_compression
|
| LONG_SYM varchar opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_medium_blob); }
|
{ $$.set(&type_handler_medium_blob, $3); }
|
||||||
| TINYTEXT opt_binary_and_compression
|
| TINYTEXT opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_tiny_blob); }
|
{ $$.set(&type_handler_tiny_blob, $2); }
|
||||||
| TEXT_SYM opt_field_length opt_binary_and_compression
|
| TEXT_SYM opt_field_length opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_blob, $2); }
|
{ $$.set(&type_handler_blob, $2, $3); }
|
||||||
| MEDIUMTEXT opt_binary_and_compression
|
| MEDIUMTEXT opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_medium_blob); }
|
{ $$.set(&type_handler_medium_blob, $2); }
|
||||||
| LONGTEXT opt_binary_and_compression
|
| LONGTEXT opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_long_blob); }
|
{ $$.set(&type_handler_long_blob, $2); }
|
||||||
| CLOB_ORACLE_SYM opt_binary_and_compression
|
| CLOB_ORACLE_SYM opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_long_blob); }
|
{ $$.set(&type_handler_long_blob, $2); }
|
||||||
| LONG_SYM opt_binary_and_compression
|
| LONG_SYM opt_binary_and_compression
|
||||||
{ $$.set(&type_handler_medium_blob); }
|
{ $$.set(&type_handler_medium_blob, $2); }
|
||||||
| JSON_SYM opt_compressed
|
| JSON_SYM opt_compressed
|
||||||
{
|
{
|
||||||
Lex->charset= &my_charset_utf8mb4_bin;
|
$$.set(&type_handler_long_blob_json, &my_charset_utf8mb4_bin);
|
||||||
$$.set(&type_handler_long_blob_json);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
field_type_misc:
|
field_type_misc:
|
||||||
ENUM '(' string_list ')' opt_binary
|
ENUM '(' string_list ')' opt_binary
|
||||||
{ $$.set(&type_handler_enum); }
|
{ $$.set(&type_handler_enum, $5); }
|
||||||
| SET '(' string_list ')' opt_binary
|
| SET '(' string_list ')' opt_binary
|
||||||
{ $$.set(&type_handler_set); }
|
{ $$.set(&type_handler_set, $5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
char:
|
char:
|
||||||
@@ -6272,35 +6276,38 @@ opt_precision:
|
|||||||
|
|
||||||
|
|
||||||
attribute_list:
|
attribute_list:
|
||||||
attribute_list attribute {}
|
attribute_list attribute
|
||||||
|
{
|
||||||
|
if (($$= $1).merge_collate_clause_and_collate_clause($2))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| attribute
|
| attribute
|
||||||
;
|
;
|
||||||
|
|
||||||
attribute:
|
attribute:
|
||||||
NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; }
|
NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; $$.init(); }
|
||||||
| DEFAULT column_default_expr { Lex->last_field->default_value= $2; }
|
| DEFAULT column_default_expr { Lex->last_field->default_value= $2; $$.init(); }
|
||||||
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
|
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
|
||||||
{
|
{
|
||||||
Item *item= new (thd->mem_root) Item_func_now_local(thd, $4);
|
Item *item= new (thd->mem_root) Item_func_now_local(thd, $4);
|
||||||
if (unlikely(item == NULL))
|
if (unlikely(item == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->last_field->on_update= item;
|
Lex->last_field->on_update= item;
|
||||||
|
$$.init();
|
||||||
}
|
}
|
||||||
| AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
| AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; $$.init(); }
|
||||||
| SERIAL_SYM DEFAULT VALUE_SYM
|
| SERIAL_SYM DEFAULT VALUE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG;
|
lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG;
|
||||||
lex->alter_info.flags|= ALTER_ADD_INDEX;
|
lex->alter_info.flags|= ALTER_ADD_INDEX;
|
||||||
|
$$.init();
|
||||||
}
|
}
|
||||||
| COLLATE_SYM collation_name
|
| COLLATE_SYM collation_name
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->charset && !my_charset_same(Lex->charset,$2)))
|
$$.set_collate_exact($2);
|
||||||
my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
|
||||||
$2->coll_name.str, Lex->charset->cs_name.str));
|
|
||||||
Lex->last_field->charset= $2;
|
|
||||||
}
|
}
|
||||||
| serial_attribute
|
| serial_attribute { $$.init(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_compression_method:
|
opt_compression_method:
|
||||||
@@ -6444,7 +6451,7 @@ collation_name:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_collate:
|
opt_collate_or_default:
|
||||||
/* empty */ { $$=NULL; }
|
/* empty */ { $$=NULL; }
|
||||||
| COLLATE_SYM collation_name_or_default { $$=$2; }
|
| COLLATE_SYM collation_name_or_default { $$=$2; }
|
||||||
;
|
;
|
||||||
@@ -6469,27 +6476,36 @@ charset_or_alias:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
collate: COLLATE_SYM collation_name_or_default { $$= $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
opt_binary:
|
opt_binary:
|
||||||
/* empty */ { bincmp_collation(NULL, false); }
|
/* empty */ { $$.init(); }
|
||||||
| binary {}
|
| binary
|
||||||
;
|
;
|
||||||
|
|
||||||
binary:
|
binary:
|
||||||
BYTE_SYM { bincmp_collation(&my_charset_bin, false); }
|
BYTE_SYM { $$.set_charset(&my_charset_bin); }
|
||||||
| charset_or_alias opt_bin_mod { bincmp_collation($1, $2); }
|
| charset_or_alias { $$.set_charset($1); }
|
||||||
| BINARY { bincmp_collation(NULL, true); }
|
| charset_or_alias BINARY
|
||||||
| BINARY charset_or_alias { bincmp_collation($2, true); }
|
|
||||||
| charset_or_alias collate
|
|
||||||
{
|
{
|
||||||
if (!my_charset_same($2, $1))
|
if ($$.set_charset_collate_binary($1))
|
||||||
my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
MYSQL_YYABORT;
|
||||||
$2->coll_name.str, $1->cs_name.str));
|
|
||||||
Lex->charset= $2;
|
|
||||||
}
|
}
|
||||||
| collate { Lex->charset= $1; }
|
| BINARY { $$.set_contextually_typed_binary_style(); }
|
||||||
|
| BINARY charset_or_alias
|
||||||
|
{
|
||||||
|
if ($$.set_charset_collate_binary($2))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| charset_or_alias COLLATE_SYM DEFAULT
|
||||||
|
{
|
||||||
|
$$.set_charset_collate_default($1);
|
||||||
|
}
|
||||||
|
| charset_or_alias COLLATE_SYM collation_name
|
||||||
|
{
|
||||||
|
if ($$.set_charset_collate_exact($1, $3))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| COLLATE_SYM collation_name { $$.set_collate_exact($2); }
|
||||||
|
| COLLATE_SYM DEFAULT { $$.set_collate_default(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_bin_mod:
|
opt_bin_mod:
|
||||||
@@ -7559,7 +7575,8 @@ alter_list_item:
|
|||||||
lex->alter_info.alter_rename_key_list.push_back(ak);
|
lex->alter_info.alter_rename_key_list.push_back(ak);
|
||||||
lex->alter_info.flags|= ALTER_RENAME_INDEX;
|
lex->alter_info.flags|= ALTER_RENAME_INDEX;
|
||||||
}
|
}
|
||||||
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
|
| CONVERT_SYM TO_SYM charset charset_name_or_default
|
||||||
|
opt_collate_or_default
|
||||||
{
|
{
|
||||||
if (!$4)
|
if (!$4)
|
||||||
{
|
{
|
||||||
@@ -9407,15 +9424,14 @@ opt_dyncol_type:
|
|||||||
/* empty */
|
/* empty */
|
||||||
{
|
{
|
||||||
$$.set(DYN_COL_NULL); /* automatic type */
|
$$.set(DYN_COL_NULL); /* automatic type */
|
||||||
Lex->charset= NULL;
|
|
||||||
}
|
}
|
||||||
| AS dyncol_type { $$= $2; }
|
| AS dyncol_type { $$= $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
dyncol_type:
|
dyncol_type:
|
||||||
numeric_dyncol_type { $$= $1; Lex->charset= NULL; }
|
numeric_dyncol_type
|
||||||
| temporal_dyncol_type { $$= $1; Lex->charset= NULL; }
|
| temporal_dyncol_type
|
||||||
| string_dyncol_type { $$= $1; }
|
| string_dyncol_type
|
||||||
;
|
;
|
||||||
|
|
||||||
numeric_dyncol_type:
|
numeric_dyncol_type:
|
||||||
@@ -9434,23 +9450,20 @@ temporal_dyncol_type:
|
|||||||
;
|
;
|
||||||
|
|
||||||
string_dyncol_type:
|
string_dyncol_type:
|
||||||
char
|
char opt_binary
|
||||||
{ Lex->charset= thd->variables.collation_connection; }
|
|
||||||
opt_binary
|
|
||||||
{
|
{
|
||||||
$$.set(DYN_COL_STRING);
|
if ($$.set(DYN_COL_STRING, $2, thd->variables.collation_connection))
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| nchar
|
| nchar
|
||||||
{
|
{
|
||||||
$$.set(DYN_COL_STRING);
|
$$.set(DYN_COL_STRING, national_charset_info);
|
||||||
Lex->charset= national_charset_info;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
dyncall_create_element:
|
dyncall_create_element:
|
||||||
expr ',' expr opt_dyncol_type
|
expr ',' expr opt_dyncol_type
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
|
||||||
$$= (DYNCALL_CREATE_DEF *)
|
$$= (DYNCALL_CREATE_DEF *)
|
||||||
alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF));
|
alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF));
|
||||||
if (unlikely($$ == NULL))
|
if (unlikely($$ == NULL))
|
||||||
@@ -9458,7 +9471,7 @@ dyncall_create_element:
|
|||||||
$$->key= $1;
|
$$->key= $1;
|
||||||
$$->value= $3;
|
$$->value= $3;
|
||||||
$$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type();
|
$$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type();
|
||||||
$$->cs= lex->charset;
|
$$->cs= $4.charset_collation();
|
||||||
if ($4.has_explicit_length())
|
if ($4.has_explicit_length())
|
||||||
$$->len= $4.length();
|
$$->len= $4.length();
|
||||||
else
|
else
|
||||||
@@ -9597,8 +9610,7 @@ column_default_non_parenthesized_expr:
|
|||||||
}
|
}
|
||||||
| CAST_SYM '(' expr AS cast_type ')'
|
| CAST_SYM '(' expr AS cast_type ')'
|
||||||
{
|
{
|
||||||
if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3,
|
if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3))))
|
||||||
Lex->charset))))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| CASE_SYM when_list_opt_else END
|
| CASE_SYM when_list_opt_else END
|
||||||
@@ -9614,8 +9626,7 @@ column_default_non_parenthesized_expr:
|
|||||||
}
|
}
|
||||||
| CONVERT_SYM '(' expr ',' cast_type ')'
|
| CONVERT_SYM '(' expr ',' cast_type ')'
|
||||||
{
|
{
|
||||||
if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3,
|
if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3))))
|
||||||
Lex->charset))))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| CONVERT_SYM '(' expr USING charset_name ')'
|
| CONVERT_SYM '(' expr USING charset_name ')'
|
||||||
@@ -10151,9 +10162,8 @@ function_call_nonkeyword:
|
|||||||
|
|
|
|
||||||
COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
|
COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
|
||||||
$$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(),
|
$$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(),
|
||||||
$7, lex->charset);
|
$7, $7.charset());
|
||||||
if (unlikely($$ == NULL))
|
if (unlikely($$ == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
@@ -11054,26 +11064,31 @@ in_sum_expr:
|
|||||||
|
|
||||||
cast_type:
|
cast_type:
|
||||||
BINARY opt_field_length
|
BINARY opt_field_length
|
||||||
{ $$.set(&type_handler_long_blob, $2); Lex->charset= &my_charset_bin; }
|
{ $$.set(&type_handler_long_blob, $2, &my_charset_bin); }
|
||||||
| CHAR_SYM opt_field_length
|
| CHAR_SYM opt_field_length opt_binary
|
||||||
{ Lex->charset= thd->variables.collation_connection; }
|
{
|
||||||
opt_binary
|
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||||
{ $$.set(&type_handler_long_blob, $2); }
|
thd->variables.collation_connection))
|
||||||
| VARCHAR field_length
|
MYSQL_YYABORT;
|
||||||
{ Lex->charset= thd->variables.collation_connection; }
|
}
|
||||||
opt_binary
|
| VARCHAR field_length opt_binary
|
||||||
{ $$.set(&type_handler_long_blob, $2); }
|
{
|
||||||
| VARCHAR2_ORACLE_SYM field_length
|
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||||
{ Lex->charset= thd->variables.collation_connection; }
|
thd->variables.collation_connection))
|
||||||
opt_binary
|
MYSQL_YYABORT;
|
||||||
{ $$.set(&type_handler_long_blob, $2); }
|
}
|
||||||
|
| VARCHAR2_ORACLE_SYM field_length opt_binary
|
||||||
|
{
|
||||||
|
if ($$.set(&type_handler_long_blob, $2, $3,
|
||||||
|
thd->variables.collation_connection))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| NCHAR_SYM opt_field_length
|
| NCHAR_SYM opt_field_length
|
||||||
{
|
{
|
||||||
Lex->charset= national_charset_info;
|
$$.set(&type_handler_long_blob, $2, national_charset_info);
|
||||||
$$.set(&type_handler_long_blob, $2);
|
|
||||||
}
|
}
|
||||||
| cast_type_numeric { $$= $1; Lex->charset= NULL; }
|
| cast_type_numeric { $$= $1; }
|
||||||
| cast_type_temporal { $$= $1; Lex->charset= NULL; }
|
| cast_type_temporal { $$= $1; }
|
||||||
| IDENT_sys
|
| IDENT_sys
|
||||||
{
|
{
|
||||||
if (Lex->set_cast_type_udt(&$$, $1))
|
if (Lex->set_cast_type_udt(&$$, $1))
|
||||||
@@ -11262,7 +11277,7 @@ json_table_column:
|
|||||||
!lex->json_table->m_cur_json_table_column))
|
!lex->json_table->m_cur_json_table_column))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->init_last_field(f, &$1, NULL);
|
lex->init_last_field(f, &$1);
|
||||||
}
|
}
|
||||||
json_table_column_type
|
json_table_column_type
|
||||||
{
|
{
|
||||||
@@ -11293,7 +11308,7 @@ json_table_column_type:
|
|||||||
{
|
{
|
||||||
Lex_field_type_st type;
|
Lex_field_type_st type;
|
||||||
type.set(&type_handler_slong);
|
type.set(&type_handler_slong);
|
||||||
Lex->last_field->set_attributes(thd, type, Lex->charset,
|
Lex->last_field->set_attributes(thd, type,
|
||||||
COLUMN_DEFINITION_TABLE_FIELD);
|
COLUMN_DEFINITION_TABLE_FIELD);
|
||||||
Lex->json_table->m_cur_json_table_column->
|
Lex->json_table->m_cur_json_table_column->
|
||||||
set(Json_table_column::FOR_ORDINALITY);
|
set(Json_table_column::FOR_ORDINALITY);
|
||||||
@@ -11301,20 +11316,23 @@ json_table_column_type:
|
|||||||
| json_table_field_type PATH_SYM json_text_literal
|
| json_table_field_type PATH_SYM json_text_literal
|
||||||
json_opt_on_empty_or_error
|
json_opt_on_empty_or_error
|
||||||
{
|
{
|
||||||
Lex->last_field->set_attributes(thd, $1, Lex->charset,
|
Lex->last_field->set_attributes(thd, $1,
|
||||||
COLUMN_DEFINITION_TABLE_FIELD);
|
COLUMN_DEFINITION_TABLE_FIELD);
|
||||||
if (Lex->json_table->m_cur_json_table_column->
|
if (Lex->json_table->m_cur_json_table_column->
|
||||||
set(thd, Json_table_column::PATH, $3, Lex->charset))
|
set(thd, Json_table_column::PATH, $3,
|
||||||
|
$1.lex_charset_collation()))
|
||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| json_table_field_type EXISTS PATH_SYM json_text_literal
|
| json_table_field_type EXISTS PATH_SYM json_text_literal
|
||||||
{
|
{
|
||||||
Lex->last_field->set_attributes(thd, $1, Lex->charset,
|
Lex->last_field->set_attributes(thd, $1,
|
||||||
COLUMN_DEFINITION_TABLE_FIELD);
|
COLUMN_DEFINITION_TABLE_FIELD);
|
||||||
Lex->json_table->m_cur_json_table_column->
|
if (Lex->json_table->m_cur_json_table_column->
|
||||||
set(thd, Json_table_column::EXISTS_PATH, $4, Lex->charset);
|
set(thd, Json_table_column::EXISTS_PATH, $4,
|
||||||
|
$1.lex_charset_collation()))
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -16484,7 +16502,7 @@ option_value_no_option_type:
|
|||||||
thd->parse_error();
|
thd->parse_error();
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| NAMES_SYM charset_name_or_default opt_collate
|
| NAMES_SYM charset_name_or_default opt_collate_or_default
|
||||||
{
|
{
|
||||||
if (sp_create_assignment_lex(thd, $1.pos()))
|
if (sp_create_assignment_lex(thd, $1.pos()))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@@ -17716,8 +17734,7 @@ sf_return_type:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->init_last_field(&lex->sphead->m_return_field_def,
|
lex->init_last_field(&lex->sphead->m_return_field_def,
|
||||||
&empty_clex_str,
|
&empty_clex_str);
|
||||||
thd->variables.collation_database);
|
|
||||||
}
|
}
|
||||||
field_type
|
field_type
|
||||||
{
|
{
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "my_base.h" /* ha_rows, ha_key_alg */
|
#include "my_base.h" /* ha_rows, ha_key_alg */
|
||||||
#include <mysql_com.h> /* USERNAME_LENGTH */
|
#include <mysql_com.h> /* USERNAME_LENGTH */
|
||||||
#include "sql_bitmap.h"
|
#include "sql_bitmap.h"
|
||||||
|
#include "lex_charset.h"
|
||||||
|
|
||||||
struct TABLE;
|
struct TABLE;
|
||||||
class Type_handler;
|
class Type_handler;
|
||||||
@@ -601,18 +602,24 @@ public:
|
|||||||
|
|
||||||
struct Lex_length_and_dec_st
|
struct Lex_length_and_dec_st
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
uint32 m_length;
|
uint32 m_length;
|
||||||
uint8 m_dec;
|
uint8 m_dec;
|
||||||
|
uint8 m_collation_type:LEX_CHARSET_COLLATION_TYPE_BITS;
|
||||||
bool m_has_explicit_length:1;
|
bool m_has_explicit_length:1;
|
||||||
bool m_has_explicit_dec:1;
|
bool m_has_explicit_dec:1;
|
||||||
bool m_length_overflowed:1;
|
bool m_length_overflowed:1;
|
||||||
bool m_dec_overflowed:1;
|
bool m_dec_overflowed:1;
|
||||||
|
|
||||||
|
static_assert(LEX_CHARSET_COLLATION_TYPE_BITS <= 8,
|
||||||
|
"Lex_length_and_dec_st::m_collation_type bits check");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_length= 0;
|
m_length= 0;
|
||||||
m_dec= 0;
|
m_dec= 0;
|
||||||
|
m_collation_type= 0;
|
||||||
m_has_explicit_length= false;
|
m_has_explicit_length= false;
|
||||||
m_has_explicit_dec= false;
|
m_has_explicit_dec= false;
|
||||||
m_length_overflowed= false;
|
m_length_overflowed= false;
|
||||||
@@ -622,6 +629,7 @@ public:
|
|||||||
{
|
{
|
||||||
m_length= length;
|
m_length= length;
|
||||||
m_dec= 0;
|
m_dec= 0;
|
||||||
|
m_collation_type= 0;
|
||||||
m_has_explicit_length= true;
|
m_has_explicit_length= true;
|
||||||
m_has_explicit_dec= false;
|
m_has_explicit_dec= false;
|
||||||
m_length_overflowed= false;
|
m_length_overflowed= false;
|
||||||
@@ -631,6 +639,7 @@ public:
|
|||||||
{
|
{
|
||||||
m_length= 0;
|
m_length= 0;
|
||||||
m_dec= dec;
|
m_dec= dec;
|
||||||
|
m_collation_type= 0;
|
||||||
m_has_explicit_length= false;
|
m_has_explicit_length= false;
|
||||||
m_has_explicit_dec= true;
|
m_has_explicit_dec= true;
|
||||||
m_length_overflowed= false;
|
m_length_overflowed= false;
|
||||||
@@ -640,6 +649,7 @@ public:
|
|||||||
{
|
{
|
||||||
m_length= length;
|
m_length= length;
|
||||||
m_dec= dec;
|
m_dec= dec;
|
||||||
|
m_collation_type= 0;
|
||||||
m_has_explicit_length= true;
|
m_has_explicit_length= true;
|
||||||
m_has_explicit_dec= true;
|
m_has_explicit_dec= true;
|
||||||
m_length_overflowed= false;
|
m_length_overflowed= false;
|
||||||
@@ -677,30 +687,59 @@ struct Lex_field_type_st: public Lex_length_and_dec_st
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const Type_handler *m_handler;
|
const Type_handler *m_handler;
|
||||||
|
CHARSET_INFO *m_ci;
|
||||||
public:
|
public:
|
||||||
void set(const Type_handler *handler, Lex_length_and_dec_st length_and_dec)
|
void set(const Type_handler *handler,
|
||||||
|
Lex_length_and_dec_st length_and_dec,
|
||||||
|
CHARSET_INFO *cs= NULL)
|
||||||
{
|
{
|
||||||
m_handler= handler;
|
m_handler= handler;
|
||||||
|
m_ci= cs;
|
||||||
Lex_length_and_dec_st::operator=(length_and_dec);
|
Lex_length_and_dec_st::operator=(length_and_dec);
|
||||||
}
|
}
|
||||||
|
void set(const Type_handler *handler,
|
||||||
|
const Lex_length_and_dec_st &length_and_dec,
|
||||||
|
const Lex_charset_collation_st &coll)
|
||||||
|
{
|
||||||
|
m_handler= handler;
|
||||||
|
m_ci= coll.charset_collation();
|
||||||
|
Lex_length_and_dec_st::operator=(length_and_dec);
|
||||||
|
m_collation_type= ((uint8) coll.type()) & 0x3;
|
||||||
|
}
|
||||||
|
void set(const Type_handler *handler, const Lex_charset_collation_st &coll)
|
||||||
|
{
|
||||||
|
m_handler= handler;
|
||||||
|
m_ci= coll.charset_collation();
|
||||||
|
Lex_length_and_dec_st::reset();
|
||||||
|
m_collation_type= ((uint8) coll.type()) & 0x3;
|
||||||
|
}
|
||||||
|
void set(const Type_handler *handler, CHARSET_INFO *cs= NULL)
|
||||||
|
{
|
||||||
|
m_handler= handler;
|
||||||
|
m_ci= cs;
|
||||||
|
Lex_length_and_dec_st::reset();
|
||||||
|
}
|
||||||
void set_handler_length_flags(const Type_handler *handler,
|
void set_handler_length_flags(const Type_handler *handler,
|
||||||
const Lex_length_and_dec_st &length,
|
const Lex_length_and_dec_st &length,
|
||||||
uint32 flags);
|
uint32 flags);
|
||||||
void set_handler_length(const Type_handler *handler, uint32 length)
|
void set_handler_length(const Type_handler *handler, uint32 length)
|
||||||
{
|
{
|
||||||
m_handler= handler;
|
m_handler= handler;
|
||||||
|
m_ci= NULL;
|
||||||
Lex_length_and_dec_st::set_length_only(length);
|
Lex_length_and_dec_st::set_length_only(length);
|
||||||
}
|
}
|
||||||
void set(const Type_handler *handler)
|
|
||||||
{
|
|
||||||
m_handler= handler;
|
|
||||||
Lex_length_and_dec_st::reset();
|
|
||||||
}
|
|
||||||
void set_handler(const Type_handler *handler)
|
void set_handler(const Type_handler *handler)
|
||||||
{
|
{
|
||||||
m_handler= handler;
|
m_handler= handler;
|
||||||
}
|
}
|
||||||
const Type_handler *type_handler() const { return m_handler; }
|
const Type_handler *type_handler() const { return m_handler; }
|
||||||
|
CHARSET_INFO *charset_collation() const { return m_ci; }
|
||||||
|
Lex_charset_collation lex_charset_collation() const
|
||||||
|
{
|
||||||
|
return Lex_charset_collation(m_ci,
|
||||||
|
(Lex_charset_collation_st::Type)
|
||||||
|
m_collation_type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -708,18 +747,38 @@ struct Lex_dyncol_type_st: public Lex_length_and_dec_st
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int m_type; // enum_dynamic_column_type is not visible here, so use int
|
int m_type; // enum_dynamic_column_type is not visible here, so use int
|
||||||
|
CHARSET_INFO *m_ci;
|
||||||
public:
|
public:
|
||||||
void set(int type, Lex_length_and_dec_st length_and_dec)
|
void set(int type, Lex_length_and_dec_st length_and_dec,
|
||||||
|
CHARSET_INFO *cs= NULL)
|
||||||
{
|
{
|
||||||
m_type= type;
|
m_type= type;
|
||||||
|
m_ci= cs;
|
||||||
Lex_length_and_dec_st::operator=(length_and_dec);
|
Lex_length_and_dec_st::operator=(length_and_dec);
|
||||||
}
|
}
|
||||||
void set(int type)
|
void set(int type)
|
||||||
{
|
{
|
||||||
m_type= type;
|
m_type= type;
|
||||||
|
m_ci= NULL;
|
||||||
Lex_length_and_dec_st::reset();
|
Lex_length_and_dec_st::reset();
|
||||||
}
|
}
|
||||||
|
void set(int type, CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
m_type= type;
|
||||||
|
m_ci= cs;
|
||||||
|
Lex_length_and_dec_st::reset();
|
||||||
|
}
|
||||||
|
bool set(int type, const Lex_charset_collation_st &collation,
|
||||||
|
CHARSET_INFO *charset)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *tmp= collation.resolved_to_character_set(charset);
|
||||||
|
if (!tmp)
|
||||||
|
return true;
|
||||||
|
set(type, tmp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int dyncol_type() const { return m_type; }
|
int dyncol_type() const { return m_type; }
|
||||||
|
CHARSET_INFO *charset_collation() const { return m_ci; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -630,3 +630,7 @@ struct charset_info_st my_charset_bin =
|
|||||||
&my_charset_handler,
|
&my_charset_handler,
|
||||||
&my_collation_binary_handler
|
&my_collation_binary_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct charset_info_st my_collation_contextually_typed_binary= {0};
|
||||||
|
struct charset_info_st my_collation_contextually_typed_default= {0};
|
||||||
|
Reference in New Issue
Block a user