maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #13097
Re: 2467eb2d314: MDEV-27743 Remove Lex::charset
Hi, Alexander,
I had only a couple of questions/comments, see below:
On Mar 11, Alexander Barkov wrote:
> revision-id: 2467eb2d314 (mariadb-10.6.1-330-g2467eb2d314)
> parent(s): 61b72ed3dde
> author: Alexander Barkov
> committer: Alexander Barkov
> timestamp: 2022-02-10 10:27:55 +0400
> message:
>
> MDEV-27743 Remove Lex::charset
>
> This patch also fixes:
> MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition
how do you plan to fix it in 10.2-10.8 ?
>
> diff --git a/mysql-test/main/ctype_collate_column.result b/mysql-test/main/ctype_collate_column.result
> new file mode 100644
> index 00000000000..b20be5d3a48
> --- /dev/null
> +++ b/mysql-test/main/ctype_collate_column.result
> @@ -0,0 +1,450 @@
> +#
> +# Start of 10.9 tests
> +#
> +#
> +# MDEV-27743 Remove Lex::charset
1. Jira doesn't explain what user-visible changes one can expect.
If there are none, it's not clear why you needed this big test case
2. the test is totally unreadable. Could you do a normal test
instead? Like, put `select` instead of `execute immediate`
and convert the output to a .test file?
> +#
> +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');
...
> diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result
> index 0b16d1cf6f2..70577f2c22c 100644
> --- a/mysql-test/main/ctype_latin1.result
> +++ b/mysql-test/main/ctype_latin1.result
> @@ -8889,6 +8889,38 @@ a b
> 111 111
> 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;
1. why is it in "10.2 tests" ?
2. shouldn't here be at least one test that COLLATE DEFAULT is not a no-op?
Like CREATE TABLE (... COLLATE DEFAULT ...) COLLATE _non_default ?
Or is it in your generated ctype_collate_column.test?
> +#
> # End of 10.2 tests
> #
> #
> diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test
> index 9cf0d7b4aff..dac6eab21e9 100644
> --- a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test
> +++ b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test
> @@ -36,7 +36,7 @@ set default role test_role for root@localhost;
> drop role test_role;
> 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
Heh, interesting that it worked before
good catch
> after is_role;
> alter table user add max_statement_time decimal(12,6) default 0 not null
> diff --git a/sql/structs.h b/sql/structs.h
> index 9a5006e8b47..db065c49931 100644
> --- a/sql/structs.h
> +++ b/sql/structs.h
> @@ -599,11 +599,140 @@ class DDL_options: public DDL_options_st
...
> +class Lex_collation: public Lex_collation_st
> +{
> +public:
> + Lex_collation(CHARSET_INFO *collation, Type type)
> + {
> + m_collation= collation;
> + m_type= type;
> + }
> + static Lex_collation national(bool bin_mod)
> + {
> + if (bin_mod)
> + return Lex_collation(&my_charset_utf8mb3_bin, TYPE_EXPLICIT);
> + return Lex_collation(&my_charset_utf8mb3_general_ci, TYPE_IMPLICIT);
utf8mb3? not utf8?
> + }
> +};
> +
> +
> struct Lex_length_and_dec_st
> {
> -private:
> +protected:
> uint32 m_length;
> uint8 m_dec;
> + uint8 m_collation_type:2;
> bool m_has_explicit_length:1;
> bool m_has_explicit_dec:1;
> public:
> diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
> index ae6ae9a0cc0..6ca10267187 100644
> --- a/sql/sql_lex.cc
> +++ b/sql/sql_lex.cc
> @@ -11816,3 +11784,257 @@ bool SELECT_LEX_UNIT::explainable() const
...
> +CHARSET_INFO *
> +Lex_collation_st::resolved_to_character_set(CHARSET_INFO *def) const
> +{
> + DBUG_ASSERT(def);
> + if (m_type != TYPE_CONTEXTUALLY_TYPED)
> + {
> + if (!m_collation)
> + return def; // Empty - not typed at all
> + return m_collation; // Explicitly typed
> + }
> +
> + // Contextually typed
> + DBUG_ASSERT(m_collation);
> +
> + if (m_collation == &my_charset_bin) // CHAR(10) BINARY
> + return find_bin_collation(def);
> +
> + if (m_collation == &my_charset_latin1) // CHAR(10) COLLATE DEFAULT
> + return find_default_collation(def);
Uhm. Could you create two dummy CHARSET_INFO variables for that instead?
Like
CHARSET_INFO binary_collaton, default_collation;
no need to initialize them, but to have distinct values for binary/default
and not reuse my_charset_bin and my_charset_latin1.
> +
> + /*
> + 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;
> +}
> +
> +
...
> diff --git a/sql/field.h b/sql/field.h
> index 2ed02b37cfd..fe5ba435202 100644
> --- a/sql/field.h
> +++ b/sql/field.h
> @@ -5493,6 +5492,22 @@ class Column_definition: public Sql_alloc,
> { return compression_method_ptr; }
>
> bool check_vcol_for_key(THD *thd) const;
> +
> + void set_lex_collation(const Lex_collation_st &lc)
> + {
> + charset= lc.collation();
> + if (lc.is_contextually_typed_collation())
> + flags|= BINCMP_FLAG;
> + else
> + flags&= ~BINCMP_FLAG;
Isn't COLLATE DEFAULT also contextually typed?
> + }
> + Lex_collation lex_collation() const
> + {
> + return Lex_collation(charset,
> + flags & BINCMP_FLAG ?
> + Lex_collation_st::TYPE_CONTEXTUALLY_TYPED :
> + Lex_collation_st::TYPE_IMPLICIT);
> + }
> };
>
>
Regards,
Sergei
VP of MariaDB Server Engineering
and security@xxxxxxxxxxx
Follow ups