summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql.cc88
-rw-r--r--mysql-test/r/binary_to_hex.result117
-rw-r--r--mysql-test/t/binary_to_hex.test76
3 files changed, 268 insertions, 13 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 2269563814c..6e6dc4971ac 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -142,7 +142,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
default_pager_set= 0, opt_sigint_ignore= 0,
auto_vertical_output= 0,
show_warnings= 0, executing_query= 0, interrupted_query= 0,
- ignore_spaces= 0;
+ ignore_spaces= 0, opt_binhex= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
@@ -1392,6 +1392,8 @@ static struct my_option my_long_options[] =
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"binary-as-hex", 'b', "Print binary data as hex", &opt_binhex, &opt_binhex,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -3101,7 +3103,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
- else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
+ else if (vertical || (auto_vertical_output &&
+ (terminal_width < get_result_width(result))))
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
print_tab_data(result);
@@ -3320,6 +3323,41 @@ print_field_types(MYSQL_RES *result)
}
+/* Used to determine if we should invoke print_as_hex for this field */
+
+static bool
+is_binary_field(MYSQL_FIELD *field)
+{
+ if ((field->charsetnr == 63) &&
+ (field->type == MYSQL_TYPE_BIT ||
+ field->type == MYSQL_TYPE_BLOB ||
+ field->type == MYSQL_TYPE_LONG_BLOB ||
+ field->type == MYSQL_TYPE_MEDIUM_BLOB ||
+ field->type == MYSQL_TYPE_TINY_BLOB ||
+ field->type == MYSQL_TYPE_VAR_STRING ||
+ field->type == MYSQL_TYPE_STRING ||
+ field->type == MYSQL_TYPE_VARCHAR ||
+ field->type == MYSQL_TYPE_GEOMETRY))
+ return 1;
+ return 0;
+}
+
+
+/* Print binary value as hex literal (0x ...) */
+
+static void
+print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send)
+{
+ const char *ptr= str, *end= ptr+len;
+ ulong i;
+ fprintf(output_file, "0x");
+ for(; ptr < end; ptr++)
+ fprintf(output_file, "%02X", *((uchar*)ptr));
+ for (i= 2*len+2; i < total_bytes_to_send; i++)
+ tee_putc((int)' ', output_file);
+}
+
+
static void
print_table_data(MYSQL_RES *result)
{
@@ -3346,6 +3384,8 @@ print_table_data(MYSQL_RES *result)
length=max(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
+ if (opt_binhex && is_binary_field(field))
+ length= 2 + length * 2;
field->max_length=length;
separator.fill(separator.length()+length+2,'-');
separator.append('+');
@@ -3415,7 +3455,9 @@ print_table_data(MYSQL_RES *result)
visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
extra_padding= data_length - visible_length;
- if (field_max_length > MAX_COLUMN_LENGTH)
+ if (opt_binhex && is_binary_field(field))
+ print_as_hex(PAGER, cur[off], lengths[off], field_max_length);
+ else if (field_max_length > MAX_COLUMN_LENGTH)
tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
else
{
@@ -3548,11 +3590,15 @@ print_table_data_html(MYSQL_RES *result)
if (interrupted_query)
break;
ulong *lengths=mysql_fetch_lengths(result);
+ field= mysql_fetch_fields(result);
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
(void) tee_fputs("<TD>", PAGER);
- xmlencode_print(cur[i], lengths[i]);
+ if (opt_binhex && is_binary_field(&field[i]))
+ print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
+ else
+ xmlencode_print(cur[i], lengths[i]);
(void) tee_fputs("</TD>", PAGER);
}
(void) tee_fputs("</TR>", PAGER);
@@ -3588,7 +3634,10 @@ print_table_data_xml(MYSQL_RES *result)
if (cur[i])
{
tee_fprintf(PAGER, "\">");
- xmlencode_print(cur[i], lengths[i]);
+ if (opt_binhex && is_binary_field(&fields[i]))
+ print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
+ else
+ xmlencode_print(cur[i], lengths[i]);
tee_fprintf(PAGER, "</field>\n");
}
else
@@ -3635,23 +3684,28 @@ print_table_data_vertically(MYSQL_RES *result)
{
unsigned int i;
const char *p;
-
+ if (opt_binhex && is_binary_field(field))
+ fprintf(PAGER, "0x");
for (i= 0, p= cur[off]; i < lengths[off]; i+= 1, p+= 1)
{
- if (*p == '\0')
- tee_putc((int)' ', PAGER);
+ if (opt_binhex && is_binary_field(field))
+ fprintf(PAGER, "%02X", *((uchar*)p));
else
- tee_putc((int)*p, PAGER);
+ {
+ if (*p == '\0')
+ tee_putc((int)' ', PAGER);
+ else
+ tee_putc((int)*p, PAGER);
+ }
}
tee_putc('\n', PAGER);
}
- else
+ else
tee_fprintf(PAGER, "NULL\n");
}
}
}
-
/* print_warnings should be called right after executing a statement */
static void print_warnings()
@@ -3788,11 +3842,19 @@ print_tab_data(MYSQL_RES *result)
while ((cur = mysql_fetch_row(result)))
{
lengths=mysql_fetch_lengths(result);
- safe_put_field(cur[0],lengths[0]);
+ field= mysql_fetch_fields(result);
+ if (opt_binhex && is_binary_field(&field[0]))
+ print_as_hex(PAGER, cur[0], lengths[0], lengths[0]);
+ else
+ safe_put_field(cur[0],lengths[0]);
+
for (uint off=1 ; off < mysql_num_fields(result); off++)
{
(void) tee_fputs("\t", PAGER);
- safe_put_field(cur[off], lengths[off]);
+ if (opt_binhex && field && is_binary_field(&field[off]))
+ print_as_hex(PAGER, cur[off], lengths[off], lengths[off]);
+ else
+ safe_put_field(cur[off], lengths[off]);
}
(void) tee_fputs("\n", PAGER);
}
diff --git a/mysql-test/r/binary_to_hex.result b/mysql-test/r/binary_to_hex.result
new file mode 100644
index 00000000000..a6b68834da8
--- /dev/null
+++ b/mysql-test/r/binary_to_hex.result
@@ -0,0 +1,117 @@
+USE test;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (c1 TINYBLOB,
+c2 BLOB,
+c3 MEDIUMBLOB,
+c4 LONGBLOB,
+c5 TEXT,
+c6 BIT(1),
+c7 CHAR,
+c8 VARCHAR(10),
+c9 GEOMETRY) CHARACTER SET = binary;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyblob,
+ `c2` blob,
+ `c3` mediumblob,
+ `c4` longblob,
+ `c5` blob,
+ `c6` bit(1) DEFAULT NULL,
+ `c7` binary(1) DEFAULT NULL,
+ `c8` varbinary(10) DEFAULT NULL,
+ `c9` geometry DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=binary
+INSERT INTO t1 VALUES ('tinyblob-text readable', 'blob-text readable',
+'mediumblob-text readable', 'longblob-text readable',
+'text readable', b'1', 'c', 'variable',
+POINT(1, 1));
+CREATE TABLE t2(id int, `col1` binary(10),`col2` blob);
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) DEFAULT NULL,
+ `col1` binary(10) DEFAULT NULL,
+ `col2` blob
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t2 VALUES (1, X'AB1234', X'123ABC'), (2, X'DE1234', X'123DEF');
+#Print the table contents when binary-as-hex option is off.
+SELECT * FROM t1;
+c1 c2 c3 c4 c5 c6 c7 c8 c9
+tinyblob-text readable blob-text readable mediumblob-text readable longblob-text readable text readable # c variable #
+SELECT * FROM t2;
+id col1 col2
+1 # #
+2 # #
+#Print the table contents after turning on the binary-as-hex option
+
+#Print the table contents in tab format
+
+c1 c2 c3 c4 c5 c6 c7 c8 c9
+0x74696E79626C6F622D74657874207265616461626C65 0x626C6F622D74657874207265616461626C65 0x6D656469756D626C6F622D74657874207265616461626C65 0x6C6F6E67626C6F622D74657874207265616461626C65 0x74657874207265616461626C65 0x01 0x63 0x7661726961626C65 0x000000000101000000000000000000F03F000000000000F03F
+id col1 col2
+1 0xAB123400000000000000 0x123ABC
+2 0xDE123400000000000000 0x123DEF
+
+#Print the table contents in table format
+
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
+| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 |
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
+| 0x74696E79626C6F622D74657874207265616461626C65 | 0x626C6F622D74657874207265616461626C65 | 0x6D656469756D626C6F622D74657874207265616461626C65 | 0x6C6F6E67626C6F622D74657874207265616461626C65 | 0x74657874207265616461626C65 | 0x01 | 0x63 | 0x7661726961626C65 | 0x000000000101000000000000000000F03F000000000000F03F |
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
++------+------------------------+------------+
+| id | col1 | col2 |
++------+------------------------+------------+
+| 1 | 0xAB123400000000000000 | 0x123ABC |
++------+------------------------+------------+
+
+#Print the table contents vertically
+
+*************************** 1. row ***************************
+c1: 0x74696E79626C6F622D74657874207265616461626C65
+c2: 0x626C6F622D74657874207265616461626C65
+c3: 0x6D656469756D626C6F622D74657874207265616461626C65
+c4: 0x6C6F6E67626C6F622D74657874207265616461626C65
+c5: 0x74657874207265616461626C65
+c6: 0x01
+c7: 0x63
+c8: 0x7661726961626C65
+c9: 0x000000000101000000000000000000F03F000000000000F03F
+
+#Print the table contents in xml format
+
+<?xml version="1.0"?>
+
+<resultset statement="SELECT * FROM t1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <row>
+ <field name="c1">0x74696E79626C6F622D74657874207265616461626C65</field>
+ <field name="c2">0x626C6F622D74657874207265616461626C65</field>
+ <field name="c3">0x6D656469756D626C6F622D74657874207265616461626C65</field>
+ <field name="c4">0x6C6F6E67626C6F622D74657874207265616461626C65</field>
+ <field name="c5">0x74657874207265616461626C65</field>
+ <field name="c6">0x01</field>
+ <field name="c7">0x63</field>
+ <field name="c8">0x7661726961626C65</field>
+ <field name="c9">0x000000000101000000000000000000F03F000000000000F03F</field>
+ </row>
+</resultset>
+<?xml version="1.0"?>
+
+<resultset statement="SELECT * FROM t2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <row>
+ <field name="id">1</field>
+ <field name="col1">0xAB123400000000000000</field>
+ <field name="col2">0x123ABC</field>
+ </row>
+
+ <row>
+ <field name="id">2</field>
+ <field name="col1">0xDE123400000000000000</field>
+ <field name="col2">0x123DEF</field>
+ </row>
+</resultset>
+
+#Print the table contents in html format
+
+<TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2;
diff --git a/mysql-test/t/binary_to_hex.test b/mysql-test/t/binary_to_hex.test
new file mode 100644
index 00000000000..8312a246d0c
--- /dev/null
+++ b/mysql-test/t/binary_to_hex.test
@@ -0,0 +1,76 @@
+# === Purpose ===
+# The purpose of this test case is to make
+# sure that the binary data in tables is printed
+# as hex when the option binary-as-hex is enabled.
+#
+# === Related bugs and/or worklogs ===
+# Bug #25340722 - PRINT BINARY DATA AS HEX IN THE MYSQL
+# CLIENT (CONTRIBUTION)
+#
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+--source include/not_embedded.inc
+
+USE test;
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (c1 TINYBLOB,
+ c2 BLOB,
+ c3 MEDIUMBLOB,
+ c4 LONGBLOB,
+ c5 TEXT,
+ c6 BIT(1),
+ c7 CHAR,
+ c8 VARCHAR(10),
+ c9 GEOMETRY) CHARACTER SET = binary;
+
+SHOW CREATE TABLE t1;
+
+INSERT INTO t1 VALUES ('tinyblob-text readable', 'blob-text readable',
+ 'mediumblob-text readable', 'longblob-text readable',
+ 'text readable', b'1', 'c', 'variable',
+ POINT(1, 1));
+
+CREATE TABLE t2(id int, `col1` binary(10),`col2` blob);
+
+SHOW CREATE TABLE t2;
+
+INSERT INTO t2 VALUES (1, X'AB1234', X'123ABC'), (2, X'DE1234', X'123DEF');
+
+--echo #Print the table contents when binary-as-hex option is off.
+--replace_column 6 # 9 #
+SELECT * FROM t1;
+
+--replace_column 2 # 3 #
+SELECT * FROM t2;
+
+--echo #Print the table contents after turning on the binary-as-hex option
+--echo
+--echo #Print the table contents in tab format
+--echo
+--exec $MYSQL test --binary-as-hex -e "SELECT * FROM t1; SELECT * FROM t2;"
+--echo
+--echo #Print the table contents in table format
+--echo
+--exec $MYSQL test --binary-as-hex --table -e "SELECT * FROM t1; SELECT * FROM t2 WHERE col2=0x123ABC;"
+--echo
+--echo #Print the table contents vertically
+--echo
+--exec $MYSQL test --binary-as-hex --vertical -e "SELECT * FROM t1;"
+--echo
+--echo #Print the table contents in xml format
+--echo
+--exec $MYSQL test --binary-as-hex --xml -e "SELECT * FROM t1; SELECT * FROM t2;"
+--echo
+--echo #Print the table contents in html format
+--echo
+--exec $MYSQL test --binary-as-hex --html -e "SELECT * FROM t1; SELECT * FROM t2;"
+
+#Cleanup
+DROP TABLE t1, t2;
+
+# Wait till all disconnects are completed
+ --source include/wait_until_count_sessions.inc