Bug #13909 Varchar Stored Procedure Parameter always BINARY string (ignores CHARACTER SET)
Submitted: 10 Oct 2005 21:01 Modified: 7 Dec 2005 20:43
Reporter: Roland Bouman Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Stored Routines Severity:S2 (Serious)
Version:5.0.13-rc-nt/BK 5.0 OS:Windows (WinXP/Linux)
Assigned to: Alexander Nozdrin CPU Architecture:Any

[10 Oct 2005 21:01] Roland Bouman
Description:
A varchar type stored procedure parameter is always a BINARY string. This is true even if the character set is explicitly named in the parameter declaration.

It was expected that the parameter would have the default character set of the schema, unless explicitly specified, in which case it would have the specified character set.

How to repeat:
delimiter go

select default_character_set_name
from   information_schema.schemata
where  schema_name = schema()
go

+----------------------------+
| default_character_set_name |
+----------------------------+
| latin1                     |
+----------------------------+
1 row in set (0.03 sec)

create procedure p_test(
    p_text varchar(30)
)
begin
    select charset(p_text);
end;
go

call p_test('t')
go
+-----------------+
| charset(p_text) |
+-----------------+
| binary          |
+-----------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

call p_test(_utf8't')
go
+-----------------+
| charset(p_text) |
+-----------------+
| binary          |
+-----------------+
1 row in set (0.00 sec)

drop procedure p_test
go

create procedure p_test(
    p_text varchar(30) character set utf8
)
begin
    select charset(p_text);
end;
go

call p_test('t')
go

+-----------------+
| charset(p_text) |
+-----------------+
| binary          |
+-----------------+
1 row in set (0.00 sec)

Query OK, 0 rows affect

call p_test(_utf8't')
go

+-----------------+
| charset(p_text) |
+-----------------+
| binary          |
+-----------------+
1 row in set (0.00 sec)

Suggested fix:
make parameters behave, and give them the appropriate character set.
[10 Oct 2005 23:40] MySQL Verification Team
mysql> call p_test(_utf8't')
    -> go
+------------+
| charset(x) |
+------------+
| binary     |
+------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> set @y = _utf8't';
    -> go
Query OK, 0 rows affected (0.00 sec)

mysql> select charset(@y)
    -> go
+-------------+
| charset(@y) |
+-------------+
| utf8        |
+-------------+
1 row in set (0.00 sec)

mysql> select version()
    -> go
+-----------------+
| version()       |
+-----------------+
| 5.0.15-rc-debug |
+-----------------+
1 row in set (0.00 sec)
[7 Dec 2005 20:43] Paul DuBois
Noted in 5.0.18 changelog.
[15 Jan 2006 18:41] Fermin Latas
I have this problems
Store procedure:

DELIMITER $$

DROP PROCEDURE IF EXISTS `loteria`.`p_1x2_partidos_estadistica_partido` $$
CREATE PROCEDURE `p_1x2_partidos_estadistica_partido`(
IN _nombre_equipo_local VARCHAR(150),IN _nombre_equipo_visitante VARCHAR(150),
IN _temporada DECIMAL(4,0),IN _jornada DECIMAL(2,0))
BEGIN
  DECLARE __nombre_equipo_local VARCHAR(150);
  DECLARE _id_equipo_local INT;
  DECLARE _id_equipo_visitante INT;

  #SELECT charset(_nombre_equipo_local);
  #SELECT @@COLLATION_CONNECTION,@@CHARACTER_SET_CLIENT;
  SET CHARACTER_SET_CLIENT=latin1;
  #SET COLLATION_CONNECTION=latin1_spanish_ci;

  SElECT id INTO _id_equipo_local FROM 1x2_equipos WHERE nombre=_nombre_equipo_local;
  SElECT id FROM 1x2_equipos WHERE nombre=_nombre_equipo_visitante INTO _id_equipo_visitante;

  #Traza
  SELECT _nombre_equipo_local,_id_equipo_local,
        _nombre_equipo_visitante,_id_equipo_visitante,
        _temporada,_jornada;

   #CALL loteria.p_1x2_partidos_estadisticaXtemporada_mostrar(-1,_temporada,-1,-1);
   CALL loteria.p_1x2_partidos_estadisticaXtemporada(-1,_temporada,-1,-1);

  #SELECT 1x2_equipos.nombre AS nombre_equipo,temporada,ganados,empatados,perdidos,dif_partidos,
  #  goles_metidos,goles_encajados,dif_goles,
  #  dif_goles_local,dif_goles_visitante,ganados_local,empatados_local,perdidos_local,
  #  ganados_visitante,empatados_visitante,perdidos_visitante,goles_local_encajados,goles_local_metidos,
  #  goles_visitante_encajados,goles_visitante_metidos
  #FROM  loteria.tmp_1x2_partidos_estadisticaXtemporada,1x2_equipos
  #WHERE loteria.tmp_1x2_partidos_estadisticaXtemporada.fk_equipo=1x2_equipos.id
  #  AND temporada=_temporada
  #  AND nombre IN(_nombre_equipo_local,_nombre_equipo_visitante)
  #ORDER BY nombre,temporada DESC;

  SELECT 1x2_equipos.nombre AS nombre_equipo,temporada,ganados,empatados,perdidos,dif_partidos,
    goles_metidos,goles_encajados,dif_goles,
    dif_goles_local,dif_goles_visitante,ganados_local,empatados_local,perdidos_local,
    ganados_visitante,empatados_visitante,perdidos_visitante,goles_local_encajados,goles_local_metidos,
    goles_visitante_encajados,goles_visitante_metidos
  FROM  loteria.tmp_1x2_partidos_estadisticaXtemporada,1x2_equipos
  WHERE loteria.tmp_1x2_partidos_estadisticaXtemporada.fk_equipo=1x2_equipos.id
    AND temporada=_temporada
    AND 1x2_equipos.id IN(_id_equipo_local,_id_equipo_visitante)
  ORDER BY 1x2_equipos.nombre,tmp_1x2_partidos_estadisticaXtemporada.temporada DESC;

END $$

DELIMITER ;

EXECUTE:
CALL p_1x2_partidos_estadistica_partido(_utf8'Fútbol Club Barcelona',_utf8'Real Madrid Club de Fútbol',2005,5)

RESULT:

'Fútbol Club Barcelona', NULL, 'Real Madrid Club de Fútbol',NULL, '2005', '5'

I force to _utf8 and failed (_utf8'Fútbol Club Barcelona')
Suggestions.

Regards 
Fermín Latas