diff options
author | unknown <cmiller@zippy.(none)> | 2006-03-03 16:26:38 -0500 |
---|---|---|
committer | unknown <cmiller@zippy.(none)> | 2006-03-03 16:26:38 -0500 |
commit | aa0611127a6f8ca3742d59338aec3189fc71b6da (patch) | |
tree | df16c9d0887285cd9c8c342eb3670d4e177ad929 | |
parent | 58bfde2f497d6ba734192083f50b51a54a399c5b (diff) | |
download | mariadb-git-aa0611127a6f8ca3742d59338aec3189fc71b6da.tar.gz |
Bug#16859 involves truncating column data at NUL characters. Instead, the
client will now substitute spaces for NULs, so that the grid isn't messed up
due to silently consumed NULs and that the full field is shown.
client/mysql.cc:
For non-numbers, print each character at a time, instead of using the
fprintf() facility, which interprets an array of chars as a C string, which
is necessarily NUL terminated. We mustn't terminate on NULs, and since we
know the length of the data, we needn't.
mysql-test/r/mysql.result:
Add a test.
mysql-test/t/mysql.test:
Add a test.
-rw-r--r-- | client/mysql.cc | 55 | ||||
-rw-r--r-- | mysql-test/r/mysql.result | 7 | ||||
-rw-r--r-- | mysql-test/t/mysql.test | 5 |
3 files changed, 59 insertions, 8 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 8d578aac58b..eb6970691bb 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -185,6 +185,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...); void tee_fputs(const char *s, FILE *file); void tee_puts(const char *s, FILE *file); void tee_putc(int c, FILE *file); +static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width); /* The names of functions that actually do the manipulation. */ static int get_options(int argc,char **argv); static int com_quit(String *str,char*), @@ -2308,20 +2309,29 @@ print_table_data(MYSQL_RES *result) for (uint off= 0; off < mysql_num_fields(result); off++) { const char *str= cur[off] ? cur[off] : "NULL"; + uint currlength; + uint maxlength; + uint numcells; + field= mysql_fetch_field(result); - uint maxlength= field->max_length; + maxlength= field->max_length; + currlength= (uint) lengths[off]; + numcells= charset_info->cset->numcells(charset_info, + str, str + currlength); if (maxlength > MAX_COLUMN_LENGTH) { - tee_fputs(str, PAGER); - tee_fputs(" |", PAGER); + tee_print_sized_data(str, currlength, maxlength); + tee_fputs(" |", PAGER); } else { - uint currlength= (uint) lengths[off]; - uint numcells= charset_info->cset->numcells(charset_info, - str, str + currlength); - tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", - maxlength + currlength - numcells, str); + if (num_flag[off] != 0) + tee_fprintf(PAGER, " %-*s|", maxlength + currlength - numcells, str); + else + { + tee_print_sized_data(str, currlength, maxlength); + tee_fputs(" |", PAGER); + } } } (void) tee_fputs("\n", PAGER); @@ -2332,6 +2342,35 @@ print_table_data(MYSQL_RES *result) static void +tee_print_sized_data(const char *data, unsigned int length, unsigned int width) +{ + /* + 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 + least my) console driver, and that messes up the pretty table + grid. (The \0 is also the reason we can't use fprintf() .) + */ + unsigned int i; + const char *p; + + tee_putc(' ', PAGER); + + for (i= 0, p= data; i < length; i+= 1, p+= 1) + { + if (*p == '\0') + tee_putc((int)' ', PAGER); + else + tee_putc((int)*p, PAGER); + } + + i+= 1; + for ( ; i < width; i+= 1) + tee_putc((int)' ', PAGER); +} + + + +static void print_table_data_html(MYSQL_RES *result) { MYSQL_ROW cur; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 611813d9c3f..57067bea36b 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -69,3 +69,10 @@ c_cp932 ソ ソ ソ ++----------------------+------------+--------+ +| concat('>',col1,'<') | col2 | col3 | ++----------------------+------------+--------+ +| >a < | b | 123421 | +| >a < | 0123456789 | 4 | +| >abcd< | | 4 | ++----------------------+------------+--------+ diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 4712e7e8266..dbf65845e6a 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -56,3 +56,8 @@ drop table t1; --exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set character_set_client= cp932; select 'ƒ\'" --exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select 'ƒ\'" --exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select 'ƒ\'" + +# +# 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 |