mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Bug#25340722 - PRINT BINARY DATA AS HEX IN THE MYSQL
CLIENT (CONTRIBUTION) DESCRIPTION: ============ Binary data should be printed as hex in the mysql client when the option binary-as-hex is enabled. ANALYSIS: ========= The fix deals only with mysql command line client. It does not change, at all, the data sent to the applications. Printing binary data as hex also allows to use the output in the where clause of the query. FIX: ==== A new option 'binary-as-hex' is introduced to print the binary contents as hex in the mysql client. The option is disabled by default. When the option is enabled, we convert the binary data to hex before printing the contents irrespective of whether it is in tabular, xml or html format.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user