1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-30 05:23:50 +03:00
Files
mariadb/sql
Alexander Barkov 3a37afec29 MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
The bug happens because of a combination of unfortunate circumstances:

1. Arguments args[0] and args[2] of Item_func_concat point recursively
(through Item_direct_view_ref's) to the same Item_func_conv_charset.
Both args[0]->args[0]->ref[0] and args[2]->args[0]->ref[0] refer to
this Item_func_conv_charset.

2. When Item_func_concat::args[0]->val_str() is called,
Item_func_conv_charset::val_str() writes its result to
Item_func_conc_charset::tmp_value.

3. Then, for optimization purposes (to avoid copying),
Item_func_substr::val_str() initializes Item_func_substr::tmp_value
to point to the buffer fragment owned by Item_func_conv_charset::tmp_value
Item_func_substr::tmp_value is returned as a result of
Item_func_concat::args[0]->val_str().

4. Due to optimization to avoid memory reallocs,
Item_func_concat::val_str() remembers the result of args[0]->val_str()
in "res" and further uses "res" to collect the return value.

5. When Item_func_concat::args[2]->val_str() is called,
Item_func_conv_charset::tmp_value gets overwritten (see #1),
which effectively overwrites args[0]'s Item_func_substr::tmp_value (see #3),
which effectively overwrites "res" (see #4).

This patch does the following:

a. Changes Item_func_conv_charset::val_str(String *str) to use
   tmp_value and str the other way around. After this change tmp_value
   is used to store a temporary result, while str is used to return the value.
   The fixes the second problem (without SUBSTR):
     SELECT CONCAT(t2,'-',t2) c2
       FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
   As Item_func_concat::val_str() supplies two different buffers when calling
   args[0]->val_str() and args[2]->val_str(), in the new reduction the result
   created during args[0]->val_str() does not get overwritten by
   args[2]->val_str().

b. Fixing the same problem in val_str() for similar classes

   Item_func_to_base64
   Item_func_from_base64
   Item_func_weight_string
   Item_func_hex
   Item_func_unhex
   Item_func_quote
   Item_func_compress
   Item_func_uncompress
   Item_func_des_encrypt
   Item_func_des_decrypt
   Item_func_conv_charset
   Item_func_reverse
   Item_func_soundex
   Item_func_aes_encrypt
   Item_func_aes_decrypt
   Item_func_buffer

c. Fixing Item_func::val_str_from_val_str_ascii() the same way.
   Now Item_str_ascii_func::ascii_buff is used for temporary value,
   while the parameter passed to val_str() is used to return the result.
   This fixes the same problem when conversion (from ASCII to e.g. UCS2)
   takes place. See the ctype_ucs.test for example queries that returned
   wrong results before the fix.

d. Some Item_func descendand classes had temporary String buffers
   (tmp_value and tmp_str), but did not really use them.
   Removing these temporary buffers from:

   Item_func_decode_histogram
   Item_func_format
   Item_func_binlog_gtid_pos
   Item_func_spatial_collection:

e. Removing Item_func_buffer::tmp_value, because it's not used any more.

f. Renaming Item_func_[un]compress::buffer to "tmp_value",
   for consistency with other classes.

Note, this patch does not fix the following classes
(although they have a similar problem):

   Item_str_conv
   Item_func_make_set
   Item_char_typecast

They have a complex implementations and simple swapping between "tmp_value"
and "str" won't work. These classes will be fixed separately.
2017-06-19 12:45:32 +04:00
..
2017-03-21 11:35:50 +01:00
2014-01-06 10:52:35 +05:30
2013-07-21 16:39:19 +02:00
2014-03-16 13:59:44 +01:00
2014-03-16 13:59:44 +01:00
2014-03-16 21:03:01 +01:00
2014-02-26 15:28:07 +01:00
2016-02-15 22:50:59 +01:00
2016-06-21 14:11:02 +02:00
2014-03-19 09:58:06 +01:00
2014-03-16 21:03:01 +01:00
2014-02-26 15:28:07 +01:00
2014-03-16 21:03:01 +01:00
2017-03-03 01:37:54 +02:00
2014-03-26 22:25:38 +01:00
2013-06-27 12:51:34 +03:00
2017-05-29 13:15:36 +03:00
2017-04-21 18:34:06 +02:00
2017-04-21 18:34:06 +02:00
2014-03-23 15:15:07 +04:00
2014-02-26 15:28:07 +01:00
2014-01-06 10:52:35 +05:30
2016-06-21 14:11:02 +02:00
2014-03-16 21:03:01 +01:00
2017-03-08 11:40:43 +02:00
2017-05-20 00:59:40 +02:00
2015-06-02 22:07:47 +02:00
2015-06-02 22:07:47 +02:00
2014-10-29 15:20:46 +03:00
2014-03-16 21:03:01 +01:00
2016-09-27 09:21:19 +02:00
2013-07-21 16:39:19 +02:00
2014-08-07 18:06:56 +02:00
2017-05-20 00:59:40 +02:00
2014-03-15 18:24:15 +01:00
2017-03-03 01:37:54 +02:00
2014-03-16 21:03:01 +01:00
2014-05-09 12:35:11 +02:00
2015-10-23 18:49:02 +03:00
2014-08-07 18:06:56 +02:00
2016-12-09 16:33:48 +01:00
2014-03-16 13:59:44 +01:00
2014-08-07 18:06:56 +02:00
2014-03-15 18:24:15 +01:00
2014-03-16 21:03:01 +01:00
2016-02-15 22:50:59 +01:00
2014-09-04 12:15:05 +04:00
2014-03-15 18:24:15 +01:00
2014-03-16 13:59:44 +01:00
2017-04-21 18:34:06 +02:00
2014-03-16 21:03:01 +01:00
2016-11-28 11:55:36 +05:30
2016-09-27 09:21:19 +02:00
2014-03-16 21:03:01 +01:00
2014-03-13 16:43:11 +02:00
2014-03-16 21:03:01 +01:00
2013-08-12 14:17:51 +02:00
2017-04-21 18:34:06 +02:00
2017-01-17 16:22:25 +01:00
2013-10-29 15:08:44 +01:00
2017-04-21 18:34:06 +02:00
2017-01-14 19:59:34 +02:00
2017-03-03 01:37:54 +02:00
2015-05-05 15:23:47 +02:00
2015-10-24 20:06:59 +02:00
2014-06-06 00:07:27 +02:00
2013-10-17 17:50:30 +04:00
2013-10-18 12:36:03 -07:00
2016-08-10 19:19:05 +02:00
2017-03-03 01:37:54 +02:00
2014-06-10 10:34:58 -07:00
2014-02-22 22:51:20 +01:00
2017-04-21 18:34:06 +02:00
2016-04-26 23:05:26 +02:00
2013-11-11 23:40:53 +02:00
2016-08-10 19:19:05 +02:00
2014-10-09 10:30:11 +02:00
2014-03-15 18:24:15 +01:00
2013-04-09 16:07:35 +02:00
2014-02-10 15:12:17 +01:00
2014-03-16 21:03:01 +01:00
2014-03-27 22:26:58 +01:00
2016-10-26 20:45:35 -07:00
2016-10-26 20:45:35 -07:00
2017-01-14 19:59:34 +02:00
2015-05-04 22:00:24 +02:00
2014-06-06 00:07:27 +02:00
2015-12-13 00:10:40 +01:00
2016-08-10 19:19:05 +02:00
2017-01-14 19:59:34 +02:00
2015-11-06 17:56:56 +01:00
2015-05-04 22:00:24 +02:00
2014-02-26 15:28:07 +01:00
2015-03-06 18:41:32 +01:00
2017-01-12 03:37:13 +02:00
2017-03-15 17:48:30 +01:00
2017-01-14 19:59:34 +02:00
2014-01-06 10:52:35 +05:30
2015-05-04 22:00:24 +02:00
2015-06-02 22:07:47 +02:00