From 64a5fab00e68c1e684282180a6fdae73735cc95e Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 22 May 2022 21:25:31 +0400 Subject: [PATCH] Step#1 MDEV-27896 Wrong result upon `COLLATE latin1_bin CHARACTER SET latin1` on the table or the database level - Adding data type aliases: using Lex_column_charset_collation_attrs_st = Lex_charset_collation_st; using Lex_column_charset_collation_attrs = Lex_charset_collation; and using them all around the code (except lex_charset.*) instead of the original names. - Renaming Lex_field_type_st::lex_charset_collation() to charset_collation_attrs() - Renaming Column_definition::set_lex_charset_collation() to set_charset_collation_attrs() - Renaming Column_definition::lex_charset_collation() to charset_collation_attrs() Rationale: The name "Lex_charset_collation" was a not very good name. It does not tell details about its properties: 1. if the charset is optional (yes) 2. if the collation is optional (yes) 3. if the charset can be exact (yes) or context (no) 4. if the collation can be: exact (yes) or context (yes) 5. if the clauses can be repeated multiple times (yes) We'll need a few new data types soon with different properties. For example, to fix MDEV-27896 and MDEV-27782, we'll need a new data type which is very like Lex_charset_collation, but additionally supports CHARACTER SET DEFAULT (which is allowed on table and database level, but is not allowed on the column level yet), i.e. with: "the charset can be exact (yes) or context (yes)" in N3. So we'll have to rename Lex_charset_collation to something else, e.g.: Lex_exact_charset_extended_collation_attrs, and add a new data type: e.g. Lex_extended_charset_extended_collation_attrs Also, we'll possibly allow CHARACTER SET DEFAULT at the column level for consistency with other places. So the storge on the column level can change: - from Lex_exact_charset_extended_collation_attrs - to Lex_extended_charset_extended_collation_attrs Adding the aliases introduces a convenient abstraction against upcoming renames and c++ data type changes. --- sql/field.h | 5 +++-- sql/item_func.h | 2 +- sql/json_table.cc | 2 +- sql/json_table.h | 2 +- sql/lex_charset.h | 4 ++++ sql/sql_table.cc | 2 +- sql/sql_type.cc | 2 +- sql/sql_yacc.yy | 8 ++++---- sql/structs.h | 13 +++++++------ 9 files changed, 23 insertions(+), 17 deletions(-) diff --git a/sql/field.h b/sql/field.h index 7b279ffb41e..b35530491ba 100644 --- a/sql/field.h +++ b/sql/field.h @@ -5501,7 +5501,8 @@ public: bool check_vcol_for_key(THD *thd) const; - void set_lex_charset_collation(const Lex_charset_collation_st &lc) + void set_charset_collation_attrs(const + Lex_column_charset_collation_attrs_st &lc) { charset= lc.charset_collation(); if (lc.is_contextually_typed_collation()) @@ -5509,7 +5510,7 @@ public: else flags&= ~CONTEXT_COLLATION_FLAG; } - Lex_charset_collation lex_charset_collation() const + Lex_column_charset_collation_attrs charset_collation_attrs() const { return Lex_charset_collation( charset, diff --git a/sql/item_func.h b/sql/item_func.h index 185242b7901..a4122f78e87 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -3773,7 +3773,7 @@ public: } bool set(const Type_handler *handler, const Lex_length_and_dec_st & length_and_dec, - const Lex_charset_collation_st &cscl, + const Lex_column_charset_collation_attrs_st &cscl, CHARSET_INFO *defcs) { CHARSET_INFO *tmp= cscl.resolved_to_character_set(defcs); diff --git a/sql/json_table.cc b/sql/json_table.cc index e2f90aa2a9a..a9e882291b6 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -874,7 +874,7 @@ 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) + const Lex_column_charset_collation_attrs_st &cl) { if (cl.is_empty() || cl.is_contextually_typed_collate_default()) return set(thd, ctype, path, nullptr); diff --git a/sql/json_table.h b/sql/json_table.h index 2cadb07961e..6398b061889 100644 --- a/sql/json_table.h +++ b/sql/json_table.h @@ -161,7 +161,7 @@ public: } 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); + const Lex_column_charset_collation_attrs_st &cl); Json_table_column(Create_field *f, Json_table_nested_path *nest) : m_field(f), m_nest(nest), m_explicit_cs(NULL) { diff --git a/sql/lex_charset.h b/sql/lex_charset.h index abbe761df36..5d3a893bd9b 100644 --- a/sql/lex_charset.h +++ b/sql/lex_charset.h @@ -196,4 +196,8 @@ public: }; +using Lex_column_charset_collation_attrs_st = Lex_charset_collation_st; +using Lex_column_charset_collation_attrs = Lex_charset_collation; + + #endif // LEX_CHARSET_INCLUDED diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fee561bb386..b0a10a86bad 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2202,7 +2202,7 @@ bool check_duplicates_in_interval(const char *set_or_name, bool Column_definition:: prepare_charset_for_string(const Column_derived_attributes *dattr) { - CHARSET_INFO *tmp= lex_charset_collation(). + CHARSET_INFO *tmp= charset_collation_attrs(). resolved_to_character_set(dattr->charset()); if (!tmp) return true; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index f81f6c19d87..0ede2b3fee2 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2715,7 +2715,7 @@ Type_handler::Column_definition_set_attributes(THD *thd, column_definition_type_t type) const { - def->set_lex_charset_collation(attr.lex_charset_collation()); + def->set_charset_collation_attrs(attr.charset_collation_attrs()); def->set_length_and_dec(attr); return false; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4f87b4eae46..71a1299bb82 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5789,10 +5789,10 @@ field_type_or_serial: } field_def { - Lex_charset_collation tmp= $1.lex_charset_collation(); + Lex_charset_collation tmp= $1.charset_collation_attrs(); if (tmp.merge_charset_clause_and_collate_clause($3)) MYSQL_YYABORT; - Lex->last_field->set_lex_charset_collation(tmp); + Lex->last_field->set_charset_collation_attrs(tmp); } | SERIAL_SYM { @@ -11358,7 +11358,7 @@ json_table_column_type: COLUMN_DEFINITION_TABLE_FIELD); if (Lex->json_table->m_cur_json_table_column-> set(thd, Json_table_column::PATH, $3, - $1.lex_charset_collation())) + $1.charset_collation_attrs())) { MYSQL_YYABORT; } @@ -11369,7 +11369,7 @@ json_table_column_type: COLUMN_DEFINITION_TABLE_FIELD); if (Lex->json_table->m_cur_json_table_column-> set(thd, Json_table_column::EXISTS_PATH, $4, - $1.lex_charset_collation())) + $1.charset_collation_attrs())) MYSQL_YYABORT; } ; diff --git a/sql/structs.h b/sql/structs.h index eab15c4d92b..2c68937ec99 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -699,14 +699,15 @@ public: } void set(const Type_handler *handler, const Lex_length_and_dec_st &length_and_dec, - const Lex_charset_collation_st &coll) + const Lex_column_charset_collation_attrs_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) + void set(const Type_handler *handler, + const Lex_column_charset_collation_attrs_st &coll) { m_handler= handler; m_ci= coll.charset_collation(); @@ -734,10 +735,10 @@ public: } const Type_handler *type_handler() const { return m_handler; } CHARSET_INFO *charset_collation() const { return m_ci; } - Lex_charset_collation lex_charset_collation() const + Lex_column_charset_collation_attrs charset_collation_attrs() const { - return Lex_charset_collation(m_ci, - (Lex_charset_collation_st::Type) + return Lex_column_charset_collation_attrs(m_ci, + (Lex_column_charset_collation_attrs_st::Type) m_collation_type); } }; @@ -768,7 +769,7 @@ public: m_ci= cs; Lex_length_and_dec_st::reset(); } - bool set(int type, const Lex_charset_collation_st &collation, + bool set(int type, const Lex_column_charset_collation_attrs_st &collation, CHARSET_INFO *charset) { CHARSET_INFO *tmp= collation.resolved_to_character_set(charset);