summaryrefslogtreecommitdiff
path: root/sql/lex_charset.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/lex_charset.cc')
-rw-r--r--sql/lex_charset.cc113
1 files changed, 94 insertions, 19 deletions
diff --git a/sql/lex_charset.cc b/sql/lex_charset.cc
index b83d175307f..cfb74a0bf04 100644
--- a/sql/lex_charset.cc
+++ b/sql/lex_charset.cc
@@ -45,7 +45,7 @@ raise_ER_CONFLICTING_DECLARATIONS(const char *clause1,
const char *name2,
bool reverse_order)
{
- char def[MY_CS_NAME_SIZE * 2];
+ char def[MY_CS_CHARACTER_SET_NAME_SIZE * 2];
my_snprintf(def, sizeof(def), "%s (%s)", name1, name1_part2);
raise_ER_CONFLICTING_DECLARATIONS(clause1, def,
clause2, name2,
@@ -127,19 +127,43 @@ Lex_exact_collation::
raise_if_conflicts_with_context_collation(const Lex_context_collation &cl,
bool reverse_order) const
{
- if (cl.is_contextually_typed_collate_default() &&
- !(m_ci->state & MY_CS_PRIMARY))
+ if (cl.is_contextually_typed_collate_default())
{
- raise_ER_CONFLICTING_DECLARATIONS("COLLATE ", m_ci->coll_name.str,
- "COLLATE ", "DEFAULT", reverse_order);
- return true;
+ if (!(m_ci->state & MY_CS_PRIMARY))
+ {
+ raise_ER_CONFLICTING_DECLARATIONS("COLLATE ", m_ci->coll_name.str,
+ "COLLATE ", "DEFAULT", reverse_order);
+ return true;
+ }
+ return false;
}
- if (cl.is_contextually_typed_binary_style() &&
- !(m_ci->state & MY_CS_BINSORT))
+ if (cl.is_contextually_typed_binary_style())
{
- raise_ER_CONFLICTING_DECLARATIONS("COLLATE ", m_ci->coll_name.str,
- "", "BINARY", reverse_order);
+ if (!(m_ci->state & MY_CS_BINSORT))
+ {
+ raise_ER_CONFLICTING_DECLARATIONS("COLLATE ", m_ci->coll_name.str,
+ "", "BINARY", reverse_order);
+ return true;
+ }
+ return false;
+ }
+
+ DBUG_ASSERT(!strncmp(cl.charset_info()->coll_name.str,
+ STRING_WITH_LEN("utf8mb4_uca1400_")));
+
+ Charset_loader_server loader;
+ CHARSET_INFO *ci= loader.get_exact_collation_by_context_name(
+ m_ci,
+ cl.collation_name_context_suffix().str,
+ MYF(0));
+ if (m_ci != ci)
+ {
+ raise_ER_CONFLICTING_DECLARATIONS("COLLATE ",
+ m_ci->coll_name.str,
+ "COLLATE ",
+ cl.collation_name_for_show().str,
+ reverse_order);
return true;
}
return false;
@@ -153,9 +177,16 @@ Lex_context_collation::raise_if_not_equal(const Lex_context_collation &cl) const
Only equal context collations are possible here so far:
- Column grammar only supports BINARY, but does not support COLLATE DEFAULT
- DB/Table grammar only support COLLATE DEFAULT
- But we'll have different collations here - uca140 is coming soon.
*/
- DBUG_ASSERT(m_ci == cl.m_ci);
+ if (m_ci != cl.m_ci)
+ {
+ my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
+ is_contextually_typed_binary_style() ? "" : "COLLATE ",
+ collation_name_for_show().str,
+ cl.is_contextually_typed_binary_style() ? "" : "COLLATE ",
+ cl.collation_name_for_show().str);
+ return true;
+ }
return false;
}
@@ -193,12 +224,16 @@ bool Lex_exact_charset_opt_extended_collate::
return false;
}
- /*
- A non-binary and non-default contextually typed collation.
- We don't have such yet - the parser cannot produce this.
- But we have "uca1400_as_ci" coming soon.
- */
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!strncmp(cl.charset_info()->coll_name.str,
+ STRING_WITH_LEN("utf8mb4_uca1400_")));
+
+ CHARSET_INFO *ci= Charset_loader_server().
+ get_exact_collation_by_context_name_or_error(m_ci,
+ cl.charset_info()->coll_name.str + 8, MYF(0));
+ if (!ci)
+ return true;
+ m_ci= ci;
+ m_with_collate= true;
return false;
}
@@ -244,7 +279,7 @@ bool Lex_extended_collation_st::
CONTEXT + EXACT
CHAR(10) COLLATE DEFAULT .. COLLATE latin1_swedish_ci
CHAR(10) BINARY .. COLLATE latin1_bin
- CHAR(10) COLLATE uca1400_as_ci .. COLLATE latin1_bin - coming soon
+ CHAR(10) COLLATE uca1400_as_ci .. COLLATE latin1_bin
*/
if (rhs.raise_if_conflicts_with_context_collation(
Lex_context_collation(m_ci), true))
@@ -320,6 +355,38 @@ bool Lex_extended_collation_st::merge(const Lex_extended_collation_st &rhs)
}
+LEX_CSTRING Lex_context_collation::collation_name_for_show() const
+{
+ if (is_contextually_typed_collate_default())
+ return LEX_CSTRING({STRING_WITH_LEN("DEFAULT")});
+ if (is_contextually_typed_binary_style())
+ return LEX_CSTRING({STRING_WITH_LEN("BINARY")});
+ return collation_name_context_suffix();
+}
+
+
+bool Lex_extended_collation_st::set_by_name(const char *name, myf my_flags)
+{
+ Charset_loader_server loader;
+ CHARSET_INFO *cs;
+
+ if (!strncasecmp(name, STRING_WITH_LEN("uca1400_")))
+ {
+ if (!(cs= loader.get_context_collation_or_error(name, my_flags)))
+ return true;
+
+ *this= Lex_extended_collation(Lex_context_collation(cs));
+ return false;
+ }
+
+ if (!(cs= loader.get_exact_collation_or_error(name, my_flags)))
+ return true;
+
+ *this= Lex_extended_collation(Lex_exact_collation(cs));
+ return false;
+}
+
+
/** find a collation with binary comparison rules
*/
CHARSET_INFO *Lex_exact_charset_opt_extended_collate::find_bin_collation() const
@@ -499,6 +566,14 @@ bool Lex_exact_charset_opt_extended_collate::
// CHARACTER SET latin1 [COLLATE latin1_bin] .. COLLATE latin1_bin
if (m_with_collate)
return Lex_exact_collation(m_ci).raise_if_not_equal(cl);
+ return merge_exact_collation_override(cl);
+}
+
+
+bool Lex_exact_charset_opt_extended_collate::
+ merge_exact_collation_override(const Lex_exact_collation &cl)
+{
+ // CHARACTER SET latin1 [COLLATE latin1_bin] .. COLLATE latin1_bin
if (raise_if_not_applicable(cl))
return true;
*this= Lex_exact_charset_opt_extended_collate(cl);