[MDEV-9429] COLUMN_GET on a subkey with more than three key value pairs returns a corrupted dyncol_blob Created: 2016-01-18  Updated: 2017-01-27  Resolved: 2016-02-21

Status: Closed
Project: MariaDB Server
Component/s: Dynamic Columns
Affects Version/s: 10.1.10
Fix Version/s: 10.1.12

Type: Bug Priority: Major
Reporter: Rich Theobald Assignee: Oleksandr Byelkin
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

Ubuntu 14.04


Sprint: 10.1.12

 Description   

MariaDB> select column_json(column_get(column_create('test1', column_create('key1','value1','key2','value2')) , 'test1' as char));
+-------------------------------------------------------------------------------------------------------------------+
| column_json(column_get(column_create('test1', column_create('key1','value1','key2','value2')) , 'test1' as char)) |
+-------------------------------------------------------------------------------------------------------------------+
| {"key1":"value1","key2":"value2"}                                                                                 |
+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
 
MariaDB> select column_json(column_get(column_create('test1', column_create('key1','value1','key2','value2','key3','value3')) , 'test1' as char));
ERROR 1919 (HY000): Encountered illegal format of dynamic column string



 Comments   
Comment by Elena Stepanova [ 2016-01-18 ]

I can reproduce it with utf8 names (not with latin1).

I am not sure it is a bug though, as in this query you are trying to convert a blob to char:

column_get(column_create('test1', column_create('key1','value1','key2','value2','key3','value3')) , 'test1' as char)

If you execute just it

set names utf8;
select column_get(column_create('test1', column_create('key1','value1','key2','value2','key3','value3')) , 'test1' as char);

you'll get

+----------------------------------------------------------------------------------------------------------------------+
| column_get(column_create('test1', column_create('key1','value1','key2','value2','key3','value3')) , 'test1' as char) |
+----------------------------------------------------------------------------------------------------------------------+
|  
        s ? key1key2key3!value1!value2!value3                                                                   |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
 
MariaDB [test]> show warnings;
+---------+------+----------------------------------------------------------------------------+
| Level   | Code | Message                                                                    |
+---------+------+----------------------------------------------------------------------------+
| Warning | 1300 | Invalid utf8 character string: '\xE3\x00key1key2key3!value1!value2!value3' |
+---------+------+----------------------------------------------------------------------------+
1 row in set (0.00 sec)

So, further attempt to read an already invalid value does not go to well.
I suppose column_create has the right to return non-utf8 symbols. Shouldn't there be as binary instead?

ATTN bar and sanja as experts on character sets and dynamic columns, correspondingly.

Comment by Oleksandr Byelkin [ 2016-01-18 ]

AFAIK column_create/column_add return result in binary charset (at least it should). But probably it goes wrong somewhere.

Comment by Elena Stepanova [ 2016-02-16 ]

Assigning to sanja for further analysis (please reassign to or consult with bar if necessary).

Comment by Oleksandr Byelkin [ 2016-02-21 ]

In second test suite we trying to send back to the client binary string (packed Dynamic Column) via charset which do not support all possible characters combination (utf8). So it is normal (I checked in debugger that the problem is in attempt to check binary data as utf8).

Comment by Oleksandr Byelkin [ 2016-02-21 ]

For original test suite we have the same problem. Correct query is:
select column_json(column_get(column_create('test1', column_create('key1','value1','key2','value2','key3','value3')) , 'test1' as BINARY));

(Notice BINARY).

Comment by Oleksandr Byelkin [ 2016-02-21 ]

I'll add note to the documentation about safe charset.

Comment by Tom [ 2017-01-27 ]

1. Before

In good-old 10.0, char was understood as binary

MariaDB [(none)]> show variables like 'version';
+---------------+--------------------------------+
| Variable_name | Value                          |
+---------------+--------------------------------+
| version       | 10.0.27-MariaDB-1~trusty-wsrep |
+---------------+--------------------------------+
1 row in set (0.00 sec)
 
MariaDB [(none)]>  SELECT (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS char), 'int' AS char) * 2);
+-----------------------------------------------------------------------------------------------------------------+
| (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS char), 'int' AS char) * 2) |
+-----------------------------------------------------------------------------------------------------------------+
|                                                                                                             246 |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
 
MariaDB [(none)]> SELECT (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS binary), 'int' AS char) * 2);
+-------------------------------------------------------------------------------------------------------------------+
| (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS binary), 'int' AS char) * 2) |
+-------------------------------------------------------------------------------------------------------------------+
|                                                                                                               246 |
+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

2. After

Now we need to do more work in our ORM

MariaDB [(none)]> show variables like 'version';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| version       | 10.1.20-MariaDB |
+---------------+-----------------+
1 row in set (0.00 sec)
 
MariaDB [(none)]> SELECT (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS char), 'int' AS char) * 2);
+-----------------------------------------------------------------------------------------------------------------+
| (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS char), 'int' AS char) * 2) |
+-----------------------------------------------------------------------------------------------------------------+
|                                                                                                             -64 |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
 
MariaDB [(none)]> SHOW WARNINGS;
+---------+------+---------------------------------------+
| Level   | Code | Message                               |
+---------+------+---------------------------------------+
| Warning | 1300 | Invalid utf8 character string: '\xF6' |
+---------+------+---------------------------------------+
1 row in set (0.00 sec)
 
MariaDB [(none)]> SELECT (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS binary), 'int' AS char) * 2);
+-------------------------------------------------------------------------------------------------------------------+
| (COLUMN_GET(COLUMN_GET(COLUMN_CREATE('child', COLUMN_CREATE('int', 123)), 'child' AS binary), 'int' AS char) * 2) |
+-------------------------------------------------------------------------------------------------------------------+
|                                                                                                               246 |
+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Comment by Tom [ 2017-01-27 ]

I like the 10.0 behavior better because Maria is more friendly if she understands from the outer COLUMN_GET context that, well, obviously this 'child' as char needs to be taken as binary.

Is there any value to the improvement in 10.1?

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