20 #define SHOW_VERSION "9.10"
22 #include "client_priv.h"
23 #include "my_default.h"
27 #include <mysqld_error.h>
30 #include <sslopt-vars.h>
31 #include <welcome_copyright_notice.h>
33 static char * host=0, *opt_password=0, *user=0;
34 static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0;
35 static my_bool tty_password= 0, opt_table_type= 0;
36 static my_bool debug_info_flag= 0, debug_check_flag= 0;
37 static uint my_end_arg= 0;
38 static uint opt_verbose=0;
39 static char *default_charset= (
char*) MYSQL_AUTODETECT_CHARSET_NAME;
40 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
43 static char *shared_memory_base_name=0;
45 static uint opt_protocol=0;
46 static char *opt_bind_addr = NULL;
48 static void get_options(
int *argc,
char ***argv);
49 static uint opt_mysql_port=0;
50 static int list_dbs(
MYSQL *mysql,
const char *wild);
51 static int list_tables(
MYSQL *mysql,
const char *db,
const char *
table);
52 static int list_table_status(
MYSQL *mysql,
const char *db,
const char *
table);
53 static int list_fields(
MYSQL *mysql,
const char *db,
const char *
table,
55 static void print_header(
const char *header,uint head_length,...);
56 static void print_row(
const char *header,uint head_length,...);
57 static void print_trailer(uint length,...);
58 static void print_res_header(
MYSQL_RES *result);
59 static void print_res_top(
MYSQL_RES *result);
60 static void print_res_row(
MYSQL_RES *result,MYSQL_ROW cur);
62 static const char *load_default_groups[]= {
"mysqlshow",
"client",0 };
63 static char * opt_mysql_unix_port=0;
65 int main(
int argc,
char **argv)
68 my_bool first_argument_uses_wildcards=0;
73 my_getopt_use_args_separator= TRUE;
74 if (load_defaults(
"my",load_default_groups,&argc,&argv))
76 my_getopt_use_args_separator= FALSE;
78 get_options(&argc,&argv);
83 char *pos= argv[argc-1], *
to;
84 for (to= pos ; *pos ; pos++, to++)
89 first_argument_uses_wildcards= 1;
93 first_argument_uses_wildcards= 1;
97 first_argument_uses_wildcards= 1;
107 if (first_argument_uses_wildcards)
114 fprintf(stderr,
"%s: Too many arguments\n",my_progname);
119 mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
123 mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
124 opt_ssl_capath, opt_ssl_cipher);
125 mysql_options(&mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
126 mysql_options(&mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
128 mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
129 (
char*)&opt_ssl_verify_server_cert);
132 mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(
char*)&opt_protocol);
134 mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
136 if (shared_memory_base_name)
137 mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
139 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
141 if (opt_plugin_dir && *opt_plugin_dir)
142 mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
144 if (opt_default_auth && *opt_default_auth)
145 mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
147 mysql_options(&mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
148 mysql_options4(&mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
149 "program_name",
"mysqlshow");
150 if (!(mysql_real_connect(&mysql,host,user,opt_password,
151 (first_argument_uses_wildcards) ?
"" :
152 argv[0],opt_mysql_port,opt_mysql_unix_port,
155 fprintf(stderr,
"%s: %s\n",my_progname,mysql_error(&mysql));
161 case 0: error=list_dbs(&mysql,wild);
break;
164 error=list_table_status(&mysql,argv[0],wild);
166 error=list_tables(&mysql,argv[0],wild);
169 if (opt_status && ! wild)
170 error=list_table_status(&mysql,argv[0],argv[1]);
172 error=list_fields(&mysql,argv[0],argv[1],wild);
176 my_free(opt_password);
178 my_free(shared_memory_base_name);
185 static struct my_option my_long_options[] =
187 {
"bind-address", 0,
"IP address to bind to.",
188 (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
189 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
190 {
"character-sets-dir",
'c',
"Directory for character set files.",
191 &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
193 {
"default-character-set", OPT_DEFAULT_CHARSET,
194 "Set the default character set.", &default_charset,
195 &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
197 "Show number of rows per table (may be slow for non-MyISAM tables).",
198 &opt_count, &opt_count, 0, GET_BOOL, NO_ARG, 0, 0, 0,
200 {
"compress",
'C',
"Use compression in server/client protocol.",
201 &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
203 {
"debug",
'#',
"Output debug log. Often this is 'd:t:o,filename'.",
204 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
205 {
"debug-check", OPT_DEBUG_CHECK,
"Check memory and open file usage at exit.",
206 &debug_check_flag, &debug_check_flag, 0,
207 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
208 {
"debug-info", OPT_DEBUG_INFO,
"Print some debug info at exit.",
209 &debug_info_flag, &debug_info_flag,
210 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
211 {
"default_auth", OPT_DEFAULT_AUTH,
212 "Default authentication client-side plugin to use.",
213 &opt_default_auth, &opt_default_auth, 0,
214 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
215 {
"help",
'?',
"Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
217 {
"host",
'h',
"Connect to host.", &host, &host, 0, GET_STR,
218 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
219 {
"status",
'i',
"Shows a lot of extra information about each table.",
220 &opt_status, &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
222 {
"keys",
'k',
"Show keys for table.", &opt_show_keys,
223 &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
225 "Password to use when connecting to server. If password is not given, it's "
226 "solicited on the tty.",
227 0, 0, 0, GET_PASSWORD, OPT_ARG, 0, 0, 0, 0, 0, 0},
228 {
"plugin_dir", OPT_PLUGIN_DIR,
"Directory for client-side plugins.",
229 &opt_plugin_dir, &opt_plugin_dir, 0,
230 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
231 {
"port",
'P',
"Port number to use for connection or 0 for default to, in "
232 "order of preference, my.cnf, $MYSQL_TCP_PORT, "
233 #if MYSQL_PORT_DEFAULT == 0
236 "built-in default (" STRINGIFY_ARG(MYSQL_PORT)
").",
238 &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
241 {
"pipe",
'W',
"Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
242 NO_ARG, 0, 0, 0, 0, 0, 0},
244 {
"protocol", OPT_MYSQL_PROTOCOL,
245 "The protocol to use for connection (tcp, socket, pipe, memory).",
246 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
248 {
"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
249 "Base name of shared memory.", &shared_memory_base_name,
250 &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
253 {
"show-table-type",
't',
"Show table type column.",
254 &opt_table_type, &opt_table_type, 0, GET_BOOL,
255 NO_ARG, 0, 0, 0, 0, 0, 0},
256 {
"socket",
'S',
"The socket file to use for connection.",
257 &opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR,
258 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
259 #include <sslopt-longopts.h>
260 #ifndef DONT_ALLOW_USER_CHANGE
261 {
"user",
'u',
"User for login if not current user.", &user,
262 &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
265 "More verbose output; you can use this multiple times to get even more "
267 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
268 {
"version",
'V',
"Output version information and exit.", 0, 0, 0, GET_NO_ARG,
269 NO_ARG, 0, 0, 0, 0, 0, 0},
270 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
274 static void print_version(
void)
276 printf(
"%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION,
277 MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
281 static void usage(
void)
284 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE(
"2000"));
285 puts(
"Shows the structure of a MySQL database (databases, tables, and columns).\n");
286 printf(
"Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname);
288 If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\
289 what\'s matched by the wildcard is shown.\n\
290 If no database is given then all matching databases are shown.\n\
291 If no table is given, then all matching tables in database are shown.\n\
292 If no column is given, then all matching columns and column types in table\n\
294 print_defaults(
"my",load_default_groups);
295 my_print_help(my_long_options);
296 my_print_variables(my_long_options);
301 get_one_option(
int optid,
const struct my_option *opt __attribute__((unused)),
309 if (argument == disabled_my_option)
310 argument= (
char*)
"";
313 char *start=argument;
314 my_free(opt_password);
315 opt_password=my_strdup(argument,MYF(MY_FAE));
316 while (*argument) *argument++=
'x';
326 opt_protocol = MYSQL_PROTOCOL_PIPE;
329 case OPT_MYSQL_PROTOCOL:
330 opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
334 DBUG_PUSH(argument ? argument :
"d:t:o");
337 #include <sslopt-case.h>
352 get_options(
int *argc,
char ***argv)
356 if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
360 opt_password=get_tty_password(NullS);
370 my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
371 if (debug_check_flag)
372 my_end_arg= MY_CHECK_ERROR;
378 list_dbs(
MYSQL *mysql,
const char *wild)
381 uint length, counter = 0;
383 char tables[NAME_LEN+1], rows[NAME_LEN+1];
387 MYSQL_ROW row= NULL, rrow;
389 if (!(result=mysql_list_dbs(mysql,wild)))
391 fprintf(stderr,
"%s: Cannot list databases: %s\n",my_progname,
402 if (wild && mysql_num_rows(result) == 1)
404 row= mysql_fetch_row(result);
405 if (!my_strcasecmp(&my_charset_latin1, row[0], wild))
407 mysql_free_result(result);
409 return list_table_status(mysql, wild, NULL);
411 return list_tables(mysql, wild, NULL);
416 printf(
"Wildcard: %s\n",wild);
419 length=(uint) strlen(header);
420 field=mysql_fetch_field(result);
421 if (length < field->max_length)
422 length=field->max_length;
425 print_header(header,length,NullS);
426 else if (opt_verbose == 1)
427 print_header(header,length,
"Tables",6,NullS);
429 print_header(header,length,
"Tables",6,
"Total Rows",12,NullS);
432 while (row || (row= mysql_fetch_row(result)))
438 if (!(mysql_select_db(mysql,row[0])))
440 MYSQL_RES *tresult = mysql_list_tables(mysql,(
char*)NULL);
441 if (mysql_affected_rows(mysql) > 0)
443 sprintf(tables,
"%6lu",(ulong) mysql_affected_rows(mysql));
449 while ((trow = mysql_fetch_row(tresult)))
451 sprintf(query,
"SELECT COUNT(*) FROM `%s`",trow[0]);
452 if (!(mysql_query(mysql,query)))
455 if ((rresult = mysql_store_result(mysql)))
457 rrow = mysql_fetch_row(rresult);
458 rowcount += (ulong) strtoull(rrow[0], (
char**) 0, 10);
459 mysql_free_result(rresult);
463 sprintf(rows,
"%12lu",rowcount);
468 sprintf(tables,
"%6d",0);
469 sprintf(rows,
"%12d",0);
471 mysql_free_result(tresult);
475 strmov(tables,
"N/A");
481 print_row(row[0],length,0);
482 else if (opt_verbose == 1)
483 print_row(row[0],length,tables,6,NullS);
485 print_row(row[0],length,tables,6,rows,12,NullS);
490 print_trailer(length,
491 (opt_verbose > 0 ? 6 : 0),
492 (opt_verbose > 1 ? 12 :0),
495 if (counter && opt_verbose)
496 printf(
"%u row%s in set.\n",counter,(counter > 1) ?
"s" :
"");
497 mysql_free_result(result);
503 list_tables(
MYSQL *mysql,
const char *db,
const char *
table)
506 uint head_length, counter = 0;
507 char query[255], rows[NAME_LEN], fields[16];
512 if (mysql_select_db(mysql,db))
514 fprintf(stderr,
"%s: Cannot connect to db %s: %s\n",my_progname,db,
524 mysql_real_escape_string(mysql, rows, table, (
unsigned long)strlen(table));
525 my_snprintf(query,
sizeof(query),
"show%s tables like '%s'",
526 opt_table_type ?
" full" :
"", rows);
529 my_snprintf(query,
sizeof(query),
"show%s tables",
530 opt_table_type ?
" full" :
"");
531 if (mysql_query(mysql, query) || !(result= mysql_store_result(mysql)))
533 fprintf(stderr,
"%s: Cannot list tables in %s: %s\n",my_progname,db,
537 printf(
"Database: %s",db);
539 printf(
" Wildcard: %s",table);
543 head_length=(uint) strlen(header);
544 field=mysql_fetch_field(result);
545 if (head_length < field->max_length)
546 head_length=field->max_length;
551 print_header(header,head_length,
"table_type",10,NullS);
552 else if (opt_verbose == 1)
553 print_header(header,head_length,
"table_type",10,
"Columns",8,NullS);
556 print_header(header,head_length,
"table_type",10,
"Columns",8,
557 "Total Rows",10,NullS);
563 print_header(header,head_length,NullS);
564 else if (opt_verbose == 1)
565 print_header(header,head_length,
"Columns",8,NullS);
567 print_header(header,head_length,
"Columns",8,
"Total Rows",10,NullS);
570 while ((row = mysql_fetch_row(result)))
575 if (!(mysql_select_db(mysql,db)))
577 MYSQL_RES *rresult = mysql_list_fields(mysql,row[0],NULL);
581 strmov(fields,
"N/A");
586 sprintf(fields,
"%8u",(uint) mysql_num_fields(rresult));
587 mysql_free_result(rresult);
592 sprintf(query,
"SELECT COUNT(*) FROM `%s`",row[0]);
593 if (!(mysql_query(mysql,query)))
595 if ((rresult = mysql_store_result(mysql)))
597 rrow = mysql_fetch_row(rresult);
598 rowcount += (
unsigned long) strtoull(rrow[0], (
char**) 0, 10);
599 mysql_free_result(rresult);
601 sprintf(rows,
"%10lu",rowcount);
604 sprintf(rows,
"%10d",0);
610 strmov(fields,
"N/A");
617 print_row(row[0],head_length,row[1],10,NullS);
618 else if (opt_verbose == 1)
619 print_row(row[0],head_length,row[1],10,fields,8,NullS);
621 print_row(row[0],head_length,row[1],10,fields,8,rows,10,NullS);
626 print_row(row[0],head_length,NullS);
627 else if (opt_verbose == 1)
628 print_row(row[0],head_length, fields,8, NullS);
630 print_row(row[0],head_length, fields,8, rows,10, NullS);
634 print_trailer(head_length,
635 (opt_table_type ? 10 : opt_verbose > 0 ? 8 : 0),
636 (opt_table_type ? (opt_verbose > 0 ? 8 : 0)
637 : (opt_verbose > 1 ? 10 :0)),
638 !opt_table_type ? 0 : opt_verbose > 1 ? 10 :0,
641 if (counter && opt_verbose)
642 printf(
"%u row%s in set.\n\n",counter,(counter > 1) ?
"s" :
"");
644 mysql_free_result(result);
650 list_table_status(
MYSQL *mysql,
const char *db,
const char *wild)
652 char query[1024],*end;
656 end=strxmov(query,
"show table status from `",db,
"`",NullS);
658 strxmov(end,
" like '",wild,
"'",NullS);
659 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
661 fprintf(stderr,
"%s: Cannot get status for db: %s, table: %s: %s\n",
662 my_progname,db,wild ? wild :
"",mysql_error(mysql));
663 if (mysql_errno(mysql) == ER_PARSE_ERROR)
664 fprintf(stderr,
"This error probably means that your MySQL server doesn't support the\n\'show table status' command.\n");
668 printf(
"Database: %s",db);
670 printf(
" Wildcard: %s",wild);
673 print_res_header(result);
674 while ((row=mysql_fetch_row(result)))
675 print_res_row(result,row);
676 print_res_top(result);
677 mysql_free_result(result);
687 list_fields(
MYSQL *mysql,
const char *db,
const char *table,
690 char query[1024],*end;
693 ulong UNINIT_VAR(rows);
695 if (mysql_select_db(mysql,db))
697 fprintf(stderr,
"%s: Cannot connect to db: %s: %s\n",my_progname,db,
704 sprintf(query,
"select count(*) from `%s`", table);
705 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
707 fprintf(stderr,
"%s: Cannot get record count for db: %s, table: %s: %s\n",
708 my_progname,db,table,mysql_error(mysql));
711 row= mysql_fetch_row(result);
712 rows= (ulong) strtoull(row[0], (
char**) 0, 10);
713 mysql_free_result(result);
716 end=strmov(strmov(strmov(query,
"show /*!32332 FULL */ columns from `"),table),
"`");
718 strxmov(end,
" like '",wild,
"'",NullS);
719 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
721 fprintf(stderr,
"%s: Cannot list columns in db: %s, table: %s: %s\n",
722 my_progname,db,table,mysql_error(mysql));
726 printf(
"Database: %s Table: %s", db, table);
728 printf(
" Rows: %lu", rows);
730 printf(
" Wildcard: %s",wild);
733 print_res_header(result);
734 while ((row=mysql_fetch_row(result)))
735 print_res_row(result,row);
736 print_res_top(result);
739 end=strmov(strmov(strmov(query,
"show keys from `"),table),
"`");
740 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
742 fprintf(stderr,
"%s: Cannot list keys in db: %s, table: %s: %s\n",
743 my_progname,db,table,mysql_error(mysql));
746 if (mysql_num_rows(result))
748 print_res_header(result);
749 while ((row=mysql_fetch_row(result)))
750 print_res_row(result,row);
751 print_res_top(result);
754 puts(
"Table has no keys");
756 mysql_free_result(result);
766 print_header(
const char *header,uint head_length,...)
769 uint length,
i,str_length,pre_space;
772 va_start(args,head_length);
774 field=header; length=head_length;
777 for (i=0 ; i < length+2 ; i++)
780 if (!(field=va_arg(args,
char *)))
782 length=va_arg(args,uint);
787 va_start(args,head_length);
788 field=header; length=head_length;
792 str_length=(uint) strlen(field);
793 if (str_length > length)
795 pre_space=(uint) (((
int) length-(int) str_length)/2)+1;
796 for (i=0 ; i < pre_space ; i++)
798 for (i = 0 ; i < str_length ; i++)
800 length=length+2-str_length-pre_space;
801 for (i=0 ; i < length ; i++)
804 if (!(field=va_arg(args,
char *)))
806 length=va_arg(args,uint);
811 va_start(args,head_length);
813 field=header; length=head_length;
816 for (i=0 ; i < length+2 ; i++)
819 if (!(field=va_arg(args,
char *)))
821 length=va_arg(args,uint);
829 print_row(
const char *header,uint head_length,...)
833 uint
i,length,field_length;
835 va_start(args,head_length);
836 field=header; length=head_length;
842 field_length=(uint) strlen(field);
843 for (i=field_length ; i <= length ; i++)
845 if (!(field=va_arg(args,
char *)))
847 length=va_arg(args,uint);
856 print_trailer(uint head_length,...)
861 va_start(args,head_length);
866 for (i=0 ; i < length+2 ; i++)
869 if (!(length=va_arg(args,uint)))
877 static void print_res_header(
MYSQL_RES *result)
881 print_res_top(result);
882 mysql_field_seek(result,0);
884 while ((field = mysql_fetch_field(result)))
886 printf(
" %-*s|",(
int) field->max_length+1,field->name);
889 print_res_top(result);
893 static void print_res_top(
MYSQL_RES *result)
899 mysql_field_seek(result,0);
900 while((field = mysql_fetch_field(result)))
902 if ((length=(uint) strlen(field->name)) > field->max_length)
903 field->max_length=length;
905 length=field->max_length;
906 for (i=length+2 ; i--> 0 ; )
914 static void print_res_row(
MYSQL_RES *result,MYSQL_ROW cur)
919 mysql_field_seek(result,0);
920 for (i=0 ; i < mysql_num_fields(result); i++)
922 field = mysql_fetch_field(result);
923 length=field->max_length;
924 printf(
" %-*s|",length+1,cur[i] ? (
char*) cur[i] :
"");