summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun <varun.gupta@mariadb.com>2019-06-10 15:56:36 +0530
committerVarun <varun.gupta@mariadb.com>2019-06-11 15:44:58 +0530
commita0cb7551a4467fbce74f3ced78549bf92866c11f (patch)
treea06c13af6dd33cf207d636276ca213e106e95299
parent40ff8019d2a00071f533bb3210b4d3a552e95bc8 (diff)
downloadmariadb-git-a0cb7551a4467fbce74f3ced78549bf92866c11f.tar.gz
MDEV-18880: Optimizer trace prints date in hexadecimal
Introduced 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.
-rw-r--r--mysql-test/main/opt_trace.result298
-rw-r--r--mysql-test/main/opt_trace.test54
-rw-r--r--mysql-test/main/opt_trace_ucs2.result54
-rw-r--r--mysql-test/main/opt_trace_ucs2.test10
-rw-r--r--sql/field.cc55
-rw-r--r--sql/field.h14
-rw-r--r--sql/opt_range.cc32
-rw-r--r--sql/sql_string.cc12
-rw-r--r--sql/sql_string.h3
9 files changed, 501 insertions, 31 deletions
diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result
index 3e4b7fe6e8a..82a2196545d 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,290 @@ 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='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='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='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='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= '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='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 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": 2,
+ "cost": 3.6324,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+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 981a53ac1ad..916b9313ca6 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -444,4 +444,58 @@ 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='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='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='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='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= '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='ab\n';
+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/mysql-test/main/opt_trace_ucs2.result b/mysql-test/main/opt_trace_ucs2.result
new file mode 100644
index 00000000000..306fdbf94ad
--- /dev/null
+++ b/mysql-test/main/opt_trace_ucs2.result
@@ -0,0 +1,54 @@
+create or replace table t1 (col1 char(10) character set ucs2, filler char(100), key(col1)) ;
+insert into t1 values ('a', 'a');
+insert into t1 values ('a', 'a');
+set optimizer_trace=1;
+explain format=json select * from t1 force index(col1) where col1 >='a';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["col1"],
+ "key": "col1",
+ "key_length": "21",
+ "used_key_parts": ["col1"],
+ "rows": 2,
+ "filtered": 100,
+ "index_condition": "t1.col1 >= 'a'"
+ }
+ }
+}
+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": "col1",
+ "ranges":
+ [
+ "(a) <= (col1)"
+ ],
+ "rowid_ordered": false,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 2,
+ "cost": 3.7609,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
diff --git a/mysql-test/main/opt_trace_ucs2.test b/mysql-test/main/opt_trace_ucs2.test
new file mode 100644
index 00000000000..827dc403d58
--- /dev/null
+++ b/mysql-test/main/opt_trace_ucs2.test
@@ -0,0 +1,10 @@
+--source include/not_embedded.inc
+--source include/have_ucs2.inc
+
+create or replace table t1 (col1 char(10) character set ucs2, filler char(100), key(col1)) ;
+insert into t1 values ('a', 'a');
+insert into t1 values ('a', 'a');
+set optimizer_trace=1;
+explain format=json select * from t1 force index(col1) where col1 >='a';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
diff --git a/sql/field.cc b/sql/field.cc
index a671195ba2b..46e33dc8526 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11242,3 +11242,58 @@ 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, uint32 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, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ {
+ size_t len= field_charset->cset->lengthsp(field_charset, (const char*) ptr, length);
+ print_key_value_binary(out, ptr, static_cast<uint32>(len));
+ }
+ else
+ {
+ THD *thd= get_thd();
+ sql_mode_t sql_mode_backup= thd->variables.sql_mode;
+ thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
+ val_str(out,out);
+ thd->variables.sql_mode= sql_mode_backup;
+ }
+}
+
+
+void Field_varstring::print_key_value(String *out, uint32 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, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ {
+ uchar *blob;
+ memcpy(&blob, ptr+packlength, sizeof(uchar*));
+ print_key_value_binary(out, blob, get_length());
+ }
+ else
+ val_str(out, out);
+}
+
+
+void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
+{
+ out->append_semi_hex((const char*)key, length, charset());
+} \ No newline at end of file
diff --git a/sql/field.h b/sql/field.h
index ceb4a8bb93f..8b65f2e95e4 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1383,6 +1383,8 @@ public:
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, uint32 length);
+ void print_key_value_binary(String *out, const uchar* key, uint32 length);
protected:
bool set_warning(unsigned int code, int cuted_increment) const
{
@@ -3592,6 +3594,7 @@ public:
{ 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, uint32 length);
private:
int save_field_metadata(uchar *first_byte);
};
@@ -3697,6 +3700,7 @@ public:
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, uint32 length);
private:
int save_field_metadata(uchar *first_byte);
};
@@ -4035,6 +4039,7 @@ public:
uint32 char_length() const;
uint32 character_octet_length() const;
uint is_equal(Create_field *new_field);
+ void print_key_value(String *out, uint32 length);
friend void TABLE::remember_blob_values(String *blob_storage);
friend void TABLE::restore_blob_values(String *blob_storage);
@@ -4159,6 +4164,10 @@ public:
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, uint32 length)
+ {
+ out->append(STRING_WITH_LEN("unprintable_geometry_value"));
+ }
};
uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields);
@@ -4466,6 +4475,11 @@ public:
{
return get_mm_leaf_int(param, key_part, cond, op, value, true);
}
+ void print_key_value(String *out, uint32 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 bff5bd371b6..d0c4ed2ffbc 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -15835,12 +15835,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())
@@ -15859,28 +15857,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(&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.cc b/sql/sql_string.cc
index 410f52a8c74..1b567ecb325 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1196,3 +1196,15 @@ uint convert_to_printable(char *to, size_t to_len,
*t= '\0';
return (uint) (t - to);
}
+
+
+bool String::append_semi_hex(const char *s, uint len, CHARSET_INFO *cs)
+{
+ size_t dst_len= len * 4 + 1; //extra length for the '\0' character
+ if (reserve(dst_len))
+ return true;
+ uint nbytes= convert_to_printable(Ptr + str_length, dst_len, s, len, cs);
+ DBUG_ASSERT((ulonglong) str_length + nbytes < UINT_MAX32);
+ str_length+= nbytes;
+ return false;
+}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index caefee7ec09..d8edf5e81f0 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -674,6 +674,7 @@ public:
int reserve(size_t space_needed)
{
+ DBUG_ASSERT((ulonglong) str_length + space_needed < UINT_MAX32);
return realloc(str_length + space_needed);
}
int reserve(size_t space_needed, size_t grow_by);
@@ -959,6 +960,8 @@ public:
{
return !sortcmp(this, other, cs);
}
+private:
+ bool append_semi_hex(const char *s, uint len, CHARSET_INFO *cs);
};