[Commits] 98189b6: MDEV-18880: Optimizer trace prints date in hexadecimal
revision-id: 98189b6df7a7f88efc9b7a199a436eb3022fd157 (mariadb-10.4.3-168-g98189b6) parent(s): 517a56c1884e74b7c7606b56b0884537e792089e author: Varun Gupta committer: Varun Gupta timestamp: 2019-04-10 13:49:16 +0530 message: MDEV-18880: Optimizer trace prints date in hexadecimal Introducded a print_key_value function to makes sure that the trace prints data in readable format for readable characters and the rest of the characters are printed as hexadecimal. --- mysql-test/main/opt_trace.result | 442 ++++++++++++++++++++++++++++++++++++++- mysql-test/main/opt_trace.test | 56 +++++ sql/field.cc | 59 ++++++ sql/field.h | 15 ++ sql/opt_range.cc | 34 +-- sql/sql_string.h | 5 + 6 files changed, 579 insertions(+), 32 deletions(-) diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index ed5881e..3aec8aa 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -1446,7 +1446,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { { "index": "id", "covering": true, - "ranges": ["(0x24a20f) <= (a)"], + "ranges": ["(2001-01-04) <= (a)"], "rows": 9, "cost": 2.35 } @@ -1462,7 +1462,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "rows": 9, "cost": 2.35, "key_parts_used_for_access": ["id"], - "ranges": ["(0x24a20f) <= (a)"], + "ranges": ["(2001-01-04) <= (a)"], "chosen": false, "cause": "cost" }, @@ -1624,7 +1624,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { { "index": "id", "covering": true, - "ranges": ["(0x24a20f) <= (a) <= (0x24a20f)"], + "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"], "rows": 9, "cost": 2.35 } @@ -1640,7 +1640,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "rows": 9, "cost": 2.35, "key_parts_used_for_access": ["id", "a"], - "ranges": ["(0x24a20f) <= (a) <= (0x24a20f)"], + "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"], "chosen": false, "cause": "cost" }, @@ -6130,7 +6130,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "index": "start_date", "ranges": [ - "(0x4ac60f,NULL) < (start_date,end_date)" + "(2019-02-10,NULL) < (start_date,end_date)" ], "rowid_ordered": false, "using_mrr": false, @@ -6214,7 +6214,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "index": "i_b", "ranges": [ - "(0xd95b94336a9946a39cf5b58cfe772d8c) <= (b) <= (0xd95b94336a9946a39cf5b58cfe772d8c)" + "(\xD9[\x943j\x99F\xA3\x9C\xF5\xB5\x8C\xFEw-\x8C) <= (b) <= (\xD9[\x943j\x99F\xA3\x9C\xF5\xB5\x8C\xFEw-\x8C)" ], "rowid_ordered": true, "using_mrr": false, @@ -6268,4 +6268,434 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) } ] drop table t1; +# +# MDEV-18880: Optimizer trace prints date in hexadecimal +# +CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10) CHARSET BINARY , INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 13 const 1 Using index condition +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "i_b", + "ranges": + [ + "(ab\x0A) <= (b) <= (ab\x0A)" + ], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 1, + "cost": 2.3787, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +ALTER TABLE t1 modify column b BINARY(10) AFTER i; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 11 const 1 Using index condition +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "i_b", + "ranges": + [ + "(ab\x0A\x00\x00\x00\x00\x00\x00\x00) <= (b) <= (ab\x0A\x00\x00\x00\x00\x00\x00\x00)" + ], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 1, + "cost": 2.3785, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +ALTER TABLE t1 modify column b VARBINARY(10) AFTER i; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 13 const 1 Using index condition +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "i_b", + "ranges": + [ + "(ab\x0A) <= (b) <= (ab\x0A)" + ], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 1, + "cost": 2.3787, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +drop table t1; +CREATE TABLE t1(i INT PRIMARY KEY, b CHAR(10), INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 11 const 1 Using index condition +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "i_b", + "ranges": + [ + "(ab\n) <= (b) <= (ab\n)" + ], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 1, + "cost": 2.3785, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +drop table t1; +CREATE TABLE t1(i INT PRIMARY KEY, b blob , INDEX i_b(b)); +Warnings: +Note 1071 Specified key was too long; max key length is 1000 bytes +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 1003 const 1 Using where +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "i_b", + "ranges": + [ + "(ab\x0A) <= (b) <= (ab\x0A)" + ], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 1, + "cost": 3.5719, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +drop table t1; +CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10), INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, 'ab\n'); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i_b i_b 13 const 2 Using index condition +select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n') { + "steps": [ + { + "join_preparation": { + "select_id": 1, + "steps": [ + { + "expanded_query": "select t1.i AS i,t1.b AS b from t1 where t1.b = 'ab\n'" + } + ] + } + }, + { + "join_optimization": { + "select_id": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "t1.b = 'ab\n'", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "multiple equal('ab\n', t1.b)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "multiple equal('ab\n', t1.b)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "multiple equal('ab\n', t1.b)" + } + ] + } + }, + { + "table_dependencies": [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [] + } + ] + }, + { + "ref_optimizer_key_uses": [ + { + "table": "t1", + "field": "b", + "equals": "'ab\n'", + "null_rejecting": false + } + ] + }, + { + "rows_estimation": [ + { + "table": "t1", + "range_analysis": { + "table_scan": { + "rows": 2, + "cost": 4.5098 + }, + "potential_range_indexes": [ + { + "index": "PRIMARY", + "usable": false, + "cause": "not applicable" + }, + { + "index": "i_b", + "usable": true, + "key_parts": ["b"] + } + ], + "setup_range_conditions": [], + "group_index_range": { + "chosen": false, + "cause": "no group by or distinct" + }, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "i_b", + "ranges": ["(ab\n) <= (b) <= (ab\n)"], + "rowid_ordered": true, + "using_mrr": false, + "index_only": false, + "rows": 2, + "cost": 3.6324, + "chosen": true + } + ], + "analyzing_roworder_intersect": { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": [] + }, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "range_scan", + "index": "i_b", + "rows": 2, + "ranges": ["(ab\n) <= (b) <= (ab\n)"] + }, + "rows_for_plan": 2, + "cost_for_plan": 3.6324, + "chosen": true + } + } + }, + { + "selectivity_for_indexes": [ + { + "index_name": "i_b", + "selectivity_from_index": 1 + } + ], + "selectivity_for_columns": [], + "cond_selectivity": 1 + } + ] + }, + { + "considered_execution_plans": [ + { + "plan_prefix": [], + "table": "t1", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "i_b", + "used_range_estimates": true, + "rows": 2, + "cost": 3, + "chosen": true + }, + { + "type": "scan", + "chosen": false, + "cause": "cost" + } + ] + } + } + ] + }, + { + "attaching_conditions_to_tables": { + "original_condition": "t1.b = 'ab\n'", + "attached_conditions_computation": [], + "attached_conditions_summary": [ + { + "table": "t1", + "attached": "t1.b = 'ab\n'" + } + ] + } + } + ] + } + }, + { + "join_execution": { + "select_id": 1, + "steps": [] + } + } + ] +} 0 0 +drop table t1; +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table one_k (a int); +insert into one_k select A.a + B.a*10 + C.a*100 from t0 A, t0 B, t0 C; +create table t1 (start_date date, end_date date, filler char(100), key(start_date, end_date)) ; +insert into t1 select date_add(now(), interval a day), date_add(now(), interval (a+7) day), 'data' from one_k; +explain format=json select * from t1 force index(start_date) where start_date >= '2019-02-10' and end_date <'2019-04-01'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["start_date"], + "key": "start_date", + "key_length": "8", + "used_key_parts": ["start_date", "end_date"], + "rows": 1000, + "filtered": 100, + "index_condition": "t1.start_date >= '2019-02-10' and t1.end_date < '2019-04-01'" + } + } +} +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) +[ + + { + "range_scan_alternatives": + [ + + { + "index": "start_date", + "ranges": + [ + "(2019-02-10,NULL) < (start_date,end_date)" + ], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 1000, + "cost": 1282.2, + "chosen": true + } + ], + "analyzing_roworder_intersect": + { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": + [ + ] + } +] +drop table t1, t0, one_k; set optimizer_trace='enabled=off'; diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 981a53a..36bdc86 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -444,4 +444,60 @@ select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) fr drop table t1; +--echo # +--echo # MDEV-18880: Optimizer trace prints date in hexadecimal +--echo # + +CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10) CHARSET BINARY , INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +ALTER TABLE t1 modify column b BINARY(10) AFTER i; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +ALTER TABLE t1 modify column b VARBINARY(10) AFTER i; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +drop table t1; + +CREATE TABLE t1(i INT PRIMARY KEY, b CHAR(10), INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +drop table t1; + + +CREATE TABLE t1(i INT PRIMARY KEY, b blob , INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, NULL); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +drop table t1; + +CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10), INDEX i_b(b)); +INSERT INTO t1 VALUES (1, 'ab\n'); +INSERT INTO t1 VALUES (2, 'ab\n'); +set optimizer_trace=1; +EXPLAIN SELECT * FROM t1 WHERE b IN ('ab\n'); +select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +#select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +drop table t1; +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table one_k (a int); +insert into one_k select A.a + B.a*10 + C.a*100 from t0 A, t0 B, t0 C; +create table t1 (start_date date, end_date date, filler char(100), key(start_date, end_date)) ; +--disable_warnings +insert into t1 select date_add(now(), interval a day), date_add(now(), interval (a+7) day), 'data' from one_k; +--enable_warnings +explain format=json select * from t1 force index(start_date) where start_date >= '2019-02-10' and end_date <'2019-04-01'; +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +drop table t1, t0, one_k; + set optimizer_trace='enabled=off'; diff --git a/sql/field.cc b/sql/field.cc index 4a93464..12fd423 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11228,3 +11228,62 @@ bool Field::val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to) thd->variables.sql_mode= sql_mode_backup; return rc; } + + +void Field::print_key_value(String *out, uint length) +{ + if (charset() == &my_charset_bin) + print_key_value_binary(out, ptr, length); + else + val_str(out); +} + + +void Field_string::print_key_value(String *out, uint length) +{ + if (charset() == &my_charset_bin) + { + length= field_charset->cset->lengthsp(field_charset, (const char*) ptr, length); + print_key_value_binary(out, ptr, length); + } + else + val_str(out,out); +} + + +void Field_varstring::print_key_value(String *out, uint length) +{ + if (charset() == &my_charset_bin) + print_key_value_binary(out, get_data(), get_length()); + else + val_str(out,out); +} + + +void Field_blob::print_key_value(String *out, uint length) +{ + uchar *blob; + memcpy(&blob, ptr+packlength, sizeof(uchar*)); + print_key_value_binary(out, blob, get_length()); +} + + +void Field::print_key_value_binary(String *out, const uchar* key, uint length) +{ + size_t dst_len= length*4; + StringBuffer<128> tmp(system_charset_info); + tmp.reserve(dst_len); + + tmp.copy_semi_hex((const char*) key, static_cast<size_t>(length), charset()); + out->append(tmp.c_ptr_safe(), tmp.length(), charset()); +} + + +void Field::print_key_value_helper(String *out, uint length) +{ + THD *thd= get_thd(); + sql_mode_t sql_mode_backup= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + print_key_value(out, length); + thd->variables.sql_mode= sql_mode_backup; +} diff --git a/sql/field.h b/sql/field.h index 8bd7343..35ca939 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1380,6 +1380,9 @@ class Field: public Value_source virtual int set_time() { return 1; } bool set_warning(Sql_condition::enum_warning_level, unsigned int code, int cuted_increment, ulong current_row=0) const; + virtual void print_key_value(String *out, uint length); + virtual void print_key_value_helper(String *out, uint length); + void print_key_value_binary(String *out, const uchar* key, uint length); protected: bool set_warning(unsigned int code, int cuted_increment) const { @@ -3587,6 +3590,7 @@ class Field_string :public Field_longstr { { return charset() == &my_charset_bin ? FALSE : TRUE; } Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type); virtual uint get_key_image(uchar *buff,uint length, imagetype type); + void print_key_value(String *out, uint length); private: int save_field_metadata(uchar *first_byte); }; @@ -3692,6 +3696,8 @@ class Field_varstring :public Field_longstr { uint is_equal(Create_field *new_field); void hash(ulong *nr, ulong *nr2); uint length_size() { return length_bytes; } + void print_key_value(String *out, uint length); + private: int save_field_metadata(uchar *first_byte); }; @@ -4029,6 +4035,7 @@ class Field_blob :public Field_longstr { uint32 char_length() const; uint32 character_octet_length() const; uint is_equal(Create_field *new_field); + void print_key_value(String *out, uint length); friend void TABLE::remember_blob_values(String *blob_storage); friend void TABLE::restore_blob_values(String *blob_storage); @@ -4153,6 +4160,10 @@ class Field_geom :public Field_blob { geometry_type get_geometry_type() { return geom_type; }; static geometry_type geometry_type_merge(geometry_type, geometry_type); uint get_srid() { return srid; } + void print_key_value(String *out, uint length) + { + out->append(STRING_WITH_LEN("unprintable_geometry_value")); + } }; uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields); @@ -4445,6 +4456,10 @@ class Field_bit :public Field { { return get_mm_leaf_int(param, key_part, cond, op, value, true); } + void print_key_value(String *out, uint length) + { + val_int_as_str(out, 1); + } private: virtual size_t do_last_null_byte() const; int save_field_metadata(uchar *first_byte); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7c40a99..3ceb484 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -15785,7 +15785,7 @@ static void append_range_all_keyparts(Json_writer_array *range_trace, uint n_key_parts= param.table->actual_n_key_parts(keyinfo); seq.keyno= idx; seq.real_keyno= param.real_keynr[idx]; - seq.param= ¶m; + seq.param= ¶m; seq.start= keypart; const KEY_PART_INFO *cur_key_part= key_parts + keypart->part; seq_it= seq_if.init((void *) &seq, 0, flags); @@ -15828,12 +15828,10 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part, { // Byte 0 of a nullable key is the null-byte. If set, key is NULL. if (field->real_maybe_null() && *key) + { out->append(STRING_WITH_LEN("NULL")); - else - (field->type() == MYSQL_TYPE_GEOMETRY) - ? out->append(STRING_WITH_LEN("unprintable_geometry_value")) - : out->append(STRING_WITH_LEN("unprintable_blob_value")); - goto next; + goto next; + } } if (field->real_maybe_null()) @@ -15852,28 +15850,12 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part, store_length--; } - /* - Binary data cannot be converted to UTF8 which is what the - optimizer trace expects. If the column is binary, the hex - representation is printed to the trace instead. - */ - if (field->flags & BINARY_FLAG) - { - out->append("0x"); - for (uint i = 0; i < store_length; i++) - { - out->append(_dig_vec_lower[*(key + i) >> 4]); - out->append(_dig_vec_lower[*(key + i) & 0x0F]); - } - goto next; - } - field->set_key_image(key, key_part->length); - if (field->type() == MYSQL_TYPE_BIT) - (void)field->val_int_as_str(&tmp, 1); // may change tmp's charset + field->print_key_value_helper(&tmp, key_part->length); + if (field->charset() == &my_charset_bin) + out->append(tmp.ptr(), tmp.length(), tmp.charset()); else - field->val_str(&tmp); // may change tmp's charset - out->append(tmp.ptr(), tmp.length(), tmp.charset()); + tmp.print(out, system_charset_info); next: if (key + store_length < key_end) diff --git a/sql/sql_string.h b/sql/sql_string.h index fa941c8..d5a795d 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -951,6 +951,11 @@ class String: public Charset, public Binary_string { return !sortcmp(this, other, cs); } + void copy_semi_hex(const char *st, size_t len, CHARSET_INFO *cs) + { + uint length= convert_to_printable(Ptr, len*4, st, len, cs); + str_length+= length; + } };
participants (1)
-
varun