Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mysql-test/main/user_var.result
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,13 @@ collation(@a:=_latin2'test')
latin2_general_ci
select coercibility(@a:=_latin2'test');
coercibility(@a:=_latin2'test')
6
5
select collation(@a:=_latin2'test' collate latin2_bin);
collation(@a:=_latin2'test' collate latin2_bin)
latin2_bin
select coercibility(@a:=_latin2'test' collate latin2_bin);
coercibility(@a:=_latin2'test' collate latin2_bin)
6
5
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST';
(@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'
0
Expand Down
24 changes: 24 additions & 0 deletions mysql-test/main/user_var_collation.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# MDEV-39530 Collation mix issue after update
#
# Reproduce the environment from the report: character_set_collations
# maps utf8mb3 to utf8mb3_uca1400_ai_ci and the connection uses that
# collation.
SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_ci;
SELECT @@character_set_collations, @@collation_connection;
@@character_set_collations @@collation_connection
utf8mb3=utf8mb3_uca1400_ai_ci,ucs2=ucs2_uca1400_ai_ci,utf8mb4=utf8mb4_uca1400_ai_ci,utf16=utf16_uca1400_ai_ci,utf32=utf32_uca1400_ai_ci utf8mb3_uca1400_ai_ci
CREATE TABLE file (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Path` varchar(800) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT INTO file VALUES (1,"text");
# This query used to work in 11.4 but raises
# ER_CANT_AGGREGATE_2COLLATIONS in 12.1+
SELECT IF((@p:=(SELECT f.Path FROM file f WHERE f.ID=1 AND f.Path REGEXP "^xx"))!="",1,2);
IF((@p:=(SELECT f.Path FROM file f WHERE f.ID=1 AND f.Path REGEXP "^xx"))!="",1,2)
2
DROP TABLE file;
#
# End of test
#
26 changes: 26 additions & 0 deletions mysql-test/main/user_var_collation.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--echo #
--echo # MDEV-39530 Collation mix issue after update
--echo #

--echo # Reproduce the environment from the report: character_set_collations
--echo # maps utf8mb3 to utf8mb3_uca1400_ai_ci and the connection uses that
--echo # collation.
SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_ci;
SELECT @@character_set_collations, @@collation_connection;

CREATE TABLE file (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Path` varchar(800) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;

INSERT INTO file VALUES (1,"text");

--echo # This query used to work in 11.4 but raises
--echo # ER_CANT_AGGREGATE_2COLLATIONS in 12.1+
SELECT IF((@p:=(SELECT f.Path FROM file f WHERE f.ID=1 AND f.Path REGEXP "^xx"))!="",1,2);

DROP TABLE file;

--echo #
--echo # End of test
--echo #
12 changes: 10 additions & 2 deletions sql/item_func.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4840,9 +4840,17 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
if (!m_var_entry->charset() || !null_item)
m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ?
&my_charset_numeric : args[0]->collation.collation);
/*
A user variable assignment (e.g. @p:=expr) must expose the same collation
derivation as reading the variable back with Item_func_get_user_var, which
uses DERIVATION_USERVAR (see MDEV-35041). Using DERIVATION_COERCIBLE here
made the assignment as strong as a string literal, causing "Illegal mix of
collations" conflicts against literals that carry the (possibly different)
connection collation (MDEV-39530).
*/
collation.set(m_var_entry->charset(),
args[0]->collation.derivation == DERIVATION_NUMERIC ?
DERIVATION_NUMERIC : DERIVATION_COERCIBLE);
DERIVATION_NUMERIC : DERIVATION_USERVAR);
switch (args[0]->result_type()) {
case STRING_RESULT:
case TIME_RESULT:
Expand Down Expand Up @@ -4907,7 +4915,7 @@ Item_func_set_user_var::fix_length_and_dec(THD *thd)
}
else
{
collation.set(DERIVATION_COERCIBLE);
collation.set(DERIVATION_USERVAR);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line appears to be redundant. The fix_fields function, which is called just before fix_length_and_dec, already sets the correct derivation. Removing this line avoids redundant assignments or incorrect overwriting of DERIVATION_NUMERIC.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed a good suggestion. I'd fix the fix_fields's setting and remove these.

fix_length_and_charset(args[0]->max_char_length(),
args[0]->collation.collation);
}
Expand Down