mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug#18265: mysql client: No longer right-justifies numeric columns
Also fixes a new bug for which "NULL" wasn't printed (because the data it represents has length zero). (Discovered my Paul DuBois.) client/mysql.cc: Cleaned up the interactive-session table-printing function. - No longer rely on the length of the data to pad column boundries. - Be smarter about how we detect if the column is NULL. - Document how multibyte characters affect the output printing. - Use more descriptive variable names. More importantly, (re-)add these features that were crippled in an earlier change: - Print "NULL". - Right-justify numbers. mysql-test/r/mysql.result: Updated old result and added new case. mysql-test/t/mysql.test: Added new test case.
This commit is contained in:
@ -185,7 +185,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...);
|
|||||||
void tee_fputs(const char *s, FILE *file);
|
void tee_fputs(const char *s, FILE *file);
|
||||||
void tee_puts(const char *s, FILE *file);
|
void tee_puts(const char *s, FILE *file);
|
||||||
void tee_putc(int c, FILE *file);
|
void tee_putc(int c, FILE *file);
|
||||||
static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width);
|
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
|
||||||
/* The names of functions that actually do the manipulation. */
|
/* The names of functions that actually do the manipulation. */
|
||||||
static int get_options(int argc,char **argv);
|
static int get_options(int argc,char **argv);
|
||||||
static int com_quit(String *str,char*),
|
static int com_quit(String *str,char*),
|
||||||
@ -2315,32 +2315,49 @@ print_table_data(MYSQL_RES *result)
|
|||||||
mysql_field_seek(result, 0);
|
mysql_field_seek(result, 0);
|
||||||
for (uint off= 0; off < mysql_num_fields(result); off++)
|
for (uint off= 0; off < mysql_num_fields(result); off++)
|
||||||
{
|
{
|
||||||
const char *str= cur[off] ? cur[off] : "NULL";
|
const char *buffer;
|
||||||
uint currlength;
|
uint data_length;
|
||||||
uint maxlength;
|
uint field_max_length;
|
||||||
uint numcells;
|
bool right_justified;
|
||||||
|
uint visible_length;
|
||||||
|
uint extra_padding;
|
||||||
|
|
||||||
|
if (lengths[off] == 0)
|
||||||
|
{
|
||||||
|
buffer= "NULL";
|
||||||
|
data_length= 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer= cur[off];
|
||||||
|
data_length= (uint) lengths[off];
|
||||||
|
}
|
||||||
|
|
||||||
field= mysql_fetch_field(result);
|
field= mysql_fetch_field(result);
|
||||||
maxlength= field->max_length;
|
field_max_length= field->max_length;
|
||||||
currlength= (uint) lengths[off];
|
|
||||||
numcells= charset_info->cset->numcells(charset_info,
|
/*
|
||||||
str, str + currlength);
|
How many text cells on the screen will this string span? If it contains
|
||||||
if (maxlength > MAX_COLUMN_LENGTH)
|
multibyte characters, then the number of characters we occupy on screen
|
||||||
{
|
will be fewer than the number of bytes we occupy in memory.
|
||||||
tee_print_sized_data(str, currlength, maxlength);
|
|
||||||
tee_fputs(" |", PAGER);
|
We need to find how much screen real-estate we will occupy to know how
|
||||||
}
|
many extra padding-characters we should send with the printing function.
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (num_flag[off] != 0)
|
if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
|
||||||
tee_fprintf(PAGER, " %-*s|", maxlength + currlength - numcells, str);
|
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
|
||||||
else
|
else
|
||||||
{
|
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
|
||||||
tee_print_sized_data(str, currlength, maxlength);
|
}
|
||||||
tee_fputs(" | ", PAGER);
|
tee_fputs(" | ", PAGER);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
(void) tee_fputs("\n", PAGER);
|
(void) tee_fputs("\n", PAGER);
|
||||||
}
|
}
|
||||||
tee_puts((char*) separator.ptr(), PAGER);
|
tee_puts((char*) separator.ptr(), PAGER);
|
||||||
@ -2349,10 +2366,9 @@ print_table_data(MYSQL_RES *result)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
|
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
It is not a number, so print each character justified to the left.
|
|
||||||
For '\0's print ASCII spaces instead, as '\0' is eaten by (at
|
For '\0's print ASCII spaces instead, as '\0' is eaten by (at
|
||||||
least my) console driver, and that messes up the pretty table
|
least my) console driver, and that messes up the pretty table
|
||||||
grid. (The \0 is also the reason we can't use fprintf() .)
|
grid. (The \0 is also the reason we can't use fprintf() .)
|
||||||
@ -2360,9 +2376,14 @@ tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
tee_putc(' ', PAGER);
|
total_bytes_to_send -= 1;
|
||||||
|
/* Off by one, perhaps mistakenly accounting for a terminating NUL. */
|
||||||
|
|
||||||
for (i= 0, p= data; i < length; i+= 1, p+= 1)
|
if (right_justified)
|
||||||
|
for (i= 0; i < (total_bytes_to_send - data_length); i++)
|
||||||
|
tee_putc((int)' ', PAGER);
|
||||||
|
|
||||||
|
for (i= 0, p= data; i < data_length; i+= 1, p+= 1)
|
||||||
{
|
{
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
tee_putc((int)' ', PAGER);
|
tee_putc((int)' ', PAGER);
|
||||||
@ -2370,8 +2391,8 @@ tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
|
|||||||
tee_putc((int)*p, PAGER);
|
tee_putc((int)*p, PAGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
i+= 1;
|
if (! right_justified)
|
||||||
for ( ; i < width; i+= 1)
|
for (i= 0; i < (total_bytes_to_send - data_length); i++)
|
||||||
tee_putc((int)' ', PAGER);
|
tee_putc((int)' ', PAGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3361,7 +3382,7 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
|
|||||||
if (info_type == INFO_ERROR)
|
if (info_type == INFO_ERROR)
|
||||||
{
|
{
|
||||||
if (!opt_nobeep)
|
if (!opt_nobeep)
|
||||||
putchar('\007'); /* This should make a bell */
|
putchar('\a'); /* This should make a bell */
|
||||||
vidattr(A_STANDOUT);
|
vidattr(A_STANDOUT);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -74,5 +74,14 @@ c_cp932
|
|||||||
+----------------------+------------+--------+
|
+----------------------+------------+--------+
|
||||||
| >a < | b | 123421 |
|
| >a < | b | 123421 |
|
||||||
| >a < | 0123456789 | 4 |
|
| >a < | 0123456789 | 4 |
|
||||||
| >abcd< | | 4 |
|
| >abcd< | NULL | 4 |
|
||||||
+----------------------+------------+--------+
|
+----------------------+------------+--------+
|
||||||
|
+------+------+---------------------------+
|
||||||
|
| i | j | k |
|
||||||
|
+------+------+---------------------------+
|
||||||
|
| 1 | NULL | NULL |
|
||||||
|
| NULL | NULL | <-----------------------> |
|
||||||
|
| NULL | NULL | <----- |
|
||||||
|
| NULL | NULL | Τη γλώσσα |
|
||||||
|
| NULL | NULL | ᛖᚴ ᚷᛖᛏ |
|
||||||
|
+------+------+---------------------------+
|
||||||
|
@ -61,3 +61,9 @@ drop table t1;
|
|||||||
# Bug#16859 -- NULLs in columns must not truncate data as if a C-language "string".
|
# Bug#16859 -- NULLs in columns must not truncate data as if a C-language "string".
|
||||||
#
|
#
|
||||||
--exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1
|
--exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#18265 -- mysql client: No longer right-justifies numeric columns
|
||||||
|
#
|
||||||
|
--exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1;"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user