Details
-
Task
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
Description
Under terms of MDEV-10306 we changed a few Item_func descendants to return the result in the String passed as a parameter to val_str() instead of the class member such as tmp_value. This fixed incorrect results, but caused more my_alloc / my_free.
Consider this script:
DROP TABLE IF EXISTS t1; |
CREATE TABLE t1 (a VARCHAR(500)); |
INSERT INTO t1 VALUES (REPEAT('a',500)),(REPEAT('b',500)); |
SELECT HEX(a) FROM t1; |
This is an except from Protocol::send_result_set_row:
bool Protocol::send_result_set_row(List<Item> *row_items) |
{
|
char buffer[MAX_FIELD_WIDTH]; |
String str_buffer(buffer, sizeof (buffer), &my_charset_bin); |
List_iterator_fast<Item> it(*row_items);
|
...
|
for (Item *item= it++; item; item= it++) |
{
|
if (item->send(this, &str_buffer)) |
...
|
}
|
}
|
Notice, the local buffer str_buffer is shared between columns of the same record, but it is not shared between multiple records of the same result set.
The buffer str_buffer is recursively passed to Item_func_hex::val_str_ascii(), which has to do alloc(1001) on every row, because the result does not fit into
MAX_FIELD_WIDTH bytes originally available in str_buffer.
Under terms of this task we will:
- Add a new String member in Protocol, e.g. Protocol::tmp_value.
- Fix Protocol::send_result_set_row() to use this new member instead of the local buffer
This will allow to share the memory allocated on the first row for the consequent rows.