Bug#27580 SPACE() function collation bug?

Problem: when character_set_connection=utf8,
mixing SPACE() with a non-Unicode column (e.g. for concat)
produced "illegal mix of collations" error.
Fix: Item_string() corresponding to space character
is now created using "ASCII" repertoire. Previously
it was incorrectly created using "UNICODE" repertoure, which
didn't allow to convert results of SPACE() to a non-Unicode
character set.
parent 4c01449b
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -51,8 +53,22 @@ SELECT c1 as want1result from t1 where c1 like 'locatio%'; ...@@ -51,8 +53,22 @@ SELECT c1 as want1result from t1 where c1 like 'locatio%';
SELECT c1 as want1result from t1 where c1 like 'location%'; SELECT c1 as want1result from t1 where c1 like 'location%';
DROP TABLE t1; DROP TABLE t1;
#
# Bug#27580 SPACE() function collation bug?
#
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
# Restore settings # Restore settings
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
...@@ -3,6 +3,8 @@ SET @test_character_set= 'big5'; ...@@ -3,6 +3,8 @@ SET @test_character_set= 'big5';
SET @test_collation= 'big5_chinese_ci'; SET @test_collation= 'big5_chinese_ci';
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%'; ...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%';
want1result want1result
location location
DROP TABLE t1; DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=big5
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET NAMES big5; SET NAMES big5;
SET collation_connection='big5_chinese_ci'; SET collation_connection='big5_chinese_ci';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
......
...@@ -2,6 +2,158 @@ DROP TABLE IF EXISTS t1; ...@@ -2,6 +2,158 @@ DROP TABLE IF EXISTS t1;
SHOW COLLATION LIKE 'cp1250_czech_cs'; SHOW COLLATION LIKE 'cp1250_czech_cs';
Collation Charset Id Default Compiled Sortlen Collation Charset Id Default Compiled Sortlen
cp1250_czech_cs cp1250 34 Yes 2 cp1250_czech_cs cp1250 34 Yes 2
SET @test_character_set= 'cp1250';
SET @test_collation= 'cp1250_general_ci';
SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set;
SET collation_server= @test_collation;
CREATE DATABASE d1;
USE d1;
CREATE TABLE t1 (c CHAR(10), KEY(c));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c char(10) cp1250_general_ci YES MUL NULL
INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
want3results
aaa
aaaa
aaaaa
DROP TABLE t1;
CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c1 varchar(15) cp1250_general_ci YES MUL NULL
INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
SELECT c1 as want3results from t1 where c1 like 'l%';
want3results
location
loberge
lotre
SELECT c1 as want3results from t1 where c1 like 'lo%';
want3results
location
loberge
lotre
SELECT c1 as want1result from t1 where c1 like 'loc%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'loca%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locat%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locati%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locatio%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'location%';
want1result
location
DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1250
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1;
USE test;
SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET @test_character_set= 'cp1250';
SET @test_collation= 'cp1250_czech_cs';
SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set;
SET collation_server= @test_collation;
CREATE DATABASE d1;
USE d1;
CREATE TABLE t1 (c CHAR(10), KEY(c));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c char(10) cp1250_czech_cs YES MUL NULL
INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
want3results
aaa
aaaa
aaaaa
DROP TABLE t1;
CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c1 varchar(15) cp1250_czech_cs YES MUL NULL
INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
SELECT c1 as want3results from t1 where c1 like 'l%';
want3results
location
loberge
lotre
SELECT c1 as want3results from t1 where c1 like 'lo%';
want3results
location
loberge
lotre
SELECT c1 as want1result from t1 where c1 like 'loc%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'loca%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locat%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locati%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locatio%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'location%';
want1result
location
DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) collate cp1250_czech_cs default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_czech_cs
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1;
USE test;
SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
CREATE TABLE t1 (a char(16)) character set cp1250 collate cp1250_czech_cs; CREATE TABLE t1 (a char(16)) character set cp1250 collate cp1250_czech_cs;
INSERT INTO t1 VALUES (''); INSERT INTO t1 VALUES ('');
SELECT a, length(a), a='', a=' ', a=' ' FROM t1; SELECT a, length(a), a='', a=' ', a=' ' FROM t1;
......
...@@ -3,6 +3,8 @@ SET @test_character_set= 'euckr'; ...@@ -3,6 +3,8 @@ SET @test_character_set= 'euckr';
SET @test_collation= 'euckr_korean_ci'; SET @test_collation= 'euckr_korean_ci';
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%'; ...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%';
want1result want1result
location location
DROP TABLE t1; DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=euckr
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET NAMES euckr; SET NAMES euckr;
SET collation_connection='euckr_korean_ci'; SET collation_connection='euckr_korean_ci';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
......
...@@ -3,6 +3,8 @@ SET @test_character_set= 'gb2312'; ...@@ -3,6 +3,8 @@ SET @test_character_set= 'gb2312';
SET @test_collation= 'gb2312_chinese_ci'; SET @test_collation= 'gb2312_chinese_ci';
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%'; ...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%';
want1result want1result
location location
DROP TABLE t1; DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=gb2312
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET NAMES gb2312; SET NAMES gb2312;
SET collation_connection='gb2312_chinese_ci'; SET collation_connection='gb2312_chinese_ci';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
......
...@@ -3,6 +3,8 @@ SET @test_character_set= 'gbk'; ...@@ -3,6 +3,8 @@ SET @test_character_set= 'gbk';
SET @test_collation= 'gbk_chinese_ci'; SET @test_collation= 'gbk_chinese_ci';
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%'; ...@@ -52,10 +54,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%';
want1result want1result
location location
DROP TABLE t1; DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET NAMES gbk; SET NAMES gbk;
SET collation_connection='gbk_chinese_ci'; SET collation_connection='gbk_chinese_ci';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
......
...@@ -2538,6 +2538,8 @@ SET @test_character_set= 'utf8'; ...@@ -2538,6 +2538,8 @@ SET @test_character_set= 'utf8';
SET @test_collation= 'utf8_swedish_ci'; SET @test_collation= 'utf8_swedish_ci';
SET @safe_character_set_server= @@character_set_server; SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server; SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set; SET character_set_server= @test_character_set;
SET collation_server= @test_collation; SET collation_server= @test_collation;
CREATE DATABASE d1; CREATE DATABASE d1;
...@@ -2587,10 +2589,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%'; ...@@ -2587,10 +2589,27 @@ SELECT c1 as want1result from t1 where c1 like 'location%';
want1result want1result
location location
DROP TABLE t1; DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) collate utf8_swedish_ci default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1; DROP DATABASE d1;
USE test; USE test;
SET character_set_server= @safe_character_set_server; SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server; SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
create table t1 (a varchar(1)) character set utf8 collate utf8_estonian_ci; create table t1 (a varchar(1)) character set utf8 collate utf8_estonian_ci;
insert into t1 values ('A'),('B'),('C'),('a'),('b'),('c'); insert into t1 values ('A'),('B'),('C'),('a'),('b'),('c');
select a, a regexp '[a]' from t1 order by binary a; select a, a regexp '[a]' from t1 order by binary a;
......
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
SET @test_character_set= 'ucs2';
SET @test_collation= 'ucs2_general_ci';
SET @safe_character_set_server= @@character_set_server;
SET @safe_collation_server= @@collation_server;
SET @safe_character_set_client= @@character_set_client;
SET @safe_character_set_results= @@character_set_results;
SET character_set_server= @test_character_set;
SET collation_server= @test_collation;
CREATE DATABASE d1;
USE d1;
CREATE TABLE t1 (c CHAR(10), KEY(c));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c char(10) ucs2_general_ci YES MUL NULL
INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
want3results
aaa
aaaa
aaaaa
DROP TABLE t1;
CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
c1 varchar(15) ucs2_general_ci YES MUL NULL
INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
SELECT c1 as want3results from t1 where c1 like 'l%';
want3results
location
loberge
lotre
SELECT c1 as want3results from t1 where c1 like 'lo%';
want3results
location
loberge
lotre
SELECT c1 as want1result from t1 where c1 like 'loc%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'loca%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locat%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locati%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'locatio%';
want1result
location
SELECT c1 as want1result from t1 where c1 like 'location%';
want1result
location
DROP TABLE t1;
set names utf8;
create table t1 (
name varchar(10),
level smallint unsigned);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`name` varchar(10) default NULL,
`level` smallint(5) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=ucs2
insert into t1 values ('string',1);
select concat(name,space(level)), concat(name, repeat(' ',level)) from t1;
concat(name,space(level)) concat(name, repeat(' ',level))
string string
drop table t1;
DROP DATABASE d1;
USE test;
SET character_set_server= @safe_character_set_server;
SET collation_server= @safe_collation_server;
SET character_set_client= @safe_character_set_client;
SET character_set_results= @safe_character_set_results;
SET NAMES latin1; SET NAMES latin1;
SET character_set_connection=ucs2; SET character_set_connection=ucs2;
select 'a' = 'a', 'a' = 'a ', 'a ' = 'a'; select 'a' = 'a', 'a' = 'a ', 'a ' = 'a';
......
...@@ -6,6 +6,16 @@ DROP TABLE IF EXISTS t1; ...@@ -6,6 +6,16 @@ DROP TABLE IF EXISTS t1;
SHOW COLLATION LIKE 'cp1250_czech_cs'; SHOW COLLATION LIKE 'cp1250_czech_cs';
SET @test_character_set= 'cp1250';
SET @test_collation= 'cp1250_general_ci';
-- source include/ctype_common.inc
SET @test_character_set= 'cp1250';
SET @test_collation= 'cp1250_czech_cs';
-- source include/ctype_common.inc
# #
# Bugs: #8840: Empty string comparison and character set 'cp1250' # Bugs: #8840: Empty string comparison and character set 'cp1250'
# #
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
--enable_warnings --enable_warnings
SET @test_character_set= 'ucs2';
SET @test_collation= 'ucs2_general_ci';
-- source include/ctype_common.inc
SET NAMES latin1; SET NAMES latin1;
SET character_set_connection=ucs2; SET character_set_connection=ucs2;
-- source include/endspace.inc -- source include/endspace.inc
......
...@@ -361,13 +361,13 @@ Item *create_func_space(Item *a) ...@@ -361,13 +361,13 @@ Item *create_func_space(Item *a)
if (cs->mbminlen > 1) if (cs->mbminlen > 1)
{ {
uint dummy_errors; uint dummy_errors;
sp= new Item_string("",0,cs); sp= new Item_string("", 0, cs, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
if (sp) if (sp)
sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors); sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
} }
else else
{ {
sp= new Item_string(" ",1,cs); sp= new Item_string(" ", 1, cs, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
} }
return sp ? new Item_func_repeat(sp, a) : 0; return sp ? new Item_func_repeat(sp, a) : 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment