[MDEV-11292] Item_func_sp::fix_length_and_dec() does not set collation derivation properly Created: 2016-11-16  Updated: 2020-06-05

Status: Stalled
Project: MariaDB Server
Component/s: Character Sets
Affects Version/s: 5.5, 10.1, 10.2, 10.3, 10.4
Fix Version/s: 10.5

Type: Bug Priority: Minor
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This piece of code:

void Item_func_sp::fix_length_and_dec()
{
  DBUG_ENTER("Item_func_sp::fix_length_and_dec");
 
  DBUG_ASSERT(sp_result_field);
  Type_std_attributes::set(sp_result_field);
  maybe_null= 1;
 
  DBUG_VOID_RETURN;
}

sets all Type_std_attributes members but collation.derivation, which remains DERIVATION_COERCIBLE by default.

This query is a prove:

DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INT RETURN 10;
SELECT
  COERCIBILITY(f1()),
  COERCIBILITY(10),
  COERCIBILITY(LENGTH('a'));

+--------------------+------------------+---------------------------+
| COERCIBILITY(f1()) | COERCIBILITY(10) | COERCIBILITY(LENGTH('a')) |
+--------------------+------------------+---------------------------+
|                  4 |                5 |                         5 |
+--------------------+------------------+---------------------------+

Notice, the first column erroneously returns 4, which means DERIVATION_COERCIBLE, while the second and the third column correctly return 5, which is DERIVATION_NUMERIC.

This can result in wrong character set during aggregation.
Here's an example:

DROP FUNCTION IF EXISTS f1;
DROP TABLE IF EXISTS t1;
CREATE FUNCTION f1() RETURNS INT RETURN 10;
CREATE TABLE t1 AS SELECT
  CONCAT(f1(),_utf8'a') as c1,
  CONCAT(10,_utf8'a') as c2,
  CONCAT(LENGTH('a'),_utf8'a') as c3;
SHOW CREATE TABLE t1;

+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                              |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `c1` varchar(12) DEFAULT NULL,
  `c2` varchar(3) CHARACTER SET utf8 NOT NULL,
  `c3` varchar(11) CHARACTER SET utf8 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Notice, character set for c1 was erroneously set to latin1. The expected character set is utf8, like it was correctly set for c2 and c3.

SP functions should set its derivation to:

  • DERIVATION_NUMERIC for numeric and temporal data types
  • DERIVATION_IMPLICIT for string data types

This was forgotten during "WL#2649: Number-to-string conversions".


Generated at Thu Feb 08 07:48:49 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.