[MDEV-9653] Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool) Created: 2016-02-28  Updated: 2016-04-20  Resolved: 2016-03-18

Status: Closed
Project: MariaDB Server
Component/s: OTHER
Affects Version/s: 10.1
Fix Version/s: 10.1.13

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-9745 Crash with CASE WHEN TRUE THEN COALES... Closed
Sprint: 10.1.13

 Description   

SELECT CASE 0 WHEN 1 THEN ( CASE 2 WHEN 3 THEN NULL END ) WHEN 4 THEN 5 END;

Stack trace from 10.1 commit 66832b619510f5b9724d8db1eac48bdafb9225e9

mysqld: /src/10.1/sql/my_decimal.h:213: uint my_decimal_length_to_precision(uint, uint, bool): Assertion `length || !scale' failed.
160228 17:50:59 [ERROR] mysqld got signal 6 ;
 
#7  0x00007f6f1a7a71d2 in __assert_fail () from /lib64/libc.so.6
#8  0x0000562a24b7abe8 in my_decimal_length_to_precision (length=0, scale=31, unsigned_flag=false) at /src/10.1/sql/my_decimal.h:213
#9  0x0000562a24bc85ba in Item_func_case::agg_num_lengths (this=0x7f6f10e53408, arg=0x7f6f10e53110) at /src/10.1/sql/item_cmpfunc.cc:3085
#10 0x0000562a24bc8908 in Item_func_case::fix_length_and_dec (this=0x7f6f10e53408) at /src/10.1/sql/item_cmpfunc.cc:3158
#11 0x0000562a24beef0e in Item_func::fix_fields (this=0x7f6f10e53408, thd=0x7f6f165c9330, ref=0x7f6f10e535a0) at /src/10.1/sql/item_func.cc:234
#12 0x0000562a24bc848d in Item_func_case::fix_fields (this=0x7f6f10e53408, thd=0x7f6f165c9330, ref=0x7f6f10e535a0) at /src/10.1/sql/item_cmpfunc.cc:3063
#13 0x0000562a248f30b9 in setup_fields (thd=0x7f6f165c9330, ref_pointer_array=0x7f6f10e53c90, fields=..., mark_used_columns=MARK_COLUMNS_READ, sum_func_list=0x7f6f10e53a80, allow_sum_func=true) at /src/10.1/sql/sql_base.cc:7896
#14 0x0000562a2498aaba in JOIN::prepare (this=0x7f6f10e53720, rref_pointer_array=0x7f6f165cd6c0, tables_init=0x0, wild_num=0, conds_init=0x0, og_num=0, order_init=0x0, skip_order_by=false, group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x7f6f165cd448, unit_arg=0x7f6f165ccd48) at /src/10.1/sql/sql_select.cc:795
#15 0x0000562a24994214 in mysql_select (thd=0x7f6f165c9330, rref_pointer_array=0x7f6f165cd6c0, tables=0x0, wild_num=0, fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7f6f10e53700, unit=0x7f6f165ccd48, select_lex=0x7f6f165cd448) at /src/10.1/sql/sql_select.cc:3429
#16 0x0000562a24989d6b in handle_select (thd=0x7f6f165c9330, lex=0x7f6f165ccc80, result=0x7f6f10e53700, setup_tables_done_option=0) at /src/10.1/sql/sql_select.cc:384
#17 0x0000562a2495a096 in execute_sqlcom_select (thd=0x7f6f165c9330, all_tables=0x0) at /src/10.1/sql/sql_parse.cc:5936
#18 0x0000562a2494fe72 in mysql_execute_command (thd=0x7f6f165c9330) at /src/10.1/sql/sql_parse.cc:2962
#19 0x0000562a2495d6de in mysql_parse (thd=0x7f6f165c9330, rawbuf=0x7f6f10e52d08 "SELECT CASE 0 WHEN 1 THEN ( CASE 2 WHEN 3 THEN NULL END ) WHEN 4 THEN 5 END", length=75, parser_state=0x7f6f1ca755e0) at /src/10.1/sql/sql_parse.cc:7336
#20 0x0000562a2494c0d9 in dispatch_command (command=COM_QUERY, thd=0x7f6f165c9330, packet=0x7f6f157c9eb1 "SELECT CASE 0 WHEN 1 THEN ( CASE 2 WHEN 3 THEN NULL END ) WHEN 4 THEN 5 END", packet_length=75) at /src/10.1/sql/sql_parse.cc:1488
#21 0x0000562a2494ae0b in do_command (thd=0x7f6f165c9330) at /src/10.1/sql/sql_parse.cc:1109
#22 0x0000562a24a80bc0 in do_handle_one_connection (thd_arg=0x7f6f165c9330) at /src/10.1/sql/sql_connect.cc:1349
#23 0x0000562a24a80924 in handle_one_connection (arg=0x7f6f165c9330) at /src/10.1/sql/sql_connect.cc:1261
#24 0x0000562a25188afa in pfs_spawn_thread (arg=0x7f6f151b0bf0) at /src/10.1/storage/perfschema/pfs.cc:1860
#25 0x00007f6f1c6f00a4 in start_thread () from /lib64/libpthread.so.0
#26 0x00007f6f1a85e04d in clone () from /lib64/libc.so.6

The problem appeared in 10.1 tree with this commit:

commit cc9cfecab78bde9376e4406bf24506e92fdaaeac
Author: Alexander Barkov <bar@mariadb.org>
Date:   Wed Sep 30 12:37:34 2015 +0400
 
    MDEV-8865 Wrong field type or metadata for COALESCE(signed_int_column, unsigned_int_column)
    Item_func_hybrid_field_type did not return correct field_type(), cmp_type()
    and result_type() in some cases, because cached_result_type and
    cached_field_type were set in independent pieces of the code and
    did not properly match to each other.
    Fix:
    - Removing Item_func_hybrid_result_type
    - Deriving Item_func_hybrid_field_type directly from Item_func
    - Introducing a new class Type_handler which guarantees that
      field_type(), cmp_type() and result_type() are always properly synchronized
      and using the new class in Item_func_hybrid_field_type.



 Comments   
Comment by Alexander Barkov [ 2016-03-16 ]

The problem is also repeatable with the following queries:

SELECT CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END;
SELECT CASE WHEN TRUE THEN COALESCE(NULL) ELSE 4 END;

Comment by Alexander Barkov [ 2016-03-16 ]

The crash did not happen before MDEV-8865, because cached_result_type and cached_field_type were out of sync:

(gdb) p	cached_result_type
$1 = STRING_RESULT
(gdb) p cached_field_type 
$2 = MYSQL_TYPE_LONGLONG

so length aggregation went through count_string_result_length().

After MDEV-8865, length aggregation goes through agg_num_lengths(), which does not expect Items to have max_length=0 and decimals=31 (NOT_FIXED_DEC) at the same time.

Comment by Alexander Barkov [ 2016-03-17 ]

A related problem:

SELECT COALESCE(COALESCE(NULL), 1.1);

Field   1:  `COALESCE(COALESCE(NULL), 1.1)`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     34
Max_length: 33
Decimals:   31
Flags:      BINARY NUM 
+-----------------------------------+
| COALESCE(COALESCE(NULL), 1.1)     |
+-----------------------------------+
| 1.1000000000000000000000000000000 |
+-----------------------------------+

Decimals==31 is wrong here. It should be 1.
The result should 1.1, without trailing zeros.

Comment by Alexander Barkov [ 2016-03-17 ]

SELECT IF(0, COALESCE(NULL), 1.1);

Field   1:  `IF(0, COALESCE(NULL), 1.1)`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     34
Max_length: 33
Decimals:   31
Flags:      BINARY NUM 
+-----------------------------------+
| IF(0, COALESCE(NULL), 1.1)        |
+-----------------------------------+
| 1.1000000000000000000000000000000 |
+-----------------------------------+

decimals==31 is wrong.

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