1
/* Copyright (C) 2000-2008 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
* Commands compatible with mSQL by David J. Hughes
20
* Michael 'Monty' Widenius
21
* Andi Gutmans <andi@zend.com>
22
* Zeev Suraski <zeev@zend.com>
23
* Jani Tolonen <jani@mysql.com>
24
* Matt Wagner <matt@mysql.com>
25
* Jeremy Cole <jcole@mysql.com>
26
* Tonu Samuel <tonu@mysql.com>
27
* Harrison Fisk <harrison@mysql.com>
31
#include "client_priv.h"
35
#ifndef __GNU_LIBRARY__
36
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
38
#include "my_readline.h"
42
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
46
const char *VER= "14.14";
48
/* Don't try to make a nice table if the data is too big */
49
#define MAX_COLUMN_LENGTH 1024
51
/* Buffer to hold 'version' and 'version_comment' */
52
#define MAX_SERVER_VERSION_LENGTH 128
54
/* Array of options to pass to libemysqld */
55
#define MAX_SERVER_ARGS 64
57
void* sql_alloc(unsigned size); // Don't use mysqld alloc for these
58
void sql_element_free(void *ptr);
59
#include "sql_string.h"
62
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
66
#if defined(HAVE_TERMIOS_H)
69
#elif defined(HAVE_TERMBITS_H)
71
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
72
#include <asm/termbits.h> // Standard linux
75
#if defined(HAVE_TERMCAP_H)
81
#undef SYSV // hack to avoid syntax error
88
#undef bcmp // Fix problem with new readline
90
#include <readline/readline.h>
93
//int vidattr(long unsigned int attrs); // Was missing in sun curses
96
#if !defined(HAVE_VIDATTR)
98
#define vidattr(A) {} // Can't get this to work
101
#ifdef FN_NO_CASE_SENCE
102
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
104
#define cmp_database(cs,A,B) strcmp((A),(B))
107
#if !defined( __WIN__) && !defined(__NETWARE__) && !defined(THREAD)
111
#include "completion_hash.h"
113
#define PROMPT_CHAR '\\'
114
#define DEFAULT_DELIMITER ";"
116
typedef struct st_status
119
ulong query_start_line;
121
LINE_BUFFER *line_buff;
122
bool batch,add_to_history;
127
static char **defaults_argv;
129
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
130
typedef enum enum_info_type INFO_TYPE;
132
static MYSQL mysql; /* The connection */
133
static my_bool ignore_errors=0,wait_flag=0,quick=0,
134
connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
135
opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
136
opt_compress=0, using_opt_local_infile=0,
137
vertical=0, line_numbers=1, column_names=1,opt_html=0,
138
opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
139
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
140
default_charset_used= 0, opt_secure_auth= 0,
141
default_pager_set= 0, opt_sigint_ignore= 0,
142
auto_vertical_output= 0,
143
show_warnings= 0, executing_query= 0, interrupted_query= 0;
144
static my_bool debug_info_flag, debug_check_flag;
145
static my_bool column_types_flag;
146
static my_bool preserve_comments= 0;
147
static ulong opt_max_allowed_packet, opt_net_buffer_length;
148
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
149
static uint my_end_arg;
150
static char * opt_mysql_unix_port=0;
151
static int connect_flag=CLIENT_INTERACTIVE;
152
static char *current_host,*current_db,*current_user=0,*opt_password=0,
153
*current_prompt=0, *delimiter_str= 0,
154
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
155
static char *histfile;
156
static char *histfile_tmp;
157
static String glob_buffer,old_buffer;
158
static String processed_prompt;
159
static char *full_username=0,*part_username=0,*default_prompt=0;
160
static int wait_time = 5;
161
static STATUS status;
162
static ulong select_limit,max_join_size,opt_connect_timeout=0;
163
static char mysql_charsets_dir[FN_REFLEN+1];
164
static const char *xmlmeta[] = {
171
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
172
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
173
"Aug","Sep","Oct","Nov","Dec"};
174
static char default_pager[FN_REFLEN];
175
static char pager[FN_REFLEN], outfile[FN_REFLEN];
176
static FILE *PAGER, *OUTFILE;
177
static MEM_ROOT hash_mem_root;
178
static uint prompt_counter;
179
static char delimiter[16]= DEFAULT_DELIMITER;
180
static uint delimiter_length= 1;
181
unsigned short terminal_width= 80;
184
static char *shared_memory_base_name=0;
186
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
187
static CHARSET_INFO *charset_info= &my_charset_latin1;
189
const char *default_dbug_option="d:t:o,/tmp/mysql.trace";
191
void tee_fprintf(FILE *file, const char *fmt, ...);
192
void tee_fputs(const char *s, FILE *file);
193
void tee_puts(const char *s, FILE *file);
194
void tee_putc(int c, FILE *file);
195
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
196
/* The names of functions that actually do the manipulation. */
197
static int get_options(int argc,char **argv);
198
extern "C" my_bool get_one_option(int optid, const struct my_option *opt,
200
static int com_quit(String *str,char*),
201
com_go(String *str,char*), com_ego(String *str,char*),
202
com_print(String *str,char*),
203
com_help(String *str,char*), com_clear(String *str,char*),
204
com_connect(String *str,char*), com_status(String *str,char*),
205
com_use(String *str,char*), com_source(String *str, char*),
206
com_rehash(String *str, char*), com_tee(String *str, char*),
207
com_notee(String *str, char*), com_charset(String *str,char*),
208
com_prompt(String *str, char*), com_delimiter(String *str, char*),
209
com_warnings(String *str, char*), com_nowarnings(String *str, char*);
212
static int com_nopager(String *str, char*), com_pager(String *str, char*),
213
com_edit(String *str,char*), com_shell(String *str, char *);
216
static int read_and_execute(bool interactive);
217
static int sql_connect(char *host,char *database,char *user,char *password,
219
static const char *server_version_string(MYSQL *mysql);
220
static int put_info(const char *str,INFO_TYPE info,uint error=0,
221
const char *sql_state=0);
222
static int put_error(MYSQL *mysql);
223
static void safe_put_field(const char *pos,ulong length);
224
static void xmlencode_print(const char *src, uint length);
225
static void init_pager();
226
static void end_pager();
227
static void init_tee(const char *);
228
static void end_tee();
229
static const char* construct_prompt();
230
static char *get_arg(char *line, my_bool get_next_arg);
231
static void init_username();
232
static void add_int_to_prompt(int toadd);
233
static int get_result_width(MYSQL_RES *res);
234
static int get_field_disp_length(MYSQL_FIELD * field);
236
/* A structure which contains information on the commands this program
240
const char *name; /* User printable name of the function. */
241
char cmd_char; /* msql command character */
242
int (*func)(String *str,char *); /* Function to call to do the job. */
243
bool takes_params; /* Max parameters for command */
244
const char *doc; /* Documentation for this function. */
247
static COMMANDS commands[] = {
248
{ "?", '?', com_help, 1, "Synonym for `help'." },
249
{ "clear", 'c', com_clear, 0, "Clear command."},
250
{ "connect",'r', com_connect,1,
251
"Reconnect to the server. Optional arguments are db and host." },
252
{ "delimiter", 'd', com_delimiter, 1,
253
"Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
255
{ "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},
257
{ "ego", 'G', com_ego, 0,
258
"Send command to mysql server, display result vertically."},
259
{ "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."},
260
{ "go", 'g', com_go, 0, "Send command to mysql server." },
261
{ "help", 'h', com_help, 1, "Display this help." },
263
{ "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
265
{ "notee", 't', com_notee, 0, "Don't write into outfile." },
267
{ "pager", 'P', com_pager, 1,
268
"Set PAGER [to_pager]. Print the query results via PAGER." },
270
{ "print", 'p', com_print, 0, "Print current command." },
271
{ "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
272
{ "quit", 'q', com_quit, 0, "Quit mysql." },
273
{ "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
274
{ "source", '.', com_source, 1,
275
"Execute an SQL script file. Takes a file name as an argument."},
276
{ "status", 's', com_status, 0, "Get status information from the server."},
278
{ "system", '!', com_shell, 1, "Execute a system shell command."},
280
{ "tee", 'T', com_tee, 1,
281
"Set outfile [to_outfile]. Append everything into given outfile." },
282
{ "use", 'u', com_use, 1,
283
"Use another database. Takes database name as argument." },
284
{ "charset", 'C', com_charset, 1,
285
"Switch to another charset. Might be needed for processing binlog with multi-byte charsets." },
286
{ "warnings", 'W', com_warnings, 0,
287
"Show warnings after every statement." },
288
{ "nowarning", 'w', com_nowarnings, 0,
289
"Don't show warnings after every statement." },
290
/* Get bash-like expansion for some commands */
291
{ "create table", 0, 0, 0, ""},
292
{ "create database", 0, 0, 0, ""},
293
{ "show databases", 0, 0, 0, ""},
294
{ "show fields from", 0, 0, 0, ""},
295
{ "show keys from", 0, 0, 0, ""},
296
{ "show tables", 0, 0, 0, ""},
297
{ "load data from", 0, 0, 0, ""},
298
{ "alter table", 0, 0, 0, ""},
299
{ "set option", 0, 0, 0, ""},
300
{ "lock tables", 0, 0, 0, ""},
301
{ "unlock tables", 0, 0, 0, ""},
302
/* generated 2006-12-28. Refresh occasionally from lexer. */
303
{ "ACTION", 0, 0, 0, ""},
304
{ "ADD", 0, 0, 0, ""},
305
{ "AFTER", 0, 0, 0, ""},
306
{ "AGAINST", 0, 0, 0, ""},
307
{ "AGGREGATE", 0, 0, 0, ""},
308
{ "ALL", 0, 0, 0, ""},
309
{ "ALGORITHM", 0, 0, 0, ""},
310
{ "ALTER", 0, 0, 0, ""},
311
{ "ANALYZE", 0, 0, 0, ""},
312
{ "AND", 0, 0, 0, ""},
313
{ "ANY", 0, 0, 0, ""},
314
{ "AS", 0, 0, 0, ""},
315
{ "ASC", 0, 0, 0, ""},
316
{ "ASCII", 0, 0, 0, ""},
317
{ "ASENSITIVE", 0, 0, 0, ""},
318
{ "AUTO_INCREMENT", 0, 0, 0, ""},
319
{ "AVG", 0, 0, 0, ""},
320
{ "AVG_ROW_LENGTH", 0, 0, 0, ""},
321
{ "BACKUP", 0, 0, 0, ""},
322
{ "BDB", 0, 0, 0, ""},
323
{ "BEFORE", 0, 0, 0, ""},
324
{ "BEGIN", 0, 0, 0, ""},
325
{ "BERKELEYDB", 0, 0, 0, ""},
326
{ "BETWEEN", 0, 0, 0, ""},
327
{ "BIGINT", 0, 0, 0, ""},
328
{ "BINARY", 0, 0, 0, ""},
329
{ "BINLOG", 0, 0, 0, ""},
330
{ "BIT", 0, 0, 0, ""},
331
{ "BLOB", 0, 0, 0, ""},
332
{ "BOOL", 0, 0, 0, ""},
333
{ "BOOLEAN", 0, 0, 0, ""},
334
{ "BOTH", 0, 0, 0, ""},
335
{ "BTREE", 0, 0, 0, ""},
336
{ "BY", 0, 0, 0, ""},
337
{ "BYTE", 0, 0, 0, ""},
338
{ "CACHE", 0, 0, 0, ""},
339
{ "CALL", 0, 0, 0, ""},
340
{ "CASCADE", 0, 0, 0, ""},
341
{ "CASCADED", 0, 0, 0, ""},
342
{ "CASE", 0, 0, 0, ""},
343
{ "CHAIN", 0, 0, 0, ""},
344
{ "CHANGE", 0, 0, 0, ""},
345
{ "CHANGED", 0, 0, 0, ""},
346
{ "CHAR", 0, 0, 0, ""},
347
{ "CHARACTER", 0, 0, 0, ""},
348
{ "CHARSET", 0, 0, 0, ""},
349
{ "CHECK", 0, 0, 0, ""},
350
{ "CHECKSUM", 0, 0, 0, ""},
351
{ "CIPHER", 0, 0, 0, ""},
352
{ "CLIENT", 0, 0, 0, ""},
353
{ "CLOSE", 0, 0, 0, ""},
354
{ "CODE", 0, 0, 0, ""},
355
{ "COLLATE", 0, 0, 0, ""},
356
{ "COLLATION", 0, 0, 0, ""},
357
{ "COLUMN", 0, 0, 0, ""},
358
{ "COLUMNS", 0, 0, 0, ""},
359
{ "COMMENT", 0, 0, 0, ""},
360
{ "COMMIT", 0, 0, 0, ""},
361
{ "COMMITTED", 0, 0, 0, ""},
362
{ "COMPACT", 0, 0, 0, ""},
363
{ "COMPRESSED", 0, 0, 0, ""},
364
{ "CONCURRENT", 0, 0, 0, ""},
365
{ "CONDITION", 0, 0, 0, ""},
366
{ "CONNECTION", 0, 0, 0, ""},
367
{ "CONSISTENT", 0, 0, 0, ""},
368
{ "CONSTRAINT", 0, 0, 0, ""},
369
{ "CONTAINS", 0, 0, 0, ""},
370
{ "CONTINUE", 0, 0, 0, ""},
371
{ "CONVERT", 0, 0, 0, ""},
372
{ "CREATE", 0, 0, 0, ""},
373
{ "CROSS", 0, 0, 0, ""},
374
{ "CUBE", 0, 0, 0, ""},
375
{ "CURRENT_DATE", 0, 0, 0, ""},
376
{ "CURRENT_TIME", 0, 0, 0, ""},
377
{ "CURRENT_TIMESTAMP", 0, 0, 0, ""},
378
{ "CURRENT_USER", 0, 0, 0, ""},
379
{ "CURSOR", 0, 0, 0, ""},
380
{ "DATA", 0, 0, 0, ""},
381
{ "DATABASE", 0, 0, 0, ""},
382
{ "DATABASES", 0, 0, 0, ""},
383
{ "DATE", 0, 0, 0, ""},
384
{ "DATETIME", 0, 0, 0, ""},
385
{ "DAY", 0, 0, 0, ""},
386
{ "DAY_HOUR", 0, 0, 0, ""},
387
{ "DAY_MICROSECOND", 0, 0, 0, ""},
388
{ "DAY_MINUTE", 0, 0, 0, ""},
389
{ "DAY_SECOND", 0, 0, 0, ""},
390
{ "DEALLOCATE", 0, 0, 0, ""},
391
{ "DEC", 0, 0, 0, ""},
392
{ "DECIMAL", 0, 0, 0, ""},
393
{ "DECLARE", 0, 0, 0, ""},
394
{ "DEFAULT", 0, 0, 0, ""},
395
{ "DEFINER", 0, 0, 0, ""},
396
{ "DELAYED", 0, 0, 0, ""},
397
{ "DELAY_KEY_WRITE", 0, 0, 0, ""},
398
{ "DELETE", 0, 0, 0, ""},
399
{ "DESC", 0, 0, 0, ""},
400
{ "DESCRIBE", 0, 0, 0, ""},
401
{ "DES_KEY_FILE", 0, 0, 0, ""},
402
{ "DETERMINISTIC", 0, 0, 0, ""},
403
{ "DIRECTORY", 0, 0, 0, ""},
404
{ "DISABLE", 0, 0, 0, ""},
405
{ "DISCARD", 0, 0, 0, ""},
406
{ "DISTINCT", 0, 0, 0, ""},
407
{ "DISTINCTROW", 0, 0, 0, ""},
408
{ "DIV", 0, 0, 0, ""},
409
{ "DO", 0, 0, 0, ""},
410
{ "DOUBLE", 0, 0, 0, ""},
411
{ "DROP", 0, 0, 0, ""},
412
{ "DUAL", 0, 0, 0, ""},
413
{ "DUMPFILE", 0, 0, 0, ""},
414
{ "DUPLICATE", 0, 0, 0, ""},
415
{ "DYNAMIC", 0, 0, 0, ""},
416
{ "EACH", 0, 0, 0, ""},
417
{ "ELSE", 0, 0, 0, ""},
418
{ "ELSEIF", 0, 0, 0, ""},
419
{ "ENABLE", 0, 0, 0, ""},
420
{ "ENCLOSED", 0, 0, 0, ""},
421
{ "END", 0, 0, 0, ""},
422
{ "ENGINE", 0, 0, 0, ""},
423
{ "ENGINES", 0, 0, 0, ""},
424
{ "ENUM", 0, 0, 0, ""},
425
{ "ERRORS", 0, 0, 0, ""},
426
{ "ESCAPE", 0, 0, 0, ""},
427
{ "ESCAPED", 0, 0, 0, ""},
428
{ "EVENTS", 0, 0, 0, ""},
429
{ "EXECUTE", 0, 0, 0, ""},
430
{ "EXISTS", 0, 0, 0, ""},
431
{ "EXIT", 0, 0, 0, ""},
432
{ "EXPANSION", 0, 0, 0, ""},
433
{ "EXPLAIN", 0, 0, 0, ""},
434
{ "EXTENDED", 0, 0, 0, ""},
435
{ "FALSE", 0, 0, 0, ""},
436
{ "FAST", 0, 0, 0, ""},
437
{ "FETCH", 0, 0, 0, ""},
438
{ "FIELDS", 0, 0, 0, ""},
439
{ "FILE", 0, 0, 0, ""},
440
{ "FIRST", 0, 0, 0, ""},
441
{ "FIXED", 0, 0, 0, ""},
442
{ "FLOAT", 0, 0, 0, ""},
443
{ "FLOAT4", 0, 0, 0, ""},
444
{ "FLOAT8", 0, 0, 0, ""},
445
{ "FLUSH", 0, 0, 0, ""},
446
{ "FOR", 0, 0, 0, ""},
447
{ "FORCE", 0, 0, 0, ""},
448
{ "FOREIGN", 0, 0, 0, ""},
449
{ "FOUND", 0, 0, 0, ""},
450
{ "FRAC_SECOND", 0, 0, 0, ""},
451
{ "FROM", 0, 0, 0, ""},
452
{ "FULL", 0, 0, 0, ""},
453
{ "FULLTEXT", 0, 0, 0, ""},
454
{ "FUNCTION", 0, 0, 0, ""},
455
{ "GEOMETRY", 0, 0, 0, ""},
456
{ "GEOMETRYCOLLECTION", 0, 0, 0, ""},
457
{ "GET_FORMAT", 0, 0, 0, ""},
458
{ "GLOBAL", 0, 0, 0, ""},
459
{ "GRANT", 0, 0, 0, ""},
460
{ "GRANTS", 0, 0, 0, ""},
461
{ "GROUP", 0, 0, 0, ""},
462
{ "HANDLER", 0, 0, 0, ""},
463
{ "HASH", 0, 0, 0, ""},
464
{ "HAVING", 0, 0, 0, ""},
465
{ "HELP", 0, 0, 0, ""},
466
{ "HIGH_PRIORITY", 0, 0, 0, ""},
467
{ "HOSTS", 0, 0, 0, ""},
468
{ "HOUR", 0, 0, 0, ""},
469
{ "HOUR_MICROSECOND", 0, 0, 0, ""},
470
{ "HOUR_MINUTE", 0, 0, 0, ""},
471
{ "HOUR_SECOND", 0, 0, 0, ""},
472
{ "IDENTIFIED", 0, 0, 0, ""},
473
{ "IF", 0, 0, 0, ""},
474
{ "IGNORE", 0, 0, 0, ""},
475
{ "IMPORT", 0, 0, 0, ""},
476
{ "IN", 0, 0, 0, ""},
477
{ "INDEX", 0, 0, 0, ""},
478
{ "INDEXES", 0, 0, 0, ""},
479
{ "INFILE", 0, 0, 0, ""},
480
{ "INNER", 0, 0, 0, ""},
481
{ "INNOBASE", 0, 0, 0, ""},
482
{ "INNODB", 0, 0, 0, ""},
483
{ "INOUT", 0, 0, 0, ""},
484
{ "INSENSITIVE", 0, 0, 0, ""},
485
{ "INSERT", 0, 0, 0, ""},
486
{ "INSERT_METHOD", 0, 0, 0, ""},
487
{ "INT", 0, 0, 0, ""},
488
{ "INT1", 0, 0, 0, ""},
489
{ "INT2", 0, 0, 0, ""},
490
{ "INT3", 0, 0, 0, ""},
491
{ "INT4", 0, 0, 0, ""},
492
{ "INT8", 0, 0, 0, ""},
493
{ "INTEGER", 0, 0, 0, ""},
494
{ "INTERVAL", 0, 0, 0, ""},
495
{ "INTO", 0, 0, 0, ""},
496
{ "IO_THREAD", 0, 0, 0, ""},
497
{ "IS", 0, 0, 0, ""},
498
{ "ISOLATION", 0, 0, 0, ""},
499
{ "ISSUER", 0, 0, 0, ""},
500
{ "ITERATE", 0, 0, 0, ""},
501
{ "INVOKER", 0, 0, 0, ""},
502
{ "JOIN", 0, 0, 0, ""},
503
{ "KEY", 0, 0, 0, ""},
504
{ "KEYS", 0, 0, 0, ""},
505
{ "KILL", 0, 0, 0, ""},
506
{ "LANGUAGE", 0, 0, 0, ""},
507
{ "LAST", 0, 0, 0, ""},
508
{ "LEADING", 0, 0, 0, ""},
509
{ "LEAVE", 0, 0, 0, ""},
510
{ "LEAVES", 0, 0, 0, ""},
511
{ "LEFT", 0, 0, 0, ""},
512
{ "LEVEL", 0, 0, 0, ""},
513
{ "LIKE", 0, 0, 0, ""},
514
{ "LIMIT", 0, 0, 0, ""},
515
{ "LINES", 0, 0, 0, ""},
516
{ "LINESTRING", 0, 0, 0, ""},
517
{ "LOAD", 0, 0, 0, ""},
518
{ "LOCAL", 0, 0, 0, ""},
519
{ "LOCALTIME", 0, 0, 0, ""},
520
{ "LOCALTIMESTAMP", 0, 0, 0, ""},
521
{ "LOCK", 0, 0, 0, ""},
522
{ "LOCKS", 0, 0, 0, ""},
523
{ "LOGS", 0, 0, 0, ""},
524
{ "LONG", 0, 0, 0, ""},
525
{ "LONGBLOB", 0, 0, 0, ""},
526
{ "LONGTEXT", 0, 0, 0, ""},
527
{ "LOOP", 0, 0, 0, ""},
528
{ "LOW_PRIORITY", 0, 0, 0, ""},
529
{ "MASTER", 0, 0, 0, ""},
530
{ "MASTER_CONNECT_RETRY", 0, 0, 0, ""},
531
{ "MASTER_HOST", 0, 0, 0, ""},
532
{ "MASTER_LOG_FILE", 0, 0, 0, ""},
533
{ "MASTER_LOG_POS", 0, 0, 0, ""},
534
{ "MASTER_PASSWORD", 0, 0, 0, ""},
535
{ "MASTER_PORT", 0, 0, 0, ""},
536
{ "MASTER_SERVER_ID", 0, 0, 0, ""},
537
{ "MASTER_SSL", 0, 0, 0, ""},
538
{ "MASTER_SSL_CA", 0, 0, 0, ""},
539
{ "MASTER_SSL_CAPATH", 0, 0, 0, ""},
540
{ "MASTER_SSL_CERT", 0, 0, 0, ""},
541
{ "MASTER_SSL_CIPHER", 0, 0, 0, ""},
542
{ "MASTER_SSL_KEY", 0, 0, 0, ""},
543
{ "MASTER_USER", 0, 0, 0, ""},
544
{ "MATCH", 0, 0, 0, ""},
545
{ "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""},
546
{ "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""},
547
{ "MAX_ROWS", 0, 0, 0, ""},
548
{ "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""},
549
{ "MAX_USER_CONNECTIONS", 0, 0, 0, ""},
550
{ "MEDIUM", 0, 0, 0, ""},
551
{ "MEDIUMBLOB", 0, 0, 0, ""},
552
{ "MEDIUMINT", 0, 0, 0, ""},
553
{ "MEDIUMTEXT", 0, 0, 0, ""},
554
{ "MERGE", 0, 0, 0, ""},
555
{ "MICROSECOND", 0, 0, 0, ""},
556
{ "MIDDLEINT", 0, 0, 0, ""},
557
{ "MIGRATE", 0, 0, 0, ""},
558
{ "MINUTE", 0, 0, 0, ""},
559
{ "MINUTE_MICROSECOND", 0, 0, 0, ""},
560
{ "MINUTE_SECOND", 0, 0, 0, ""},
561
{ "MIN_ROWS", 0, 0, 0, ""},
562
{ "MOD", 0, 0, 0, ""},
563
{ "MODE", 0, 0, 0, ""},
564
{ "MODIFIES", 0, 0, 0, ""},
565
{ "MODIFY", 0, 0, 0, ""},
566
{ "MONTH", 0, 0, 0, ""},
567
{ "MULTILINESTRING", 0, 0, 0, ""},
568
{ "MULTIPOINT", 0, 0, 0, ""},
569
{ "MULTIPOLYGON", 0, 0, 0, ""},
570
{ "MUTEX", 0, 0, 0, ""},
571
{ "NAME", 0, 0, 0, ""},
572
{ "NAMES", 0, 0, 0, ""},
573
{ "NATIONAL", 0, 0, 0, ""},
574
{ "NATURAL", 0, 0, 0, ""},
575
{ "NDB", 0, 0, 0, ""},
576
{ "NDBCLUSTER", 0, 0, 0, ""},
577
{ "NCHAR", 0, 0, 0, ""},
578
{ "NEW", 0, 0, 0, ""},
579
{ "NEXT", 0, 0, 0, ""},
580
{ "NO", 0, 0, 0, ""},
581
{ "NONE", 0, 0, 0, ""},
582
{ "NOT", 0, 0, 0, ""},
583
{ "NO_WRITE_TO_BINLOG", 0, 0, 0, ""},
584
{ "NULL", 0, 0, 0, ""},
585
{ "NUMERIC", 0, 0, 0, ""},
586
{ "NVARCHAR", 0, 0, 0, ""},
587
{ "OFFSET", 0, 0, 0, ""},
588
{ "OLD_PASSWORD", 0, 0, 0, ""},
589
{ "ON", 0, 0, 0, ""},
590
{ "ONE", 0, 0, 0, ""},
591
{ "ONE_SHOT", 0, 0, 0, ""},
592
{ "OPEN", 0, 0, 0, ""},
593
{ "OPTIMIZE", 0, 0, 0, ""},
594
{ "OPTION", 0, 0, 0, ""},
595
{ "OPTIONALLY", 0, 0, 0, ""},
596
{ "OR", 0, 0, 0, ""},
597
{ "ORDER", 0, 0, 0, ""},
598
{ "OUT", 0, 0, 0, ""},
599
{ "OUTER", 0, 0, 0, ""},
600
{ "OUTFILE", 0, 0, 0, ""},
601
{ "PACK_KEYS", 0, 0, 0, ""},
602
{ "PARTIAL", 0, 0, 0, ""},
603
{ "PASSWORD", 0, 0, 0, ""},
604
{ "PHASE", 0, 0, 0, ""},
605
{ "POINT", 0, 0, 0, ""},
606
{ "POLYGON", 0, 0, 0, ""},
607
{ "PRECISION", 0, 0, 0, ""},
608
{ "PREPARE", 0, 0, 0, ""},
609
{ "PREV", 0, 0, 0, ""},
610
{ "PRIMARY", 0, 0, 0, ""},
611
{ "PRIVILEGES", 0, 0, 0, ""},
612
{ "PROCEDURE", 0, 0, 0, ""},
613
{ "PROCESS", 0, 0, 0, ""},
614
{ "PROCESSLIST", 0, 0, 0, ""},
615
{ "PURGE", 0, 0, 0, ""},
616
{ "QUARTER", 0, 0, 0, ""},
617
{ "QUERY", 0, 0, 0, ""},
618
{ "QUICK", 0, 0, 0, ""},
619
{ "RAID0", 0, 0, 0, ""},
620
{ "RAID_CHUNKS", 0, 0, 0, ""},
621
{ "RAID_CHUNKSIZE", 0, 0, 0, ""},
622
{ "RAID_TYPE", 0, 0, 0, ""},
623
{ "READ", 0, 0, 0, ""},
624
{ "READS", 0, 0, 0, ""},
625
{ "REAL", 0, 0, 0, ""},
626
{ "RECOVER", 0, 0, 0, ""},
627
{ "REDUNDANT", 0, 0, 0, ""},
628
{ "REFERENCES", 0, 0, 0, ""},
629
{ "REGEXP", 0, 0, 0, ""},
630
{ "RELAY_LOG_FILE", 0, 0, 0, ""},
631
{ "RELAY_LOG_POS", 0, 0, 0, ""},
632
{ "RELAY_THREAD", 0, 0, 0, ""},
633
{ "RELEASE", 0, 0, 0, ""},
634
{ "RELOAD", 0, 0, 0, ""},
635
{ "RENAME", 0, 0, 0, ""},
636
{ "REPAIR", 0, 0, 0, ""},
637
{ "REPEATABLE", 0, 0, 0, ""},
638
{ "REPLACE", 0, 0, 0, ""},
639
{ "REPLICATION", 0, 0, 0, ""},
640
{ "REPEAT", 0, 0, 0, ""},
641
{ "REQUIRE", 0, 0, 0, ""},
642
{ "RESET", 0, 0, 0, ""},
643
{ "RESTORE", 0, 0, 0, ""},
644
{ "RESTRICT", 0, 0, 0, ""},
645
{ "RESUME", 0, 0, 0, ""},
646
{ "RETURN", 0, 0, 0, ""},
647
{ "RETURNS", 0, 0, 0, ""},
648
{ "REVOKE", 0, 0, 0, ""},
649
{ "RIGHT", 0, 0, 0, ""},
650
{ "RLIKE", 0, 0, 0, ""},
651
{ "ROLLBACK", 0, 0, 0, ""},
652
{ "ROLLUP", 0, 0, 0, ""},
653
{ "ROUTINE", 0, 0, 0, ""},
654
{ "ROW", 0, 0, 0, ""},
655
{ "ROWS", 0, 0, 0, ""},
656
{ "ROW_FORMAT", 0, 0, 0, ""},
657
{ "RTREE", 0, 0, 0, ""},
658
{ "SAVEPOINT", 0, 0, 0, ""},
659
{ "SCHEMA", 0, 0, 0, ""},
660
{ "SCHEMAS", 0, 0, 0, ""},
661
{ "SECOND", 0, 0, 0, ""},
662
{ "SECOND_MICROSECOND", 0, 0, 0, ""},
663
{ "SECURITY", 0, 0, 0, ""},
664
{ "SELECT", 0, 0, 0, ""},
665
{ "SENSITIVE", 0, 0, 0, ""},
666
{ "SEPARATOR", 0, 0, 0, ""},
667
{ "SERIAL", 0, 0, 0, ""},
668
{ "SERIALIZABLE", 0, 0, 0, ""},
669
{ "SESSION", 0, 0, 0, ""},
670
{ "SET", 0, 0, 0, ""},
671
{ "SHARE", 0, 0, 0, ""},
672
{ "SHOW", 0, 0, 0, ""},
673
{ "SHUTDOWN", 0, 0, 0, ""},
674
{ "SIGNED", 0, 0, 0, ""},
675
{ "SIMPLE", 0, 0, 0, ""},
676
{ "SLAVE", 0, 0, 0, ""},
677
{ "SNAPSHOT", 0, 0, 0, ""},
678
{ "SMALLINT", 0, 0, 0, ""},
679
{ "SOME", 0, 0, 0, ""},
680
{ "SONAME", 0, 0, 0, ""},
681
{ "SOUNDS", 0, 0, 0, ""},
682
{ "SPATIAL", 0, 0, 0, ""},
683
{ "SPECIFIC", 0, 0, 0, ""},
684
{ "SQL", 0, 0, 0, ""},
685
{ "SQLEXCEPTION", 0, 0, 0, ""},
686
{ "SQLSTATE", 0, 0, 0, ""},
687
{ "SQLWARNING", 0, 0, 0, ""},
688
{ "SQL_BIG_RESULT", 0, 0, 0, ""},
689
{ "SQL_BUFFER_RESULT", 0, 0, 0, ""},
690
{ "SQL_CACHE", 0, 0, 0, ""},
691
{ "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""},
692
{ "SQL_NO_CACHE", 0, 0, 0, ""},
693
{ "SQL_SMALL_RESULT", 0, 0, 0, ""},
694
{ "SQL_THREAD", 0, 0, 0, ""},
695
{ "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
696
{ "SQL_TSI_SECOND", 0, 0, 0, ""},
697
{ "SQL_TSI_MINUTE", 0, 0, 0, ""},
698
{ "SQL_TSI_HOUR", 0, 0, 0, ""},
699
{ "SQL_TSI_DAY", 0, 0, 0, ""},
700
{ "SQL_TSI_WEEK", 0, 0, 0, ""},
701
{ "SQL_TSI_MONTH", 0, 0, 0, ""},
702
{ "SQL_TSI_QUARTER", 0, 0, 0, ""},
703
{ "SQL_TSI_YEAR", 0, 0, 0, ""},
704
{ "SSL", 0, 0, 0, ""},
705
{ "START", 0, 0, 0, ""},
706
{ "STARTING", 0, 0, 0, ""},
707
{ "STATUS", 0, 0, 0, ""},
708
{ "STOP", 0, 0, 0, ""},
709
{ "STORAGE", 0, 0, 0, ""},
710
{ "STRAIGHT_JOIN", 0, 0, 0, ""},
711
{ "STRING", 0, 0, 0, ""},
712
{ "STRIPED", 0, 0, 0, ""},
713
{ "SUBJECT", 0, 0, 0, ""},
714
{ "SUPER", 0, 0, 0, ""},
715
{ "SUSPEND", 0, 0, 0, ""},
716
{ "TABLE", 0, 0, 0, ""},
717
{ "TABLES", 0, 0, 0, ""},
718
{ "TABLESPACE", 0, 0, 0, ""},
719
{ "TEMPORARY", 0, 0, 0, ""},
720
{ "TEMPTABLE", 0, 0, 0, ""},
721
{ "TERMINATED", 0, 0, 0, ""},
722
{ "TEXT", 0, 0, 0, ""},
723
{ "THEN", 0, 0, 0, ""},
724
{ "TIME", 0, 0, 0, ""},
725
{ "TIMESTAMP", 0, 0, 0, ""},
726
{ "TIMESTAMPADD", 0, 0, 0, ""},
727
{ "TIMESTAMPDIFF", 0, 0, 0, ""},
728
{ "TINYBLOB", 0, 0, 0, ""},
729
{ "TINYINT", 0, 0, 0, ""},
730
{ "TINYTEXT", 0, 0, 0, ""},
731
{ "TO", 0, 0, 0, ""},
732
{ "TRAILING", 0, 0, 0, ""},
733
{ "TRANSACTION", 0, 0, 0, ""},
734
{ "TRIGGER", 0, 0, 0, ""},
735
{ "TRIGGERS", 0, 0, 0, ""},
736
{ "TRUE", 0, 0, 0, ""},
737
{ "TRUNCATE", 0, 0, 0, ""},
738
{ "TYPE", 0, 0, 0, ""},
739
{ "TYPES", 0, 0, 0, ""},
740
{ "UNCOMMITTED", 0, 0, 0, ""},
741
{ "UNDEFINED", 0, 0, 0, ""},
742
{ "UNDO", 0, 0, 0, ""},
743
{ "UNICODE", 0, 0, 0, ""},
744
{ "UNION", 0, 0, 0, ""},
745
{ "UNIQUE", 0, 0, 0, ""},
746
{ "UNKNOWN", 0, 0, 0, ""},
747
{ "UNLOCK", 0, 0, 0, ""},
748
{ "UNSIGNED", 0, 0, 0, ""},
749
{ "UNTIL", 0, 0, 0, ""},
750
{ "UPDATE", 0, 0, 0, ""},
751
{ "UPGRADE", 0, 0, 0, ""},
752
{ "USAGE", 0, 0, 0, ""},
753
{ "USE", 0, 0, 0, ""},
754
{ "USER", 0, 0, 0, ""},
755
{ "USER_RESOURCES", 0, 0, 0, ""},
756
{ "USE_FRM", 0, 0, 0, ""},
757
{ "USING", 0, 0, 0, ""},
758
{ "UTC_DATE", 0, 0, 0, ""},
759
{ "UTC_TIME", 0, 0, 0, ""},
760
{ "UTC_TIMESTAMP", 0, 0, 0, ""},
761
{ "VALUE", 0, 0, 0, ""},
762
{ "VALUES", 0, 0, 0, ""},
763
{ "VARBINARY", 0, 0, 0, ""},
764
{ "VARCHAR", 0, 0, 0, ""},
765
{ "VARCHARACTER", 0, 0, 0, ""},
766
{ "VARIABLES", 0, 0, 0, ""},
767
{ "VARYING", 0, 0, 0, ""},
768
{ "WARNINGS", 0, 0, 0, ""},
769
{ "WEEK", 0, 0, 0, ""},
770
{ "WHEN", 0, 0, 0, ""},
771
{ "WHERE", 0, 0, 0, ""},
772
{ "WHILE", 0, 0, 0, ""},
773
{ "VIEW", 0, 0, 0, ""},
774
{ "WITH", 0, 0, 0, ""},
775
{ "WORK", 0, 0, 0, ""},
776
{ "WRITE", 0, 0, 0, ""},
777
{ "X509", 0, 0, 0, ""},
778
{ "XOR", 0, 0, 0, ""},
779
{ "XA", 0, 0, 0, ""},
780
{ "YEAR", 0, 0, 0, ""},
781
{ "YEAR_MONTH", 0, 0, 0, ""},
782
{ "ZEROFILL", 0, 0, 0, ""},
783
{ "ABS", 0, 0, 0, ""},
784
{ "ACOS", 0, 0, 0, ""},
785
{ "ADDDATE", 0, 0, 0, ""},
786
{ "ADDTIME", 0, 0, 0, ""},
787
{ "AES_ENCRYPT", 0, 0, 0, ""},
788
{ "AES_DECRYPT", 0, 0, 0, ""},
789
{ "AREA", 0, 0, 0, ""},
790
{ "ASIN", 0, 0, 0, ""},
791
{ "ASBINARY", 0, 0, 0, ""},
792
{ "ASTEXT", 0, 0, 0, ""},
793
{ "ASWKB", 0, 0, 0, ""},
794
{ "ASWKT", 0, 0, 0, ""},
795
{ "ATAN", 0, 0, 0, ""},
796
{ "ATAN2", 0, 0, 0, ""},
797
{ "BENCHMARK", 0, 0, 0, ""},
798
{ "BIN", 0, 0, 0, ""},
799
{ "BIT_COUNT", 0, 0, 0, ""},
800
{ "BIT_OR", 0, 0, 0, ""},
801
{ "BIT_AND", 0, 0, 0, ""},
802
{ "BIT_XOR", 0, 0, 0, ""},
803
{ "CAST", 0, 0, 0, ""},
804
{ "CEIL", 0, 0, 0, ""},
805
{ "CEILING", 0, 0, 0, ""},
806
{ "BIT_LENGTH", 0, 0, 0, ""},
807
{ "CENTROID", 0, 0, 0, ""},
808
{ "CHAR_LENGTH", 0, 0, 0, ""},
809
{ "CHARACTER_LENGTH", 0, 0, 0, ""},
810
{ "COALESCE", 0, 0, 0, ""},
811
{ "COERCIBILITY", 0, 0, 0, ""},
812
{ "COMPRESS", 0, 0, 0, ""},
813
{ "CONCAT", 0, 0, 0, ""},
814
{ "CONCAT_WS", 0, 0, 0, ""},
815
{ "CONNECTION_ID", 0, 0, 0, ""},
816
{ "CONV", 0, 0, 0, ""},
817
{ "CONVERT_TZ", 0, 0, 0, ""},
818
{ "COUNT", 0, 0, 0, ""},
819
{ "COS", 0, 0, 0, ""},
820
{ "COT", 0, 0, 0, ""},
821
{ "CRC32", 0, 0, 0, ""},
822
{ "CROSSES", 0, 0, 0, ""},
823
{ "CURDATE", 0, 0, 0, ""},
824
{ "CURTIME", 0, 0, 0, ""},
825
{ "DATE_ADD", 0, 0, 0, ""},
826
{ "DATEDIFF", 0, 0, 0, ""},
827
{ "DATE_FORMAT", 0, 0, 0, ""},
828
{ "DATE_SUB", 0, 0, 0, ""},
829
{ "DAYNAME", 0, 0, 0, ""},
830
{ "DAYOFMONTH", 0, 0, 0, ""},
831
{ "DAYOFWEEK", 0, 0, 0, ""},
832
{ "DAYOFYEAR", 0, 0, 0, ""},
833
{ "DECODE", 0, 0, 0, ""},
834
{ "DEGREES", 0, 0, 0, ""},
835
{ "DES_ENCRYPT", 0, 0, 0, ""},
836
{ "DES_DECRYPT", 0, 0, 0, ""},
837
{ "DIMENSION", 0, 0, 0, ""},
838
{ "DISJOINT", 0, 0, 0, ""},
839
{ "ELT", 0, 0, 0, ""},
840
{ "ENCODE", 0, 0, 0, ""},
841
{ "ENCRYPT", 0, 0, 0, ""},
842
{ "ENDPOINT", 0, 0, 0, ""},
843
{ "ENVELOPE", 0, 0, 0, ""},
844
{ "EQUALS", 0, 0, 0, ""},
845
{ "EXTERIORRING", 0, 0, 0, ""},
846
{ "EXTRACT", 0, 0, 0, ""},
847
{ "EXP", 0, 0, 0, ""},
848
{ "EXPORT_SET", 0, 0, 0, ""},
849
{ "FIELD", 0, 0, 0, ""},
850
{ "FIND_IN_SET", 0, 0, 0, ""},
851
{ "FLOOR", 0, 0, 0, ""},
852
{ "FORMAT", 0, 0, 0, ""},
853
{ "FOUND_ROWS", 0, 0, 0, ""},
854
{ "FROM_DAYS", 0, 0, 0, ""},
855
{ "FROM_UNIXTIME", 0, 0, 0, ""},
856
{ "GET_LOCK", 0, 0, 0, ""},
857
{ "GEOMETRYN", 0, 0, 0, ""},
858
{ "GEOMETRYTYPE", 0, 0, 0, ""},
859
{ "GEOMCOLLFROMTEXT", 0, 0, 0, ""},
860
{ "GEOMCOLLFROMWKB", 0, 0, 0, ""},
861
{ "GEOMETRYCOLLECTIONFROMTEXT", 0, 0, 0, ""},
862
{ "GEOMETRYCOLLECTIONFROMWKB", 0, 0, 0, ""},
863
{ "GEOMETRYFROMTEXT", 0, 0, 0, ""},
864
{ "GEOMETRYFROMWKB", 0, 0, 0, ""},
865
{ "GEOMFROMTEXT", 0, 0, 0, ""},
866
{ "GEOMFROMWKB", 0, 0, 0, ""},
867
{ "GLENGTH", 0, 0, 0, ""},
868
{ "GREATEST", 0, 0, 0, ""},
869
{ "GROUP_CONCAT", 0, 0, 0, ""},
870
{ "GROUP_UNIQUE_USERS", 0, 0, 0, ""},
871
{ "HEX", 0, 0, 0, ""},
872
{ "IFNULL", 0, 0, 0, ""},
873
{ "INET_ATON", 0, 0, 0, ""},
874
{ "INET_NTOA", 0, 0, 0, ""},
875
{ "INSTR", 0, 0, 0, ""},
876
{ "INTERIORRINGN", 0, 0, 0, ""},
877
{ "INTERSECTS", 0, 0, 0, ""},
878
{ "ISCLOSED", 0, 0, 0, ""},
879
{ "ISEMPTY", 0, 0, 0, ""},
880
{ "ISNULL", 0, 0, 0, ""},
881
{ "IS_FREE_LOCK", 0, 0, 0, ""},
882
{ "IS_USED_LOCK", 0, 0, 0, ""},
883
{ "LAST_INSERT_ID", 0, 0, 0, ""},
884
{ "ISSIMPLE", 0, 0, 0, ""},
885
{ "LAST_DAY", 0, 0, 0, ""},
886
{ "LCASE", 0, 0, 0, ""},
887
{ "LEAST", 0, 0, 0, ""},
888
{ "LENGTH", 0, 0, 0, ""},
889
{ "LN", 0, 0, 0, ""},
890
{ "LINEFROMTEXT", 0, 0, 0, ""},
891
{ "LINEFROMWKB", 0, 0, 0, ""},
892
{ "LINESTRINGFROMTEXT", 0, 0, 0, ""},
893
{ "LINESTRINGFROMWKB", 0, 0, 0, ""},
894
{ "LOAD_FILE", 0, 0, 0, ""},
895
{ "LOCATE", 0, 0, 0, ""},
896
{ "LOG", 0, 0, 0, ""},
897
{ "LOG2", 0, 0, 0, ""},
898
{ "LOG10", 0, 0, 0, ""},
899
{ "LOWER", 0, 0, 0, ""},
900
{ "LPAD", 0, 0, 0, ""},
901
{ "LTRIM", 0, 0, 0, ""},
902
{ "MAKE_SET", 0, 0, 0, ""},
903
{ "MAKEDATE", 0, 0, 0, ""},
904
{ "MAKETIME", 0, 0, 0, ""},
905
{ "MASTER_POS_WAIT", 0, 0, 0, ""},
906
{ "MAX", 0, 0, 0, ""},
907
{ "MBRCONTAINS", 0, 0, 0, ""},
908
{ "MBRDISJOINT", 0, 0, 0, ""},
909
{ "MBREQUAL", 0, 0, 0, ""},
910
{ "MBRINTERSECTS", 0, 0, 0, ""},
911
{ "MBROVERLAPS", 0, 0, 0, ""},
912
{ "MBRTOUCHES", 0, 0, 0, ""},
913
{ "MBRWITHIN", 0, 0, 0, ""},
914
{ "MD5", 0, 0, 0, ""},
915
{ "MID", 0, 0, 0, ""},
916
{ "MIN", 0, 0, 0, ""},
917
{ "MLINEFROMTEXT", 0, 0, 0, ""},
918
{ "MLINEFROMWKB", 0, 0, 0, ""},
919
{ "MPOINTFROMTEXT", 0, 0, 0, ""},
920
{ "MPOINTFROMWKB", 0, 0, 0, ""},
921
{ "MPOLYFROMTEXT", 0, 0, 0, ""},
922
{ "MPOLYFROMWKB", 0, 0, 0, ""},
923
{ "MONTHNAME", 0, 0, 0, ""},
924
{ "MULTILINESTRINGFROMTEXT", 0, 0, 0, ""},
925
{ "MULTILINESTRINGFROMWKB", 0, 0, 0, ""},
926
{ "MULTIPOINTFROMTEXT", 0, 0, 0, ""},
927
{ "MULTIPOINTFROMWKB", 0, 0, 0, ""},
928
{ "MULTIPOLYGONFROMTEXT", 0, 0, 0, ""},
929
{ "MULTIPOLYGONFROMWKB", 0, 0, 0, ""},
930
{ "NAME_CONST", 0, 0, 0, ""},
931
{ "NOW", 0, 0, 0, ""},
932
{ "NULLIF", 0, 0, 0, ""},
933
{ "NUMGEOMETRIES", 0, 0, 0, ""},
934
{ "NUMINTERIORRINGS", 0, 0, 0, ""},
935
{ "NUMPOINTS", 0, 0, 0, ""},
936
{ "OCTET_LENGTH", 0, 0, 0, ""},
937
{ "OCT", 0, 0, 0, ""},
938
{ "ORD", 0, 0, 0, ""},
939
{ "OVERLAPS", 0, 0, 0, ""},
940
{ "PERIOD_ADD", 0, 0, 0, ""},
941
{ "PERIOD_DIFF", 0, 0, 0, ""},
942
{ "PI", 0, 0, 0, ""},
943
{ "POINTFROMTEXT", 0, 0, 0, ""},
944
{ "POINTFROMWKB", 0, 0, 0, ""},
945
{ "POINTN", 0, 0, 0, ""},
946
{ "POLYFROMTEXT", 0, 0, 0, ""},
947
{ "POLYFROMWKB", 0, 0, 0, ""},
948
{ "POLYGONFROMTEXT", 0, 0, 0, ""},
949
{ "POLYGONFROMWKB", 0, 0, 0, ""},
950
{ "POSITION", 0, 0, 0, ""},
951
{ "POW", 0, 0, 0, ""},
952
{ "POWER", 0, 0, 0, ""},
953
{ "QUOTE", 0, 0, 0, ""},
954
{ "RADIANS", 0, 0, 0, ""},
955
{ "RAND", 0, 0, 0, ""},
956
{ "RELEASE_LOCK", 0, 0, 0, ""},
957
{ "REVERSE", 0, 0, 0, ""},
958
{ "ROUND", 0, 0, 0, ""},
959
{ "ROW_COUNT", 0, 0, 0, ""},
960
{ "RPAD", 0, 0, 0, ""},
961
{ "RTRIM", 0, 0, 0, ""},
962
{ "SEC_TO_TIME", 0, 0, 0, ""},
963
{ "SESSION_USER", 0, 0, 0, ""},
964
{ "SUBDATE", 0, 0, 0, ""},
965
{ "SIGN", 0, 0, 0, ""},
966
{ "SIN", 0, 0, 0, ""},
967
{ "SHA", 0, 0, 0, ""},
968
{ "SHA1", 0, 0, 0, ""},
969
{ "SLEEP", 0, 0, 0, ""},
970
{ "SOUNDEX", 0, 0, 0, ""},
971
{ "SPACE", 0, 0, 0, ""},
972
{ "SQRT", 0, 0, 0, ""},
973
{ "SRID", 0, 0, 0, ""},
974
{ "STARTPOINT", 0, 0, 0, ""},
975
{ "STD", 0, 0, 0, ""},
976
{ "STDDEV", 0, 0, 0, ""},
977
{ "STDDEV_POP", 0, 0, 0, ""},
978
{ "STDDEV_SAMP", 0, 0, 0, ""},
979
{ "STR_TO_DATE", 0, 0, 0, ""},
980
{ "STRCMP", 0, 0, 0, ""},
981
{ "SUBSTR", 0, 0, 0, ""},
982
{ "SUBSTRING", 0, 0, 0, ""},
983
{ "SUBSTRING_INDEX", 0, 0, 0, ""},
984
{ "SUBTIME", 0, 0, 0, ""},
985
{ "SUM", 0, 0, 0, ""},
986
{ "SYSDATE", 0, 0, 0, ""},
987
{ "SYSTEM_USER", 0, 0, 0, ""},
988
{ "TAN", 0, 0, 0, ""},
989
{ "TIME_FORMAT", 0, 0, 0, ""},
990
{ "TIME_TO_SEC", 0, 0, 0, ""},
991
{ "TIMEDIFF", 0, 0, 0, ""},
992
{ "TO_DAYS", 0, 0, 0, ""},
993
{ "TOUCHES", 0, 0, 0, ""},
994
{ "TRIM", 0, 0, 0, ""},
995
{ "UCASE", 0, 0, 0, ""},
996
{ "UNCOMPRESS", 0, 0, 0, ""},
997
{ "UNCOMPRESSED_LENGTH", 0, 0, 0, ""},
998
{ "UNHEX", 0, 0, 0, ""},
999
{ "UNIQUE_USERS", 0, 0, 0, ""},
1000
{ "UNIX_TIMESTAMP", 0, 0, 0, ""},
1001
{ "UPPER", 0, 0, 0, ""},
1002
{ "UUID", 0, 0, 0, ""},
1003
{ "VARIANCE", 0, 0, 0, ""},
1004
{ "VAR_POP", 0, 0, 0, ""},
1005
{ "VAR_SAMP", 0, 0, 0, ""},
1006
{ "VERSION", 0, 0, 0, ""},
1007
{ "WEEKDAY", 0, 0, 0, ""},
1008
{ "WEEKOFYEAR", 0, 0, 0, ""},
1009
{ "WITHIN", 0, 0, 0, ""},
1010
{ "X", 0, 0, 0, ""},
1011
{ "Y", 0, 0, 0, ""},
1012
{ "YEARWEEK", 0, 0, 0, ""},
1014
{ (char *)NULL, 0, 0, 0, ""}
1017
static const char *load_default_groups[]= { "mysql","client",0 };
1019
static int embedded_server_arg_count= 0;
1020
static char *embedded_server_args[MAX_SERVER_ARGS];
1021
static const char *embedded_server_groups[]=
1022
{ "server", "embedded", "mysql_SERVER", 0 };
1024
#ifdef HAVE_READLINE
1026
HIST_ENTRY is defined for libedit, but not for the real readline
1027
Need to redefine it for real readline to find it
1029
#if !defined(HAVE_HIST_ENTRY)
1030
typedef struct _hist_entry {
1036
extern "C" int add_history(const char *command); /* From readline directory */
1037
extern "C" int read_history(const char *command);
1038
extern "C" int write_history(const char *command);
1039
extern "C" HIST_ENTRY *history_get(int num);
1040
extern "C" int history_length;
1041
static int not_in_history(const char *line);
1042
static void initialize_readline (char *name);
1043
static void fix_history(String *final_command);
1046
static COMMANDS *find_command(char *name,char cmd_name);
1047
static bool add_line(String &buffer,char *line,char *in_string,
1049
static void remove_cntrl(String &buffer);
1050
static void print_table_data(MYSQL_RES *result);
1051
static void print_table_data_html(MYSQL_RES *result);
1052
static void print_table_data_xml(MYSQL_RES *result);
1053
static void print_tab_data(MYSQL_RES *result);
1054
static void print_table_data_vertically(MYSQL_RES *result);
1055
static void print_warnings(void);
1056
static ulong start_timer(void);
1057
static void end_timer(ulong start_time,char *buff);
1058
static void mysql_end_timer(ulong start_time,char *buff);
1059
static void nice_time(double sec,char *buff,bool part_second);
1060
extern "C" sig_handler mysql_end(int sig);
1061
extern "C" sig_handler handle_sigint(int sig);
1062
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1063
static sig_handler window_resize(int sig);
1066
int main(int argc,char *argv[])
1072
DBUG_PROCESS(argv[0]);
1074
delimiter_str= delimiter;
1075
default_prompt = my_strdup(getenv("MYSQL_PS1") ?
1076
getenv("MYSQL_PS1") :
1077
"mysql> ",MYF(MY_WME));
1078
current_prompt = my_strdup(default_prompt,MYF(MY_WME));
1081
outfile[0]=0; // no (default) outfile
1082
strmov(pager, "stdout"); // the default, if --pager wasn't given
1084
char *tmp=getenv("PAGER");
1085
if (tmp && strlen(tmp))
1087
default_pager_set= 1;
1088
strmov(default_pager, tmp);
1091
if (!isatty(0) || !isatty(1))
1093
status.batch=1; opt_silent=1;
1097
status.add_to_history=1;
1098
status.exit_status=1;
1102
The file descriptor-layer may be out-of-sync with the file-number layer,
1103
so we make sure that "stdout" is really open. If its file is closed then
1104
explicitly close the FD layer.
1106
int stdout_fileno_copy;
1107
stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */
1108
if (stdout_fileno_copy == -1)
1111
close(stdout_fileno_copy); /* Clean up dup(). */
1114
load_defaults("my",load_default_groups,&argc,&argv);
1116
if (get_options(argc, (char **) argv))
1118
free_defaults(defaults_argv);
1122
if (status.batch && !status.line_buff &&
1123
!(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin)))
1125
free_defaults(defaults_argv);
1129
if (mysql_server_init(embedded_server_arg_count, embedded_server_args,
1130
(char**) embedded_server_groups))
1133
free_defaults(defaults_argv);
1137
glob_buffer.realloc(512);
1138
completion_hash_init(&ht, 128);
1139
init_alloc_root(&hash_mem_root, 16384, 0);
1140
bzero((char*) &mysql, sizeof(mysql));
1141
if (sql_connect(current_host,current_db,current_user,opt_password,
1144
quick= 1; // Avoid history
1145
status.exit_status= 1;
1149
ignore_errors=1; // Don't abort monitor
1151
if (opt_sigint_ignore)
1152
signal(SIGINT, SIG_IGN);
1154
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
1155
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
1157
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1158
/* Readline will call this if it installs a handler */
1159
signal(SIGWINCH, window_resize);
1160
/* call the SIGWINCH handler to get the default term width */
1164
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
1166
sprintf((char*) glob_buffer.ptr(),
1167
"Your MySQL connection id is %lu\nServer version: %s\n",
1168
mysql_thread_id(&mysql), server_version_string(&mysql));
1169
put_info((char*) glob_buffer.ptr(),INFO_INFO);
1171
#ifdef HAVE_READLINE
1172
initialize_readline((char*) my_progname);
1173
if (!status.batch && !quick && !opt_html && !opt_xml)
1175
/* read-history from file, default ~/.mysql_history*/
1176
if (getenv("MYSQL_HISTFILE"))
1177
histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
1178
else if (getenv("HOME"))
1180
histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1181
+ (uint) strlen("/.mysql_history")+2,
1184
sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
1185
char link_name[FN_REFLEN];
1186
if (my_readlink(link_name, histfile, 0) == 0 &&
1187
strncmp(link_name, "/dev/null", 10) == 0)
1189
/* The .mysql_history file is a symlink to /dev/null, don't use it */
1190
my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
1197
tee_fprintf(stdout, "Reading history-file %s\n",histfile);
1198
read_history(histfile);
1199
if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1202
fprintf(stderr, "Couldn't allocate memory for temp histfile!\n");
1205
sprintf(histfile_tmp, "%s.TMP", histfile);
1211
"Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
1213
"Type 'help [[%]function name[%]]' to get help on usage of function.\n");
1215
put_info(buff,INFO_INFO);
1216
status.exit_status= read_and_execute(!status.batch);
1221
DBUG_RETURN(0); // Keep compiler happy
1225
sig_handler mysql_end(int sig)
1227
mysql_close(&mysql);
1228
#ifdef HAVE_READLINE
1229
if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
1233
tee_fprintf(stdout, "Writing history-file %s\n",histfile);
1234
if (!write_history(histfile_tmp))
1235
my_rename(histfile_tmp, histfile, MYF(MY_WME));
1237
batch_readline_end(status.line_buff);
1238
completion_hash_free(&ht);
1239
free_root(&hash_mem_root,MYF(0));
1243
put_info(sig ? "Aborted" : "Bye", INFO_RESULT);
1246
processed_prompt.free();
1247
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1248
my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1249
my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1250
my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
1251
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
1252
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
1253
my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
1254
my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
1255
my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
1256
my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
1258
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1260
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
1261
while (embedded_server_arg_count > 1)
1262
my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
1264
free_defaults(defaults_argv);
1266
exit(status.exit_status);
1271
This function handles sigint calls
1272
If query is in process, kill query
1273
no query in process, terminate like previous behavior
1275
sig_handler handle_sigint(int sig)
1277
char kill_buffer[40];
1278
MYSQL *kill_mysql= NULL;
1280
/* terminate if no query being executed, or we already tried interrupting */
1281
if (!executing_query || interrupted_query)
1284
kill_mysql= mysql_init(kill_mysql);
1285
if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
1286
"", opt_mysql_port, opt_mysql_unix_port,0))
1289
/* kill_buffer is always big enough because max length of %lu is 15 */
1290
sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
1291
mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
1292
mysql_close(kill_mysql);
1293
tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
1295
interrupted_query= 1;
1302
When SIGINT is raised on Windows, the OS creates a new thread to handle the
1303
interrupt. Once that thread completes, the main thread continues running
1304
only to find that it's resources have already been free'd when the sigint
1305
handler called mysql_end().
1315
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1316
sig_handler window_resize(int sig)
1318
struct winsize window_size;
1320
if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
1321
terminal_width= window_size.ws_col;
1325
static struct my_option my_long_options[] =
1327
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1329
{"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1332
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
1333
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1335
{"auto-rehash", OPT_AUTO_REHASH,
1336
"Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.",
1337
(uchar**) &opt_rehash, (uchar**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
1339
{"no-auto-rehash", 'A',
1340
"No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
1341
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1342
{"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1343
"Automatically switch to vertical output mode if the result is wider than the terminal width.",
1344
(uchar**) &auto_vertical_output, (uchar**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1346
"Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1347
{"character-sets-dir", OPT_CHARSETS_DIR,
1348
"Directory where character sets are.", (uchar**) &charsets_dir,
1349
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1350
{"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
1351
(uchar**) &column_types_flag, (uchar**) &column_types_flag,
1352
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1353
{"comments", 'c', "Preserve comments. Send comments to the server."
1354
" The default is --skip-comments (discard comments), enable with --comments",
1355
(uchar**) &preserve_comments, (uchar**) &preserve_comments,
1356
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1357
{"compress", 'C', "Use compression in server/client protocol.",
1358
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1362
{"debug", '#', "This is a non-debug version. Catch this and exit",
1363
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
1365
{"debug", '#', "Output debug log", (uchar**) &default_dbug_option,
1366
(uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1368
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
1369
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
1370
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1371
{"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag,
1372
(uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1373
{"database", 'D', "Database to use.", (uchar**) ¤t_db,
1374
(uchar**) ¤t_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1375
{"default-character-set", OPT_DEFAULT_CHARSET,
1376
"Set the default character set.", (uchar**) &default_charset,
1377
(uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1378
{"delimiter", OPT_DELIMITER, "Delimiter to be used.", (uchar**) &delimiter_str,
1379
(uchar**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1380
{"execute", 'e', "Execute command and quit. (Disables --force and history file)", 0,
1381
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1382
{"vertical", 'E', "Print the output of a query (rows) vertically.",
1383
(uchar**) &vertical, (uchar**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1385
{"force", 'f', "Continue even if we get an sql error.",
1386
(uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1388
{"named-commands", 'G',
1389
"Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.",
1390
(uchar**) &named_cmds, (uchar**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1392
{"no-named-commands", 'g',
1393
"Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
1394
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1395
{"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
1396
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1397
{"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
1398
(uchar**) &opt_local_infile,
1399
(uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
1400
{"no-beep", 'b', "Turn off beep on error.", (uchar**) &opt_nobeep,
1401
(uchar**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1402
{"host", 'h', "Connect to host.", (uchar**) ¤t_host,
1403
(uchar**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1404
{"html", 'H', "Produce HTML output.", (uchar**) &opt_html, (uchar**) &opt_html,
1405
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1406
{"xml", 'X', "Produce XML output", (uchar**) &opt_xml, (uchar**) &opt_xml, 0,
1407
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1408
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
1409
(uchar**) &line_numbers, (uchar**) &line_numbers, 0, GET_BOOL,
1410
NO_ARG, 1, 0, 0, 0, 0, 0},
1411
{"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
1412
NO_ARG, 0, 0, 0, 0, 0, 0},
1413
{"unbuffered", 'n', "Flush buffer after each query.", (uchar**) &unbuffered,
1414
(uchar**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1415
{"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
1416
(uchar**) &column_names, (uchar**) &column_names, 0, GET_BOOL,
1417
NO_ARG, 1, 0, 0, 0, 0, 0},
1418
{"skip-column-names", 'N',
1419
"Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
1420
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1421
{"set-variable", 'O',
1422
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
1423
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1424
{"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C)",
1425
(uchar**) &opt_sigint_ignore, (uchar**) &opt_sigint_ignore, 0, GET_BOOL,
1426
NO_ARG, 0, 0, 0, 0, 0, 0},
1427
{"one-database", 'o',
1428
"Only update the default database. This is useful for skipping updates to other database in the update log.",
1429
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1431
{"pager", OPT_PAGER,
1432
"Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.",
1433
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1434
{"no-pager", OPT_NOPAGER,
1435
"Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
1436
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1439
"Password to use when connecting to server. If password is not given it's asked from the tty.",
1440
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1442
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
1443
NO_ARG, 0, 0, 0, 0, 0, 0},
1445
{"port", 'P', "Port number to use for connection or 0 for default to, in "
1446
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
1447
#if MYSQL_PORT_DEFAULT == 0
1450
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
1451
(uchar**) &opt_mysql_port,
1452
(uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1453
{"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
1454
(uchar**) ¤t_prompt, (uchar**) ¤t_prompt, 0, GET_STR_ALLOC,
1455
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1456
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1457
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1459
"Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file.",
1460
(uchar**) &quick, (uchar**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1461
{"raw", 'r', "Write fields without conversion. Used with --batch.",
1462
(uchar**) &opt_raw_data, (uchar**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1464
{"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
1465
(uchar**) &opt_reconnect, (uchar**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
1466
{"silent", 's', "Be more silent. Print results with a tab as separator, each row on new line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
1469
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
1470
"Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
1471
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1473
{"socket", 'S', "Socket file to use for connection.",
1474
(uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
1475
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1476
{"table", 't', "Output in table format.", (uchar**) &output_tables,
1477
(uchar**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1479
"Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default.",
1480
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1481
{"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
1482
NO_ARG, 0, 0, 0, 0, 0, 0},
1483
#ifndef DONT_ALLOW_USER_CHANGE
1484
{"user", 'u', "User for login if not current user.", (uchar**) ¤t_user,
1485
(uchar**) ¤t_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1487
{"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
1488
(uchar**) &safe_updates, (uchar**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
1490
{"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
1491
(uchar**) &safe_updates, (uchar**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
1493
{"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
1494
0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1495
{"version", 'V', "Output version information and exit.", 0, 0, 0,
1496
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1497
{"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
1498
NO_ARG, 0, 0, 0, 0, 0, 0},
1499
{"connect_timeout", OPT_CONNECT_TIMEOUT,
1500
"Number of seconds before connection timeout.",
1501
(uchar**) &opt_connect_timeout,
1502
(uchar**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
1504
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1505
"Max packet length to send to, or receive from server",
1506
(uchar**) &opt_max_allowed_packet, (uchar**) &opt_max_allowed_packet, 0,
1507
GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
1508
(longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1509
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
1510
"Buffer for TCP/IP and socket communication",
1511
(uchar**) &opt_net_buffer_length, (uchar**) &opt_net_buffer_length, 0, GET_ULONG,
1512
REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
1513
{"select_limit", OPT_SELECT_LIMIT,
1514
"Automatic limit for SELECT when using --safe-updates",
1515
(uchar**) &select_limit,
1516
(uchar**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
1518
{"max_join_size", OPT_MAX_JOIN_SIZE,
1519
"Automatic limit for rows in a join when using --safe-updates",
1520
(uchar**) &max_join_size,
1521
(uchar**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1523
{"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
1524
" uses old (pre-4.1.1) protocol", (uchar**) &opt_secure_auth,
1525
(uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1526
{"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.",
1527
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1528
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
1529
(uchar**) &show_warnings, (uchar**) &show_warnings, 0, GET_BOOL, NO_ARG,
1531
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1535
static void usage(int version)
1537
/* Divert all help information on NetWare to logger screen. */
1539
#define printf consoleprintf
1542
#if defined(USE_LIBEDIT_INTERFACE)
1543
const char* readline= "";
1545
const char* readline= "readline";
1548
#ifdef HAVE_READLINE
1549
printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n",
1550
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
1551
readline, rl_library_version);
1553
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER,
1554
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
1560
Copyright (C) 2000-2008 MySQL AB\n\
1561
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
1562
and you are welcome to modify and redistribute it under the GPL license\n");
1563
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
1564
my_print_help(my_long_options);
1565
print_defaults("my", load_default_groups);
1566
my_print_variables(my_long_options);
1567
NETWARE_SET_SCREEN_MODE(1);
1575
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
1580
case OPT_AUTO_CLOSE:
1581
setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
1584
case OPT_CHARSETS_DIR:
1585
strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir) - 1);
1586
charsets_dir = mysql_charsets_dir;
1588
case OPT_DEFAULT_CHARSET:
1589
default_charset_used= 1;
1592
if (argument == disabled_my_option)
1594
strmov(delimiter, DEFAULT_DELIMITER);
1598
/* Check that delimiter does not contain a backslash */
1599
if (!strstr(argument, "\\"))
1601
strmake(delimiter, argument, sizeof(delimiter) - 1);
1605
put_info("DELIMITER cannot contain a backslash character", INFO_ERROR);
1609
delimiter_length= (uint)strlen(delimiter);
1610
delimiter_str= delimiter;
1612
case OPT_LOCAL_INFILE:
1613
using_opt_local_infile=1;
1616
if (argument == disabled_my_option)
1625
printf("WARNING: option deprecated; use --disable-tee instead.\n");
1630
if (argument == disabled_my_option)
1635
if (argument && strlen(argument))
1637
default_pager_set= 1;
1638
strmake(pager, argument, sizeof(pager) - 1);
1639
strmov(default_pager, pager);
1641
else if (default_pager_set)
1642
strmov(pager, default_pager);
1648
printf("WARNING: option deprecated; use --disable-pager instead.\n");
1651
case OPT_MYSQL_PROTOCOL:
1652
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
1655
case OPT_SERVER_ARG:
1656
#ifdef EMBEDDED_LIBRARY
1658
When the embedded server is being tested, the client needs to be
1659
able to pass command-line arguments to the embedded server so it can
1660
locate the language files and data directory.
1662
if (!embedded_server_arg_count)
1664
embedded_server_arg_count= 1;
1665
embedded_server_args[0]= (char*) "";
1667
if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
1668
!(embedded_server_args[embedded_server_arg_count++]=
1669
my_strdup(argument, MYF(MY_FAE))))
1671
put_info("Can't use server argument", INFO_ERROR);
1674
#else /*EMBEDDED_LIBRARY */
1675
printf("WARNING: --server-arg option not supported in this configuration.\n");
1686
status.add_to_history= 0;
1687
if (!status.line_buff)
1688
ignore_errors= 0; // do it for the first -e only
1689
if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
1693
if (argument == disabled_my_option)
1696
one_database= skip_updates= 1;
1699
if (argument == disabled_my_option)
1700
argument= (char*) ""; // Don't require password
1703
char *start= argument;
1704
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1705
opt_password= my_strdup(argument, MYF(MY_FAE));
1706
while (*argument) *argument++= 'x'; // Destroy argument
1715
DBUG_PUSH(argument ? argument : default_dbug_option);
1719
if (argument == disabled_my_option)
1725
if (argument == disabled_my_option)
1732
status.add_to_history= 0;
1733
set_if_bigger(opt_silent,1); // more silent
1748
static int get_options(int argc, char **argv)
1750
char *tmp, *pagpoint;
1752
MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
1754
tmp= (char *) getenv("MYSQL_HOST");
1756
current_host= my_strdup(tmp, MYF(MY_WME));
1758
pagpoint= getenv("PAGER");
1759
if (!((char*) (pagpoint)))
1761
strmov(pager, "stdout");
1765
strmov(pager, pagpoint);
1766
strmov(default_pager, pager);
1768
opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
1769
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
1771
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
1774
*mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
1775
*mysql_params->p_net_buffer_length= opt_net_buffer_length;
1777
if (status.batch) /* disable pager and outfile in this case */
1779
strmov(default_pager, "stdout");
1780
strmov(pager, "stdout");
1782
default_pager_set= 0;
1785
connect_flag= 0; /* Not in interactive mode */
1788
if (strcmp(default_charset, charset_info->csname) &&
1789
!(charset_info= get_charset_by_csname(default_charset,
1790
MY_CS_PRIMARY, MYF(MY_WME))))
1800
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
1801
current_db= my_strdup(*argv, MYF(MY_WME));
1804
opt_password= get_tty_password(NullS);
1805
if (debug_info_flag)
1806
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1807
if (debug_check_flag)
1808
my_end_arg= MY_CHECK_ERROR;
1812
static int read_and_execute(bool interactive)
1814
#if defined(__NETWARE__)
1815
char linebuffer[254];
1818
#if defined(__WIN__)
1825
ulong line_number=0;
1828
status.exit_status=1;
1834
line=batch_readline(status.line_buff);
1836
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
1837
Editors like "notepad" put this marker in
1838
the very beginning of a text file when
1839
you save the file using "Unicode UTF-8" format.
1842
(uchar) line[0] == 0xEF &&
1843
(uchar) line[1] == 0xBB &&
1844
(uchar) line[2] == 0xBF)
1847
if (!glob_buffer.length())
1848
status.query_start_line=line_number;
1852
char *prompt= (char*) (ml_comment ? " /*> " :
1853
glob_buffer.is_empty() ? construct_prompt() :
1854
!in_string ? " -> " :
1856
" '> " : (in_string == '`' ?
1859
if (opt_outfile && glob_buffer.is_empty())
1862
#if defined( __WIN__) || defined(__NETWARE__)
1863
tee_fputs(prompt, stdout);
1864
#if defined(__NETWARE__)
1865
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
1866
/* Remove the '\n' */
1869
char *p = strrchr(line, '\n');
1873
#else defined(__WIN__)
1874
if (!tmpbuf.is_alloced())
1875
tmpbuf.alloc(65535);
1881
line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen);
1882
buffer.append(line, clen);
1884
if we got buffer fully filled than there is a chance that
1885
something else is still in console input buffer
1887
} while (tmpbuf.alloced_length() <= clen);
1889
An empty line is returned from my_cgets when there's error reading :
1893
line= buffer.c_ptr();
1894
#endif /* __NETWARE__ */
1897
fputs(prompt, OUTFILE);
1898
line= readline(prompt);
1899
#endif /* defined( __WIN__) || defined(__NETWARE__) */
1902
When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
1903
which may cause coredump.
1905
if (opt_outfile && line)
1906
fprintf(OUTFILE, "%s\n", line);
1908
if (!line) // End of file
1910
status.exit_status=0;
1915
Check if line is a mysql command line
1916
(We want to allow help, print and clear anywhere at line start
1918
if ((named_cmds || glob_buffer.is_empty())
1919
&& !ml_comment && !in_string && (com=find_command(line,0)))
1921
if ((*com->func)(&glob_buffer,line) > 0)
1923
if (glob_buffer.is_empty()) // If buffer was emptied
1925
#ifdef HAVE_READLINE
1926
if (interactive && status.add_to_history && not_in_history(line))
1931
if (add_line(glob_buffer,line,&in_string,&ml_comment))
1934
/* if in batch mode, send last query even if it doesn't end with \g or go */
1936
if (!interactive && !status.exit_status)
1938
remove_cntrl(glob_buffer);
1939
if (!glob_buffer.is_empty())
1941
status.exit_status=1;
1942
if (com_go(&glob_buffer,line) <= 0)
1943
status.exit_status=0;
1947
#if defined( __WIN__) || defined(__NETWARE__)
1950
#if defined( __WIN__)
1954
return status.exit_status;
1958
static COMMANDS *find_command(char *name,char cmd_char)
1962
DBUG_ENTER("find_command");
1963
DBUG_PRINT("enter",("name: '%s' char: %d", name ? name : "NULL", cmd_char));
1972
while (my_isspace(charset_info,*name))
1975
If there is an \\g in the row or if the row has a delimiter but
1976
this is not a delimiter command, let add_line() take care of
1977
parsing the row and calling find_command()
1979
if (strstr(name, "\\g") || (strstr(name, delimiter) &&
1980
!(strlen(name) >= 9 &&
1981
!my_strnncoll(charset_info,
1983
(const uchar*) "delimiter",
1985
DBUG_RETURN((COMMANDS *) 0);
1986
if ((end=strcont(name," \t")))
1988
len=(uint) (end - name);
1989
while (my_isspace(charset_info,*end))
1992
end=0; // no arguments to function
1995
len=(uint) strlen(name);
1998
for (uint i= 0; commands[i].name; i++)
2000
if (commands[i].func &&
2002
!my_strnncoll(charset_info,(uchar*)name,len,
2003
(uchar*)commands[i].name,len) &&
2004
!commands[i].name[len] &&
2005
(!end || (end && commands[i].takes_params))) ||
2006
!name && commands[i].cmd_char == cmd_char))
2008
DBUG_PRINT("exit",("found command: %s", commands[i].name));
2009
DBUG_RETURN(&commands[i]);
2012
DBUG_RETURN((COMMANDS *) 0);
2016
static bool add_line(String &buffer,char *line,char *in_string,
2020
char buff[80], *pos, *out;
2024
DBUG_ENTER("add_line");
2026
if (!line[0] && buffer.is_empty())
2028
#ifdef HAVE_READLINE
2029
if (status.add_to_history && line[0] && not_in_history(line))
2032
char *end_of_line=line+(uint) strlen(line);
2034
for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
2036
if (!preserve_comments)
2038
// Skip spaces at the beggining of a statement
2039
if (my_isspace(charset_info,inchar) && (out == line) &&
2045
// Accept multi-byte characters as-is
2047
if (use_mb(charset_info) &&
2048
(length= my_ismbchar(charset_info, pos, end_of_line)))
2050
if (!*ml_comment || preserve_comments)
2061
if (!*ml_comment && inchar == '\\' &&
2062
!(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))
2064
// Found possbile one character command like \c
2066
if (!(inchar = (uchar) *++pos))
2067
break; // readline adds one '\'
2068
if (*in_string || inchar == 'N') // \N is short for NULL
2069
{ // Don't allow commands in string
2071
*out++= (char) inchar;
2074
if ((com=find_command(NullS,(char) inchar)))
2076
// Flush previously accepted characters
2079
buffer.append(line, (uint) (out-line));
2083
if ((*com->func)(&buffer,pos-1) > 0)
2084
DBUG_RETURN(1); // Quit
2085
if (com->takes_params)
2090
If a client-side macro appears inside a server-side comment,
2091
discard all characters in the comment after the macro (that is,
2092
until the end of the comment rather than the next delimiter)
2094
for (pos++; *pos && (*pos != '*' || *(pos + 1) != '/'); pos++)
2101
*pos && (*pos != *delimiter ||
2102
!is_prefix(pos + 1, delimiter + 1)) ; pos++)
2103
; // Remove parameters
2107
pos+= delimiter_length - 1; // Point at last delim char
2113
sprintf(buff,"Unknown command '\\%c'.",inchar);
2114
if (put_info(buff,INFO_ERROR) > 0)
2117
*out++=(char) inchar;
2121
else if (!*ml_comment && !*in_string &&
2122
(end_of_line - pos) >= 10 &&
2123
!my_strnncoll(charset_info, (uchar*) pos, 10,
2124
(const uchar*) "delimiter ", 10))
2126
// Flush previously accepted characters
2129
buffer.append(line, (uint32) (out - line));
2133
// Flush possible comments in the buffer
2134
if (!buffer.is_empty())
2136
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
2142
Delimiter wants the get rest of the given line as argument to
2143
allow one to change ';' to ';;' and back
2146
if (com_delimiter(&buffer, pos) > 0)
2152
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
2154
// Found a statement. Continue parsing after the delimiter
2155
pos+= delimiter_length;
2157
if (preserve_comments)
2159
while (my_isspace(charset_info, *pos))
2162
// Flush previously accepted characters
2165
buffer.append(line, (uint32) (out-line));
2169
if (preserve_comments && ((*pos == '#') ||
2172
my_isspace(charset_info, pos[2]))))
2174
// Add trailing single line comments to this statement
2181
if ((com= find_command(buffer.c_ptr(), 0)))
2184
if ((*com->func)(&buffer, buffer.c_ptr()) > 0)
2185
DBUG_RETURN(1); // Quit
2189
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
2194
else if (!*ml_comment && (!*in_string && (inchar == '#' ||
2195
inchar == '-' && pos[1] == '-' &&
2196
my_isspace(charset_info,pos[2]))))
2198
// Flush previously accepted characters
2201
buffer.append(line, (uint32) (out - line));
2205
// comment to end of line
2206
if (preserve_comments)
2211
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
2214
if (preserve_comments)
2216
*out++= *pos++; // copy '/'
2217
*out++= *pos; // copy '*'
2224
buffer.append(line,(uint) (out-line));
2228
else if (*ml_comment && !ss_comment && inchar == '*' && *(pos + 1) == '/')
2230
if (preserve_comments)
2232
*out++= *pos++; // copy '*'
2233
*out++= *pos; // copy '/'
2240
buffer.append(line, (uint32) (out - line));
2243
// Consumed a 2 chars or more, and will add 1 at most,
2244
// so using the 'line' buffer to edit data in place is ok.
2248
{ // Add found char to buffer
2249
if (!*in_string && inchar == '/' && *(pos + 1) == '*' &&
2252
else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/')
2254
if (inchar == *in_string)
2256
else if (!*ml_comment && !*in_string &&
2257
(inchar == '\'' || inchar == '"' || inchar == '`'))
2258
*in_string= (char) inchar;
2259
if (!*ml_comment || preserve_comments)
2261
if (need_space && !my_isspace(charset_info, (char)inchar))
2264
*out++= (char) inchar;
2268
if (out != line || !buffer.is_empty())
2271
uint length=(uint) (out-line);
2272
if (buffer.length() + length >= buffer.alloced_length())
2273
buffer.realloc(buffer.length()+length+IO_SIZE);
2274
if ((!*ml_comment || preserve_comments) && buffer.append(line, length))
2280
/*****************************************************************
2281
Interface to Readline Completion
2282
******************************************************************/
2284
#ifdef HAVE_READLINE
2286
static char *new_command_generator(const char *text, int);
2287
extern "C" char **new_mysql_completion (const char *text, int start, int end);
2290
Tell the GNU Readline library how to complete. We want to try to complete
2291
on command names if this is the first word in the line, or on filenames
2295
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE)
2296
extern "C" char *no_completion(const char*,int)
2298
extern "C" char *no_completion()
2301
return 0; /* No filename completion */
2304
/* glues pieces of history back together if in pieces */
2305
static void fix_history(String *final_command)
2307
int total_lines = 1;
2308
char *ptr = final_command->c_ptr();
2309
String fixed_buffer; /* Converted buffer */
2310
char str_char = '\0'; /* Character if we are in a string or not */
2312
/* find out how many lines we have and remove newlines */
2313
while (*ptr != '\0')
2316
/* string character */
2320
if (str_char == '\0') /* open string */
2322
else if (str_char == *ptr) /* close string */
2324
fixed_buffer.append(ptr,1);
2328
not in string, change to space
2329
if in string, leave it alone
2331
fixed_buffer.append(str_char == '\0' ? " " : "\n");
2335
fixed_buffer.append('\\');
2336
/* need to see if the backslash is escaping anything */
2340
/* special characters that need escaping */
2341
if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2342
fixed_buffer.append(ptr,1);
2349
fixed_buffer.append(ptr,1);
2353
if (total_lines > 1)
2354
add_history(fixed_buffer.ptr());
2358
returns 0 if line matches the previous history entry
2359
returns 1 if the line doesn't match the previous history entry
2361
static int not_in_history(const char *line)
2363
HIST_ENTRY *oldhist = history_get(history_length);
2367
if (strcmp(oldhist->line,line) == 0)
2372
static void initialize_readline (char *name)
2374
/* Allow conditional parsing of the ~/.inputrc file. */
2375
rl_readline_name = name;
2377
/* Tell the completer that we want a crack first. */
2378
rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
2379
rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2383
Attempt to complete on the contents of TEXT. START and END show the
2384
region of TEXT that contains the word to complete. We can use the
2385
entire line in case we want to do some simple parsing. Return the
2386
array of matches, or NULL if there aren't any.
2389
char **new_mysql_completion (const char *text,
2390
int start __attribute__((unused)),
2391
int end __attribute__((unused)))
2393
if (!status.batch && !quick)
2394
return rl_completion_matches(text, new_command_generator);
2399
static char *new_command_generator(const char *text,int state)
2408
textlen=(uint) strlen(text);
2411
{ /* lookup in the hash */
2416
b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2424
ptr= strdup(e->str);
2430
{ /* traverse the entire hash, ugly but works */
2434
/* find the first used bucket */
2435
for (i=0 ; i < ht.nTableSize ; i++)
2437
if (ht.arBuckets[i])
2439
b = ht.arBuckets[i];
2447
{ /* find valid entry in bucket */
2448
if ((uint) strlen(e->str) == b->nKeyLength)
2449
ptr = strdup(e->str);
2450
/* find the next used entry */
2453
{ /* find the next used bucket */
2457
for (i++ ; i<ht.nTableSize; i++)
2459
if (ht.arBuckets[i])
2461
b = ht.arBuckets[i];
2478
/* Build up the completion hash */
2480
static void build_completion_hash(bool rehash, bool write_info)
2482
COMMANDS *cmd=commands;
2483
MYSQL_RES *databases=0,*tables=0;
2485
static char ***field_names= 0;
2486
MYSQL_ROW database_row,table_row;
2487
MYSQL_FIELD *sql_field;
2488
char buf[NAME_LEN*2+2]; // table name plus field name plus 2
2490
DBUG_ENTER("build_completion_hash");
2492
if (status.batch || quick || !current_db)
2493
DBUG_VOID_RETURN; // We don't need completion in batches
2497
/* Free old used memory */
2500
completion_hash_clean(&ht);
2501
free_root(&hash_mem_root,MYF(0));
2503
/* hash this file's known subset of SQL commands */
2505
add_word(&ht,(char*) cmd->name);
2509
/* hash MySQL functions (to be implemented) */
2511
/* hash all database names */
2512
if (mysql_query(&mysql,"show databases") == 0)
2514
if (!(databases = mysql_store_result(&mysql)))
2515
put_info(mysql_error(&mysql),INFO_INFO);
2518
while ((database_row=mysql_fetch_row(databases)))
2520
char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
2522
add_word(&ht,(char*) str);
2524
mysql_free_result(databases);
2527
/* hash all table names */
2528
if (mysql_query(&mysql,"show tables")==0)
2530
if (!(tables = mysql_store_result(&mysql)))
2531
put_info(mysql_error(&mysql),INFO_INFO);
2534
if (mysql_num_rows(tables) > 0 && !opt_silent && write_info)
2536
tee_fprintf(stdout, "\
2537
Reading table information for completion of table and column names\n\
2538
You can turn off this feature to get a quicker startup with -A\n\n");
2540
while ((table_row=mysql_fetch_row(tables)))
2542
char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
2544
!completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
2550
/* hash all field names, both with the table prefix and without it */
2551
if (!tables) /* no tables */
2555
mysql_data_seek(tables,0);
2556
if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
2557
(uint) (mysql_num_rows(tables)+1))))
2559
mysql_free_result(tables);
2563
while ((table_row=mysql_fetch_row(tables)))
2565
if ((fields=mysql_list_fields(&mysql,(const char*) table_row[0],NullS)))
2567
num_fields=mysql_num_fields(fields);
2568
if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2572
mysql_free_result(fields);
2575
field_names[i][num_fields*2]= '\0';
2577
while ((sql_field=mysql_fetch_field(fields)))
2579
sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name);
2580
field_names[i][j] = strdup_root(&hash_mem_root,buf);
2581
add_word(&ht,field_names[i][j]);
2582
field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
2584
if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
2585
(uint) strlen(field_names[i][num_fields+j])))
2586
add_word(&ht,field_names[i][num_fields+j]);
2589
mysql_free_result(fields);
2596
mysql_free_result(tables);
2597
field_names[i]=0; // End pointer
2601
/* for gnu readline */
2605
extern char *index(const char *,int c),*rindex(const char *,int);
2607
char *index(const char *s,int c)
2611
if (*s == (char) c) return (char*) s;
2612
if (!*s++) return NullS;
2616
char *rindex(const char *s,int c)
2621
do if (*s == (char) c) t = (char*) s; while (*s++);
2626
#endif /* HAVE_READLINE */
2629
static int reconnect(void)
2631
/* purecov: begin tested */
2634
put_info("No connection. Trying to reconnect...",INFO_INFO);
2635
(void) com_connect((String *) 0, 0);
2637
com_rehash(NULL, NULL);
2640
return put_info("Can't connect to the server\n",INFO_ERROR);
2645
static void get_current_db()
2649
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
2651
/* In case of error below current_db will be NULL */
2652
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
2653
(res= mysql_use_result(&mysql)))
2655
MYSQL_ROW row= mysql_fetch_row(res);
2657
current_db= my_strdup(row[0], MYF(MY_WME));
2658
mysql_free_result(res);
2662
/***************************************************************************
2663
The different commands
2664
***************************************************************************/
2666
int mysql_real_query_for_lazy(const char *buf, int length)
2668
for (uint retry=0;; retry++)
2671
if (!mysql_real_query(&mysql,buf,length))
2673
error= put_error(&mysql);
2674
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
2682
int mysql_store_result_for_lazy(MYSQL_RES **result)
2684
if ((*result=mysql_store_result(&mysql)))
2687
if (mysql_error(&mysql)[0])
2688
return put_error(&mysql);
2692
static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *last_char)
2694
char ccat= (*cur)[num_cat][0];
2695
if (*last_char != ccat)
2697
put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO);
2700
tee_fprintf(PAGER, " %s\n", (*cur)[num_name]);
2704
static int com_server_help(String *buffer __attribute__((unused)),
2705
char *line __attribute__((unused)), char *help_arg)
2708
const char *server_cmd= buffer->ptr();
2713
if (help_arg[0] != '\'')
2715
char *end_arg= strend(help_arg);
2718
while (my_isspace(charset_info,*end_arg))
2722
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2723
server_cmd= cmd_buf;
2728
old_buffer= *buffer;
2732
if (!connected && reconnect())
2735
if ((error= mysql_real_query_for_lazy(server_cmd,(int)strlen(server_cmd))) ||
2736
(error= mysql_store_result_for_lazy(&result)))
2741
unsigned int num_fields= mysql_num_fields(result);
2742
my_ulonglong num_rows= mysql_num_rows(result);
2743
mysql_fetch_fields(result);
2744
if (num_fields==3 && num_rows==1)
2746
if (!(cur= mysql_fetch_row(result)))
2753
tee_fprintf(PAGER, "Name: \'%s\'\n", cur[0]);
2754
tee_fprintf(PAGER, "Description:\n%s", cur[1]);
2755
if (cur[2] && *((char*)cur[2]))
2756
tee_fprintf(PAGER, "Examples:\n%s", cur[2]);
2757
tee_fprintf(PAGER, "\n");
2760
else if (num_fields >= 2 && num_rows)
2765
int num_name= 0, num_cat= 0;
2767
if (num_fields == 2)
2769
put_info("Many help items for your request exist.", INFO_INFO);
2770
put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO);
2774
else if ((cur= mysql_fetch_row(result)))
2776
tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
2777
put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO);
2780
print_help_item(&cur,1,2,&last_char);
2783
while ((cur= mysql_fetch_row(result)))
2784
print_help_item(&cur,num_name,num_cat,&last_char);
2785
tee_fprintf(PAGER, "\n");
2790
put_info("\nNothing found", INFO_INFO);
2791
put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO);
2796
mysql_free_result(result);
2801
com_help(String *buffer __attribute__((unused)),
2802
char *line __attribute__((unused)))
2805
char * help_arg= strchr(line,' '), buff[32], *end;
2808
while (my_isspace(charset_info,*help_arg))
2811
return com_server_help(buffer,line,help_arg);
2814
put_info("\nFor information about MySQL products and services, visit:\n"
2815
" http://www.mysql.com/\n"
2816
"For developer information, including the MySQL Reference Manual, "
2818
" http://dev.mysql.com/\n"
2819
"To buy MySQL Network Support, training, or other products, visit:\n"
2820
" https://shop.mysql.com/\n", INFO_INFO);
2821
put_info("List of all MySQL commands:", INFO_INFO);
2823
put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO);
2824
for (i = 0; commands[i].name; i++)
2826
end= strmov(buff, commands[i].name);
2827
for (j= (int)strlen(commands[i].name); j < 10; j++)
2828
end= strmov(end, " ");
2829
if (commands[i].func)
2830
tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2831
commands[i].cmd_char, commands[i].doc);
2833
if (connected && mysql_get_server_version(&mysql) >= 40100)
2834
put_info("\nFor server side help, type 'help contents'\n", INFO_INFO);
2841
com_clear(String *buffer,char *line __attribute__((unused)))
2843
#ifdef HAVE_READLINE
2844
if (status.add_to_history)
2845
fix_history(buffer);
2853
com_charset(String *buffer __attribute__((unused)), char *line)
2855
char buff[256], *param;
2856
CHARSET_INFO * new_cs;
2857
strmake(buff, line, sizeof(buff) - 1);
2858
param= get_arg(buff, 0);
2859
if (!param || !*param)
2861
return put_info("Usage: \\C char_setname | charset charset_name",
2864
new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
2867
charset_info= new_cs;
2868
mysql_set_character_set(&mysql, charset_info->csname);
2869
default_charset= (char *)charset_info->csname;
2870
default_charset_used= 1;
2871
put_info("Charset changed", INFO_INFO);
2873
else put_info("Charset is not found", INFO_INFO);
2880
-1 if not fatal error
2886
com_go(String *buffer,char *line __attribute__((unused)))
2888
char buff[200]; /* about 110 chars used so far */
2889
char time_buff[52+3+1]; /* time max + space&parens + NUL */
2891
ulong timer, warnings= 0;
2895
interrupted_query= 0;
2898
old_buffer= *buffer; // Save for edit command
2902
/* Remove garbage for nicer messages */
2903
remove_cntrl(*buffer);
2905
if (buffer->is_empty())
2907
if (status.batch) // Ignore empty quries
2909
return put_info("No query specified\n",INFO_ERROR);
2912
if (!connected && reconnect())
2914
buffer->length(0); // Remove query on error
2915
return opt_reconnect ? -1 : 1; // Fatal error
2918
(void) com_print(buffer,0);
2921
(buffer->length() < 4 || my_strnncoll(charset_info,
2922
(const uchar*)buffer->ptr(),4,
2923
(const uchar*)"SET ",4)))
2925
(void) put_info("Ignoring query to other database",INFO_INFO);
2929
timer=start_timer();
2931
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
2933
#ifdef HAVE_READLINE
2934
if (status.add_to_history)
2936
buffer->append(vertical ? "\\G" : delimiter);
2937
/* Append final command onto history */
2938
fix_history(buffer);
2953
if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
2955
error= put_error(&mysql);
2961
error= mysql_store_result_for_lazy(&result);
2966
if (verbose >= 3 || !opt_silent)
2967
mysql_end_timer(timer,time_buff);
2971
/* Every branch must truncate buff . */
2974
if (!mysql_num_rows(result) && ! quick && !column_types_flag)
2976
strmov(buff, "Empty set");
2980
We must print XML header and footer
2981
to produce a well-formed XML even if
2982
the result set is empty (Bug#27608).
2985
print_table_data_xml(result);
2993
print_table_data_html(result);
2995
print_table_data_xml(result);
2996
else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
2997
print_table_data_vertically(result);
2998
else if (opt_silent && verbose <= 2 && !output_tables)
2999
print_tab_data(result);
3001
print_table_data(result);
3002
sprintf(buff,"%ld %s in set",
3003
(long) mysql_num_rows(result),
3004
(long) mysql_num_rows(result) == 1 ? "row" : "rows");
3006
if (mysql_errno(&mysql))
3007
error= put_error(&mysql);
3010
else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0)
3011
strmov(buff,"Query OK");
3013
sprintf(buff,"Query OK, %ld %s affected",
3014
(long) mysql_affected_rows(&mysql),
3015
(long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows");
3018
if ((warnings= mysql_warning_count(&mysql)))
3022
pos=int10_to_str(warnings, pos, 10);
3023
pos=strmov(pos, " warning");
3027
strmov(pos, time_buff);
3028
put_info(buff,INFO_RESULT);
3029
if (mysql_info(&mysql))
3030
put_info(mysql_info(&mysql),INFO_RESULT);
3031
put_info("",INFO_RESULT); // Empty row
3033
if (result && !mysql_eof(result)) /* Something wrong when using quick */
3034
error= put_error(&mysql);
3035
else if (unbuffered)
3037
mysql_free_result(result);
3038
} while (!(err= mysql_next_result(&mysql)));
3040
error= put_error(&mysql);
3044
/* Show warnings if any or error occured */
3045
if (show_warnings == 1 && (warnings >= 1 || error))
3048
if (!error && !status.batch &&
3049
(mysql.server_status & SERVER_STATUS_DB_DROPPED))
3053
return error; /* New command follows */
3057
static void init_pager()
3062
if (!(PAGER= popen(pager, "w")))
3064
tee_fprintf(stdout, "popen() failed! defaulting PAGER to stdout!\n");
3073
static void end_pager()
3082
static void init_tee(const char *file_name)
3087
if (!(new_outfile= my_fopen(file_name, O_APPEND | O_WRONLY, MYF(MY_WME))))
3089
tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
3092
OUTFILE = new_outfile;
3093
strmake(outfile, file_name, FN_REFLEN-1);
3094
tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
3100
static void end_tee()
3102
my_fclose(OUTFILE, MYF(0));
3110
com_ego(String *buffer,char *line)
3113
bool oldvertical=vertical;
3115
result=com_go(buffer,line);
3116
vertical=oldvertical;
3121
static const char *fieldtype2str(enum enum_field_types type)
3124
case MYSQL_TYPE_BIT: return "BIT";
3125
case MYSQL_TYPE_BLOB: return "BLOB";
3126
case MYSQL_TYPE_DATE: return "DATE";
3127
case MYSQL_TYPE_DATETIME: return "DATETIME";
3128
case MYSQL_TYPE_NEWDECIMAL: return "NEWDECIMAL";
3129
case MYSQL_TYPE_DECIMAL: return "DECIMAL";
3130
case MYSQL_TYPE_DOUBLE: return "DOUBLE";
3131
case MYSQL_TYPE_ENUM: return "ENUM";
3132
case MYSQL_TYPE_FLOAT: return "FLOAT";
3133
case MYSQL_TYPE_GEOMETRY: return "GEOMETRY";
3134
case MYSQL_TYPE_INT24: return "INT24";
3135
case MYSQL_TYPE_LONG: return "LONG";
3136
case MYSQL_TYPE_LONGLONG: return "LONGLONG";
3137
case MYSQL_TYPE_LONG_BLOB: return "LONG_BLOB";
3138
case MYSQL_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
3139
case MYSQL_TYPE_NEWDATE: return "NEWDATE";
3140
case MYSQL_TYPE_NULL: return "NULL";
3141
case MYSQL_TYPE_SET: return "SET";
3142
case MYSQL_TYPE_SHORT: return "SHORT";
3143
case MYSQL_TYPE_STRING: return "STRING";
3144
case MYSQL_TYPE_TIME: return "TIME";
3145
case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP";
3146
case MYSQL_TYPE_TINY: return "TINY";
3147
case MYSQL_TYPE_TINY_BLOB: return "TINY_BLOB";
3148
case MYSQL_TYPE_VAR_STRING: return "VAR_STRING";
3149
case MYSQL_TYPE_YEAR: return "YEAR";
3150
default: return "?-unknown-?";
3154
static char *fieldflags2str(uint f) {
3155
static char buf[1024];
3158
#define ff2s_check_flag(X) \
3159
if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
3160
ff2s_check_flag(NOT_NULL);
3161
ff2s_check_flag(PRI_KEY);
3162
ff2s_check_flag(UNIQUE_KEY);
3163
ff2s_check_flag(MULTIPLE_KEY);
3164
ff2s_check_flag(BLOB);
3165
ff2s_check_flag(UNSIGNED);
3166
ff2s_check_flag(ZEROFILL);
3167
ff2s_check_flag(BINARY);
3168
ff2s_check_flag(ENUM);
3169
ff2s_check_flag(AUTO_INCREMENT);
3170
ff2s_check_flag(TIMESTAMP);
3171
ff2s_check_flag(SET);
3172
ff2s_check_flag(NO_DEFAULT_VALUE);
3173
ff2s_check_flag(NUM);
3174
ff2s_check_flag(PART_KEY);
3175
ff2s_check_flag(GROUP);
3176
ff2s_check_flag(UNIQUE);
3177
ff2s_check_flag(BINCMP);
3178
ff2s_check_flag(ON_UPDATE_NOW);
3179
#undef ff2s_check_flag
3181
sprintf(s, " unknows=0x%04x", f);
3186
print_field_types(MYSQL_RES *result)
3191
while ((field = mysql_fetch_field(result)))
3193
tee_fprintf(PAGER, "Field %3u: `%s`\n"
3199
"Collation: %s (%u)\n"
3205
field->name, field->catalog, field->db, field->table,
3206
field->org_table, fieldtype2str(field->type),
3207
get_charset_name(field->charsetnr), field->charsetnr,
3208
field->length, field->max_length, field->decimals,
3209
fieldflags2str(field->flags));
3211
tee_puts("", PAGER);
3216
print_table_data(MYSQL_RES *result)
3218
String separator(256);
3223
num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
3224
if (column_types_flag)
3226
print_field_types(result);
3227
if (!mysql_num_rows(result))
3229
mysql_field_seek(result,0);
3231
separator.copy("+",1,charset_info);
3232
while ((field = mysql_fetch_field(result)))
3234
uint length= column_names ? field->name_length : 0;
3236
length=max(length,field->length);
3238
length=max(length,field->max_length);
3239
if (length < 4 && !IS_NOT_NULL(field->flags))
3240
length=4; // Room for "NULL"
3241
field->max_length=length;
3242
separator.fill(separator.length()+length+2,'-');
3243
separator.append('+');
3245
separator.append('\0'); // End marker for \0
3246
tee_puts((char*) separator.ptr(), PAGER);
3249
mysql_field_seek(result,0);
3250
(void) tee_fputs("|", PAGER);
3251
for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
3253
uint name_length= (uint) strlen(field->name);
3254
uint numcells= charset_info->cset->numcells(charset_info,
3256
field->name + name_length);
3257
uint display_length= field->max_length + name_length - numcells;
3258
tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3261
num_flag[off]= IS_NUM(field->type);
3263
(void) tee_fputs("\n", PAGER);
3264
tee_puts((char*) separator.ptr(), PAGER);
3267
while ((cur= mysql_fetch_row(result)))
3269
if (interrupted_query)
3271
ulong *lengths= mysql_fetch_lengths(result);
3272
(void) tee_fputs("| ", PAGER);
3273
mysql_field_seek(result, 0);
3274
for (uint off= 0; off < mysql_num_fields(result); off++)
3278
uint field_max_length;
3279
uint visible_length;
3282
if (cur[off] == NULL)
3290
data_length= (uint) lengths[off];
3293
field= mysql_fetch_field(result);
3294
field_max_length= field->max_length;
3297
How many text cells on the screen will this string span? If it contains
3298
multibyte characters, then the number of characters we occupy on screen
3299
will be fewer than the number of bytes we occupy in memory.
3301
We need to find how much screen real-estate we will occupy to know how
3302
many extra padding-characters we should send with the printing function.
3304
visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
3305
extra_padding= data_length - visible_length;
3307
if (field_max_length > MAX_COLUMN_LENGTH)
3308
tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
3311
if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
3312
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
3314
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
3316
tee_fputs(" | ", PAGER);
3318
(void) tee_fputs("\n", PAGER);
3320
tee_puts((char*) separator.ptr(), PAGER);
3321
my_afree((uchar*) num_flag);
3325
Return the length of a field after it would be rendered into text.
3327
This doesn't know or care about multibyte characters. Assume we're
3328
using such a charset. We can't know that all of the upcoming rows
3329
for this column will have bytes that each render into some fraction
3330
of a character. It's at least possible that a row has bytes that
3331
all render into one character each, and so the maximum length is
3332
still the number of bytes. (Assumption 1: This can't be better
3333
because we can never know the number of characters that the DB is
3334
going to send -- only the number of bytes. 2: Chars <= Bytes.)
3336
@param field Pointer to a field to be inspected
3338
@returns number of character positions to be used, at most
3340
static int get_field_disp_length(MYSQL_FIELD *field)
3342
uint length= column_names ? field->name_length : 0;
3345
length= max(length, field->length);
3347
length= max(length, field->max_length);
3349
if (length < 4 && !IS_NOT_NULL(field->flags))
3350
length= 4; /* Room for "NULL" */
3356
For a new result, return the max number of characters that any
3357
upcoming row may return.
3359
@param result Pointer to the result to judge
3361
@returns The max number of characters in any row of this result
3363
static int get_result_width(MYSQL_RES *result)
3365
unsigned int len= 0;
3367
MYSQL_FIELD_OFFSET offset;
3370
offset= mysql_field_tell(result);
3371
DBUG_ASSERT(offset == 0);
3376
while ((field= mysql_fetch_field(result)) != NULL)
3377
len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
3379
(void) mysql_field_seek(result, offset);
3381
return len + 1; /* plus final bar. */
3385
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
3388
For '\0's print ASCII spaces instead, as '\0' is eaten by (at
3389
least my) console driver, and that messes up the pretty table
3390
grid. (The \0 is also the reason we can't use fprintf() .)
3395
if (right_justified)
3396
for (i= data_length; i < total_bytes_to_send; i++)
3397
tee_putc((int)' ', PAGER);
3399
for (i= 0, p= data; i < data_length; i+= 1, p+= 1)
3402
tee_putc((int)' ', PAGER);
3404
tee_putc((int)*p, PAGER);
3407
if (! right_justified)
3408
for (i= data_length; i < total_bytes_to_send; i++)
3409
tee_putc((int)' ', PAGER);
3415
print_table_data_html(MYSQL_RES *result)
3420
mysql_field_seek(result,0);
3421
(void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
3424
while((field = mysql_fetch_field(result)))
3426
tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
3427
(field->name[0] ? field->name :
3428
" ") : "NULL"));
3430
(void) tee_fputs("</TR>", PAGER);
3432
while ((cur = mysql_fetch_row(result)))
3434
if (interrupted_query)
3436
ulong *lengths=mysql_fetch_lengths(result);
3437
(void) tee_fputs("<TR>", PAGER);
3438
for (uint i=0; i < mysql_num_fields(result); i++)
3440
(void) tee_fputs("<TD>", PAGER);
3441
safe_put_field(cur[i],lengths[i]);
3442
(void) tee_fputs("</TD>", PAGER);
3444
(void) tee_fputs("</TR>", PAGER);
3446
(void) tee_fputs("</TABLE>", PAGER);
3451
print_table_data_xml(MYSQL_RES *result)
3454
MYSQL_FIELD *fields;
3456
mysql_field_seek(result,0);
3458
tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
3459
xmlencode_print(glob_buffer.ptr(), (int)strlen(glob_buffer.ptr()));
3460
tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
3463
fields = mysql_fetch_fields(result);
3464
while ((cur = mysql_fetch_row(result)))
3466
if (interrupted_query)
3468
ulong *lengths=mysql_fetch_lengths(result);
3469
(void) tee_fputs("\n <row>\n", PAGER);
3470
for (uint i=0; i < mysql_num_fields(result); i++)
3472
tee_fprintf(PAGER, "\t<field name=\"");
3473
xmlencode_print(fields[i].name, (uint) strlen(fields[i].name));
3476
tee_fprintf(PAGER, "\">");
3477
xmlencode_print(cur[i], lengths[i]);
3478
tee_fprintf(PAGER, "</field>\n");
3481
tee_fprintf(PAGER, "\" xsi:nil=\"true\" />\n");
3483
(void) tee_fputs(" </row>\n", PAGER);
3485
(void) tee_fputs("</resultset>\n", PAGER);
3490
print_table_data_vertically(MYSQL_RES *result)
3496
while ((field = mysql_fetch_field(result)))
3498
uint length= field->name_length;
3499
if (length > max_length)
3501
field->max_length=length;
3504
mysql_field_seek(result,0);
3505
for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
3507
if (interrupted_query)
3509
mysql_field_seek(result,0);
3511
"*************************** %d. row ***************************\n", row_count);
3512
for (uint off=0; off < mysql_num_fields(result); off++)
3514
field= mysql_fetch_field(result);
3515
tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
3516
tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
3522
/* print_warnings should be called right after executing a statement */
3524
static void print_warnings()
3529
my_ulonglong num_rows;
3531
/* Save current error before calling "show warnings" */
3532
uint error= mysql_errno(&mysql);
3534
/* Get the warnings */
3535
query= "show warnings";
3536
mysql_real_query_for_lazy(query, strlen(query));
3537
mysql_store_result_for_lazy(&result);
3539
/* Bail out when no warnings */
3540
if (!(num_rows= mysql_num_rows(result)))
3543
cur= mysql_fetch_row(result);
3546
Don't print a duplicate of the current error. It is possible for SHOW
3547
WARNINGS to return multiple errors with the same code, but different
3548
messages. To be safe, skip printing the duplicate only if it is the only
3551
if (!cur || num_rows == 1 && error == (uint) strtoul(cur[1], NULL, 10))
3554
/* Print the warnings */
3558
tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3559
} while ((cur= mysql_fetch_row(result)));
3563
mysql_free_result(result);
3567
static const char *array_value(const char **array, char key)
3569
for (; *array; array+= 2)
3577
xmlencode_print(const char *src, uint length)
3580
tee_fputs("NULL", PAGER);
3583
for (const char *p = src; *p && length; *p++, length--)
3586
if ((t = array_value(xmlmeta, *p)))
3587
tee_fputs(t, PAGER);
3589
tee_putc(*p, PAGER);
3596
safe_put_field(const char *pos,ulong length)
3599
tee_fputs("NULL", PAGER);
3603
tee_fputs(pos, PAGER);
3604
else for (const char *end=pos+length ; pos != end ; pos++)
3608
if (use_mb(charset_info) &&
3609
(l = my_ismbchar(charset_info, pos, end)))
3612
tee_putc(*pos++, PAGER);
3618
tee_fputs("\\0", PAGER); // This makes everything hard
3619
else if (*pos == '\t')
3620
tee_fputs("\\t", PAGER); // This would destroy tab format
3621
else if (*pos == '\n')
3622
tee_fputs("\\n", PAGER); // This too
3623
else if (*pos == '\\')
3624
tee_fputs("\\\\", PAGER);
3626
tee_putc(*pos, PAGER);
3633
print_tab_data(MYSQL_RES *result)
3639
if (opt_silent < 2 && column_names)
3642
while ((field = mysql_fetch_field(result)))
3645
(void) tee_fputs("\t", PAGER);
3646
(void) tee_fputs(field->name, PAGER);
3648
(void) tee_fputs("\n", PAGER);
3650
while ((cur = mysql_fetch_row(result)))
3652
lengths=mysql_fetch_lengths(result);
3653
safe_put_field(cur[0],lengths[0]);
3654
for (uint off=1 ; off < mysql_num_fields(result); off++)
3656
(void) tee_fputs("\t", PAGER);
3657
safe_put_field(cur[off], lengths[off]);
3659
(void) tee_fputs("\n", PAGER);
3664
com_tee(String *buffer, char *line __attribute__((unused)))
3666
char file_name[FN_REFLEN], *end, *param;
3670
while (my_isspace(charset_info,*line))
3672
if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
3674
if (!strlen(outfile))
3676
printf("No previous outfile available, you must give a filename!\n");
3679
else if (opt_outfile)
3681
tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
3685
param = outfile; //resume using the old outfile
3688
/* eliminate the spaces before the parameters */
3689
while (my_isspace(charset_info,*param))
3691
end= strmake(file_name, param, sizeof(file_name) - 1);
3692
/* remove end space from command line */
3693
while (end > file_name && (my_isspace(charset_info,end[-1]) ||
3694
my_iscntrl(charset_info,end[-1])))
3697
if (end == file_name)
3699
printf("No outfile specified!\n");
3702
init_tee(file_name);
3708
com_notee(String *buffer __attribute__((unused)),
3709
char *line __attribute__((unused)))
3713
tee_fprintf(stdout, "Outfile disabled.\n");
3718
Sorry, this command is not available in Windows.
3723
com_pager(String *buffer, char *line __attribute__((unused)))
3725
char pager_name[FN_REFLEN], *end, *param;
3729
/* Skip spaces in front of the pager command */
3730
while (my_isspace(charset_info, *line))
3732
/* Skip the pager command */
3733
param= strchr(line, ' ');
3734
/* Skip the spaces between the command and the argument */
3735
while (param && my_isspace(charset_info, *param))
3737
if (!param || !strlen(param)) // if pager was not given, use the default
3739
if (!default_pager_set)
3741
tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3743
strmov(pager, "stdout");
3747
strmov(pager, default_pager);
3751
end= strmake(pager_name, param, sizeof(pager_name)-1);
3752
while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
3753
my_iscntrl(charset_info,end[-1])))
3756
strmov(pager, pager_name);
3757
strmov(default_pager, pager_name);
3760
tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3766
com_nopager(String *buffer __attribute__((unused)),
3767
char *line __attribute__((unused)))
3769
strmov(pager, "stdout");
3772
tee_fprintf(stdout, "PAGER set to stdout\n");
3779
Sorry, you can't send the result to an editor in Win32
3784
com_edit(String *buffer,char *line __attribute__((unused)))
3786
char filename[FN_REFLEN],buff[160];
3790
if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY,
3793
if (buffer->is_empty() && !old_buffer.is_empty())
3794
(void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(),
3797
(void) my_write(fd,(uchar*) buffer->ptr(),buffer->length(),MYF(MY_WME));
3798
(void) my_close(fd,MYF(0));
3800
if (!(editor = (char *)getenv("EDITOR")) &&
3801
!(editor = (char *)getenv("VISUAL")))
3803
strxmov(buff,editor," ",filename,NullS);
3804
(void) system(buff);
3807
if (!my_stat(filename,&stat_arg,MYF(MY_WME)))
3809
if ((fd = my_open(filename,O_RDONLY, MYF(MY_WME))) < 0)
3811
(void) buffer->alloc((uint) stat_arg.st_size);
3812
if ((tmp=read(fd,(char*) buffer->ptr(),buffer->alloced_length())) >= 0L)
3813
buffer->length((uint) tmp);
3816
(void) my_close(fd,MYF(0));
3817
(void) my_delete(filename,MYF(MY_WME));
3824
/* If arg is given, exit without errors. This happens on command 'quit' */
3827
com_quit(String *buffer __attribute__((unused)),
3828
char *line __attribute__((unused)))
3830
/* let the screen auto close on a normal shutdown */
3831
NETWARE_SET_SCREEN_MODE(SCR_AUTOCLOSE_ON_EXIT);
3832
status.exit_status=0;
3837
com_rehash(String *buffer __attribute__((unused)),
3838
char *line __attribute__((unused)))
3840
#ifdef HAVE_READLINE
3841
build_completion_hash(1, 0);
3849
com_shell(String *buffer, char *line __attribute__((unused)))
3853
/* Skip space from line begin */
3854
while (my_isspace(charset_info, *line))
3856
if (!(shell_cmd = strchr(line, ' ')))
3858
put_info("Usage: \\! shell-command", INFO_ERROR);
3862
The output of the shell command does not
3863
get directed to the pager or the outfile
3865
if (system(shell_cmd) == -1)
3867
put_info(strerror(errno), INFO_ERROR, errno);
3876
com_print(String *buffer,char *line __attribute__((unused)))
3878
tee_puts("--------------", stdout);
3879
(void) tee_fputs(buffer->c_ptr(), stdout);
3880
if (!buffer->length() || (*buffer)[buffer->length()-1] != '\n')
3881
tee_putc('\n', stdout);
3882
tee_puts("--------------\n", stdout);
3883
return 0; /* If empty buffer */
3888
com_connect(String *buffer, char *line)
3890
char *tmp, buff[256];
3891
bool save_rehash= opt_rehash;
3894
bzero(buff, sizeof(buff));
3898
Two null bytes are needed in the end of buff to allow
3899
get_arg to find end of string the second time it's called.
3901
tmp= strmake(buff, line, sizeof(buff)-2);
3905
tmp= get_arg(buff, 0);
3908
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
3909
current_db= my_strdup(tmp, MYF(MY_WME));
3910
tmp= get_arg(buff, 1);
3913
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
3914
current_host=my_strdup(tmp,MYF(MY_WME));
3919
/* Quick re-connect */
3920
opt_rehash= 0; /* purecov: tested */
3922
buffer->length(0); // command used
3926
error=sql_connect(current_host,current_db,current_user,opt_password,0);
3927
opt_rehash= save_rehash;
3931
sprintf(buff,"Connection id: %lu",mysql_thread_id(&mysql));
3932
put_info(buff,INFO_INFO);
3933
sprintf(buff,"Current database: %.128s\n",
3934
current_db ? current_db : "*** NONE ***");
3935
put_info(buff,INFO_INFO);
3941
static int com_source(String *buffer, char *line)
3943
char source_name[FN_REFLEN], *end, *param;
3944
LINE_BUFFER *line_buff;
3949
/* Skip space from file name */
3950
while (my_isspace(charset_info,*line))
3952
if (!(param = strchr(line, ' '))) // Skip command name
3953
return put_info("Usage: \\. <filename> | source <filename>",
3955
while (my_isspace(charset_info,*param))
3957
end=strmake(source_name,param,sizeof(source_name)-1);
3958
while (end > source_name && (my_isspace(charset_info,end[-1]) ||
3959
my_iscntrl(charset_info,end[-1])))
3962
unpack_filename(source_name,source_name);
3963
/* open file name */
3964
if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
3966
char buff[FN_REFLEN+60];
3967
sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3968
return put_info(buff, INFO_ERROR, 0);
3971
if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file)))
3973
my_fclose(sql_file,MYF(0));
3974
return put_info("Can't initialize batch_readline", INFO_ERROR, 0);
3977
/* Save old status */
3979
bfill((char*) &status,sizeof(status),(char) 0);
3981
status.batch=old_status.batch; // Run in batch mode
3982
status.line_buff=line_buff;
3983
status.file_name=source_name;
3984
glob_buffer.length(0); // Empty command buffer
3985
error= read_and_execute(false);
3986
status=old_status; // Continue as before
3987
my_fclose(sql_file,MYF(0));
3988
batch_readline_end(line_buff);
3995
com_delimiter(String *buffer __attribute__((unused)), char *line)
3997
char buff[256], *tmp;
3999
strmake(buff, line, sizeof(buff) - 1);
4000
tmp= get_arg(buff, 0);
4004
put_info("DELIMITER must be followed by a 'delimiter' character or string",
4010
if (strstr(tmp, "\\"))
4012
put_info("DELIMITER cannot contain a backslash character", INFO_ERROR);
4016
strmake(delimiter, tmp, sizeof(delimiter) - 1);
4017
delimiter_length= (int)strlen(delimiter);
4018
delimiter_str= delimiter;
4024
com_use(String *buffer __attribute__((unused)), char *line)
4026
char *tmp, buff[FN_REFLEN + 1];
4029
bzero(buff, sizeof(buff));
4030
strmake(buff, line, sizeof(buff) - 1);
4031
tmp= get_arg(buff, 0);
4034
put_info("USE must be followed by a database name", INFO_ERROR);
4038
We need to recheck the current database, because it may change
4039
under our feet, for example if DROP DATABASE or RENAME DATABASE
4040
(latter one not yet available by the time the comment was written)
4044
if (!current_db || cmp_database(charset_info, current_db,tmp))
4049
select_db= 0; // don't do mysql_select_db()
4052
select_db= 2; // do mysql_select_db() and build_completion_hash()
4057
USE to the current db specified.
4058
We do need to send mysql_select_db() to make server
4059
update database level privileges, which might
4060
change since last USE (see bug#10979).
4061
For performance purposes, we'll skip rebuilding of completion hash.
4064
select_db= 1; // do only mysql_select_db(), without completion
4070
reconnect once if connection is down or if connection was found to
4071
be down during query
4073
if (!connected && reconnect())
4074
return opt_reconnect ? -1 : 1; // Fatal error
4075
if (mysql_select_db(&mysql,tmp))
4077
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR)
4078
return put_error(&mysql);
4081
return opt_reconnect ? -1 : 1; // Fatal error
4082
if (mysql_select_db(&mysql,tmp))
4083
return put_error(&mysql);
4085
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
4086
current_db=my_strdup(tmp,MYF(MY_WME));
4087
#ifdef HAVE_READLINE
4089
build_completion_hash(opt_rehash, 1);
4093
put_info("Database changed",INFO_INFO);
4098
com_warnings(String *buffer __attribute__((unused)),
4099
char *line __attribute__((unused)))
4102
put_info("Show warnings enabled.",INFO_INFO);
4107
com_nowarnings(String *buffer __attribute__((unused)),
4108
char *line __attribute__((unused)))
4111
put_info("Show warnings disabled.",INFO_INFO);
4116
Gets argument from a command on the command line. If get_next_arg is
4117
not defined, skips the command and returns the first argument. The
4118
line is modified by adding zero to the end of the argument. If
4119
get_next_arg is defined, then the function searches for end of string
4120
first, after found, returns the next argument and adds zero to the
4121
end. If you ever wish to use this feature, remember to initialize all
4122
items in the array to zero first.
4125
char *get_arg(char *line, my_bool get_next_arg)
4128
my_bool quoted= 0, valid_arg= 0;
4134
for (; *ptr; ptr++) ;
4140
/* skip leading white spaces */
4141
while (my_isspace(charset_info, *ptr))
4143
if (*ptr == '\\') // short command was used
4146
while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
4151
while (my_isspace(charset_info, *ptr))
4153
if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
4159
for (start=ptr ; *ptr; ptr++)
4161
if (*ptr == '\\' && ptr[1]) // escaped character
4163
// Remove the backslash
4166
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
4172
valid_arg= ptr != start;
4173
return valid_arg ? start : NullS;
4178
sql_real_connect(char *host,char *database,char *user,char *password,
4184
mysql_close(&mysql);
4187
if (opt_connect_timeout)
4189
uint timeout=opt_connect_timeout;
4190
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
4194
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
4195
if (opt_secure_auth)
4196
mysql_options(&mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
4197
if (using_opt_local_infile)
4198
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
4199
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
4201
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
4202
opt_ssl_capath, opt_ssl_cipher);
4203
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
4204
(char*)&opt_ssl_verify_server_cert);
4207
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
4209
if (shared_memory_base_name)
4210
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
4214
char init_command[100];
4215
sprintf(init_command,
4216
"SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%lu,SQL_MAX_JOIN_SIZE=%lu",
4217
select_limit,max_join_size);
4218
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
4220
if (default_charset_used)
4221
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
4222
if (!mysql_real_connect(&mysql, host, user, password,
4223
database, opt_mysql_port, opt_mysql_unix_port,
4224
connect_flag | CLIENT_MULTI_STATEMENTS))
4227
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
4228
mysql_errno(&mysql) != CR_CONNECTION_ERROR))
4230
(void) put_error(&mysql);
4231
(void) fflush(stdout);
4232
return ignore_errors ? -1 : 1; // Abort
4234
return -1; // Retryable
4237
#ifndef EMBEDDED_LIBRARY
4238
mysql.reconnect= debug_info_flag; // We want to know if this happens
4242
#ifdef HAVE_READLINE
4243
build_completion_hash(opt_rehash, 1);
4250
sql_connect(char *host,char *database,char *user,char *password,uint silent)
4257
if ((error=sql_real_connect(host,database,user,password,wait_flag)) >= 0)
4261
tee_fputs("\n", stderr);
4262
(void) fflush(stderr);
4267
return ignore_errors ? -1 : 1;
4268
if (!message && !silent)
4271
tee_fputs("Waiting",stderr); (void) fflush(stderr);
4273
(void) sleep(wait_time);
4276
putc('.',stderr); (void) fflush(stderr);
4285
com_status(String *buffer __attribute__((unused)),
4286
char *line __attribute__((unused)))
4288
const char *status_str;
4293
tee_puts("--------------", stdout);
4294
usage(1); /* Print version */
4297
tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
4299
Don't remove "limit 1",
4300
it is protection againts SQL_SELECT_LIMIT=0
4302
if (!mysql_query(&mysql,"select DATABASE(), USER() limit 1") &&
4303
(result=mysql_use_result(&mysql)))
4305
MYSQL_ROW cur=mysql_fetch_row(result);
4308
tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
4309
tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
4311
mysql_free_result(result);
4313
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
4314
if ((status_str= mysql_get_ssl_cipher(&mysql)))
4315
tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
4318
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
4319
tee_puts("SSL:\t\t\tNot in use", stdout);
4324
tee_fprintf(stdout, "\nNo connection\n");
4331
tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4335
tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
4336
tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
4338
tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
4339
tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&mysql));
4340
tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql));
4341
tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql));
4342
if ((id= mysql_insert_id(&mysql)))
4343
tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
4345
/* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
4346
if (!mysql_query(&mysql,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
4347
(result=mysql_use_result(&mysql)))
4349
MYSQL_ROW cur=mysql_fetch_row(result);
4352
tee_fprintf(stdout, "Server characterset:\t%s\n", cur[2] ? cur[2] : "");
4353
tee_fprintf(stdout, "Db characterset:\t%s\n", cur[3] ? cur[3] : "");
4354
tee_fprintf(stdout, "Client characterset:\t%s\n", cur[0] ? cur[0] : "");
4355
tee_fprintf(stdout, "Conn. characterset:\t%s\n", cur[1] ? cur[1] : "");
4357
mysql_free_result(result);
4361
/* Probably pre-4.1 server */
4362
tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname);
4363
tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname);
4366
#ifndef EMBEDDED_LIBRARY
4367
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
4368
tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
4370
tee_fprintf(stdout, "UNIX socket:\t\t%s\n", mysql.unix_socket);
4371
if (mysql.net.compress)
4372
tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
4375
if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
4378
const char *pos= strchr(status_str,' ');
4380
tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str);
4381
if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec)))
4383
nice_time((double) sec,buff,0);
4384
tee_puts(buff, stdout); /* print nice time */
4385
while (*status_str == ' ')
4386
status_str++; /* to next info */
4387
tee_putc('\n', stdout);
4388
tee_puts(status_str, stdout);
4394
tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n");
4396
tee_fprintf(stdout, "\
4397
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4398
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n\
4399
SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n\
4400
Max number of examined row combination in a join is set to: %lu\n\n",
4401
select_limit, max_join_size);
4403
tee_puts("--------------\n", stdout);
4408
server_version_string(MYSQL *con)
4410
static char buf[MAX_SERVER_VERSION_LENGTH] = "";
4412
/* Only one thread calls this, so no synchronization is needed */
4418
bufp= strnmov(buf, mysql_get_server_info(con), sizeof buf);
4420
/* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
4421
if (!mysql_query(con, "select @@version_comment limit 1") &&
4422
(result = mysql_use_result(con)))
4424
MYSQL_ROW cur = mysql_fetch_row(result);
4427
bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
4429
mysql_free_result(result);
4432
/* str*nmov doesn't guarantee NUL-termination */
4433
if (bufp == buf + sizeof buf)
4434
buf[sizeof buf - 1] = '\0';
4441
put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
4443
FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
4444
static int inited=0;
4448
if (info_type == INFO_ERROR)
4450
(void) fflush(file);
4451
fprintf(file,"ERROR");
4455
(void) fprintf(file," %d (%s)",error, sqlstate);
4457
(void) fprintf(file," %d",error);
4459
if (status.query_start_line && line_numbers)
4461
(void) fprintf(file," at line %lu",status.query_start_line);
4462
if (status.file_name)
4463
(void) fprintf(file," in file: '%s'", status.file_name);
4465
(void) fprintf(file,": %s\n",str);
4466
(void) fflush(file);
4470
else if (info_type == INFO_RESULT && verbose > 1)
4471
tee_puts(str, file);
4474
return info_type == INFO_ERROR ? -1 : 0;
4476
if (!opt_silent || info_type == INFO_ERROR)
4481
#ifdef HAVE_SETUPTERM
4482
(void) setupterm((char *)0, 1, (int *) 0);
4485
if (info_type == INFO_ERROR)
4488
putchar('\a'); /* This should make a bell */
4489
vidattr(A_STANDOUT);
4493
(void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate);
4495
(void) tee_fprintf(file, "ERROR %d: ", error);
4498
tee_puts("ERROR: ", file);
4502
(void) tee_puts(str, file);
4507
return info_type == INFO_ERROR ? -1 : 0;
4512
put_error(MYSQL *con)
4514
return put_info(mysql_error(con), INFO_ERROR, mysql_errno(con),
4515
mysql_sqlstate(con));
4519
static void remove_cntrl(String &buffer)
4522
end=(start=(char*) buffer.ptr())+buffer.length();
4523
while (start < end && !my_isgraph(charset_info,end[-1]))
4525
buffer.length((uint) (end-start));
4529
void tee_fprintf(FILE *file, const char *fmt, ...)
4534
va_start(args, fmt);
4535
(void) vfprintf(file, fmt, args);
4540
va_start(args, fmt);
4541
(void) vfprintf(OUTFILE, fmt, args);
4547
void tee_fputs(const char *s, FILE *file)
4556
void tee_puts(const char *s, FILE *file)
4564
fputc('\n', OUTFILE);
4568
void tee_putc(int c, FILE *file)
4575
#if defined( __WIN__) || defined(__NETWARE__)
4578
#include <sys/times.h>
4579
#ifdef _SC_CLK_TCK // For mit-pthreads
4580
#undef CLOCKS_PER_SEC
4581
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
4585
static ulong start_timer(void)
4587
#if defined( __WIN__) || defined(__NETWARE__)
4591
return times(&tms_tmp);
4597
Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
4599
len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds") -> 52
4601
static void nice_time(double sec,char *buff,bool part_second)
4604
if (sec >= 3600.0*24)
4606
tmp=(ulong) floor(sec/(3600.0*24));
4608
buff=int10_to_str((long) tmp, buff, 10);
4609
buff=strmov(buff,tmp > 1 ? " days " : " day ");
4613
tmp=(ulong) floor(sec/3600.0);
4615
buff=int10_to_str((long) tmp, buff, 10);
4616
buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
4620
tmp=(ulong) floor(sec/60.0);
4622
buff=int10_to_str((long) tmp, buff, 10);
4623
buff=strmov(buff," min ");
4626
sprintf(buff,"%.2f sec",sec);
4628
sprintf(buff,"%d sec",(int) sec);
4632
static void end_timer(ulong start_time,char *buff)
4634
nice_time((double) (start_timer() - start_time) /
4635
CLOCKS_PER_SEC,buff,1);
4639
static void mysql_end_timer(ulong start_time,char *buff)
4643
end_timer(start_time,buff+2);
4644
strmov(strend(buff),")");
4647
static const char* construct_prompt()
4649
processed_prompt.free(); // Erase the old prompt
4650
time_t lclock = time(NULL); // Get the date struct
4651
struct tm *t = localtime(&lclock);
4653
/* parse thru the settings for the prompt */
4654
for (char *c = current_prompt; *c ; *c++)
4656
if (*c != PROMPT_CHAR)
4657
processed_prompt.append(*c);
4662
c--; // stop it from going beyond if ends with %
4665
add_int_to_prompt(++prompt_counter);
4669
processed_prompt.append(mysql_get_server_info(&mysql));
4671
processed_prompt.append("not_connected");
4674
processed_prompt.append(current_db ? current_db : "(none)");
4679
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4680
if (strstr(prompt, "Localhost"))
4681
processed_prompt.append("localhost");
4684
const char *end=strcend(prompt,' ');
4685
processed_prompt.append(prompt, (uint) (end-prompt));
4691
#ifndef EMBEDDED_LIBRARY
4694
processed_prompt.append("not_connected");
4698
const char *host_info = mysql_get_host_info(&mysql);
4699
if (strstr(host_info, "memory"))
4701
processed_prompt.append( mysql.host );
4703
else if (strstr(host_info,"TCP/IP") ||
4705
add_int_to_prompt(mysql.port);
4708
char *pos=strrchr(mysql.unix_socket,'/');
4709
processed_prompt.append(pos ? pos+1 : mysql.unix_socket);
4717
processed_prompt.append(full_username ? full_username :
4718
(current_user ? current_user : "(unknown)"));
4723
processed_prompt.append(part_username ? part_username :
4724
(current_user ? current_user : "(unknown)"));
4727
processed_prompt.append(PROMPT_CHAR);
4730
processed_prompt.append('\n');
4734
processed_prompt.append(' ');
4737
if (t->tm_hour < 10)
4738
processed_prompt.append('0');
4739
add_int_to_prompt(t->tm_hour);
4743
getHour = t->tm_hour % 12;
4747
processed_prompt.append('0');
4748
add_int_to_prompt(getHour);
4752
processed_prompt.append('0');
4753
add_int_to_prompt(t->tm_min);
4757
getYear = t->tm_year % 100;
4759
processed_prompt.append('0');
4760
add_int_to_prompt(getYear);
4763
add_int_to_prompt(t->tm_year+1900);
4767
dateTime = ctime(&lclock);
4768
processed_prompt.append(strtok(dateTime,"\n"));
4772
processed_prompt.append('0');
4773
add_int_to_prompt(t->tm_sec);
4776
processed_prompt.append(day_names[t->tm_wday]);
4779
processed_prompt.append(t->tm_hour < 12 ? "am" : "pm");
4782
add_int_to_prompt(t->tm_mon+1);
4785
processed_prompt.append(month_names[t->tm_mon]);
4788
processed_prompt.append("'");
4791
processed_prompt.append('"');
4794
processed_prompt.append(';');
4797
processed_prompt.append('\t');
4800
processed_prompt.append(delimiter_str);
4803
processed_prompt.append(c);
4807
processed_prompt.append('\0');
4808
return processed_prompt.ptr();
4812
static void add_int_to_prompt(int toadd)
4815
int10_to_str(toadd,buffer,10);
4816
processed_prompt.append(buffer);
4819
static void init_username()
4821
my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
4822
my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
4825
if (!mysql_query(&mysql,"select USER()") &&
4826
(result=mysql_use_result(&mysql)))
4828
MYSQL_ROW cur=mysql_fetch_row(result);
4829
full_username=my_strdup(cur[0],MYF(MY_WME));
4830
part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
4831
(void) mysql_fetch_row(result); // Read eof
4835
static int com_prompt(String *buffer, char *line)
4837
char *ptr=strchr(line, ' ');
4839
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4840
current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
4842
tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
4844
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4848
#ifndef EMBEDDED_LIBRARY
4849
/* Keep sql_string library happy */
4851
void *sql_alloc(size_t Size)
4853
return my_malloc(Size,MYF(MY_WME));
4856
void sql_element_free(void *ptr)
4858
my_free(ptr,MYF(0));
4860
#endif /* EMBEDDED_LIBRARY */