~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.c

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2010 Vijay Samuel
5
4
 *  Copyright (C) 2008 MySQL
6
5
 *
7
6
 *  This program is free software; you can redistribute it and/or modify
19
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
19
 */
21
20
 
22
 
/* drizzle command tool
 
21
/* mysql command tool
23
22
 * Commands compatible with mSQL by David J. Hughes
24
23
 *
25
24
 * Written by:
34
33
 *
35
34
 **/
36
35
 
37
 
#include <config.h>
38
 
#include <libdrizzle/drizzle_client.h>
39
 
 
40
 
#include "server_detect.h"
41
 
#include "get_password.h"
42
 
 
43
 
#include <boost/date_time/posix_time/posix_time.hpp>
44
 
 
45
 
#include <cerrno>
46
 
#include <string>
47
 
#include <drizzled/gettext.h>
48
 
#include <iostream>
49
 
#include <fstream>
50
 
#include <map>
51
 
#include <algorithm>
52
 
#include <limits.h>
53
 
#include <cassert>
 
36
#include "client_priv.h"
 
37
#include <m_ctype.h>
54
38
#include <stdarg.h>
55
 
#include <math.h>
56
 
#include <memory>
57
 
#include <client/linebuffer.h>
 
39
#include <my_dir.h>
 
40
#ifndef __GNU_LIBRARY__
 
41
#define __GNU_LIBRARY__               // Skip warnings in getopt.h
 
42
#endif
 
43
#include <readline/history.h>
 
44
#include "my_readline.h"
58
45
#include <signal.h>
59
 
#include <sys/ioctl.h>
60
 
#include <drizzled/configmake.h>
61
 
#include <drizzled/utf8/utf8.h>
62
 
#include <cstdlib>
 
46
#include <violite.h>
 
47
 
 
48
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
 
49
#include <locale.h>
 
50
#endif
 
51
 
 
52
#include <glib.h>
 
53
 
 
54
const char *VER= "14.14";
 
55
 
 
56
/* Don't try to make a nice table if the data is too big */
 
57
#define MAX_COLUMN_LENGTH            1024
 
58
 
 
59
/* Buffer to hold 'version' and 'version_comment' */
 
60
#define MAX_SERVER_VERSION_LENGTH     128
 
61
 
 
62
/* Array of options to pass to libemysqld */
 
63
#define MAX_SERVER_ARGS               64
 
64
 
 
65
void* sql_alloc(unsigned size);      // Don't use mysqld alloc for these
 
66
void sql_element_free(void *ptr);
63
67
 
64
68
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
65
69
#include <curses.h>
66
 
#ifdef __sun
67
 
#undef clear
68
 
#undef erase
69
 
#endif
70
70
#include <term.h>
71
71
#else
72
72
#if defined(HAVE_TERMIOS_H)
75
75
#elif defined(HAVE_TERMBITS_H)
76
76
#include <termbits.h>
77
77
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
78
 
#include <asm/termbits.h>    // Standard linux
 
78
#include <asm/termbits.h>               // Standard linux
79
79
#endif
 
80
#undef VOID
80
81
#if defined(HAVE_TERMCAP_H)
81
82
#include <termcap.h>
82
83
#else
83
84
#ifdef HAVE_CURSES_H
84
85
#include <curses.h>
85
86
#endif
86
 
#undef SYSV        // hack to avoid syntax error
 
87
#undef SYSV                             // hack to avoid syntax error
87
88
#ifdef HAVE_TERM_H
88
89
#include <term.h>
89
90
#endif
90
91
#endif
91
92
#endif
92
93
 
93
 
#ifdef HAVE_LIBREADLINE
94
 
#  if defined(HAVE_READLINE_READLINE_H)
95
 
#    include <readline/readline.h>
96
 
#  elif defined(HAVE_READLINE_H)
97
 
#    include <readline.h>
98
 
#  else /* !defined(HAVE_READLINE_H) */
99
 
extern char *readline ();
100
 
#  endif /* !defined(HAVE_READLINE_H) */
101
 
char *cmdline = NULL;
102
 
#else /* !defined(HAVE_READLINE_READLINE_H) */
103
 
  /* no readline */
104
 
#  error Readline Required
105
 
#endif /* HAVE_LIBREADLINE */
106
 
 
107
 
#ifdef HAVE_READLINE_HISTORY
108
 
#  if defined(HAVE_READLINE_HISTORY_H)
109
 
#    include <readline/history.h>
110
 
#  elif defined(HAVE_HISTORY_H)
111
 
#    include <history.h>
112
 
#  else /* !defined(HAVE_HISTORY_H) */
113
 
extern void add_history ();
114
 
extern int write_history ();
115
 
extern int read_history ();
116
 
#  endif /* defined(HAVE_READLINE_HISTORY_H) */
117
 
    /* no history */
118
 
#endif /* HAVE_READLINE_HISTORY */
119
 
 
120
 
/**
121
 
 Make the old readline interface look like the new one.
122
 
*/
123
 
#ifndef HAVE_RL_COMPLETION
124
 
typedef char **rl_completion_func_t(const char *, int, int);
125
 
#define rl_completion_matches(str, func) \
126
 
  completion_matches((char *)str, (CPFunction *)func)
127
 
#endif
128
 
 
129
 
#ifdef HAVE_RL_COMPENTRY
130
 
# ifdef HAVE_WORKING_RL_COMPENTRY
131
 
typedef rl_compentry_func_t drizzle_compentry_func_t;
132
 
# else
133
 
/* Snow Leopard ships an rl_compentry which cannot be assigned to
134
 
 * rl_completion_entry_function. We must undo the complete and total
135
 
 * ass-bagery.
136
 
 */
137
 
typedef Function drizzle_compentry_func_t;
138
 
# endif
139
 
#else
140
 
typedef Function drizzle_compentry_func_t;
141
 
#endif
142
 
 
143
 
#if defined(HAVE_LOCALE_H)
144
 
#include <locale.h>
145
 
#endif
146
 
 
 
94
#undef bcmp                             // Fix problem with new readline
 
95
 
 
96
#include <readline/readline.h>
147
97
 
148
98
 
149
99
#if !defined(HAVE_VIDATTR)
150
100
#undef vidattr
151
 
#define vidattr(A) {}      // Can't get this to work
152
 
#endif
153
 
#include <boost/program_options.hpp>
154
 
#include <boost/scoped_ptr.hpp>
155
 
#include <drizzled/program_options/config_file.h>
156
 
 
157
 
using namespace std;
158
 
namespace po=boost::program_options;
159
 
namespace dpo=drizzled::program_options;
160
 
 
161
 
/* Don't try to make a nice table if the data is too big */
162
 
const uint32_t MAX_COLUMN_LENGTH= 1024;
163
 
 
164
 
/* Buffer to hold 'version' and 'version_comment' */
165
 
const int MAX_SERVER_VERSION_LENGTH= 128;
 
101
#define vidattr(A) {}                   // Can't get this to work
 
102
#endif
 
103
 
 
104
#ifdef FN_NO_CASE_SENCE
 
105
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
 
106
#else
 
107
#define cmp_database(cs,A,B) strcmp((A),(B))
 
108
#endif
 
109
 
 
110
#include "completion_hash.h"
166
111
 
167
112
#define PROMPT_CHAR '\\'
 
113
#define DEFAULT_DELIMITER ";"
168
114
 
169
 
class Status
 
115
typedef struct st_status
170
116
{
171
 
public:
172
 
 
173
 
  Status(int in_exit_status, 
174
 
         uint32_t in_query_start_line,
175
 
         char *in_file_name,
176
 
         LineBuffer *in_line_buff,
177
 
         bool in_batch,
178
 
         bool in_add_to_history)
179
 
    :
180
 
    exit_status(in_exit_status),
181
 
    query_start_line(in_query_start_line),
182
 
    file_name(in_file_name),
183
 
    line_buff(in_line_buff),
184
 
    batch(in_batch),
185
 
    add_to_history(in_add_to_history)
186
 
    {}
187
 
 
188
 
  Status() :
189
 
    exit_status(0),
190
 
    query_start_line(0),
191
 
    file_name(NULL),
192
 
    line_buff(NULL),
193
 
    batch(false),        
194
 
    add_to_history(false)
195
 
  {}
196
 
  
197
 
  int getExitStatus() const
198
 
  {
199
 
    return exit_status;
200
 
  }
201
 
 
202
 
  uint32_t getQueryStartLine() const
203
 
  {
204
 
    return query_start_line;
205
 
  }
206
 
 
207
 
  const char *getFileName() const
208
 
  {
209
 
    return file_name;
210
 
  }
211
 
 
212
 
  LineBuffer *getLineBuff() const
213
 
  {
214
 
    return line_buff;
215
 
  }
216
 
 
217
 
  bool getBatch() const
218
 
  {
219
 
    return batch;
220
 
  }
221
 
 
222
 
  bool getAddToHistory() const
223
 
  {
224
 
    return add_to_history;
225
 
  }
226
 
 
227
 
  void setExitStatus(int in_exit_status)
228
 
  {
229
 
    exit_status= in_exit_status;
230
 
  }
231
 
 
232
 
  void setQueryStartLine(uint32_t in_query_start_line)
233
 
  {
234
 
    query_start_line= in_query_start_line;
235
 
  }
236
 
 
237
 
  void setFileName(char *in_file_name)
238
 
  {
239
 
    file_name= in_file_name;
240
 
  }
241
 
 
242
 
  void setLineBuff(int max_size, FILE *file=NULL)
243
 
  {
244
 
    line_buff= new(std::nothrow) LineBuffer(max_size, file);
245
 
  }
246
 
 
247
 
  void setLineBuff(LineBuffer *in_line_buff)
248
 
  {
249
 
    line_buff= in_line_buff;
250
 
  }
251
 
 
252
 
  void setBatch(bool in_batch)
253
 
  {
254
 
    batch= in_batch;
255
 
  }
256
 
 
257
 
  void setAddToHistory(bool in_add_to_history)
258
 
  {
259
 
    add_to_history= in_add_to_history;
260
 
  }
261
 
 
262
 
private:
263
117
  int exit_status;
264
118
  uint32_t query_start_line;
265
119
  char *file_name;
266
 
  LineBuffer *line_buff;
 
120
  LINE_BUFFER *line_buff;
267
121
  bool batch,add_to_history;
268
 
}; 
269
 
 
270
 
static map<string, string>::iterator completion_iter;
271
 
static map<string, string>::iterator completion_end;
272
 
static map<string, string> completion_map;
273
 
static string completion_string;
274
 
 
 
122
} STATUS;
 
123
 
 
124
 
 
125
static HashTable ht;
 
126
static char **defaults_argv;
275
127
 
276
128
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
277
129
typedef enum enum_info_type INFO_TYPE;
278
130
 
279
 
static drizzle_st drizzle;      /* The library handle */
280
 
static drizzle_con_st con;      /* The connection */
281
 
static bool ignore_errors= false, quick= false,
282
 
  connected= false, opt_raw_data= false, unbuffered= false,
283
 
  output_tables= false, opt_rehash= true, skip_updates= false,
284
 
  safe_updates= false, one_database= false,
285
 
  opt_shutdown= false, opt_ping= false,
286
 
  vertical= false, line_numbers= true, column_names= true,
287
 
  opt_nopager= true, opt_outfile= false, named_cmds= false,
288
 
  opt_nobeep= false, opt_reconnect= true,
289
 
  opt_secure_auth= false,
290
 
  default_pager_set= false, opt_sigint_ignore= false,
291
 
  auto_vertical_output= false,
292
 
  show_warnings= false, executing_query= false, interrupted_query= false,
293
 
  use_drizzle_protocol= false, opt_local_infile;
294
 
static uint32_t show_progress_size= 0;
 
131
static MYSQL mysql;                     /* The connection */
 
132
static bool ignore_errors=0,wait_flag=0,quick=0,
 
133
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
 
134
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
 
135
  opt_compress=0, using_opt_local_infile=0,
 
136
  vertical=0, line_numbers=1, column_names=1,opt_html=0,
 
137
  opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
 
138
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
 
139
  default_charset_used= 0, opt_secure_auth= 0,
 
140
  default_pager_set= 0, opt_sigint_ignore= 0,
 
141
  auto_vertical_output= 0,
 
142
  show_warnings= 0, executing_query= 0, interrupted_query= 0;
 
143
static bool debug_info_flag, debug_check_flag;
295
144
static bool column_types_flag;
296
 
static bool preserve_comments= false;
297
 
static uint32_t opt_max_input_line;
298
 
static uint32_t opt_drizzle_port= 0;
299
 
static int  opt_silent, verbose= 0;
300
 
static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
 
145
static bool preserve_comments= 0;
 
146
static ulong opt_max_allowed_packet, opt_net_buffer_length;
 
147
static int verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
 
148
static uint my_end_arg;
 
149
static char * opt_mysql_unix_port=0;
 
150
static int connect_flag=CLIENT_INTERACTIVE;
 
151
static char *current_host,*current_db,*current_user=0,*opt_password=0,
 
152
  *delimiter_str= 0,*current_prompt=0,
 
153
  *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
301
154
static char *histfile;
302
155
static char *histfile_tmp;
303
 
static string *glob_buffer;
304
 
static string *processed_prompt= NULL;
305
 
static char *default_prompt= NULL;
306
 
static char *full_username= NULL,*part_username= NULL;
307
 
static Status status;
 
156
static GString *glob_buffer;
 
157
static GString *processed_prompt= NULL;
 
158
static GString *default_prompt= NULL;
 
159
static char *full_username=0,*part_username=0;
 
160
static int wait_time = 5;
 
161
static STATUS status;
308
162
static uint32_t select_limit;
309
163
static uint32_t max_join_size;
310
 
static uint32_t opt_connect_timeout= 0;
311
 
static ServerDetect::server_type server_type= ServerDetect::SERVER_UNKNOWN_FOUND;
312
 
std::string current_db,
313
 
  delimiter_str,  
314
 
  current_host,
315
 
  current_prompt,
316
 
  current_user,
317
 
  opt_verbose,
318
 
  current_password,
319
 
  opt_password,
320
 
  opt_protocol;
321
 
 
322
 
static const char* get_day_name(int day_of_week)
323
 
{
324
 
  switch(day_of_week)
325
 
  {
326
 
  case 0:
327
 
    return _("Sun");
328
 
  case 1:
329
 
    return _("Mon");
330
 
  case 2:
331
 
    return _("Tue");
332
 
  case 3:
333
 
    return _("Wed");
334
 
  case 4:
335
 
    return _("Thu");
336
 
  case 5:
337
 
    return _("Fri");
338
 
  case 6:
339
 
    return _("Sat");
340
 
  }
341
 
 
342
 
  return NULL;
343
 
}
344
 
 
345
 
static const char* get_month_name(int month)
346
 
{
347
 
  switch(month)
348
 
  {
349
 
  case 0:
350
 
    return _("Jan");
351
 
  case 1:
352
 
    return _("Feb");
353
 
  case 2:
354
 
    return _("Mar");
355
 
  case 3:
356
 
    return _("Apr");
357
 
  case 4:
358
 
    return _("May");
359
 
  case 5:
360
 
    return _("Jun");
361
 
  case 6:
362
 
    return _("Jul");
363
 
  case 7:
364
 
    return _("Aug");
365
 
  case 8:
366
 
    return _("Sep");
367
 
  case 9:
368
 
    return _("Oct");
369
 
  case 10:
370
 
    return _("Nov");
371
 
  case 11:
372
 
    return _("Dec");
373
 
  }
374
 
 
375
 
  return NULL;
376
 
}
377
 
 
378
 
/* @TODO: Remove this */
379
 
#define FN_REFLEN 512
380
 
 
381
 
static string default_pager("");
382
 
static string pager("");
383
 
static string outfile("");
 
164
static ulong opt_connect_timeout= 0;
 
165
static char mysql_charsets_dir[FN_REFLEN+1];
 
166
static const char *xmlmeta[] = {
 
167
  "&", "&amp;",
 
168
  "<", "&lt;",
 
169
  ">", "&gt;",
 
170
  "\"", "&quot;",
 
171
  0, 0
 
172
};
 
173
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
174
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
175
                                  "Aug","Sep","Oct","Nov","Dec"};
 
176
static char default_pager[FN_REFLEN];
 
177
static char pager[FN_REFLEN], outfile[FN_REFLEN];
384
178
static FILE *PAGER, *OUTFILE;
385
 
static uint32_t prompt_counter;
386
 
static char *delimiter= NULL;
387
 
static uint32_t delimiter_length= 1;
 
179
static MEM_ROOT hash_mem_root;
 
180
static uint prompt_counter;
 
181
static char delimiter[16]= DEFAULT_DELIMITER;
 
182
static uint delimiter_length= 1;
388
183
unsigned short terminal_width= 80;
389
184
 
390
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
391
 
                                      drizzle_result_st *result,
392
 
                                      uint32_t *error_code);
393
 
int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
 
185
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
 
186
static CHARSET_INFO *charset_info= &my_charset_latin1;
 
187
 
 
188
const char *default_dbug_option="d:t:o,/tmp/mysql.trace";
 
189
int mysql_real_query_for_lazy(const char *buf, int length);
 
190
int mysql_store_result_for_lazy(MYSQL_RES **result);
394
191
 
395
192
 
396
193
void tee_fprintf(FILE *file, const char *fmt, ...);
399
196
void tee_putc(int c, FILE *file);
400
197
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
401
198
/* The names of functions that actually do the manipulation. */
402
 
static int process_options(void);
403
 
static int com_quit(string *str,const char*),
404
 
  com_go(string *str,const char*), com_ego(string *str,const char*),
405
 
  com_print(string *str,const char*),
406
 
  com_help(string *str,const char*), com_clear(string *str,const char*),
407
 
  com_connect(string *str,const char*), com_status(string *str,const char*),
408
 
  com_use(string *str,const char*), com_source(string *str, const char*),
409
 
  com_shutdown(string *str,const char*),
410
 
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
411
 
  com_notee(string *str, const char*),
412
 
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
413
 
  com_warnings(string *str, const char*), com_nowarnings(string *str, const char*),
414
 
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
 
199
static int get_options(int argc,char **argv);
 
200
bool get_one_option(int optid, const struct my_option *opt,
 
201
                    char *argument);
 
202
static int com_quit(GString *str,char*),
 
203
  com_go(GString *str,char*), com_ego(GString *str,char*),
 
204
  com_print(GString *str,char*),
 
205
  com_help(GString *str,char*), com_clear(GString *str,char*),
 
206
  com_connect(GString *str,char*), com_status(GString *str,char*),
 
207
  com_use(GString *str,char*), com_source(GString *str, char*),
 
208
  com_rehash(GString *str, char*), com_tee(GString *str, char*),
 
209
  com_notee(GString *str, char*), com_charset(GString *str,char*),
 
210
  com_prompt(GString *str, char*), com_delimiter(GString *str, char*),
 
211
  com_warnings(GString *str, char*), com_nowarnings(GString *str, char*),
 
212
  com_nopager(GString *str, char*), com_pager(GString *str, char*);
415
213
 
416
214
static int read_and_execute(bool interactive);
417
 
static int sql_connect(const string &host, const string &database, const string &user, const string &password);
418
 
static const char *server_version_string(drizzle_con_st *con);
419
 
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
 
215
static int sql_connect(char *host,char *database,char *user,char *password,
 
216
                       uint silent);
 
217
static const char *server_version_string(MYSQL *mysql);
 
218
static int put_info(const char *str,INFO_TYPE info,uint error,
420
219
                    const char *sql_state);
421
 
static int put_error(drizzle_con_st *con, drizzle_result_st *res);
422
 
static void safe_put_field(const char *pos,uint32_t length);
 
220
static int put_error(MYSQL *mysql);
 
221
static void safe_put_field(const char *pos,ulong length);
 
222
static void xmlencode_print(const char *src, uint length);
423
223
static void init_pager(void);
424
224
static void end_pager(void);
425
225
static void init_tee(const char *);
428
228
static char *get_arg(char *line, bool get_next_arg);
429
229
static void init_username(void);
430
230
static void add_int_to_prompt(int toadd);
431
 
static int get_result_width(drizzle_result_st *res);
432
 
static int get_field_disp_length(drizzle_column_st * field);
433
 
static const char * strcont(const char *str, const char *set);
 
231
static int get_result_width(MYSQL_RES *res);
 
232
static int get_field_disp_length(MYSQL_FIELD * field);
434
233
 
435
 
/* A class which contains information on the commands this program
 
234
/* A structure which contains information on the commands this program
436
235
   can understand. */
437
 
class Commands
438
 
{
439
 
private:
440
 
  const char *name;        /* User printable name of the function. */
441
 
  char cmd_char;        /* msql command character */
442
 
public:
443
 
Commands(const char *in_name,
444
 
         char in_cmd_char,
445
 
         int (*in_func)(string *str,const char *name),
446
 
         bool in_takes_params,
447
 
         const char *in_doc)
448
 
  :
449
 
  name(in_name),
450
 
  cmd_char(in_cmd_char),
451
 
  func(in_func),
452
 
  takes_params(in_takes_params),
453
 
  doc(in_doc)
454
 
  {}
455
 
 
456
 
  Commands()
457
 
  :
458
 
  name(),
459
 
  cmd_char(),
460
 
  func(NULL),
461
 
  takes_params(false),
462
 
  doc()
463
 
  {}
464
 
 
465
 
  int (*func)(string *str,const char *);/* Function to call to do the job. */
466
 
 
467
 
  const char *getName() const
468
 
  {
469
 
    return name;
470
 
  }
471
 
 
472
 
  char getCmdChar() const
473
 
  {
474
 
    return cmd_char;
475
 
  }
476
 
 
477
 
  bool getTakesParams() const
478
 
  {
479
 
    return takes_params;
480
 
  }
481
 
 
482
 
  const char *getDoc() const
483
 
  {
484
 
    return doc;
485
 
  }
486
 
 
487
 
  void setName(const char *in_name)
488
 
  {
489
 
     name= in_name;
490
 
  }
491
 
 
492
 
  void setCmdChar(char in_cmd_char)
493
 
  {
494
 
    cmd_char= in_cmd_char;
495
 
  }
496
 
 
497
 
  void setTakesParams(bool in_takes_params)
498
 
  {
499
 
    takes_params= in_takes_params;
500
 
  }
501
 
 
502
 
  void setDoc(const char *in_doc)
503
 
  {
504
 
    doc= in_doc;
505
 
  }
506
 
 
507
 
private:
508
 
  bool takes_params;        /* Max parameters for command */
509
 
  const char *doc;        /* Documentation for this function.  */
510
 
}; 
511
 
 
512
 
 
513
 
static Commands commands[] = {
514
 
  Commands( "?",      '?', com_help,   0, N_("Synonym for `help'.") ),
515
 
  Commands( "clear",  'c', com_clear,  0, N_("Clear command.")),
516
 
  Commands( "connect",'r', com_connect,1,
517
 
    N_("Reconnect to the server. Optional arguments are db and host.")),
518
 
  Commands( "delimiter", 'd', com_delimiter,    1,
519
 
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") ),
520
 
  Commands( "ego",    'G', com_ego,    0,
521
 
    N_("Send command to drizzle server, display result vertically.")),
522
 
  Commands( "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")),
523
 
  Commands( "go",     'g', com_go,     0, N_("Send command to drizzle server.") ),
524
 
  Commands( "help",   'h', com_help,   0, N_("Display this help.") ),
525
 
  Commands( "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") ),
526
 
  Commands( "notee",  't', com_notee,  0, N_("Don't write into outfile.") ),
527
 
  Commands( "pager",  'P', com_pager,  1,
528
 
    N_("Set PAGER [to_pager]. Print the query results via PAGER.") ),
529
 
  Commands( "print",  'p', com_print,  0, N_("Print current command.") ),
530
 
  Commands( "prompt", 'R', com_prompt, 1, N_("Change your drizzle prompt.")),
531
 
  Commands( "quit",   'q', com_quit,   0, N_("Quit drizzle.") ),
532
 
  Commands( "rehash", '#', com_rehash, 0, N_("Rebuild completion hash.") ),
533
 
  Commands( "source", '.', com_source, 1,
534
 
    N_("Execute an SQL script file. Takes a file name as an argument.")),
535
 
  Commands( "status", 's', com_status, 0, N_("Get status information from the server.")),
536
 
  Commands( "tee",    'T', com_tee,    1,
537
 
    N_("Set outfile [to_outfile]. Append everything into given outfile.") ),
538
 
  Commands( "use",    'u', com_use,    1,
539
 
    N_("Use another schema. Takes schema name as argument.") ),
540
 
  Commands( "shutdown",    'u', com_shutdown,    1,
541
 
    N_("Shutdown the instance you are connected too.") ),
542
 
  Commands( "warnings", 'W', com_warnings,  0,
543
 
    N_("Show warnings after every statement.") ),
544
 
  Commands( "nowarning", 'w', com_nowarnings, 0,
545
 
    N_("Don't show warnings after every statement.") ),
 
236
typedef struct {
 
237
  const char *name;             /* User printable name of the function. */
 
238
  char cmd_char;                /* msql command character */
 
239
  int (*func)(GString *str,char *); /* Function to call to do the job. */
 
240
  bool takes_params;            /* Max parameters for command */
 
241
  const char *doc;              /* Documentation for this function.  */
 
242
} COMMANDS;
 
243
 
 
244
 
 
245
static COMMANDS commands[] = {
 
246
  { "?",      '?', com_help,   1, "Synonym for `help'." },
 
247
  { "clear",  'c', com_clear,  0, "Clear command."},
 
248
  { "connect",'r', com_connect,1,
 
249
    "Reconnect to the server. Optional arguments are db and host." },
 
250
  { "delimiter", 'd', com_delimiter,    1,
 
251
    "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
 
252
  { "ego",    'G', com_ego,    0,
 
253
    "Send command to mysql server, display result vertically."},
 
254
  { "exit",   'q', com_quit,   0, "Exit mysql. Same as quit."},
 
255
  { "go",     'g', com_go,     0, "Send command to mysql server." },
 
256
  { "help",   'h', com_help,   1, "Display this help." },
 
257
  { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
 
258
  { "notee",  't', com_notee,  0, "Don't write into outfile." },
 
259
  { "pager",  'P', com_pager,  1,
 
260
    "Set PAGER [to_pager]. Print the query results via PAGER." },
 
261
  { "print",  'p', com_print,  0, "Print current command." },
 
262
  { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
 
263
  { "quit",   'q', com_quit,   0, "Quit mysql." },
 
264
  { "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
 
265
  { "source", '.', com_source, 1,
 
266
    "Execute an SQL script file. Takes a file name as an argument."},
 
267
  { "status", 's', com_status, 0, "Get status information from the server."},
 
268
  { "tee",    'T', com_tee,    1,
 
269
    "Set outfile [to_outfile]. Append everything into given outfile." },
 
270
  { "use",    'u', com_use,    1,
 
271
    "Use another database. Takes database name as argument." },
 
272
  { "charset",    'C', com_charset,    1,
 
273
    "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." },
 
274
  { "warnings", 'W', com_warnings,  0,
 
275
    "Show warnings after every statement." },
 
276
  { "nowarning", 'w', com_nowarnings, 0,
 
277
    "Don't show warnings after every statement." },
546
278
  /* Get bash-like expansion for some commands */
547
 
  Commands( "create table",     0, 0, 0, ""),
548
 
  Commands( "create database",  0, 0, 0, ""),
549
 
  Commands( "show databases",   0, 0, 0, ""),
550
 
  Commands( "show fields from", 0, 0, 0, ""),
551
 
  Commands( "show keys from",   0, 0, 0, ""),
552
 
  Commands( "show tables",      0, 0, 0, ""),
553
 
  Commands( "load data from",   0, 0, 0, ""),
554
 
  Commands( "alter table",      0, 0, 0, ""),
555
 
  Commands( "set option",       0, 0, 0, ""),
556
 
  Commands( "lock tables",      0, 0, 0, ""),
557
 
  Commands( "unlock tables",    0, 0, 0, ""),
 
279
  { "create table",     0, 0, 0, ""},
 
280
  { "create database",  0, 0, 0, ""},
 
281
  { "show databases",   0, 0, 0, ""},
 
282
  { "show fields from", 0, 0, 0, ""},
 
283
  { "show keys from",   0, 0, 0, ""},
 
284
  { "show tables",      0, 0, 0, ""},
 
285
  { "load data from",   0, 0, 0, ""},
 
286
  { "alter table",      0, 0, 0, ""},
 
287
  { "set option",       0, 0, 0, ""},
 
288
  { "lock tables",      0, 0, 0, ""},
 
289
  { "unlock tables",    0, 0, 0, ""},
558
290
  /* generated 2006-12-28.  Refresh occasionally from lexer. */
559
 
  Commands( "ACTION", 0, 0, 0, ""),
560
 
  Commands( "ADD", 0, 0, 0, ""),
561
 
  Commands( "AFTER", 0, 0, 0, ""),
562
 
  Commands( "AGAINST", 0, 0, 0, ""),
563
 
  Commands( "AGGREGATE", 0, 0, 0, ""),
564
 
  Commands( "ALL", 0, 0, 0, ""),
565
 
  Commands( "ALGORITHM", 0, 0, 0, ""),
566
 
  Commands( "ALTER", 0, 0, 0, ""),
567
 
  Commands( "ANALYZE", 0, 0, 0, ""),
568
 
  Commands( "AND", 0, 0, 0, ""),
569
 
  Commands( "ANY", 0, 0, 0, ""),
570
 
  Commands( "AS", 0, 0, 0, ""),
571
 
  Commands( "ASC", 0, 0, 0, ""),
572
 
  Commands( "ASCII", 0, 0, 0, ""),
573
 
  Commands( "ASENSITIVE", 0, 0, 0, ""),
574
 
  Commands( "AUTO_INCREMENT", 0, 0, 0, ""),
575
 
  Commands( "AVG", 0, 0, 0, ""),
576
 
  Commands( "AVG_ROW_LENGTH", 0, 0, 0, ""),
577
 
  Commands( "BEFORE", 0, 0, 0, ""),
578
 
  Commands( "BEGIN", 0, 0, 0, ""),
579
 
  Commands( "BETWEEN", 0, 0, 0, ""),
580
 
  Commands( "BIGINT", 0, 0, 0, ""),
581
 
  Commands( "BINARY", 0, 0, 0, ""),
582
 
  Commands( "BIT", 0, 0, 0, ""),
583
 
  Commands( "BLOB", 0, 0, 0, ""),
584
 
  Commands( "BOOL", 0, 0, 0, ""),
585
 
  Commands( "BOOLEAN", 0, 0, 0, ""),
586
 
  Commands( "BOTH", 0, 0, 0, ""),
587
 
  Commands( "BTREE", 0, 0, 0, ""),
588
 
  Commands( "BY", 0, 0, 0, ""),
589
 
  Commands( "BYTE", 0, 0, 0, ""),
590
 
  Commands( "CACHE", 0, 0, 0, ""),
591
 
  Commands( "CALL", 0, 0, 0, ""),
592
 
  Commands( "CASCADE", 0, 0, 0, ""),
593
 
  Commands( "CASCADED", 0, 0, 0, ""),
594
 
  Commands( "CASE", 0, 0, 0, ""),
595
 
  Commands( "CHAIN", 0, 0, 0, ""),
596
 
  Commands( "CHANGE", 0, 0, 0, ""),
597
 
  Commands( "CHANGED", 0, 0, 0, ""),
598
 
  Commands( "CHAR", 0, 0, 0, ""),
599
 
  Commands( "CHARACTER", 0, 0, 0, ""),
600
 
  Commands( "CHECK", 0, 0, 0, ""),
601
 
  Commands( "CHECKSUM", 0, 0, 0, ""),
602
 
  Commands( "CLIENT", 0, 0, 0, ""),
603
 
  Commands( "CLOSE", 0, 0, 0, ""),
604
 
  Commands( "COLLATE", 0, 0, 0, ""),
605
 
  Commands( "COLLATION", 0, 0, 0, ""),
606
 
  Commands( "COLUMN", 0, 0, 0, ""),
607
 
  Commands( "COLUMNS", 0, 0, 0, ""),
608
 
  Commands( "COMMENT", 0, 0, 0, ""),
609
 
  Commands( "COMMIT", 0, 0, 0, ""),
610
 
  Commands( "COMMITTED", 0, 0, 0, ""),
611
 
  Commands( "COMPACT", 0, 0, 0, ""),
612
 
  Commands( "COMPRESSED", 0, 0, 0, ""),
613
 
  Commands( "CONCURRENT", 0, 0, 0, ""),
614
 
  Commands( "CONDITION", 0, 0, 0, ""),
615
 
  Commands( "CONNECTION", 0, 0, 0, ""),
616
 
  Commands( "CONSISTENT", 0, 0, 0, ""),
617
 
  Commands( "CONSTRAINT", 0, 0, 0, ""),
618
 
  Commands( "CONTAINS", 0, 0, 0, ""),
619
 
  Commands( "CONTINUE", 0, 0, 0, ""),
620
 
  Commands( "CONVERT", 0, 0, 0, ""),
621
 
  Commands( "CREATE", 0, 0, 0, ""),
622
 
  Commands( "CROSS", 0, 0, 0, ""),
623
 
  Commands( "CUBE", 0, 0, 0, ""),
624
 
  Commands( "CURRENT_DATE", 0, 0, 0, ""),
625
 
  Commands( "CURRENT_TIMESTAMP", 0, 0, 0, ""),
626
 
  Commands( "CURRENT_USER", 0, 0, 0, ""),
627
 
  Commands( "CURSOR", 0, 0, 0, ""),
628
 
  Commands( "DATA", 0, 0, 0, ""),
629
 
  Commands( "DATABASE", 0, 0, 0, ""),
630
 
  Commands( "DATABASES", 0, 0, 0, ""),
631
 
  Commands( "DATE", 0, 0, 0, ""),
632
 
  Commands( "DATETIME", 0, 0, 0, ""),
633
 
  Commands( "DAY", 0, 0, 0, ""),
634
 
  Commands( "DAY_HOUR", 0, 0, 0, ""),
635
 
  Commands( "DAY_MICROSECOND", 0, 0, 0, ""),
636
 
  Commands( "DAY_MINUTE", 0, 0, 0, ""),
637
 
  Commands( "DAY_SECOND", 0, 0, 0, ""),
638
 
  Commands( "DEALLOCATE", 0, 0, 0, ""),
639
 
  Commands( "DEC", 0, 0, 0, ""),
640
 
  Commands( "DECIMAL", 0, 0, 0, ""),
641
 
  Commands( "DECLARE", 0, 0, 0, ""),
642
 
  Commands( "DEFAULT", 0, 0, 0, ""),
643
 
  Commands( "DEFINER", 0, 0, 0, ""),
644
 
  Commands( "DELAYED", 0, 0, 0, ""),
645
 
  Commands( "DELETE", 0, 0, 0, ""),
646
 
  Commands( "DESC", 0, 0, 0, ""),
647
 
  Commands( "DESCRIBE", 0, 0, 0, ""),
648
 
  Commands( "DETERMINISTIC", 0, 0, 0, ""),
649
 
  Commands( "DISABLE", 0, 0, 0, ""),
650
 
  Commands( "DISCARD", 0, 0, 0, ""),
651
 
  Commands( "DISTINCT", 0, 0, 0, ""),
652
 
  Commands( "DISTINCTROW", 0, 0, 0, ""),
653
 
  Commands( "DIV", 0, 0, 0, ""),
654
 
  Commands( "DOUBLE", 0, 0, 0, ""),
655
 
  Commands( "DROP", 0, 0, 0, ""),
656
 
  Commands( "DUMPFILE", 0, 0, 0, ""),
657
 
  Commands( "DUPLICATE", 0, 0, 0, ""),
658
 
  Commands( "DYNAMIC", 0, 0, 0, ""),
659
 
  Commands( "EACH", 0, 0, 0, ""),
660
 
  Commands( "ELSE", 0, 0, 0, ""),
661
 
  Commands( "ELSEIF", 0, 0, 0, ""),
662
 
  Commands( "ENABLE", 0, 0, 0, ""),
663
 
  Commands( "ENCLOSED", 0, 0, 0, ""),
664
 
  Commands( "END", 0, 0, 0, ""),
665
 
  Commands( "ENGINE", 0, 0, 0, ""),
666
 
  Commands( "ENGINES", 0, 0, 0, ""),
667
 
  Commands( "ENUM", 0, 0, 0, ""),
668
 
  Commands( "ERRORS", 0, 0, 0, ""),
669
 
  Commands( "ESCAPE", 0, 0, 0, ""),
670
 
  Commands( "ESCAPED", 0, 0, 0, ""),
671
 
  Commands( "EXISTS", 0, 0, 0, ""),
672
 
  Commands( "EXIT", 0, 0, 0, ""),
673
 
  Commands( "EXPLAIN", 0, 0, 0, ""),
674
 
  Commands( "EXTENDED", 0, 0, 0, ""),
675
 
  Commands( "FALSE", 0, 0, 0, ""),
676
 
  Commands( "FAST", 0, 0, 0, ""),
677
 
  Commands( "FETCH", 0, 0, 0, ""),
678
 
  Commands( "FIELDS", 0, 0, 0, ""),
679
 
  Commands( "FILE", 0, 0, 0, ""),
680
 
  Commands( "FIRST", 0, 0, 0, ""),
681
 
  Commands( "FIXED", 0, 0, 0, ""),
682
 
  Commands( "FLOAT", 0, 0, 0, ""),
683
 
  Commands( "FLOAT4", 0, 0, 0, ""),
684
 
  Commands( "FLOAT8", 0, 0, 0, ""),
685
 
  Commands( "FLUSH", 0, 0, 0, ""),
686
 
  Commands( "FOR", 0, 0, 0, ""),
687
 
  Commands( "FORCE", 0, 0, 0, ""),
688
 
  Commands( "FOREIGN", 0, 0, 0, ""),
689
 
  Commands( "FOUND", 0, 0, 0, ""),
690
 
  Commands( "FRAC_SECOND", 0, 0, 0, ""),
691
 
  Commands( "FROM", 0, 0, 0, ""),
692
 
  Commands( "FULL", 0, 0, 0, ""),
693
 
  Commands( "FUNCTION", 0, 0, 0, ""),
694
 
  Commands( "GLOBAL", 0, 0, 0, ""),
695
 
  Commands( "GRANT", 0, 0, 0, ""),
696
 
  Commands( "GRANTS", 0, 0, 0, ""),
697
 
  Commands( "GROUP", 0, 0, 0, ""),
698
 
  Commands( "HANDLER", 0, 0, 0, ""),
699
 
  Commands( "HASH", 0, 0, 0, ""),
700
 
  Commands( "HAVING", 0, 0, 0, ""),
701
 
  Commands( "HELP", 0, 0, 0, ""),
702
 
  Commands( "HIGH_PRIORITY", 0, 0, 0, ""),
703
 
  Commands( "HOSTS", 0, 0, 0, ""),
704
 
  Commands( "HOUR", 0, 0, 0, ""),
705
 
  Commands( "HOUR_MICROSECOND", 0, 0, 0, ""),
706
 
  Commands( "HOUR_MINUTE", 0, 0, 0, ""),
707
 
  Commands( "HOUR_SECOND", 0, 0, 0, ""),
708
 
  Commands( "IDENTIFIED", 0, 0, 0, ""),
709
 
  Commands( "IF", 0, 0, 0, ""),
710
 
  Commands( "IGNORE", 0, 0, 0, ""),
711
 
  Commands( "IMPORT", 0, 0, 0, ""),
712
 
  Commands( "IN", 0, 0, 0, ""),
713
 
  Commands( "INDEX", 0, 0, 0, ""),
714
 
  Commands( "INDEXES", 0, 0, 0, ""),
715
 
  Commands( "INFILE", 0, 0, 0, ""),
716
 
  Commands( "INNER", 0, 0, 0, ""),
717
 
  Commands( "INNOBASE", 0, 0, 0, ""),
718
 
  Commands( "INNODB", 0, 0, 0, ""),
719
 
  Commands( "INOUT", 0, 0, 0, ""),
720
 
  Commands( "INSENSITIVE", 0, 0, 0, ""),
721
 
  Commands( "INSERT", 0, 0, 0, ""),
722
 
  Commands( "INSERT_METHOD", 0, 0, 0, ""),
723
 
  Commands( "INT", 0, 0, 0, ""),
724
 
  Commands( "INT1", 0, 0, 0, ""),
725
 
  Commands( "INT2", 0, 0, 0, ""),
726
 
  Commands( "INT3", 0, 0, 0, ""),
727
 
  Commands( "INT4", 0, 0, 0, ""),
728
 
  Commands( "INT8", 0, 0, 0, ""),
729
 
  Commands( "INTEGER", 0, 0, 0, ""),
730
 
  Commands( "INTERVAL", 0, 0, 0, ""),
731
 
  Commands( "INTO", 0, 0, 0, ""),
732
 
  Commands( "IO_THREAD", 0, 0, 0, ""),
733
 
  Commands( "IS", 0, 0, 0, ""),
734
 
  Commands( "ISOLATION", 0, 0, 0, ""),
735
 
  Commands( "ISSUER", 0, 0, 0, ""),
736
 
  Commands( "ITERATE", 0, 0, 0, ""),
737
 
  Commands( "INVOKER", 0, 0, 0, ""),
738
 
  Commands( "JOIN", 0, 0, 0, ""),
739
 
  Commands( "KEY", 0, 0, 0, ""),
740
 
  Commands( "KEYS", 0, 0, 0, ""),
741
 
  Commands( "KILL", 0, 0, 0, ""),
742
 
  Commands( "LANGUAGE", 0, 0, 0, ""),
743
 
  Commands( "LAST", 0, 0, 0, ""),
744
 
  Commands( "LEADING", 0, 0, 0, ""),
745
 
  Commands( "LEAVE", 0, 0, 0, ""),
746
 
  Commands( "LEAVES", 0, 0, 0, ""),
747
 
  Commands( "LEFT", 0, 0, 0, ""),
748
 
  Commands( "LEVEL", 0, 0, 0, ""),
749
 
  Commands( "LIKE", 0, 0, 0, ""),
750
 
  Commands( "LIMIT", 0, 0, 0, ""),
751
 
  Commands( "LINES", 0, 0, 0, ""),
752
 
  Commands( "LINESTRING", 0, 0, 0, ""),
753
 
  Commands( "LOAD", 0, 0, 0, ""),
754
 
  Commands( "LOCAL", 0, 0, 0, ""),
755
 
  Commands( "LOCALTIMESTAMP", 0, 0, 0, ""),
756
 
  Commands( "LOCK", 0, 0, 0, ""),
757
 
  Commands( "LOCKS", 0, 0, 0, ""),
758
 
  Commands( "LOGS", 0, 0, 0, ""),
759
 
  Commands( "LONG", 0, 0, 0, ""),
760
 
  Commands( "LOOP", 0, 0, 0, ""),
761
 
  Commands( "MATCH", 0, 0, 0, ""),
762
 
  Commands( "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""),
763
 
  Commands( "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""),
764
 
  Commands( "MAX_ROWS", 0, 0, 0, ""),
765
 
  Commands( "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""),
766
 
  Commands( "MAX_USER_CONNECTIONS", 0, 0, 0, ""),
767
 
  Commands( "MEDIUM", 0, 0, 0, ""),
768
 
  Commands( "MERGE", 0, 0, 0, ""),
769
 
  Commands( "MICROSECOND", 0, 0, 0, ""),
770
 
  Commands( "MIGRATE", 0, 0, 0, ""),
771
 
  Commands( "MINUTE", 0, 0, 0, ""),
772
 
  Commands( "MINUTE_MICROSECOND", 0, 0, 0, ""),
773
 
  Commands( "MINUTE_SECOND", 0, 0, 0, ""),
774
 
  Commands( "MIN_ROWS", 0, 0, 0, ""),
775
 
  Commands( "MOD", 0, 0, 0, ""),
776
 
  Commands( "MODE", 0, 0, 0, ""),
777
 
  Commands( "MODIFIES", 0, 0, 0, ""),
778
 
  Commands( "MODIFY", 0, 0, 0, ""),
779
 
  Commands( "MONTH", 0, 0, 0, ""),
780
 
  Commands( "MULTILINESTRING", 0, 0, 0, ""),
781
 
  Commands( "MULTIPOINT", 0, 0, 0, ""),
782
 
  Commands( "MULTIPOLYGON", 0, 0, 0, ""),
783
 
  Commands( "MUTEX", 0, 0, 0, ""),
784
 
  Commands( "NAME", 0, 0, 0, ""),
785
 
  Commands( "NAMES", 0, 0, 0, ""),
786
 
  Commands( "NATIONAL", 0, 0, 0, ""),
787
 
  Commands( "NATURAL", 0, 0, 0, ""),
788
 
  Commands( "NCHAR", 0, 0, 0, ""),
789
 
  Commands( "NEW", 0, 0, 0, ""),
790
 
  Commands( "NEXT", 0, 0, 0, ""),
791
 
  Commands( "NO", 0, 0, 0, ""),
792
 
  Commands( "NONE", 0, 0, 0, ""),
793
 
  Commands( "NOT", 0, 0, 0, ""),
794
 
  Commands( "NULL", 0, 0, 0, ""),
795
 
  Commands( "NUMERIC", 0, 0, 0, ""),
796
 
  Commands( "NVARCHAR", 0, 0, 0, ""),
797
 
  Commands( "OFFSET", 0, 0, 0, ""),
798
 
  Commands( "ON", 0, 0, 0, ""),
799
 
  Commands( "ONE", 0, 0, 0, ""),
800
 
  Commands( "ONE_SHOT", 0, 0, 0, ""),
801
 
  Commands( "OPEN", 0, 0, 0, ""),
802
 
  Commands( "OPTIMIZE", 0, 0, 0, ""),
803
 
  Commands( "OPTION", 0, 0, 0, ""),
804
 
  Commands( "OPTIONALLY", 0, 0, 0, ""),
805
 
  Commands( "OR", 0, 0, 0, ""),
806
 
  Commands( "ORDER", 0, 0, 0, ""),
807
 
  Commands( "OUT", 0, 0, 0, ""),
808
 
  Commands( "OUTER", 0, 0, 0, ""),
809
 
  Commands( "OUTFILE", 0, 0, 0, ""),
810
 
  Commands( "PACK_KEYS", 0, 0, 0, ""),
811
 
  Commands( "PARTIAL", 0, 0, 0, ""),
812
 
  Commands( "PASSWORD", 0, 0, 0, ""),
813
 
  Commands( "PHASE", 0, 0, 0, ""),
814
 
  Commands( "PRECISION", 0, 0, 0, ""),
815
 
  Commands( "PREPARE", 0, 0, 0, ""),
816
 
  Commands( "PREV", 0, 0, 0, ""),
817
 
  Commands( "PRIMARY", 0, 0, 0, ""),
818
 
  Commands( "PRIVILEGES", 0, 0, 0, ""),
819
 
  Commands( "PROCEDURE", 0, 0, 0, ""),
820
 
  Commands( "PROCESS", 0, 0, 0, ""),
821
 
  Commands( "PROCESSLIST", 0, 0, 0, ""),
822
 
  Commands( "PURGE", 0, 0, 0, ""),
823
 
  Commands( "QUARTER", 0, 0, 0, ""),
824
 
  Commands( "QUERY", 0, 0, 0, ""),
825
 
  Commands( "QUICK", 0, 0, 0, ""),
826
 
  Commands( "READ", 0, 0, 0, ""),
827
 
  Commands( "READS", 0, 0, 0, ""),
828
 
  Commands( "REAL", 0, 0, 0, ""),
829
 
  Commands( "RECOVER", 0, 0, 0, ""),
830
 
  Commands( "REDUNDANT", 0, 0, 0, ""),
831
 
  Commands( "REFERENCES", 0, 0, 0, ""),
832
 
  Commands( "REGEXP", 0, 0, 0, ""),
833
 
  Commands( "RELEASE", 0, 0, 0, ""),
834
 
  Commands( "RELOAD", 0, 0, 0, ""),
835
 
  Commands( "RENAME", 0, 0, 0, ""),
836
 
  Commands( "REPAIR", 0, 0, 0, ""),
837
 
  Commands( "REPEATABLE", 0, 0, 0, ""),
838
 
  Commands( "REPLACE", 0, 0, 0, ""),
839
 
  Commands( "REPEAT", 0, 0, 0, ""),
840
 
  Commands( "REQUIRE", 0, 0, 0, ""),
841
 
  Commands( "RESET", 0, 0, 0, ""),
842
 
  Commands( "RESTORE", 0, 0, 0, ""),
843
 
  Commands( "RESTRICT", 0, 0, 0, ""),
844
 
  Commands( "RESUME", 0, 0, 0, ""),
845
 
  Commands( "RETURN", 0, 0, 0, ""),
846
 
  Commands( "RETURNS", 0, 0, 0, ""),
847
 
  Commands( "REVOKE", 0, 0, 0, ""),
848
 
  Commands( "RIGHT", 0, 0, 0, ""),
849
 
  Commands( "RLIKE", 0, 0, 0, ""),
850
 
  Commands( "ROLLBACK", 0, 0, 0, ""),
851
 
  Commands( "ROLLUP", 0, 0, 0, ""),
852
 
  Commands( "ROUTINE", 0, 0, 0, ""),
853
 
  Commands( "ROW", 0, 0, 0, ""),
854
 
  Commands( "ROWS", 0, 0, 0, ""),
855
 
  Commands( "ROW_FORMAT", 0, 0, 0, ""),
856
 
  Commands( "RTREE", 0, 0, 0, ""),
857
 
  Commands( "SAVEPOINT", 0, 0, 0, ""),
858
 
  Commands( "SCHEMA", 0, 0, 0, ""),
859
 
  Commands( "SCHEMAS", 0, 0, 0, ""),
860
 
  Commands( "SECOND", 0, 0, 0, ""),
861
 
  Commands( "SECOND_MICROSECOND", 0, 0, 0, ""),
862
 
  Commands( "SECURITY", 0, 0, 0, ""),
863
 
  Commands( "SELECT", 0, 0, 0, ""),
864
 
  Commands( "SENSITIVE", 0, 0, 0, ""),
865
 
  Commands( "SEPARATOR", 0, 0, 0, ""),
866
 
  Commands( "SERIAL", 0, 0, 0, ""),
867
 
  Commands( "SERIALIZABLE", 0, 0, 0, ""),
868
 
  Commands( "SESSION", 0, 0, 0, ""),
869
 
  Commands( "SET", 0, 0, 0, ""),
870
 
  Commands( "SHARE", 0, 0, 0, ""),
871
 
  Commands( "SHOW", 0, 0, 0, ""),
872
 
  Commands( "SHUTDOWN", 0, 0, 0, ""),
873
 
  Commands( "SIGNED", 0, 0, 0, ""),
874
 
  Commands( "SIMPLE", 0, 0, 0, ""),
875
 
  Commands( "SLAVE", 0, 0, 0, ""),
876
 
  Commands( "SNAPSHOT", 0, 0, 0, ""),
877
 
  Commands( "SOME", 0, 0, 0, ""),
878
 
  Commands( "SONAME", 0, 0, 0, ""),
879
 
  Commands( "SOUNDS", 0, 0, 0, ""),
880
 
  Commands( "SPATIAL", 0, 0, 0, ""),
881
 
  Commands( "SPECIFIC", 0, 0, 0, ""),
882
 
  Commands( "SQL", 0, 0, 0, ""),
883
 
  Commands( "SQLEXCEPTION", 0, 0, 0, ""),
884
 
  Commands( "SQLSTATE", 0, 0, 0, ""),
885
 
  Commands( "SQLWARNING", 0, 0, 0, ""),
886
 
  Commands( "SQL_BIG_RESULT", 0, 0, 0, ""),
887
 
  Commands( "SQL_BUFFER_RESULT", 0, 0, 0, ""),
888
 
  Commands( "SQL_CACHE", 0, 0, 0, ""),
889
 
  Commands( "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""),
890
 
  Commands( "SQL_NO_CACHE", 0, 0, 0, ""),
891
 
  Commands( "SQL_SMALL_RESULT", 0, 0, 0, ""),
892
 
  Commands( "SQL_THREAD", 0, 0, 0, ""),
893
 
  Commands( "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""),
894
 
  Commands( "SQL_TSI_SECOND", 0, 0, 0, ""),
895
 
  Commands( "SQL_TSI_MINUTE", 0, 0, 0, ""),
896
 
  Commands( "SQL_TSI_HOUR", 0, 0, 0, ""),
897
 
  Commands( "SQL_TSI_DAY", 0, 0, 0, ""),
898
 
  Commands( "SQL_TSI_WEEK", 0, 0, 0, ""),
899
 
  Commands( "SQL_TSI_MONTH", 0, 0, 0, ""),
900
 
  Commands( "SQL_TSI_QUARTER", 0, 0, 0, ""),
901
 
  Commands( "SQL_TSI_YEAR", 0, 0, 0, ""),
902
 
  Commands( "SSL", 0, 0, 0, ""),
903
 
  Commands( "START", 0, 0, 0, ""),
904
 
  Commands( "STARTING", 0, 0, 0, ""),
905
 
  Commands( "STATUS", 0, 0, 0, ""),
906
 
  Commands( "STOP", 0, 0, 0, ""),
907
 
  Commands( "STORAGE", 0, 0, 0, ""),
908
 
  Commands( "STRAIGHT_JOIN", 0, 0, 0, ""),
909
 
  Commands( "STRING", 0, 0, 0, ""),
910
 
  Commands( "STRIPED", 0, 0, 0, ""),
911
 
  Commands( "SUBJECT", 0, 0, 0, ""),
912
 
  Commands( "SUPER", 0, 0, 0, ""),
913
 
  Commands( "SUSPEND", 0, 0, 0, ""),
914
 
  Commands( "TABLE", 0, 0, 0, ""),
915
 
  Commands( "TABLES", 0, 0, 0, ""),
916
 
  Commands( "TABLESPACE", 0, 0, 0, ""),
917
 
  Commands( "TEMPORARY", 0, 0, 0, ""),
918
 
  Commands( "TEMPTABLE", 0, 0, 0, ""),
919
 
  Commands( "TERMINATED", 0, 0, 0, ""),
920
 
  Commands( "TEXT", 0, 0, 0, ""),
921
 
  Commands( "THEN", 0, 0, 0, ""),
922
 
  Commands( "TIMESTAMP", 0, 0, 0, ""),
923
 
  Commands( "TIMESTAMPADD", 0, 0, 0, ""),
924
 
  Commands( "TIMESTAMPDIFF", 0, 0, 0, ""),
925
 
  Commands( "TO", 0, 0, 0, ""),
926
 
  Commands( "TRAILING", 0, 0, 0, ""),
927
 
  Commands( "TRANSACTION", 0, 0, 0, ""),
928
 
  Commands( "TRUE", 0, 0, 0, ""),
929
 
  Commands( "TRUNCATE", 0, 0, 0, ""),
930
 
  Commands( "TYPE", 0, 0, 0, ""),
931
 
  Commands( "TYPES", 0, 0, 0, ""),
932
 
  Commands( "UNCOMMITTED", 0, 0, 0, ""),
933
 
  Commands( "UNDEFINED", 0, 0, 0, ""),
934
 
  Commands( "UNDO", 0, 0, 0, ""),
935
 
  Commands( "UNICODE", 0, 0, 0, ""),
936
 
  Commands( "UNION", 0, 0, 0, ""),
937
 
  Commands( "UNIQUE", 0, 0, 0, ""),
938
 
  Commands( "UNKNOWN", 0, 0, 0, ""),
939
 
  Commands( "UNLOCK", 0, 0, 0, ""),
940
 
  Commands( "UNTIL", 0, 0, 0, ""),
941
 
  Commands( "UPDATE", 0, 0, 0, ""),
942
 
  Commands( "UPGRADE", 0, 0, 0, ""),
943
 
  Commands( "USAGE", 0, 0, 0, ""),
944
 
  Commands( "USE", 0, 0, 0, ""),
945
 
  Commands( "USER", 0, 0, 0, ""),
946
 
  Commands( "USER_RESOURCES", 0, 0, 0, ""),
947
 
  Commands( "USING", 0, 0, 0, ""),
948
 
  Commands( "UTC_DATE", 0, 0, 0, ""),
949
 
  Commands( "UTC_TIMESTAMP", 0, 0, 0, ""),
950
 
  Commands( "VALUE", 0, 0, 0, ""),
951
 
  Commands( "VALUES", 0, 0, 0, ""),
952
 
  Commands( "VARBINARY", 0, 0, 0, ""),
953
 
  Commands( "VARCHAR", 0, 0, 0, ""),
954
 
  Commands( "VARCHARACTER", 0, 0, 0, ""),
955
 
  Commands( "VARIABLES", 0, 0, 0, ""),
956
 
  Commands( "VARYING", 0, 0, 0, ""),
957
 
  Commands( "WARNINGS", 0, 0, 0, ""),
958
 
  Commands( "WEEK", 0, 0, 0, ""),
959
 
  Commands( "WHEN", 0, 0, 0, ""),
960
 
  Commands( "WHERE", 0, 0, 0, ""),
961
 
  Commands( "WHILE", 0, 0, 0, ""),
962
 
  Commands( "VIEW", 0, 0, 0, ""),
963
 
  Commands( "WITH", 0, 0, 0, ""),
964
 
  Commands( "WORK", 0, 0, 0, ""),
965
 
  Commands( "WRITE", 0, 0, 0, ""),
966
 
  Commands( "XOR", 0, 0, 0, ""),
967
 
  Commands( "XA", 0, 0, 0, ""),
968
 
  Commands( "YEAR", 0, 0, 0, ""),
969
 
  Commands( "YEAR_MONTH", 0, 0, 0, ""),
970
 
  Commands( "ZEROFILL", 0, 0, 0, ""),
971
 
  Commands( "ABS", 0, 0, 0, ""),
972
 
  Commands( "ACOS", 0, 0, 0, ""),
973
 
  Commands( "ADDDATE", 0, 0, 0, ""),
974
 
  Commands( "AREA", 0, 0, 0, ""),
975
 
  Commands( "ASIN", 0, 0, 0, ""),
976
 
  Commands( "ASBINARY", 0, 0, 0, ""),
977
 
  Commands( "ASTEXT", 0, 0, 0, ""),
978
 
  Commands( "ATAN", 0, 0, 0, ""),
979
 
  Commands( "ATAN2", 0, 0, 0, ""),
980
 
  Commands( "BENCHMARK", 0, 0, 0, ""),
981
 
  Commands( "BIN", 0, 0, 0, ""),
982
 
  Commands( "BIT_OR", 0, 0, 0, ""),
983
 
  Commands( "BIT_AND", 0, 0, 0, ""),
984
 
  Commands( "BIT_XOR", 0, 0, 0, ""),
985
 
  Commands( "CAST", 0, 0, 0, ""),
986
 
  Commands( "CEIL", 0, 0, 0, ""),
987
 
  Commands( "CEILING", 0, 0, 0, ""),
988
 
  Commands( "CENTROID", 0, 0, 0, ""),
989
 
  Commands( "CHAR_LENGTH", 0, 0, 0, ""),
990
 
  Commands( "CHARACTER_LENGTH", 0, 0, 0, ""),
991
 
  Commands( "COALESCE", 0, 0, 0, ""),
992
 
  Commands( "COERCIBILITY", 0, 0, 0, ""),
993
 
  Commands( "COMPRESS", 0, 0, 0, ""),
994
 
  Commands( "CONCAT", 0, 0, 0, ""),
995
 
  Commands( "CONCAT_WS", 0, 0, 0, ""),
996
 
  Commands( "CONNECTION_ID", 0, 0, 0, ""),
997
 
  Commands( "CONV", 0, 0, 0, ""),
998
 
  Commands( "CONVERT_TZ", 0, 0, 0, ""),
999
 
  Commands( "COUNT", 0, 0, 0, ""),
1000
 
  Commands( "COS", 0, 0, 0, ""),
1001
 
  Commands( "COT", 0, 0, 0, ""),
1002
 
  Commands( "CRC32", 0, 0, 0, ""),
1003
 
  Commands( "CROSSES", 0, 0, 0, ""),
1004
 
  Commands( "CURDATE", 0, 0, 0, ""),
1005
 
  Commands( "DATE_ADD", 0, 0, 0, ""),
1006
 
  Commands( "DATEDIFF", 0, 0, 0, ""),
1007
 
  Commands( "DATE_FORMAT", 0, 0, 0, ""),
1008
 
  Commands( "DATE_SUB", 0, 0, 0, ""),
1009
 
  Commands( "DAYNAME", 0, 0, 0, ""),
1010
 
  Commands( "DAYOFMONTH", 0, 0, 0, ""),
1011
 
  Commands( "DAYOFWEEK", 0, 0, 0, ""),
1012
 
  Commands( "DAYOFYEAR", 0, 0, 0, ""),
1013
 
  Commands( "DECODE", 0, 0, 0, ""),
1014
 
  Commands( "DEGREES", 0, 0, 0, ""),
1015
 
  Commands( "DES_ENCRYPT", 0, 0, 0, ""),
1016
 
  Commands( "DES_DECRYPT", 0, 0, 0, ""),
1017
 
  Commands( "DIMENSION", 0, 0, 0, ""),
1018
 
  Commands( "DISJOINT", 0, 0, 0, ""),
1019
 
  Commands( "ELT", 0, 0, 0, ""),
1020
 
  Commands( "ENCODE", 0, 0, 0, ""),
1021
 
  Commands( "ENCRYPT", 0, 0, 0, ""),
1022
 
  Commands( "ENDPOINT", 0, 0, 0, ""),
1023
 
  Commands( "ENVELOPE", 0, 0, 0, ""),
1024
 
  Commands( "EQUALS", 0, 0, 0, ""),
1025
 
  Commands( "EXTERIORRING", 0, 0, 0, ""),
1026
 
  Commands( "EXTRACT", 0, 0, 0, ""),
1027
 
  Commands( "EXP", 0, 0, 0, ""),
1028
 
  Commands( "EXPORT_SET", 0, 0, 0, ""),
1029
 
  Commands( "FIELD", 0, 0, 0, ""),
1030
 
  Commands( "FIND_IN_SET", 0, 0, 0, ""),
1031
 
  Commands( "FLOOR", 0, 0, 0, ""),
1032
 
  Commands( "FORMAT", 0, 0, 0, ""),
1033
 
  Commands( "FOUND_ROWS", 0, 0, 0, ""),
1034
 
  Commands( "FROM_DAYS", 0, 0, 0, ""),
1035
 
  Commands( "FROM_UNIXTIME", 0, 0, 0, ""),
1036
 
  Commands( "GET_LOCK", 0, 0, 0, ""),
1037
 
  Commands( "GLENGTH", 0, 0, 0, ""),
1038
 
  Commands( "GREATEST", 0, 0, 0, ""),
1039
 
  Commands( "GROUP_CONCAT", 0, 0, 0, ""),
1040
 
  Commands( "GROUP_UNIQUE_USERS", 0, 0, 0, ""),
1041
 
  Commands( "HEX", 0, 0, 0, ""),
1042
 
  Commands( "IFNULL", 0, 0, 0, ""),
1043
 
  Commands( "INSTR", 0, 0, 0, ""),
1044
 
  Commands( "INTERIORRINGN", 0, 0, 0, ""),
1045
 
  Commands( "INTERSECTS", 0, 0, 0, ""),
1046
 
  Commands( "ISCLOSED", 0, 0, 0, ""),
1047
 
  Commands( "ISEMPTY", 0, 0, 0, ""),
1048
 
  Commands( "ISNULL", 0, 0, 0, ""),
1049
 
  Commands( "IS_FREE_LOCK", 0, 0, 0, ""),
1050
 
  Commands( "IS_USED_LOCK", 0, 0, 0, ""),
1051
 
  Commands( "LAST_INSERT_ID", 0, 0, 0, ""),
1052
 
  Commands( "ISSIMPLE", 0, 0, 0, ""),
1053
 
  Commands( "LAST_DAY", 0, 0, 0, ""),
1054
 
  Commands( "LCASE", 0, 0, 0, ""),
1055
 
  Commands( "LEAST", 0, 0, 0, ""),
1056
 
  Commands( "LENGTH", 0, 0, 0, ""),
1057
 
  Commands( "LN", 0, 0, 0, ""),
1058
 
  Commands( "LOAD_FILE", 0, 0, 0, ""),
1059
 
  Commands( "LOCATE", 0, 0, 0, ""),
1060
 
  Commands( "LOG", 0, 0, 0, ""),
1061
 
  Commands( "LOG2", 0, 0, 0, ""),
1062
 
  Commands( "LOG10", 0, 0, 0, ""),
1063
 
  Commands( "LOWER", 0, 0, 0, ""),
1064
 
  Commands( "LPAD", 0, 0, 0, ""),
1065
 
  Commands( "LTRIM", 0, 0, 0, ""),
1066
 
  Commands( "MAKE_SET", 0, 0, 0, ""),
1067
 
  Commands( "MAKEDATE", 0, 0, 0, ""),
1068
 
  Commands( "MASTER_POS_WAIT", 0, 0, 0, ""),
1069
 
  Commands( "MAX", 0, 0, 0, ""),
1070
 
  Commands( "MBRCONTAINS", 0, 0, 0, ""),
1071
 
  Commands( "MBRDISJOINT", 0, 0, 0, ""),
1072
 
  Commands( "MBREQUAL", 0, 0, 0, ""),
1073
 
  Commands( "MBRINTERSECTS", 0, 0, 0, ""),
1074
 
  Commands( "MBROVERLAPS", 0, 0, 0, ""),
1075
 
  Commands( "MBRTOUCHES", 0, 0, 0, ""),
1076
 
  Commands( "MBRWITHIN", 0, 0, 0, ""),
1077
 
  Commands( "MD5", 0, 0, 0, ""),
1078
 
  Commands( "MID", 0, 0, 0, ""),
1079
 
  Commands( "MIN", 0, 0, 0, ""),
1080
 
  Commands( "MONTHNAME", 0, 0, 0, ""),
1081
 
  Commands( "NAME_CONST", 0, 0, 0, ""),
1082
 
  Commands( "NOW", 0, 0, 0, ""),
1083
 
  Commands( "NULLIF", 0, 0, 0, ""),
1084
 
  Commands( "NUMPOINTS", 0, 0, 0, ""),
1085
 
  Commands( "OCTET_LENGTH", 0, 0, 0, ""),
1086
 
  Commands( "OCT", 0, 0, 0, ""),
1087
 
  Commands( "ORD", 0, 0, 0, ""),
1088
 
  Commands( "OVERLAPS", 0, 0, 0, ""),
1089
 
  Commands( "PERIOD_ADD", 0, 0, 0, ""),
1090
 
  Commands( "PERIOD_DIFF", 0, 0, 0, ""),
1091
 
  Commands( "PI", 0, 0, 0, ""),
1092
 
  Commands( "POINTN", 0, 0, 0, ""),
1093
 
  Commands( "POSITION", 0, 0, 0, ""),
1094
 
  Commands( "POW", 0, 0, 0, ""),
1095
 
  Commands( "POWER", 0, 0, 0, ""),
1096
 
  Commands( "QUOTE", 0, 0, 0, ""),
1097
 
  Commands( "RADIANS", 0, 0, 0, ""),
1098
 
  Commands( "RAND", 0, 0, 0, ""),
1099
 
  Commands( "RELEASE_LOCK", 0, 0, 0, ""),
1100
 
  Commands( "REVERSE", 0, 0, 0, ""),
1101
 
  Commands( "ROUND", 0, 0, 0, ""),
1102
 
  Commands( "ROW_COUNT", 0, 0, 0, ""),
1103
 
  Commands( "RPAD", 0, 0, 0, ""),
1104
 
  Commands( "RTRIM", 0, 0, 0, ""),
1105
 
  Commands( "SESSION_USER", 0, 0, 0, ""),
1106
 
  Commands( "SUBDATE", 0, 0, 0, ""),
1107
 
  Commands( "SIGN", 0, 0, 0, ""),
1108
 
  Commands( "SIN", 0, 0, 0, ""),
1109
 
  Commands( "SHA", 0, 0, 0, ""),
1110
 
  Commands( "SHA1", 0, 0, 0, ""),
1111
 
  Commands( "SLEEP", 0, 0, 0, ""),
1112
 
  Commands( "SOUNDEX", 0, 0, 0, ""),
1113
 
  Commands( "SPACE", 0, 0, 0, ""),
1114
 
  Commands( "SQRT", 0, 0, 0, ""),
1115
 
  Commands( "SRID", 0, 0, 0, ""),
1116
 
  Commands( "STARTPOINT", 0, 0, 0, ""),
1117
 
  Commands( "STD", 0, 0, 0, ""),
1118
 
  Commands( "STDDEV", 0, 0, 0, ""),
1119
 
  Commands( "STDDEV_POP", 0, 0, 0, ""),
1120
 
  Commands( "STDDEV_SAMP", 0, 0, 0, ""),
1121
 
  Commands( "STR_TO_DATE", 0, 0, 0, ""),
1122
 
  Commands( "STRCMP", 0, 0, 0, ""),
1123
 
  Commands( "SUBSTR", 0, 0, 0, ""),
1124
 
  Commands( "SUBSTRING", 0, 0, 0, ""),
1125
 
  Commands( "SUBSTRING_INDEX", 0, 0, 0, ""),
1126
 
  Commands( "SUM", 0, 0, 0, ""),
1127
 
  Commands( "SYSDATE", 0, 0, 0, ""),
1128
 
  Commands( "SYSTEM_USER", 0, 0, 0, ""),
1129
 
  Commands( "TAN", 0, 0, 0, ""),
1130
 
  Commands( "TIME_FORMAT", 0, 0, 0, ""),
1131
 
  Commands( "TO_DAYS", 0, 0, 0, ""),
1132
 
  Commands( "TOUCHES", 0, 0, 0, ""),
1133
 
  Commands( "TRIM", 0, 0, 0, ""),
1134
 
  Commands( "UCASE", 0, 0, 0, ""),
1135
 
  Commands( "UNCOMPRESS", 0, 0, 0, ""),
1136
 
  Commands( "UNCOMPRESSED_LENGTH", 0, 0, 0, ""),
1137
 
  Commands( "UNHEX", 0, 0, 0, ""),
1138
 
  Commands( "UNIQUE_USERS", 0, 0, 0, ""),
1139
 
  Commands( "UNIX_TIMESTAMP", 0, 0, 0, ""),
1140
 
  Commands( "UPPER", 0, 0, 0, ""),
1141
 
  Commands( "UUID", 0, 0, 0, ""),
1142
 
  Commands( "VARIANCE", 0, 0, 0, ""),
1143
 
  Commands( "VAR_POP", 0, 0, 0, ""),
1144
 
  Commands( "VAR_SAMP", 0, 0, 0, ""),
1145
 
  Commands( "VERSION", 0, 0, 0, ""),
1146
 
  Commands( "WEEKDAY", 0, 0, 0, ""),
1147
 
  Commands( "WEEKOFYEAR", 0, 0, 0, ""),
1148
 
  Commands( "WITHIN", 0, 0, 0, ""),
1149
 
  Commands( "X", 0, 0, 0, ""),
1150
 
  Commands( "Y", 0, 0, 0, ""),
1151
 
  Commands( "YEARWEEK", 0, 0, 0, ""),
 
291
  { "ACTION", 0, 0, 0, ""},
 
292
  { "ADD", 0, 0, 0, ""},
 
293
  { "AFTER", 0, 0, 0, ""},
 
294
  { "AGAINST", 0, 0, 0, ""},
 
295
  { "AGGREGATE", 0, 0, 0, ""},
 
296
  { "ALL", 0, 0, 0, ""},
 
297
  { "ALGORITHM", 0, 0, 0, ""},
 
298
  { "ALTER", 0, 0, 0, ""},
 
299
  { "ANALYZE", 0, 0, 0, ""},
 
300
  { "AND", 0, 0, 0, ""},
 
301
  { "ANY", 0, 0, 0, ""},
 
302
  { "AS", 0, 0, 0, ""},
 
303
  { "ASC", 0, 0, 0, ""},
 
304
  { "ASCII", 0, 0, 0, ""},
 
305
  { "ASENSITIVE", 0, 0, 0, ""},
 
306
  { "AUTO_INCREMENT", 0, 0, 0, ""},
 
307
  { "AVG", 0, 0, 0, ""},
 
308
  { "AVG_ROW_LENGTH", 0, 0, 0, ""},
 
309
  { "BACKUP", 0, 0, 0, ""},
 
310
  { "BDB", 0, 0, 0, ""},
 
311
  { "BEFORE", 0, 0, 0, ""},
 
312
  { "BEGIN", 0, 0, 0, ""},
 
313
  { "BERKELEYDB", 0, 0, 0, ""},
 
314
  { "BETWEEN", 0, 0, 0, ""},
 
315
  { "BIGINT", 0, 0, 0, ""},
 
316
  { "BINARY", 0, 0, 0, ""},
 
317
  { "BINLOG", 0, 0, 0, ""},
 
318
  { "BIT", 0, 0, 0, ""},
 
319
  { "BLOB", 0, 0, 0, ""},
 
320
  { "BOOL", 0, 0, 0, ""},
 
321
  { "BOOLEAN", 0, 0, 0, ""},
 
322
  { "BOTH", 0, 0, 0, ""},
 
323
  { "BTREE", 0, 0, 0, ""},
 
324
  { "BY", 0, 0, 0, ""},
 
325
  { "BYTE", 0, 0, 0, ""},
 
326
  { "CACHE", 0, 0, 0, ""},
 
327
  { "CALL", 0, 0, 0, ""},
 
328
  { "CASCADE", 0, 0, 0, ""},
 
329
  { "CASCADED", 0, 0, 0, ""},
 
330
  { "CASE", 0, 0, 0, ""},
 
331
  { "CHAIN", 0, 0, 0, ""},
 
332
  { "CHANGE", 0, 0, 0, ""},
 
333
  { "CHANGED", 0, 0, 0, ""},
 
334
  { "CHAR", 0, 0, 0, ""},
 
335
  { "CHARACTER", 0, 0, 0, ""},
 
336
  { "CHARSET", 0, 0, 0, ""},
 
337
  { "CHECK", 0, 0, 0, ""},
 
338
  { "CHECKSUM", 0, 0, 0, ""},
 
339
  { "CIPHER", 0, 0, 0, ""},
 
340
  { "CLIENT", 0, 0, 0, ""},
 
341
  { "CLOSE", 0, 0, 0, ""},
 
342
  { "CODE", 0, 0, 0, ""},
 
343
  { "COLLATE", 0, 0, 0, ""},
 
344
  { "COLLATION", 0, 0, 0, ""},
 
345
  { "COLUMN", 0, 0, 0, ""},
 
346
  { "COLUMNS", 0, 0, 0, ""},
 
347
  { "COMMENT", 0, 0, 0, ""},
 
348
  { "COMMIT", 0, 0, 0, ""},
 
349
  { "COMMITTED", 0, 0, 0, ""},
 
350
  { "COMPACT", 0, 0, 0, ""},
 
351
  { "COMPRESSED", 0, 0, 0, ""},
 
352
  { "CONCURRENT", 0, 0, 0, ""},
 
353
  { "CONDITION", 0, 0, 0, ""},
 
354
  { "CONNECTION", 0, 0, 0, ""},
 
355
  { "CONSISTENT", 0, 0, 0, ""},
 
356
  { "CONSTRAINT", 0, 0, 0, ""},
 
357
  { "CONTAINS", 0, 0, 0, ""},
 
358
  { "CONTINUE", 0, 0, 0, ""},
 
359
  { "CONVERT", 0, 0, 0, ""},
 
360
  { "CREATE", 0, 0, 0, ""},
 
361
  { "CROSS", 0, 0, 0, ""},
 
362
  { "CUBE", 0, 0, 0, ""},
 
363
  { "CURRENT_DATE", 0, 0, 0, ""},
 
364
  { "CURRENT_TIME", 0, 0, 0, ""},
 
365
  { "CURRENT_TIMESTAMP", 0, 0, 0, ""},
 
366
  { "CURRENT_USER", 0, 0, 0, ""},
 
367
  { "CURSOR", 0, 0, 0, ""},
 
368
  { "DATA", 0, 0, 0, ""},
 
369
  { "DATABASE", 0, 0, 0, ""},
 
370
  { "DATABASES", 0, 0, 0, ""},
 
371
  { "DATE", 0, 0, 0, ""},
 
372
  { "DATETIME", 0, 0, 0, ""},
 
373
  { "DAY", 0, 0, 0, ""},
 
374
  { "DAY_HOUR", 0, 0, 0, ""},
 
375
  { "DAY_MICROSECOND", 0, 0, 0, ""},
 
376
  { "DAY_MINUTE", 0, 0, 0, ""},
 
377
  { "DAY_SECOND", 0, 0, 0, ""},
 
378
  { "DEALLOCATE", 0, 0, 0, ""},
 
379
  { "DEC", 0, 0, 0, ""},
 
380
  { "DECIMAL", 0, 0, 0, ""},
 
381
  { "DECLARE", 0, 0, 0, ""},
 
382
  { "DEFAULT", 0, 0, 0, ""},
 
383
  { "DEFINER", 0, 0, 0, ""},
 
384
  { "DELAYED", 0, 0, 0, ""},
 
385
  { "DELAY_KEY_WRITE", 0, 0, 0, ""},
 
386
  { "DELETE", 0, 0, 0, ""},
 
387
  { "DESC", 0, 0, 0, ""},
 
388
  { "DESCRIBE", 0, 0, 0, ""},
 
389
  { "DES_KEY_FILE", 0, 0, 0, ""},
 
390
  { "DETERMINISTIC", 0, 0, 0, ""},
 
391
  { "DIRECTORY", 0, 0, 0, ""},
 
392
  { "DISABLE", 0, 0, 0, ""},
 
393
  { "DISCARD", 0, 0, 0, ""},
 
394
  { "DISTINCT", 0, 0, 0, ""},
 
395
  { "DISTINCTROW", 0, 0, 0, ""},
 
396
  { "DIV", 0, 0, 0, ""},
 
397
  { "DO", 0, 0, 0, ""},
 
398
  { "DOUBLE", 0, 0, 0, ""},
 
399
  { "DROP", 0, 0, 0, ""},
 
400
  { "DUAL", 0, 0, 0, ""},
 
401
  { "DUMPFILE", 0, 0, 0, ""},
 
402
  { "DUPLICATE", 0, 0, 0, ""},
 
403
  { "DYNAMIC", 0, 0, 0, ""},
 
404
  { "EACH", 0, 0, 0, ""},
 
405
  { "ELSE", 0, 0, 0, ""},
 
406
  { "ELSEIF", 0, 0, 0, ""},
 
407
  { "ENABLE", 0, 0, 0, ""},
 
408
  { "ENCLOSED", 0, 0, 0, ""},
 
409
  { "END", 0, 0, 0, ""},
 
410
  { "ENGINE", 0, 0, 0, ""},
 
411
  { "ENGINES", 0, 0, 0, ""},
 
412
  { "ENUM", 0, 0, 0, ""},
 
413
  { "ERRORS", 0, 0, 0, ""},
 
414
  { "ESCAPE", 0, 0, 0, ""},
 
415
  { "ESCAPED", 0, 0, 0, ""},
 
416
  { "EVENTS", 0, 0, 0, ""},
 
417
  { "EXECUTE", 0, 0, 0, ""},
 
418
  { "EXISTS", 0, 0, 0, ""},
 
419
  { "EXIT", 0, 0, 0, ""},
 
420
  { "EXPANSION", 0, 0, 0, ""},
 
421
  { "EXPLAIN", 0, 0, 0, ""},
 
422
  { "EXTENDED", 0, 0, 0, ""},
 
423
  { "FALSE", 0, 0, 0, ""},
 
424
  { "FAST", 0, 0, 0, ""},
 
425
  { "FETCH", 0, 0, 0, ""},
 
426
  { "FIELDS", 0, 0, 0, ""},
 
427
  { "FILE", 0, 0, 0, ""},
 
428
  { "FIRST", 0, 0, 0, ""},
 
429
  { "FIXED", 0, 0, 0, ""},
 
430
  { "FLOAT", 0, 0, 0, ""},
 
431
  { "FLOAT4", 0, 0, 0, ""},
 
432
  { "FLOAT8", 0, 0, 0, ""},
 
433
  { "FLUSH", 0, 0, 0, ""},
 
434
  { "FOR", 0, 0, 0, ""},
 
435
  { "FORCE", 0, 0, 0, ""},
 
436
  { "FOREIGN", 0, 0, 0, ""},
 
437
  { "FOUND", 0, 0, 0, ""},
 
438
  { "FRAC_SECOND", 0, 0, 0, ""},
 
439
  { "FROM", 0, 0, 0, ""},
 
440
  { "FULL", 0, 0, 0, ""},
 
441
  { "FULLTEXT", 0, 0, 0, ""},
 
442
  { "FUNCTION", 0, 0, 0, ""},
 
443
  { "GET_FORMAT", 0, 0, 0, ""},
 
444
  { "GLOBAL", 0, 0, 0, ""},
 
445
  { "GRANT", 0, 0, 0, ""},
 
446
  { "GRANTS", 0, 0, 0, ""},
 
447
  { "GROUP", 0, 0, 0, ""},
 
448
  { "HANDLER", 0, 0, 0, ""},
 
449
  { "HASH", 0, 0, 0, ""},
 
450
  { "HAVING", 0, 0, 0, ""},
 
451
  { "HELP", 0, 0, 0, ""},
 
452
  { "HIGH_PRIORITY", 0, 0, 0, ""},
 
453
  { "HOSTS", 0, 0, 0, ""},
 
454
  { "HOUR", 0, 0, 0, ""},
 
455
  { "HOUR_MICROSECOND", 0, 0, 0, ""},
 
456
  { "HOUR_MINUTE", 0, 0, 0, ""},
 
457
  { "HOUR_SECOND", 0, 0, 0, ""},
 
458
  { "IDENTIFIED", 0, 0, 0, ""},
 
459
  { "IF", 0, 0, 0, ""},
 
460
  { "IGNORE", 0, 0, 0, ""},
 
461
  { "IMPORT", 0, 0, 0, ""},
 
462
  { "IN", 0, 0, 0, ""},
 
463
  { "INDEX", 0, 0, 0, ""},
 
464
  { "INDEXES", 0, 0, 0, ""},
 
465
  { "INFILE", 0, 0, 0, ""},
 
466
  { "INNER", 0, 0, 0, ""},
 
467
  { "INNOBASE", 0, 0, 0, ""},
 
468
  { "INNODB", 0, 0, 0, ""},
 
469
  { "INOUT", 0, 0, 0, ""},
 
470
  { "INSENSITIVE", 0, 0, 0, ""},
 
471
  { "INSERT", 0, 0, 0, ""},
 
472
  { "INSERT_METHOD", 0, 0, 0, ""},
 
473
  { "INT", 0, 0, 0, ""},
 
474
  { "INT1", 0, 0, 0, ""},
 
475
  { "INT2", 0, 0, 0, ""},
 
476
  { "INT3", 0, 0, 0, ""},
 
477
  { "INT4", 0, 0, 0, ""},
 
478
  { "INT8", 0, 0, 0, ""},
 
479
  { "INTEGER", 0, 0, 0, ""},
 
480
  { "INTERVAL", 0, 0, 0, ""},
 
481
  { "INTO", 0, 0, 0, ""},
 
482
  { "IO_THREAD", 0, 0, 0, ""},
 
483
  { "IS", 0, 0, 0, ""},
 
484
  { "ISOLATION", 0, 0, 0, ""},
 
485
  { "ISSUER", 0, 0, 0, ""},
 
486
  { "ITERATE", 0, 0, 0, ""},
 
487
  { "INVOKER", 0, 0, 0, ""},
 
488
  { "JOIN", 0, 0, 0, ""},
 
489
  { "KEY", 0, 0, 0, ""},
 
490
  { "KEYS", 0, 0, 0, ""},
 
491
  { "KILL", 0, 0, 0, ""},
 
492
  { "LANGUAGE", 0, 0, 0, ""},
 
493
  { "LAST", 0, 0, 0, ""},
 
494
  { "LEADING", 0, 0, 0, ""},
 
495
  { "LEAVE", 0, 0, 0, ""},
 
496
  { "LEAVES", 0, 0, 0, ""},
 
497
  { "LEFT", 0, 0, 0, ""},
 
498
  { "LEVEL", 0, 0, 0, ""},
 
499
  { "LIKE", 0, 0, 0, ""},
 
500
  { "LIMIT", 0, 0, 0, ""},
 
501
  { "LINES", 0, 0, 0, ""},
 
502
  { "LINESTRING", 0, 0, 0, ""},
 
503
  { "LOAD", 0, 0, 0, ""},
 
504
  { "LOCAL", 0, 0, 0, ""},
 
505
  { "LOCALTIME", 0, 0, 0, ""},
 
506
  { "LOCALTIMESTAMP", 0, 0, 0, ""},
 
507
  { "LOCK", 0, 0, 0, ""},
 
508
  { "LOCKS", 0, 0, 0, ""},
 
509
  { "LOGS", 0, 0, 0, ""},
 
510
  { "LONG", 0, 0, 0, ""},
 
511
  { "LONGTEXT", 0, 0, 0, ""},
 
512
  { "LOOP", 0, 0, 0, ""},
 
513
  { "LOW_PRIORITY", 0, 0, 0, ""},
 
514
  { "MASTER", 0, 0, 0, ""},
 
515
  { "MASTER_CONNECT_RETRY", 0, 0, 0, ""},
 
516
  { "MASTER_HOST", 0, 0, 0, ""},
 
517
  { "MASTER_LOG_FILE", 0, 0, 0, ""},
 
518
  { "MASTER_LOG_POS", 0, 0, 0, ""},
 
519
  { "MASTER_PASSWORD", 0, 0, 0, ""},
 
520
  { "MASTER_PORT", 0, 0, 0, ""},
 
521
  { "MASTER_SERVER_ID", 0, 0, 0, ""},
 
522
  { "MASTER_SSL", 0, 0, 0, ""},
 
523
  { "MASTER_SSL_CA", 0, 0, 0, ""},
 
524
  { "MASTER_SSL_CAPATH", 0, 0, 0, ""},
 
525
  { "MASTER_SSL_CERT", 0, 0, 0, ""},
 
526
  { "MASTER_SSL_CIPHER", 0, 0, 0, ""},
 
527
  { "MASTER_SSL_KEY", 0, 0, 0, ""},
 
528
  { "MASTER_USER", 0, 0, 0, ""},
 
529
  { "MATCH", 0, 0, 0, ""},
 
530
  { "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""},
 
531
  { "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""},
 
532
  { "MAX_ROWS", 0, 0, 0, ""},
 
533
  { "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""},
 
534
  { "MAX_USER_CONNECTIONS", 0, 0, 0, ""},
 
535
  { "MEDIUM", 0, 0, 0, ""},
 
536
  { "MEDIUMTEXT", 0, 0, 0, ""},
 
537
  { "MERGE", 0, 0, 0, ""},
 
538
  { "MICROSECOND", 0, 0, 0, ""},
 
539
  { "MIDDLEINT", 0, 0, 0, ""},
 
540
  { "MIGRATE", 0, 0, 0, ""},
 
541
  { "MINUTE", 0, 0, 0, ""},
 
542
  { "MINUTE_MICROSECOND", 0, 0, 0, ""},
 
543
  { "MINUTE_SECOND", 0, 0, 0, ""},
 
544
  { "MIN_ROWS", 0, 0, 0, ""},
 
545
  { "MOD", 0, 0, 0, ""},
 
546
  { "MODE", 0, 0, 0, ""},
 
547
  { "MODIFIES", 0, 0, 0, ""},
 
548
  { "MODIFY", 0, 0, 0, ""},
 
549
  { "MONTH", 0, 0, 0, ""},
 
550
  { "MULTILINESTRING", 0, 0, 0, ""},
 
551
  { "MULTIPOINT", 0, 0, 0, ""},
 
552
  { "MULTIPOLYGON", 0, 0, 0, ""},
 
553
  { "MUTEX", 0, 0, 0, ""},
 
554
  { "NAME", 0, 0, 0, ""},
 
555
  { "NAMES", 0, 0, 0, ""},
 
556
  { "NATIONAL", 0, 0, 0, ""},
 
557
  { "NATURAL", 0, 0, 0, ""},
 
558
  { "NDB", 0, 0, 0, ""},
 
559
  { "NDBCLUSTER", 0, 0, 0, ""},
 
560
  { "NCHAR", 0, 0, 0, ""},
 
561
  { "NEW", 0, 0, 0, ""},
 
562
  { "NEXT", 0, 0, 0, ""},
 
563
  { "NO", 0, 0, 0, ""},
 
564
  { "NONE", 0, 0, 0, ""},
 
565
  { "NOT", 0, 0, 0, ""},
 
566
  { "NO_WRITE_TO_BINLOG", 0, 0, 0, ""},
 
567
  { "NULL", 0, 0, 0, ""},
 
568
  { "NUMERIC", 0, 0, 0, ""},
 
569
  { "NVARCHAR", 0, 0, 0, ""},
 
570
  { "OFFSET", 0, 0, 0, ""},
 
571
  { "OLD_PASSWORD", 0, 0, 0, ""},
 
572
  { "ON", 0, 0, 0, ""},
 
573
  { "ONE", 0, 0, 0, ""},
 
574
  { "ONE_SHOT", 0, 0, 0, ""},
 
575
  { "OPEN", 0, 0, 0, ""},
 
576
  { "OPTIMIZE", 0, 0, 0, ""},
 
577
  { "OPTION", 0, 0, 0, ""},
 
578
  { "OPTIONALLY", 0, 0, 0, ""},
 
579
  { "OR", 0, 0, 0, ""},
 
580
  { "ORDER", 0, 0, 0, ""},
 
581
  { "OUT", 0, 0, 0, ""},
 
582
  { "OUTER", 0, 0, 0, ""},
 
583
  { "OUTFILE", 0, 0, 0, ""},
 
584
  { "PACK_KEYS", 0, 0, 0, ""},
 
585
  { "PARTIAL", 0, 0, 0, ""},
 
586
  { "PASSWORD", 0, 0, 0, ""},
 
587
  { "PHASE", 0, 0, 0, ""},
 
588
  { "POINT", 0, 0, 0, ""},
 
589
  { "POLYGON", 0, 0, 0, ""},
 
590
  { "PRECISION", 0, 0, 0, ""},
 
591
  { "PREPARE", 0, 0, 0, ""},
 
592
  { "PREV", 0, 0, 0, ""},
 
593
  { "PRIMARY", 0, 0, 0, ""},
 
594
  { "PRIVILEGES", 0, 0, 0, ""},
 
595
  { "PROCEDURE", 0, 0, 0, ""},
 
596
  { "PROCESS", 0, 0, 0, ""},
 
597
  { "PROCESSLIST", 0, 0, 0, ""},
 
598
  { "PURGE", 0, 0, 0, ""},
 
599
  { "QUARTER", 0, 0, 0, ""},
 
600
  { "QUERY", 0, 0, 0, ""},
 
601
  { "QUICK", 0, 0, 0, ""},
 
602
  { "RAID0", 0, 0, 0, ""},
 
603
  { "RAID_CHUNKS", 0, 0, 0, ""},
 
604
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
 
605
  { "RAID_TYPE", 0, 0, 0, ""},
 
606
  { "READ", 0, 0, 0, ""},
 
607
  { "READS", 0, 0, 0, ""},
 
608
  { "REAL", 0, 0, 0, ""},
 
609
  { "RECOVER", 0, 0, 0, ""},
 
610
  { "REDUNDANT", 0, 0, 0, ""},
 
611
  { "REFERENCES", 0, 0, 0, ""},
 
612
  { "REGEXP", 0, 0, 0, ""},
 
613
  { "RELAY_LOG_FILE", 0, 0, 0, ""},
 
614
  { "RELAY_LOG_POS", 0, 0, 0, ""},
 
615
  { "RELAY_THREAD", 0, 0, 0, ""},
 
616
  { "RELEASE", 0, 0, 0, ""},
 
617
  { "RELOAD", 0, 0, 0, ""},
 
618
  { "RENAME", 0, 0, 0, ""},
 
619
  { "REPAIR", 0, 0, 0, ""},
 
620
  { "REPEATABLE", 0, 0, 0, ""},
 
621
  { "REPLACE", 0, 0, 0, ""},
 
622
  { "REPLICATION", 0, 0, 0, ""},
 
623
  { "REPEAT", 0, 0, 0, ""},
 
624
  { "REQUIRE", 0, 0, 0, ""},
 
625
  { "RESET", 0, 0, 0, ""},
 
626
  { "RESTORE", 0, 0, 0, ""},
 
627
  { "RESTRICT", 0, 0, 0, ""},
 
628
  { "RESUME", 0, 0, 0, ""},
 
629
  { "RETURN", 0, 0, 0, ""},
 
630
  { "RETURNS", 0, 0, 0, ""},
 
631
  { "REVOKE", 0, 0, 0, ""},
 
632
  { "RIGHT", 0, 0, 0, ""},
 
633
  { "RLIKE", 0, 0, 0, ""},
 
634
  { "ROLLBACK", 0, 0, 0, ""},
 
635
  { "ROLLUP", 0, 0, 0, ""},
 
636
  { "ROUTINE", 0, 0, 0, ""},
 
637
  { "ROW", 0, 0, 0, ""},
 
638
  { "ROWS", 0, 0, 0, ""},
 
639
  { "ROW_FORMAT", 0, 0, 0, ""},
 
640
  { "RTREE", 0, 0, 0, ""},
 
641
  { "SAVEPOINT", 0, 0, 0, ""},
 
642
  { "SCHEMA", 0, 0, 0, ""},
 
643
  { "SCHEMAS", 0, 0, 0, ""},
 
644
  { "SECOND", 0, 0, 0, ""},
 
645
  { "SECOND_MICROSECOND", 0, 0, 0, ""},
 
646
  { "SECURITY", 0, 0, 0, ""},
 
647
  { "SELECT", 0, 0, 0, ""},
 
648
  { "SENSITIVE", 0, 0, 0, ""},
 
649
  { "SEPARATOR", 0, 0, 0, ""},
 
650
  { "SERIAL", 0, 0, 0, ""},
 
651
  { "SERIALIZABLE", 0, 0, 0, ""},
 
652
  { "SESSION", 0, 0, 0, ""},
 
653
  { "SET", 0, 0, 0, ""},
 
654
  { "SHARE", 0, 0, 0, ""},
 
655
  { "SHOW", 0, 0, 0, ""},
 
656
  { "SHUTDOWN", 0, 0, 0, ""},
 
657
  { "SIGNED", 0, 0, 0, ""},
 
658
  { "SIMPLE", 0, 0, 0, ""},
 
659
  { "SLAVE", 0, 0, 0, ""},
 
660
  { "SNAPSHOT", 0, 0, 0, ""},
 
661
  { "SMALLINT", 0, 0, 0, ""},
 
662
  { "SOME", 0, 0, 0, ""},
 
663
  { "SONAME", 0, 0, 0, ""},
 
664
  { "SOUNDS", 0, 0, 0, ""},
 
665
  { "SPATIAL", 0, 0, 0, ""},
 
666
  { "SPECIFIC", 0, 0, 0, ""},
 
667
  { "SQL", 0, 0, 0, ""},
 
668
  { "SQLEXCEPTION", 0, 0, 0, ""},
 
669
  { "SQLSTATE", 0, 0, 0, ""},
 
670
  { "SQLWARNING", 0, 0, 0, ""},
 
671
  { "SQL_BIG_RESULT", 0, 0, 0, ""},
 
672
  { "SQL_BUFFER_RESULT", 0, 0, 0, ""},
 
673
  { "SQL_CACHE", 0, 0, 0, ""},
 
674
  { "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""},
 
675
  { "SQL_NO_CACHE", 0, 0, 0, ""},
 
676
  { "SQL_SMALL_RESULT", 0, 0, 0, ""},
 
677
  { "SQL_THREAD", 0, 0, 0, ""},
 
678
  { "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
 
679
  { "SQL_TSI_SECOND", 0, 0, 0, ""},
 
680
  { "SQL_TSI_MINUTE", 0, 0, 0, ""},
 
681
  { "SQL_TSI_HOUR", 0, 0, 0, ""},
 
682
  { "SQL_TSI_DAY", 0, 0, 0, ""},
 
683
  { "SQL_TSI_WEEK", 0, 0, 0, ""},
 
684
  { "SQL_TSI_MONTH", 0, 0, 0, ""},
 
685
  { "SQL_TSI_QUARTER", 0, 0, 0, ""},
 
686
  { "SQL_TSI_YEAR", 0, 0, 0, ""},
 
687
  { "SSL", 0, 0, 0, ""},
 
688
  { "START", 0, 0, 0, ""},
 
689
  { "STARTING", 0, 0, 0, ""},
 
690
  { "STATUS", 0, 0, 0, ""},
 
691
  { "STOP", 0, 0, 0, ""},
 
692
  { "STORAGE", 0, 0, 0, ""},
 
693
  { "STRAIGHT_JOIN", 0, 0, 0, ""},
 
694
  { "STRING", 0, 0, 0, ""},
 
695
  { "STRIPED", 0, 0, 0, ""},
 
696
  { "SUBJECT", 0, 0, 0, ""},
 
697
  { "SUPER", 0, 0, 0, ""},
 
698
  { "SUSPEND", 0, 0, 0, ""},
 
699
  { "TABLE", 0, 0, 0, ""},
 
700
  { "TABLES", 0, 0, 0, ""},
 
701
  { "TABLESPACE", 0, 0, 0, ""},
 
702
  { "TEMPORARY", 0, 0, 0, ""},
 
703
  { "TEMPTABLE", 0, 0, 0, ""},
 
704
  { "TERMINATED", 0, 0, 0, ""},
 
705
  { "TEXT", 0, 0, 0, ""},
 
706
  { "THEN", 0, 0, 0, ""},
 
707
  { "TIME", 0, 0, 0, ""},
 
708
  { "TIMESTAMP", 0, 0, 0, ""},
 
709
  { "TIMESTAMPADD", 0, 0, 0, ""},
 
710
  { "TIMESTAMPDIFF", 0, 0, 0, ""},
 
711
  { "TINYINT", 0, 0, 0, ""},
 
712
  { "TINYTEXT", 0, 0, 0, ""},
 
713
  { "TO", 0, 0, 0, ""},
 
714
  { "TRAILING", 0, 0, 0, ""},
 
715
  { "TRANSACTION", 0, 0, 0, ""},
 
716
  { "TRIGGER", 0, 0, 0, ""},
 
717
  { "TRIGGERS", 0, 0, 0, ""},
 
718
  { "TRUE", 0, 0, 0, ""},
 
719
  { "TRUNCATE", 0, 0, 0, ""},
 
720
  { "TYPE", 0, 0, 0, ""},
 
721
  { "TYPES", 0, 0, 0, ""},
 
722
  { "UNCOMMITTED", 0, 0, 0, ""},
 
723
  { "UNDEFINED", 0, 0, 0, ""},
 
724
  { "UNDO", 0, 0, 0, ""},
 
725
  { "UNICODE", 0, 0, 0, ""},
 
726
  { "UNION", 0, 0, 0, ""},
 
727
  { "UNIQUE", 0, 0, 0, ""},
 
728
  { "UNKNOWN", 0, 0, 0, ""},
 
729
  { "UNLOCK", 0, 0, 0, ""},
 
730
  { "UNSIGNED", 0, 0, 0, ""},
 
731
  { "UNTIL", 0, 0, 0, ""},
 
732
  { "UPDATE", 0, 0, 0, ""},
 
733
  { "UPGRADE", 0, 0, 0, ""},
 
734
  { "USAGE", 0, 0, 0, ""},
 
735
  { "USE", 0, 0, 0, ""},
 
736
  { "USER", 0, 0, 0, ""},
 
737
  { "USER_RESOURCES", 0, 0, 0, ""},
 
738
  { "USE_FRM", 0, 0, 0, ""},
 
739
  { "USING", 0, 0, 0, ""},
 
740
  { "UTC_DATE", 0, 0, 0, ""},
 
741
  { "UTC_TIME", 0, 0, 0, ""},
 
742
  { "UTC_TIMESTAMP", 0, 0, 0, ""},
 
743
  { "VALUE", 0, 0, 0, ""},
 
744
  { "VALUES", 0, 0, 0, ""},
 
745
  { "VARBINARY", 0, 0, 0, ""},
 
746
  { "VARCHAR", 0, 0, 0, ""},
 
747
  { "VARCHARACTER", 0, 0, 0, ""},
 
748
  { "VARIABLES", 0, 0, 0, ""},
 
749
  { "VARYING", 0, 0, 0, ""},
 
750
  { "WARNINGS", 0, 0, 0, ""},
 
751
  { "WEEK", 0, 0, 0, ""},
 
752
  { "WHEN", 0, 0, 0, ""},
 
753
  { "WHERE", 0, 0, 0, ""},
 
754
  { "WHILE", 0, 0, 0, ""},
 
755
  { "VIEW", 0, 0, 0, ""},
 
756
  { "WITH", 0, 0, 0, ""},
 
757
  { "WORK", 0, 0, 0, ""},
 
758
  { "WRITE", 0, 0, 0, ""},
 
759
  { "X509", 0, 0, 0, ""},
 
760
  { "XOR", 0, 0, 0, ""},
 
761
  { "XA", 0, 0, 0, ""},
 
762
  { "YEAR", 0, 0, 0, ""},
 
763
  { "YEAR_MONTH", 0, 0, 0, ""},
 
764
  { "ZEROFILL", 0, 0, 0, ""},
 
765
  { "ABS", 0, 0, 0, ""},
 
766
  { "ACOS", 0, 0, 0, ""},
 
767
  { "ADDDATE", 0, 0, 0, ""},
 
768
  { "ADDTIME", 0, 0, 0, ""},
 
769
  { "AES_ENCRYPT", 0, 0, 0, ""},
 
770
  { "AES_DECRYPT", 0, 0, 0, ""},
 
771
  { "AREA", 0, 0, 0, ""},
 
772
  { "ASIN", 0, 0, 0, ""},
 
773
  { "ASBINARY", 0, 0, 0, ""},
 
774
  { "ASTEXT", 0, 0, 0, ""},
 
775
  { "ASWKB", 0, 0, 0, ""},
 
776
  { "ASWKT", 0, 0, 0, ""},
 
777
  { "ATAN", 0, 0, 0, ""},
 
778
  { "ATAN2", 0, 0, 0, ""},
 
779
  { "BENCHMARK", 0, 0, 0, ""},
 
780
  { "BIN", 0, 0, 0, ""},
 
781
  { "BIT_COUNT", 0, 0, 0, ""},
 
782
  { "BIT_OR", 0, 0, 0, ""},
 
783
  { "BIT_AND", 0, 0, 0, ""},
 
784
  { "BIT_XOR", 0, 0, 0, ""},
 
785
  { "CAST", 0, 0, 0, ""},
 
786
  { "CEIL", 0, 0, 0, ""},
 
787
  { "CEILING", 0, 0, 0, ""},
 
788
  { "BIT_LENGTH", 0, 0, 0, ""},
 
789
  { "CENTROID", 0, 0, 0, ""},
 
790
  { "CHAR_LENGTH", 0, 0, 0, ""},
 
791
  { "CHARACTER_LENGTH", 0, 0, 0, ""},
 
792
  { "COALESCE", 0, 0, 0, ""},
 
793
  { "COERCIBILITY", 0, 0, 0, ""},
 
794
  { "COMPRESS", 0, 0, 0, ""},
 
795
  { "CONCAT", 0, 0, 0, ""},
 
796
  { "CONCAT_WS", 0, 0, 0, ""},
 
797
  { "CONNECTION_ID", 0, 0, 0, ""},
 
798
  { "CONV", 0, 0, 0, ""},
 
799
  { "CONVERT_TZ", 0, 0, 0, ""},
 
800
  { "COUNT", 0, 0, 0, ""},
 
801
  { "COS", 0, 0, 0, ""},
 
802
  { "COT", 0, 0, 0, ""},
 
803
  { "CRC32", 0, 0, 0, ""},
 
804
  { "CROSSES", 0, 0, 0, ""},
 
805
  { "CURDATE", 0, 0, 0, ""},
 
806
  { "CURTIME", 0, 0, 0, ""},
 
807
  { "DATE_ADD", 0, 0, 0, ""},
 
808
  { "DATEDIFF", 0, 0, 0, ""},
 
809
  { "DATE_FORMAT", 0, 0, 0, ""},
 
810
  { "DATE_SUB", 0, 0, 0, ""},
 
811
  { "DAYNAME", 0, 0, 0, ""},
 
812
  { "DAYOFMONTH", 0, 0, 0, ""},
 
813
  { "DAYOFWEEK", 0, 0, 0, ""},
 
814
  { "DAYOFYEAR", 0, 0, 0, ""},
 
815
  { "DECODE", 0, 0, 0, ""},
 
816
  { "DEGREES", 0, 0, 0, ""},
 
817
  { "DES_ENCRYPT", 0, 0, 0, ""},
 
818
  { "DES_DECRYPT", 0, 0, 0, ""},
 
819
  { "DIMENSION", 0, 0, 0, ""},
 
820
  { "DISJOINT", 0, 0, 0, ""},
 
821
  { "ELT", 0, 0, 0, ""},
 
822
  { "ENCODE", 0, 0, 0, ""},
 
823
  { "ENCRYPT", 0, 0, 0, ""},
 
824
  { "ENDPOINT", 0, 0, 0, ""},
 
825
  { "ENVELOPE", 0, 0, 0, ""},
 
826
  { "EQUALS", 0, 0, 0, ""},
 
827
  { "EXTERIORRING", 0, 0, 0, ""},
 
828
  { "EXTRACT", 0, 0, 0, ""},
 
829
  { "EXP", 0, 0, 0, ""},
 
830
  { "EXPORT_SET", 0, 0, 0, ""},
 
831
  { "FIELD", 0, 0, 0, ""},
 
832
  { "FIND_IN_SET", 0, 0, 0, ""},
 
833
  { "FLOOR", 0, 0, 0, ""},
 
834
  { "FORMAT", 0, 0, 0, ""},
 
835
  { "FOUND_ROWS", 0, 0, 0, ""},
 
836
  { "FROM_DAYS", 0, 0, 0, ""},
 
837
  { "FROM_UNIXTIME", 0, 0, 0, ""},
 
838
  { "GET_LOCK", 0, 0, 0, ""},
 
839
  { "GLENGTH", 0, 0, 0, ""},
 
840
  { "GREATEST", 0, 0, 0, ""},
 
841
  { "GROUP_CONCAT", 0, 0, 0, ""},
 
842
  { "GROUP_UNIQUE_USERS", 0, 0, 0, ""},
 
843
  { "HEX", 0, 0, 0, ""},
 
844
  { "IFNULL", 0, 0, 0, ""},
 
845
  { "INET_ATON", 0, 0, 0, ""},
 
846
  { "INET_NTOA", 0, 0, 0, ""},
 
847
  { "INSTR", 0, 0, 0, ""},
 
848
  { "INTERIORRINGN", 0, 0, 0, ""},
 
849
  { "INTERSECTS", 0, 0, 0, ""},
 
850
  { "ISCLOSED", 0, 0, 0, ""},
 
851
  { "ISEMPTY", 0, 0, 0, ""},
 
852
  { "ISNULL", 0, 0, 0, ""},
 
853
  { "IS_FREE_LOCK", 0, 0, 0, ""},
 
854
  { "IS_USED_LOCK", 0, 0, 0, ""},
 
855
  { "LAST_INSERT_ID", 0, 0, 0, ""},
 
856
  { "ISSIMPLE", 0, 0, 0, ""},
 
857
  { "LAST_DAY", 0, 0, 0, ""},
 
858
  { "LCASE", 0, 0, 0, ""},
 
859
  { "LEAST", 0, 0, 0, ""},
 
860
  { "LENGTH", 0, 0, 0, ""},
 
861
  { "LN", 0, 0, 0, ""},
 
862
  { "LINEFROMTEXT", 0, 0, 0, ""},
 
863
  { "LINEFROMWKB", 0, 0, 0, ""},
 
864
  { "LINESTRINGFROMTEXT", 0, 0, 0, ""},
 
865
  { "LINESTRINGFROMWKB", 0, 0, 0, ""},
 
866
  { "LOAD_FILE", 0, 0, 0, ""},
 
867
  { "LOCATE", 0, 0, 0, ""},
 
868
  { "LOG", 0, 0, 0, ""},
 
869
  { "LOG2", 0, 0, 0, ""},
 
870
  { "LOG10", 0, 0, 0, ""},
 
871
  { "LOWER", 0, 0, 0, ""},
 
872
  { "LPAD", 0, 0, 0, ""},
 
873
  { "LTRIM", 0, 0, 0, ""},
 
874
  { "MAKE_SET", 0, 0, 0, ""},
 
875
  { "MAKEDATE", 0, 0, 0, ""},
 
876
  { "MAKETIME", 0, 0, 0, ""},
 
877
  { "MASTER_POS_WAIT", 0, 0, 0, ""},
 
878
  { "MAX", 0, 0, 0, ""},
 
879
  { "MBRCONTAINS", 0, 0, 0, ""},
 
880
  { "MBRDISJOINT", 0, 0, 0, ""},
 
881
  { "MBREQUAL", 0, 0, 0, ""},
 
882
  { "MBRINTERSECTS", 0, 0, 0, ""},
 
883
  { "MBROVERLAPS", 0, 0, 0, ""},
 
884
  { "MBRTOUCHES", 0, 0, 0, ""},
 
885
  { "MBRWITHIN", 0, 0, 0, ""},
 
886
  { "MD5", 0, 0, 0, ""},
 
887
  { "MID", 0, 0, 0, ""},
 
888
  { "MIN", 0, 0, 0, ""},
 
889
  { "MLINEFROMTEXT", 0, 0, 0, ""},
 
890
  { "MLINEFROMWKB", 0, 0, 0, ""},
 
891
  { "MPOINTFROMTEXT", 0, 0, 0, ""},
 
892
  { "MPOINTFROMWKB", 0, 0, 0, ""},
 
893
  { "MPOLYFROMTEXT", 0, 0, 0, ""},
 
894
  { "MPOLYFROMWKB", 0, 0, 0, ""},
 
895
  { "MONTHNAME", 0, 0, 0, ""},
 
896
  { "MULTILINESTRINGFROMTEXT", 0, 0, 0, ""},
 
897
  { "MULTILINESTRINGFROMWKB", 0, 0, 0, ""},
 
898
  { "MULTIPOINTFROMTEXT", 0, 0, 0, ""},
 
899
  { "MULTIPOINTFROMWKB", 0, 0, 0, ""},
 
900
  { "MULTIPOLYGONFROMTEXT", 0, 0, 0, ""},
 
901
  { "MULTIPOLYGONFROMWKB", 0, 0, 0, ""},
 
902
  { "NAME_CONST", 0, 0, 0, ""},
 
903
  { "NOW", 0, 0, 0, ""},
 
904
  { "NULLIF", 0, 0, 0, ""},
 
905
  { "NUMINTERIORRINGS", 0, 0, 0, ""},
 
906
  { "NUMPOINTS", 0, 0, 0, ""},
 
907
  { "OCTET_LENGTH", 0, 0, 0, ""},
 
908
  { "OCT", 0, 0, 0, ""},
 
909
  { "ORD", 0, 0, 0, ""},
 
910
  { "OVERLAPS", 0, 0, 0, ""},
 
911
  { "PERIOD_ADD", 0, 0, 0, ""},
 
912
  { "PERIOD_DIFF", 0, 0, 0, ""},
 
913
  { "PI", 0, 0, 0, ""},
 
914
  { "POINTFROMTEXT", 0, 0, 0, ""},
 
915
  { "POINTFROMWKB", 0, 0, 0, ""},
 
916
  { "POINTN", 0, 0, 0, ""},
 
917
  { "POLYFROMTEXT", 0, 0, 0, ""},
 
918
  { "POLYFROMWKB", 0, 0, 0, ""},
 
919
  { "POLYGONFROMTEXT", 0, 0, 0, ""},
 
920
  { "POLYGONFROMWKB", 0, 0, 0, ""},
 
921
  { "POSITION", 0, 0, 0, ""},
 
922
  { "POW", 0, 0, 0, ""},
 
923
  { "POWER", 0, 0, 0, ""},
 
924
  { "QUOTE", 0, 0, 0, ""},
 
925
  { "RADIANS", 0, 0, 0, ""},
 
926
  { "RAND", 0, 0, 0, ""},
 
927
  { "RELEASE_LOCK", 0, 0, 0, ""},
 
928
  { "REVERSE", 0, 0, 0, ""},
 
929
  { "ROUND", 0, 0, 0, ""},
 
930
  { "ROW_COUNT", 0, 0, 0, ""},
 
931
  { "RPAD", 0, 0, 0, ""},
 
932
  { "RTRIM", 0, 0, 0, ""},
 
933
  { "SEC_TO_TIME", 0, 0, 0, ""},
 
934
  { "SESSION_USER", 0, 0, 0, ""},
 
935
  { "SUBDATE", 0, 0, 0, ""},
 
936
  { "SIGN", 0, 0, 0, ""},
 
937
  { "SIN", 0, 0, 0, ""},
 
938
  { "SHA", 0, 0, 0, ""},
 
939
  { "SHA1", 0, 0, 0, ""},
 
940
  { "SLEEP", 0, 0, 0, ""},
 
941
  { "SOUNDEX", 0, 0, 0, ""},
 
942
  { "SPACE", 0, 0, 0, ""},
 
943
  { "SQRT", 0, 0, 0, ""},
 
944
  { "SRID", 0, 0, 0, ""},
 
945
  { "STARTPOINT", 0, 0, 0, ""},
 
946
  { "STD", 0, 0, 0, ""},
 
947
  { "STDDEV", 0, 0, 0, ""},
 
948
  { "STDDEV_POP", 0, 0, 0, ""},
 
949
  { "STDDEV_SAMP", 0, 0, 0, ""},
 
950
  { "STR_TO_DATE", 0, 0, 0, ""},
 
951
  { "STRCMP", 0, 0, 0, ""},
 
952
  { "SUBSTR", 0, 0, 0, ""},
 
953
  { "SUBSTRING", 0, 0, 0, ""},
 
954
  { "SUBSTRING_INDEX", 0, 0, 0, ""},
 
955
  { "SUBTIME", 0, 0, 0, ""},
 
956
  { "SUM", 0, 0, 0, ""},
 
957
  { "SYSDATE", 0, 0, 0, ""},
 
958
  { "SYSTEM_USER", 0, 0, 0, ""},
 
959
  { "TAN", 0, 0, 0, ""},
 
960
  { "TIME_FORMAT", 0, 0, 0, ""},
 
961
  { "TIME_TO_SEC", 0, 0, 0, ""},
 
962
  { "TIMEDIFF", 0, 0, 0, ""},
 
963
  { "TO_DAYS", 0, 0, 0, ""},
 
964
  { "TOUCHES", 0, 0, 0, ""},
 
965
  { "TRIM", 0, 0, 0, ""},
 
966
  { "UCASE", 0, 0, 0, ""},
 
967
  { "UNCOMPRESS", 0, 0, 0, ""},
 
968
  { "UNCOMPRESSED_LENGTH", 0, 0, 0, ""},
 
969
  { "UNHEX", 0, 0, 0, ""},
 
970
  { "UNIQUE_USERS", 0, 0, 0, ""},
 
971
  { "UNIX_TIMESTAMP", 0, 0, 0, ""},
 
972
  { "UPPER", 0, 0, 0, ""},
 
973
  { "UUID", 0, 0, 0, ""},
 
974
  { "VARIANCE", 0, 0, 0, ""},
 
975
  { "VAR_POP", 0, 0, 0, ""},
 
976
  { "VAR_SAMP", 0, 0, 0, ""},
 
977
  { "VERSION", 0, 0, 0, ""},
 
978
  { "WEEKDAY", 0, 0, 0, ""},
 
979
  { "WEEKOFYEAR", 0, 0, 0, ""},
 
980
  { "WITHIN", 0, 0, 0, ""},
 
981
  { "X", 0, 0, 0, ""},
 
982
  { "Y", 0, 0, 0, ""},
 
983
  { "YEARWEEK", 0, 0, 0, ""},
1152
984
  /* end sentinel */
1153
 
  Commands((char *)NULL,       0, 0, 0, "")
 
985
  { (char *)NULL,       0, 0, 0, ""}
1154
986
};
1155
987
 
 
988
static const char *load_default_groups[]= { "mysql","client",0 };
 
989
 
 
990
static int         embedded_server_arg_count= 0;
 
991
static char       *embedded_server_args[MAX_SERVER_ARGS];
 
992
static const char *embedded_server_groups[]=
 
993
{ "server", "mysql_SERVER", 0 };
1156
994
 
1157
995
int history_length;
1158
996
static int not_in_history(const char *line);
1159
 
static void initialize_readline (char *name);
1160
 
static void fix_history(string *final_command);
 
997
static void initialize_readline (const char *name);
 
998
static void fix_history(GString *final_command);
1161
999
 
1162
 
static Commands *find_command(const char *name,char cmd_name);
1163
 
static bool add_line(string *buffer,char *line,char *in_string,
 
1000
static COMMANDS *find_command(char *name,char cmd_name);
 
1001
static bool add_line(GString *buffer,char *line,char *in_string,
1164
1002
                     bool *ml_comment);
1165
 
static void remove_cntrl(string *buffer);
1166
 
static void print_table_data(drizzle_result_st *result);
1167
 
static void print_tab_data(drizzle_result_st *result);
1168
 
static void print_table_data_vertically(drizzle_result_st *result);
1169
 
static void print_warnings(uint32_t error_code);
1170
 
static boost::posix_time::ptime start_timer(void);
1171
 
static void end_timer(boost::posix_time::ptime, string &buff);
1172
 
static void drizzle_end_timer(boost::posix_time::ptime, string &buff);
1173
 
static void nice_time(boost::posix_time::time_duration duration, string &buff);
1174
 
extern "C" void drizzle_end(int sig);
1175
 
extern "C" void handle_sigint(int sig);
 
1003
static void remove_cntrl(GString *buffer);
 
1004
static void print_table_data(MYSQL_RES *result);
 
1005
static void print_table_data_html(MYSQL_RES *result);
 
1006
static void print_table_data_xml(MYSQL_RES *result);
 
1007
static void print_tab_data(MYSQL_RES *result);
 
1008
static void print_table_data_vertically(MYSQL_RES *result);
 
1009
static void print_warnings(void);
 
1010
static ulong start_timer(void);
 
1011
static void end_timer(ulong start_time,char *buff);
 
1012
static void mysql_end_timer(ulong start_time,char *buff);
 
1013
static void nice_time(double sec,char *buff,bool part_second);
 
1014
extern sig_handler mysql_end(int sig);
 
1015
extern sig_handler handle_sigint(int sig);
1176
1016
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1177
 
static void window_resize(int sig);
 
1017
static sig_handler window_resize(int sig);
1178
1018
#endif
1179
1019
 
1180
 
/**
1181
 
  Shutdown the server that we are currently connected to.
1182
 
 
1183
 
  @retval
1184
 
    true success
1185
 
  @retval
1186
 
    false failure
1187
 
*/
1188
 
static bool server_shutdown(void)
1189
 
{
1190
 
  drizzle_result_st result;
1191
 
  drizzle_return_t ret;
1192
 
 
1193
 
  if (verbose)
1194
 
  {
1195
 
    printf(_("shutting down drizzled"));
1196
 
    if (opt_drizzle_port > 0)
1197
 
      printf(_(" on port %d"), opt_drizzle_port);
1198
 
    printf("... ");
1199
 
  }
1200
 
 
1201
 
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
1202
 
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
1203
 
  {
1204
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1205
 
    {
1206
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
1207
 
              drizzle_result_error(&result));
1208
 
      drizzle_result_free(&result);
1209
 
    }
1210
 
    else
1211
 
    {
1212
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
1213
 
              drizzle_con_error(&con));
1214
 
    }
1215
 
    return false;
1216
 
  }
1217
 
 
1218
 
  drizzle_result_free(&result);
1219
 
 
1220
 
  if (verbose)
1221
 
    printf(_("done\n"));
1222
 
 
1223
 
  return true;
1224
 
}
1225
 
 
1226
 
/**
1227
 
  Ping the server that we are currently connected to.
1228
 
 
1229
 
  @retval
1230
 
    true success
1231
 
  @retval
1232
 
    false failure
1233
 
*/
1234
 
static bool server_ping(void)
1235
 
{
1236
 
  drizzle_result_st result;
1237
 
  drizzle_return_t ret;
1238
 
 
1239
 
  if (drizzle_ping(&con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
1240
 
  {
1241
 
    if (opt_silent < 2)
1242
 
      printf(_("drizzled is alive\n"));
1243
 
  }
1244
 
  else
1245
 
  {
1246
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1247
 
    {
1248
 
      fprintf(stderr, _("ping failed; error: '%s'"),
1249
 
              drizzle_result_error(&result));
1250
 
      drizzle_result_free(&result);
1251
 
    }
1252
 
    else
1253
 
    {
1254
 
      fprintf(stderr, _("drizzled won't answer to ping, error: '%s'"),
1255
 
              drizzle_con_error(&con));
1256
 
    }
1257
 
    return false;
1258
 
  }
1259
 
  drizzle_result_free(&result);
1260
 
  return true;
1261
 
}
1262
 
 
1263
 
/**
1264
 
  Execute command(s) specified by the user.
1265
 
 
1266
 
  @param error  error status of command execution.
1267
 
                If an error had occurred, this variable will be set
1268
 
                to 1 whereas on success, it shall be set to 0. This
1269
 
                value will be supplied to the exit() function used
1270
 
                by the caller.
1271
 
 
1272
 
  @retval
1273
 
    false no commands were executed
1274
 
  @retval
1275
 
    true  at least one command was executed
1276
 
*/
1277
 
static bool execute_commands(int *error)
1278
 
{
1279
 
  bool executed= false;
1280
 
  *error= 0;
1281
 
 
1282
 
  if (opt_ping)
1283
 
  {
1284
 
    if (server_ping() == false)
1285
 
      *error= 1;
1286
 
    executed= true;
1287
 
  }
1288
 
 
1289
 
  if (opt_shutdown)
1290
 
  {
1291
 
    if (server_shutdown() == false)
1292
 
      *error= 1;
1293
 
    executed= true;
1294
 
  }
1295
 
  return executed;
1296
 
}
1297
 
 
1298
 
static void check_timeout_value(uint32_t in_connect_timeout)
1299
 
{
1300
 
  opt_connect_timeout= 0;
1301
 
  if (in_connect_timeout > 3600*12)
1302
 
  {
1303
 
    cout << _("Error: Invalid Value for connect_timeout"); 
1304
 
    exit(-1);
1305
 
  }
1306
 
  opt_connect_timeout= in_connect_timeout;
1307
 
}
1308
 
 
1309
 
static void check_max_input_line(uint32_t in_max_input_line)
1310
 
{
1311
 
  opt_max_input_line= 0;
1312
 
  if (in_max_input_line < 4096 || in_max_input_line > (int64_t)2*1024L*1024L*1024L)
1313
 
  {
1314
 
    cout << _("Error: Invalid Value for max_input_line");
1315
 
    exit(-1);
1316
 
  }
1317
 
  opt_max_input_line= in_max_input_line - (in_max_input_line % 1024);
1318
 
}
1319
 
 
1320
1020
int main(int argc,char *argv[])
1321
1021
{
1322
 
try
1323
 
{
1324
 
 
1325
 
#if defined(ENABLE_NLS)
1326
 
# if defined(HAVE_LOCALE_H)
1327
 
  setlocale(LC_ALL, "");
1328
 
# endif
1329
 
  bindtextdomain("drizzle7", LOCALEDIR);
1330
 
  textdomain("drizzle7");
1331
 
#endif
1332
 
 
1333
 
  po::options_description commandline_options(_("Options used only in command line"));
1334
 
  commandline_options.add_options()
1335
 
  ("help,?",_("Displays this help and exit."))
1336
 
  ("batch,B",_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1337
 
  ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1338
 
  _("Display column type information."))
1339
 
  ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
1340
 
  _("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1341
 
  ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1342
 
  _("Print the output of a query (rows) vertically."))
1343
 
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1344
 
  _("Continue even if we get an sql error."))
1345
 
  ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
1346
 
  _("Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter."))
1347
 
  ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
1348
 
  _("Turn off beep on error."))
1349
 
  ("disable-line-numbers", _("Do not write line numbers for errors."))
1350
 
  ("disable-column-names", _("Do not write column names in results."))
1351
 
  ("skip-column-names,N", 
1352
 
  _("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1353
 
  ("set-variable,O", po::value<string>(),
1354
 
  _("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1355
 
  ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1356
 
  _("Output in table format.")) 
1357
 
  ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1358
 
  _("Only allow UPDATE and DELETE that uses keys."))
1359
 
  ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1360
 
  _("Synonym for option --safe-updates, -U."))
1361
 
  ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
1362
 
  _("-v vvv implies that verbose= 3, Used to specify verbose"))
1363
 
  ("version,V", _("Output version information and exit."))
1364
 
  ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
1365
 
  _("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1366
 
  ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1367
 
  _("Show warnings after every statement."))
1368
 
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1369
 
  _("Number of lines before each import progress report."))
1370
 
  ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1371
 
  _("Ping the server to check if it's alive."))
1372
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1373
 
  _("Configuration file defaults are not used if no-defaults is set"))
1374
 
  ;
1375
 
 
1376
 
  po::options_description drizzle_options(_("Options specific to the drizzle client"));
1377
 
  drizzle_options.add_options()
1378
 
  ("disable-auto-rehash,A",
1379
 
  _("Disable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time."))
1380
 
  ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
1381
 
  _("Automatically switch to vertical output mode if the result is wider than the terminal width."))
1382
 
  ("database,D", po::value<string>(&current_db)->default_value(""),
1383
 
  _("Database to use."))
1384
 
  ("default-character-set",po::value<string>(),
1385
 
  _("(not used)"))
1386
 
  ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1387
 
  _("Delimiter to be used."))
1388
 
  ("execute,e", po::value<string>(),
1389
 
  _("Execute command and quit. (Disables --force and history file)"))
1390
 
  ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1391
 
  _("Enable LOAD DATA LOCAL INFILE."))
1392
 
  ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1393
 
  _("Flush buffer after each query."))
1394
 
  ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1395
 
  _("Ignore SIGINT (CTRL-C)"))
1396
 
  ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
1397
 
  _("Only update the default database. This is useful for skipping updates to other database in the update log."))
1398
 
  ("pager", po::value<string>(),
1399
 
  _("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."))
1400
 
  ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1401
 
  _("Disable pager and print to stdout. See interactive help (\\h) also."))
1402
 
  ("prompt", po::value<string>(&current_prompt)->default_value(""),  
1403
 
  _("Set the drizzle prompt to this value."))
1404
 
  ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
1405
 
  _("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."))
1406
 
  ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
1407
 
  _("Write fields without conversion. Used with --batch.")) 
1408
 
  ("disable-reconnect", _("Do not reconnect if the connection is lost."))
1409
 
  ("shutdown", po::value<bool>()->zero_tokens(),
1410
 
  _("Shutdown the server"))
1411
 
  ("silent,s", _("Be more silent. Print results with a tab as separator, each row on new line."))
1412
 
  ("tee", po::value<string>(),
1413
 
  _("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."))
1414
 
  ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(), 
1415
 
  _("Disable outfile. See interactive help (\\h) also."))
1416
 
  ("connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1417
 
  _("Number of seconds before connection timeout."))
1418
 
  ("max-input-line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1419
 
  _("Max length of input line"))
1420
 
  ("select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1421
 
  _("Automatic limit for SELECT when using --safe-updates"))
1422
 
  ("max-join-size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1423
 
  _("Automatic limit for rows in a join when using --safe-updates"))
1424
 
  ;
1425
 
 
1426
 
  po::options_description client_options(_("Options specific to the client"));
1427
 
  client_options.add_options()
1428
 
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1429
 
  _("Connect to host"))
1430
 
  ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
1431
 
  _("Password to use when connecting to server. If password is not given it's asked from the tty."))
1432
 
  ("port,p", po::value<uint32_t>()->default_value(0),
1433
 
  _("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1434
 
#ifdef DRIZZLE_ADMIN_TOOL
1435
 
  ("user,u", po::value<string>(&current_user)->default_value("root"),
1436
 
#else
1437
 
  ("user,u", po::value<string>(&current_user)->default_value(""),
1438
 
#endif
1439
 
  _("User for login if not current user."))
1440
 
  ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
1441
 
  _("The protocol of connection (mysql or drizzle)."))
1442
 
  ;
1443
 
 
1444
 
  po::options_description long_options(_("Allowed Options"));
1445
 
  long_options.add(commandline_options).add(drizzle_options).add(client_options);
1446
 
 
1447
 
  std::string system_config_dir_drizzle(SYSCONFDIR); 
1448
 
  system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
1449
 
 
1450
 
  std::string system_config_dir_client(SYSCONFDIR); 
1451
 
  system_config_dir_client.append("/drizzle/client.cnf");
1452
 
 
1453
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
1454
 
 
1455
 
  if (user_config_dir.compare(0, 2, "~/") == 0)
1456
 
  {
1457
 
    char *homedir;
1458
 
    homedir= getenv("HOME");
1459
 
    if (homedir != NULL)
1460
 
      user_config_dir.replace(0, 1, homedir);
1461
 
  }
1462
 
 
1463
 
  po::variables_map vm;
1464
 
 
1465
 
  po::positional_options_description p;
1466
 
  p.add("database", 1);
1467
 
 
1468
 
  // Disable allow_guessing
1469
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1470
 
 
1471
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
1472
 
            style(style).positional(p).extra_parser(parse_password_arg).run(),
1473
 
            vm);
1474
 
 
1475
 
  if (! vm["no-defaults"].as<bool>())
1476
 
  {
1477
 
    std::string user_config_dir_drizzle(user_config_dir);
1478
 
    user_config_dir_drizzle.append("/drizzle/drizzle.cnf"); 
1479
 
 
1480
 
    std::string user_config_dir_client(user_config_dir);
1481
 
    user_config_dir_client.append("/drizzle/client.cnf");
1482
 
 
1483
 
    ifstream user_drizzle_ifs(user_config_dir_drizzle.c_str());
1484
 
    po::store(dpo::parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1485
 
 
1486
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
1487
 
    po::store(dpo::parse_config_file(user_client_ifs, client_options), vm);
1488
 
 
1489
 
    ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1490
 
    store(dpo::parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1491
 
 
1492
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
1493
 
    po::store(dpo::parse_config_file(system_client_ifs, client_options), vm);
1494
 
  }
1495
 
 
1496
 
  po::notify(vm);
1497
 
 
1498
 
#ifdef DRIZZLE_ADMIN_TOOL
1499
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1500
 
                         getenv("DRIZZLE_PS1") :
1501
 
                         "drizzleadmin> ");
1502
 
#else
1503
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1504
 
                         getenv("DRIZZLE_PS1") :
1505
 
                         "drizzle> ");
1506
 
#endif
1507
 
  if (default_prompt == NULL)
1508
 
  {
1509
 
    fprintf(stderr, _("Memory allocation error while constructing initial "
1510
 
                      "prompt. Aborting.\n"));
1511
 
    exit(ENOMEM);
1512
 
  }
1513
 
 
1514
 
  if (current_prompt.empty())
1515
 
    current_prompt= strdup(default_prompt);
1516
 
 
1517
 
  if (current_prompt.empty())
1518
 
  {
1519
 
    fprintf(stderr, _("Memory allocation error while constructing initial "
1520
 
                      "prompt. Aborting.\n"));
1521
 
    exit(ENOMEM);
1522
 
  }
1523
 
  processed_prompt= new string();
1524
 
  processed_prompt->reserve(32);
1525
 
 
 
1022
  char buff[80];
 
1023
 
 
1024
  MY_INIT(argv[0]);
 
1025
  delimiter_str= delimiter;
 
1026
  default_prompt = g_string_new(g_strdup(getenv("DRIZZLE_PS1") ?
 
1027
                                         getenv("DRIZZLE_PS1") :
 
1028
                                         "drizzle>> "));
 
1029
  current_prompt = g_strdup(default_prompt->str);
 
1030
  processed_prompt = g_string_sized_new(16);
1526
1031
  prompt_counter=0;
1527
1032
 
1528
 
  outfile.clear();      // no (default) outfile
1529
 
  pager.assign("stdout");  // the default, if --pager wasn't given
 
1033
  outfile[0]=0;                 // no (default) outfile
 
1034
  strmov(pager, "stdout");      // the default, if --pager wasn't given
1530
1035
  {
1531
 
    const char *tmp= getenv("PAGER");
 
1036
    char *tmp=getenv("PAGER");
1532
1037
    if (tmp && strlen(tmp))
1533
1038
    {
1534
1039
      default_pager_set= 1;
1535
 
      default_pager.assign(tmp);
 
1040
      strmov(default_pager, tmp);
1536
1041
    }
1537
1042
  }
1538
 
  if (! isatty(0) || ! isatty(1))
 
1043
  if (!isatty(0) || !isatty(1))
1539
1044
  {
1540
 
    status.setBatch(1); opt_silent=1;
 
1045
    status.batch=1; opt_silent=1;
 
1046
    ignore_errors=0;
1541
1047
  }
1542
1048
  else
1543
 
    status.setAddToHistory(1);
1544
 
  status.setExitStatus(1);
 
1049
    status.add_to_history=1;
 
1050
  status.exit_status=1;
1545
1051
 
1546
1052
  {
1547
1053
    /*
1557
1063
      close(stdout_fileno_copy);             /* Clean up dup(). */
1558
1064
  }
1559
1065
 
1560
 
  /* Inverted Booleans */
1561
 
 
1562
 
  line_numbers= (vm.count("disable-line-numbers")) ? false : true;
1563
 
  column_names= (vm.count("disable-column-names")) ? false : true;
1564
 
  opt_rehash= (vm.count("disable-auto-rehash")) ? false : true;
1565
 
  opt_reconnect= (vm.count("disable-reconnect")) ? false : true;
1566
 
 
1567
 
  /* Don't rehash with --shutdown */
1568
 
  if (vm.count("shutdown"))
1569
 
  {
1570
 
    opt_rehash= false;
1571
 
    opt_shutdown= true;
1572
 
  }
1573
 
 
1574
 
  if (vm.count("delimiter"))
1575
 
  {
1576
 
    /* Check that delimiter does not contain a backslash */
1577
 
    if (! strstr(delimiter_str.c_str(), "\\"))
1578
 
    {
1579
 
      delimiter= (char *)delimiter_str.c_str();  
1580
 
    }
1581
 
    else
1582
 
    {
1583
 
      put_info(_("DELIMITER cannot contain a backslash character"),
1584
 
      INFO_ERROR,0,0);
1585
 
      exit(-1);
1586
 
    }
1587
 
   
1588
 
    delimiter_length= (uint32_t)strlen(delimiter);
1589
 
  }
1590
 
  if (vm.count("tee"))
1591
 
  { 
1592
 
    if (vm["tee"].as<string>().empty())
1593
 
    {
1594
 
      if (opt_outfile)
1595
 
        end_tee();
1596
 
    }
1597
 
    else
1598
 
      init_tee(vm["tee"].as<string>().c_str());
1599
 
  }
1600
 
  if (vm["disable-tee"].as<bool>() == true)
1601
 
  {
1602
 
    if (opt_outfile)
1603
 
      end_tee();
1604
 
  }
1605
 
  if (vm.count("pager"))
1606
 
  {
1607
 
    if (vm["pager"].as<string>().empty())
1608
 
      opt_nopager= 1;
1609
 
    else
1610
 
    {
1611
 
      opt_nopager= 0;
1612
 
      if (vm[pager].as<string>().length())
1613
 
      {
1614
 
        default_pager_set= 1;
1615
 
        pager.assign(vm["pager"].as<string>());
1616
 
        default_pager.assign(pager);
1617
 
      }
1618
 
      else if (default_pager_set)
1619
 
        pager.assign(default_pager);
1620
 
      else
1621
 
        opt_nopager= 1;
1622
 
    }
1623
 
  }
1624
 
  if (vm.count("disable-pager"))
1625
 
  {
1626
 
    opt_nopager= 1;
1627
 
  }
1628
 
 
1629
 
  if (vm.count("no-auto-rehash"))
1630
 
    opt_rehash= 0;
1631
 
 
1632
 
  if (vm.count("skip-column-names"))
1633
 
    column_names= 0;
1634
 
    
1635
 
  if (vm.count("execute"))
1636
 
  {  
1637
 
    status.setBatch(1);
1638
 
    status.setAddToHistory(1);
1639
 
    if (status.getLineBuff() == NULL)
1640
 
      status.setLineBuff(opt_max_input_line,NULL);
1641
 
    if (status.getLineBuff() == NULL)
1642
 
    {
1643
 
      exit(1);
1644
 
    }
1645
 
    status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
1646
 
  }
1647
 
 
1648
 
  if (one_database)
1649
 
    skip_updates= true;
1650
 
 
1651
 
  if (vm.count("protocol"))
1652
 
  {
1653
 
    std::transform(opt_protocol.begin(), opt_protocol.end(), 
1654
 
      opt_protocol.begin(), ::tolower);
1655
 
 
1656
 
    if (not opt_protocol.compare("mysql"))
1657
 
      use_drizzle_protocol=false;
1658
 
    else if (not opt_protocol.compare("drizzle"))
1659
 
      use_drizzle_protocol=true;
1660
 
    else
1661
 
    {
1662
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1663
 
      exit(-1);
1664
 
    }
1665
 
  }
1666
 
 
1667
 
  if (vm.count("port"))
1668
 
  {
1669
 
    opt_drizzle_port= vm["port"].as<uint32_t>();
1670
 
 
1671
 
    /* If the port number is > 65535 it is not a valid port
1672
 
       This also helps with potential data loss casting unsigned long to a
1673
 
       uint32_t. */
1674
 
    if (opt_drizzle_port > 65535)
1675
 
    {
1676
 
      printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
1677
 
      exit(-1);
1678
 
    }
1679
 
  }
1680
 
 
1681
 
  if (vm.count("password"))
1682
 
  {
1683
 
    if (!opt_password.empty())
1684
 
      opt_password.erase();
1685
 
    if (current_password == PASSWORD_SENTINEL)
1686
 
    {
1687
 
      opt_password= "";
1688
 
    }
1689
 
    else
1690
 
    {
1691
 
      opt_password= current_password;
1692
 
      tty_password= false;
1693
 
    }
1694
 
  }
1695
 
  else
1696
 
  {
1697
 
      tty_password= true;
1698
 
  }
1699
 
  
1700
 
 
1701
 
  if (!opt_verbose.empty())
1702
 
  {
1703
 
    verbose= opt_verbose.length();
1704
 
  }
1705
 
 
1706
 
  if (vm.count("batch"))
1707
 
  {
1708
 
    status.setBatch(1);
1709
 
    status.setAddToHistory(0);
1710
 
    if (opt_silent < 1)
1711
 
    {
1712
 
      opt_silent= 1;
1713
 
    }
1714
 
  }
1715
 
  if (vm.count("silent"))
1716
 
  {
1717
 
    opt_silent= 2;
1718
 
  }
1719
 
  
1720
 
  if (vm.count("help") || vm.count("version"))
1721
 
  {
1722
 
    printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
1723
 
           drizzle_version(), VERSION,
1724
 
           HOST_VENDOR, HOST_OS, HOST_CPU,
1725
 
           rl_library_version);
1726
 
    if (vm.count("version"))
1727
 
      exit(0);
1728
 
    printf(_("Copyright (C) 2008 Sun Microsystems\n"
1729
 
           "This software comes with ABSOLUTELY NO WARRANTY. "
1730
 
           "This is free software,\n"
1731
 
           "and you are welcome to modify and redistribute it "
1732
 
           "under the GPL license\n"));
1733
 
    printf(_("Usage: drizzle [OPTIONS] [schema]\n"));
1734
 
    cout << long_options;
1735
 
    exit(0);
1736
 
  }
1737
 
 
1738
 
 
1739
 
  if (process_options())
1740
 
  {
1741
 
    exit(1);
1742
 
  }
1743
 
 
1744
 
  memset(&drizzle, 0, sizeof(drizzle));
1745
 
  if (sql_connect(current_host, current_db, current_user, opt_password))
1746
 
  {
1747
 
    quick= 1;          // Avoid history
1748
 
    status.setExitStatus(1);
1749
 
    drizzle_end(-1);
1750
 
  }
1751
 
 
1752
 
  int command_error;
1753
 
  if (execute_commands(&command_error) != false)
1754
 
  {
1755
 
    /* we've executed a command so exit before we go into readline mode */
1756
 
    exit(command_error);
1757
 
  }
1758
 
 
1759
 
  if (status.getBatch() && !status.getLineBuff())
1760
 
  {
1761
 
    status.setLineBuff(opt_max_input_line, stdin);
1762
 
    if (status.getLineBuff() == NULL)
1763
 
    {
1764
 
      exit(1);
1765
 
    }
1766
 
  }
1767
 
 
1768
 
  if (!status.getBatch())
1769
 
    ignore_errors=1;        // Don't abort monitor
 
1066
  load_defaults("my",load_default_groups,&argc,&argv);
 
1067
  defaults_argv=argv;
 
1068
  if (get_options(argc, (char **) argv))
 
1069
  {
 
1070
    free_defaults(defaults_argv);
 
1071
    my_end(0);
 
1072
    exit(1);
 
1073
  }
 
1074
  if (status.batch && !status.line_buff &&
 
1075
      !(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin)))
 
1076
  {
 
1077
    free_defaults(defaults_argv);
 
1078
    my_end(0);
 
1079
    exit(1);
 
1080
  }
 
1081
  if (mysql_server_init(embedded_server_arg_count, embedded_server_args,
 
1082
                        (char**) embedded_server_groups))
 
1083
  {
 
1084
    put_error(NULL);
 
1085
    free_defaults(defaults_argv);
 
1086
    my_end(0);
 
1087
    exit(1);
 
1088
  }
 
1089
  completion_hash_init(&ht, 128);
 
1090
  init_alloc_root(&hash_mem_root, 16384, 0);
 
1091
  bzero((char*) &mysql, sizeof(mysql));
 
1092
  if (sql_connect(current_host,current_db,current_user,opt_password,
 
1093
                  opt_silent))
 
1094
  {
 
1095
    quick= 1;                                   // Avoid history
 
1096
    status.exit_status= 1;
 
1097
    mysql_end(-1);
 
1098
  }
 
1099
  if (!status.batch)
 
1100
    ignore_errors=1;                            // Don't abort monitor
1770
1101
 
1771
1102
  if (opt_sigint_ignore)
1772
1103
    signal(SIGINT, SIG_IGN);
1773
1104
  else
1774
1105
    signal(SIGINT, handle_sigint);              // Catch SIGINT to clean up
1775
 
  signal(SIGQUIT, drizzle_end);      // Catch SIGQUIT to clean up
 
1106
  signal(SIGQUIT, mysql_end);                   // Catch SIGQUIT to clean up
1776
1107
 
1777
1108
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1778
1109
  /* Readline will call this if it installs a handler */
1780
1111
  /* call the SIGWINCH handler to get the default term width */
1781
1112
  window_resize(0);
1782
1113
#endif
1783
 
  std::vector<char> output_buff;
1784
 
  output_buff.resize(512);
1785
 
 
1786
 
  snprintf(&output_buff[0], output_buff.size(), 
1787
 
           _("Welcome to the Drizzle client..  Commands end with %s or \\g."), 
1788
 
           delimiter);
1789
 
 
1790
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
1791
 
 
1792
 
  glob_buffer= new string();
1793
 
  glob_buffer->reserve(512);
1794
 
 
1795
 
  snprintf(&output_buff[0], output_buff.size(),
1796
 
          _("Your Drizzle connection id is %u\nConnection protocol: %s\nServer version: %s\n"),
1797
 
          drizzle_con_thread_id(&con),
1798
 
          opt_protocol.c_str(),
1799
 
          server_version_string(&con));
1800
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
1801
 
 
1802
 
 
1803
 
  initialize_readline((char *)current_prompt.c_str());
1804
 
  if (!status.getBatch() && !quick)
 
1114
 
 
1115
  put_info("Welcome to the Drizzle client..  Commands end with ; or \\g.",
 
1116
           INFO_INFO,0,0);
 
1117
  glob_buffer = g_string_sized_new(512);
 
1118
  g_string_printf(glob_buffer,
 
1119
                  "Your Drizzle connection id is %u\nServer version: %s\n",
 
1120
                  mysql_thread_id(&mysql), server_version_string(&mysql));
 
1121
  put_info(glob_buffer->str,INFO_INFO,0,0);
 
1122
  g_string_truncate(glob_buffer,0);
 
1123
 
 
1124
  initialize_readline(my_progname);
 
1125
  if (!status.batch && !quick && !opt_html && !opt_xml)
1805
1126
  {
1806
 
    /* read-history from file, default ~/.drizzle_history*/
1807
 
    if (getenv("DRIZZLE_HISTFILE"))
1808
 
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
 
1127
    /* read-history from file, default ~/.mysql_history*/
 
1128
    if (getenv("MYSQL_HISTFILE"))
 
1129
      histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1809
1130
    else if (getenv("HOME"))
1810
1131
    {
1811
 
      histfile=(char*) malloc(strlen(getenv("HOME")) + strlen("/.drizzle_history") + 2);
 
1132
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
 
1133
                                 + (uint) strlen("/.mysql_history")+2,
 
1134
                                 MYF(MY_WME));
1812
1135
      if (histfile)
1813
 
        sprintf(histfile,"%s/.drizzle_history",getenv("HOME"));
 
1136
        sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
1814
1137
      char link_name[FN_REFLEN];
1815
 
      ssize_t sym_link_size= readlink(histfile,link_name,FN_REFLEN-1);
1816
 
      if (sym_link_size >= 0)
 
1138
      if (my_readlink(link_name, histfile, 0) == 0 &&
 
1139
          strncmp(link_name, "/dev/null", 10) == 0)
1817
1140
      {
1818
 
        link_name[sym_link_size]= '\0';
1819
 
        if (strncmp(link_name, "/dev/null", 10) == 0)
1820
 
        {
1821
 
          /* The .drizzle_history file is a symlink to /dev/null, don't use it */
1822
 
          free(histfile);
1823
 
          histfile= 0;
1824
 
        }
 
1141
        /* The .mysql_history file is a symlink to /dev/null, don't use it */
 
1142
        my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
 
1143
        histfile= 0;
1825
1144
      }
1826
1145
    }
1827
1146
    if (histfile)
1828
1147
    {
1829
1148
      if (verbose)
1830
 
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
 
1149
        tee_fprintf(stdout, "Reading history-file %s\n",histfile);
1831
1150
      read_history(histfile);
1832
 
      if (!(histfile_tmp= (char*) malloc((uint32_t) strlen(histfile) + 5)))
 
1151
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
 
1152
                                            MYF(MY_WME))))
1833
1153
      {
1834
 
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
 
1154
        fprintf(stderr, "Couldn't allocate memory for temp histfile!\n");
1835
1155
        exit(1);
1836
1156
      }
1837
1157
      sprintf(histfile_tmp, "%s.TMP", histfile);
1838
1158
    }
1839
1159
  }
 
1160
  sprintf(buff, "%s",
 
1161
          "Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
1840
1162
 
1841
 
  put_info(_("Type 'help;' or '\\h' for help. "
1842
 
             "Type '\\c' to clear the buffer.\n"),INFO_INFO,0,0);
1843
 
  status.setExitStatus(read_and_execute(!status.getBatch()));
 
1163
  put_info(buff,INFO_INFO,0,0);
 
1164
  status.exit_status= read_and_execute(!status.batch);
1844
1165
  if (opt_outfile)
1845
1166
    end_tee();
1846
 
  drizzle_end(0);
1847
 
}
1848
 
 
1849
 
  catch(exception &err)
1850
 
  {
1851
 
    cerr << _("Error:") << err.what() << endl;
1852
 
  }
1853
 
  return(0);        // Keep compiler happy
1854
 
}
1855
 
 
1856
 
void drizzle_end(int sig)
 
1167
  mysql_end(0);
 
1168
#ifndef _lint
 
1169
  return(0);                            // Keep compiler happy
 
1170
#endif
 
1171
}
 
1172
 
 
1173
sig_handler mysql_end(int sig)
1857
1174
{
1858
 
  drizzle_con_free(&con);
1859
 
  drizzle_free(&drizzle);
1860
 
  if (!status.getBatch() && !quick && histfile)
 
1175
  mysql_close(&mysql);
 
1176
  if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
1861
1177
  {
1862
1178
    /* write-history */
1863
1179
    if (verbose)
1864
 
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
 
1180
      tee_fprintf(stdout, "Writing history-file %s\n",histfile);
1865
1181
    if (!write_history(histfile_tmp))
1866
 
      rename(histfile_tmp, histfile);
 
1182
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1867
1183
  }
1868
 
  delete status.getLineBuff();
1869
 
  status.setLineBuff(0);
 
1184
  batch_readline_end(status.line_buff);
 
1185
  completion_hash_free(&ht);
 
1186
  free_root(&hash_mem_root,MYF(0));
1870
1187
 
1871
1188
  if (sig >= 0)
1872
 
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1873
 
  delete glob_buffer;
1874
 
  delete processed_prompt;
1875
 
  opt_password.erase();
1876
 
  free(histfile);
1877
 
  free(histfile_tmp);
1878
 
  current_db.erase();
1879
 
  current_host.erase();
1880
 
  current_user.erase();
1881
 
  free(full_username);
1882
 
  free(part_username);
1883
 
  free(default_prompt);
1884
 
  current_prompt.erase();
1885
 
  exit(status.getExitStatus());
 
1189
    put_info(sig ? "Aborted" : "Bye", INFO_RESULT,0,0);
 
1190
  assert(glob_buffer != NULL);
 
1191
  g_string_free(glob_buffer,true);
 
1192
  assert(processed_prompt != NULL);
 
1193
  g_string_free(processed_prompt,true);
 
1194
  assert(default_prompt != NULL);
 
1195
  g_string_free(default_prompt,true);
 
1196
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
1197
  my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
 
1198
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
 
1199
  my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
 
1200
  my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
1201
  my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
1202
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
 
1203
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
1204
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
 
1205
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1206
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1207
  while (embedded_server_arg_count > 1)
 
1208
    my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
 
1209
  mysql_server_end();
 
1210
  free_defaults(defaults_argv);
 
1211
  my_end(my_end_arg);
 
1212
  exit(status.exit_status);
1886
1213
}
1887
1214
 
1888
1215
 
1891
1218
  If query is in process, kill query
1892
1219
  no query in process, terminate like previous behavior
1893
1220
*/
1894
 
extern "C"
1895
 
void handle_sigint(int sig)
 
1221
sig_handler handle_sigint(int sig)
1896
1222
{
1897
1223
  char kill_buffer[40];
1898
 
  boost::scoped_ptr<drizzle_con_st> kill_drizzle(new drizzle_con_st);
1899
 
  drizzle_result_st res;
1900
 
  drizzle_return_t ret;
 
1224
  MYSQL *kill_mysql= NULL;
1901
1225
 
1902
1226
  /* terminate if no query being executed, or we already tried interrupting */
1903
1227
  if (!executing_query || interrupted_query) {
1904
1228
    goto err;
1905
1229
  }
1906
1230
 
1907
 
  if (drizzle_con_add_tcp(&drizzle, kill_drizzle.get(), current_host.c_str(),
1908
 
    opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
1909
 
    use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
 
1231
  kill_mysql= mysql_init(kill_mysql);
 
1232
  if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
 
1233
                          "", opt_mysql_port, opt_mysql_unix_port,0))
1910
1234
  {
1911
1235
    goto err;
1912
1236
  }
1913
1237
 
1914
1238
  /* kill_buffer is always big enough because max length of %lu is 15 */
1915
 
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u",
1916
 
          drizzle_con_thread_id(&con));
1917
 
 
1918
 
  if (drizzle_query_str(kill_drizzle.get(), &res, kill_buffer, &ret) != NULL)
1919
 
    drizzle_result_free(&res);
1920
 
 
1921
 
  drizzle_con_free(kill_drizzle.get());
1922
 
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
 
1239
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u", mysql_thread_id(&mysql));
 
1240
  mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
 
1241
  mysql_close(kill_mysql);
 
1242
  tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
1923
1243
 
1924
1244
  interrupted_query= 1;
1925
1245
 
1926
1246
  return;
1927
1247
 
1928
1248
err:
1929
 
  drizzle_end(sig);
 
1249
  mysql_end(sig);
1930
1250
}
1931
1251
 
1932
1252
 
1933
1253
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1934
 
void window_resize(int)
 
1254
sig_handler window_resize(int sig __attribute__((__unused__)))
1935
1255
{
1936
1256
  struct winsize window_size;
1937
1257
 
1940
1260
}
1941
1261
#endif
1942
1262
 
1943
 
 
1944
 
 
1945
 
static int process_options(void)
 
1263
static struct my_option my_long_options[] =
 
1264
{
 
1265
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1266
   0, 0, 0, 0, 0},
 
1267
  {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1268
   0, 0, 0, 0, 0},
 
1269
  {"auto-rehash", OPT_AUTO_REHASH,
 
1270
   "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.",
 
1271
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
 
1272
   0, 0},
 
1273
  {"no-auto-rehash", 'A',
 
1274
   "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.",
 
1275
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1276
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
 
1277
   "Automatically switch to vertical output mode if the result is wider than the terminal width.",
 
1278
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1279
  {"batch", 'B',
 
1280
   "Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1281
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
1282
   "Directory where character sets are.", (char**) &charsets_dir,
 
1283
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1284
  {"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
 
1285
   (char**) &column_types_flag, (char**) &column_types_flag,
 
1286
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1287
  {"comments", 'c', "Preserve comments. Send comments to the server."
 
1288
   " The default is --skip-comments (discard comments), enable with --comments",
 
1289
   (char**) &preserve_comments, (char**) &preserve_comments,
 
1290
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1291
  {"compress", 'C', "Use compression in server/client protocol.",
 
1292
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1293
   0, 0, 0},
 
1294
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
 
1295
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
1296
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1297
  {"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
 
1298
   (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1299
  {"database", 'D', "Database to use.", (char**) &current_db,
 
1300
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1301
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
1302
   "Set the default character set.", (char**) &default_charset,
 
1303
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1304
  {"delimiter", OPT_DELIMITER, "Delimiter to be used.", (char**) &delimiter_str,
 
1305
   (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1306
  {"execute", 'e', "Execute command and quit. (Disables --force and history file)", 0,
 
1307
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1308
  {"vertical", 'E', "Print the output of a query (rows) vertically.",
 
1309
   (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
1310
   0},
 
1311
  {"force", 'f', "Continue even if we get an sql error.",
 
1312
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
1313
   0, 0, 0, 0},
 
1314
  {"named-commands", 'G',
 
1315
   "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.",
 
1316
   (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
1317
   0, 0},
 
1318
  {"no-named-commands", 'g',
 
1319
   "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.",
 
1320
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1321
  {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
 
1322
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1323
  {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
 
1324
   (char**) &opt_local_infile,
 
1325
   (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1326
  {"no-beep", 'b', "Turn off beep on error.", (char**) &opt_nobeep,
 
1327
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1328
  {"host", 'h', "Connect to host.", (char**) &current_host,
 
1329
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1330
  {"html", 'H', "Produce HTML output.", (char**) &opt_html, (char**) &opt_html,
 
1331
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1332
  {"xml", 'X', "Produce XML output", (char**) &opt_xml, (char**) &opt_xml, 0,
 
1333
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1334
  {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
 
1335
   (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
 
1336
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1337
  {"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,
 
1338
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1339
  {"unbuffered", 'n', "Flush buffer after each query.", (char**) &unbuffered,
 
1340
   (char**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1341
  {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
 
1342
   (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
 
1343
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1344
  {"skip-column-names", 'N',
 
1345
   "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
 
1346
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1347
  {"set-variable", 'O',
 
1348
   "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
 
1349
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1350
  {"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C)",
 
1351
   (char**) &opt_sigint_ignore,  (char**) &opt_sigint_ignore, 0, GET_BOOL,
 
1352
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1353
  {"one-database", 'o',
 
1354
   "Only update the default database. This is useful for skipping updates to other database in the update log.",
 
1355
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1356
  {"pager", OPT_PAGER,
 
1357
   "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.",
 
1358
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1359
  {"no-pager", OPT_NOPAGER,
 
1360
   "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
 
1361
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1362
  {"password", 'p',
 
1363
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
 
1364
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1365
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
1366
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
1367
#if MYSQL_PORT_DEFAULT == 0
 
1368
   "/etc/services, "
 
1369
#endif
 
1370
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
 
1371
   (char**) &opt_mysql_port,
 
1372
   (char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,  0},
 
1373
  {"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
 
1374
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
 
1375
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1376
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
1377
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1378
  {"quick", 'q',
 
1379
   "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.",
 
1380
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1381
  {"raw", 'r', "Write fields without conversion. Used with --batch.",
 
1382
   (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1383
   0, 0, 0},
 
1384
  {"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
 
1385
   (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
1386
  {"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,
 
1387
   0, 0},
 
1388
  {"socket", 'S', "Socket file to use for connection.",
 
1389
   (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
 
1390
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1391
  {"table", 't', "Output in table format.", (char**) &output_tables,
 
1392
   (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1393
  {"tee", OPT_TEE,
 
1394
   "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.",
 
1395
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1396
  {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
 
1397
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1398
#ifndef DONT_ALLOW_USER_CHANGE
 
1399
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
 
1400
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1401
#endif
 
1402
  {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
 
1403
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1404
   0, 0, 0, 0},
 
1405
  {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
 
1406
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1407
   0, 0, 0, 0},
 
1408
  {"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
 
1409
   0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1410
  {"version", 'V', "Output version information and exit.", 0, 0, 0,
 
1411
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1412
  {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
 
1413
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1414
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
 
1415
   "Number of seconds before connection timeout.",
 
1416
   (char**) &opt_connect_timeout,
 
1417
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
 
1418
   0, 0},
 
1419
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
 
1420
   "Max packet length to send to, or receive from server",
 
1421
   (char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
 
1422
   GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
 
1423
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1424
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
 
1425
   "Buffer for TCP/IP and socket communication",
 
1426
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_ULONG,
 
1427
   REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1428
  {"select_limit", OPT_SELECT_LIMIT,
 
1429
   "Automatic limit for SELECT when using --safe-updates",
 
1430
   (char**) &select_limit,
 
1431
   (char**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
 
1432
   0, 1, 0},
 
1433
  {"max_join_size", OPT_MAX_JOIN_SIZE,
 
1434
   "Automatic limit for rows in a join when using --safe-updates",
 
1435
   (char**) &max_join_size,
 
1436
   (char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
 
1437
   0, 1, 0},
 
1438
  {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
 
1439
   " uses old (pre-4.1.1) protocol", (char**) &opt_secure_auth,
 
1440
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1441
  {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.",
 
1442
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1443
  {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
 
1444
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
 
1445
   0, 0, 0, 0, 0, 0},
 
1446
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1447
};
 
1448
 
 
1449
 
 
1450
static void usage(int version)
 
1451
{
 
1452
  const char* readline= "readline";
 
1453
 
 
1454
  printf("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n",
 
1455
         my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
 
1456
         readline, rl_library_version);
 
1457
 
 
1458
  if (version)
 
1459
    return;
 
1460
  printf("\
 
1461
Copyright (C) 2000-2008 MySQL AB\n                                      \
 
1462
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
 
1463
and you are welcome to modify and redistribute it under the GPL license\n");
 
1464
  printf("Usage: %s [OPTIONS] [database]\n", my_progname);
 
1465
  my_print_help(my_long_options);
 
1466
  print_defaults("my", load_default_groups);
 
1467
  my_print_variables(my_long_options);
 
1468
}
 
1469
 
 
1470
 
 
1471
bool
 
1472
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
1473
               char *argument)
 
1474
{
 
1475
  switch(optid) {
 
1476
  case OPT_CHARSETS_DIR:
 
1477
    strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir) - 1);
 
1478
    charsets_dir = mysql_charsets_dir;
 
1479
    break;
 
1480
  case  OPT_DEFAULT_CHARSET:
 
1481
    default_charset_used= 1;
 
1482
    break;
 
1483
  case OPT_DELIMITER:
 
1484
    if (argument == disabled_my_option)
 
1485
    {
 
1486
      strmov(delimiter, DEFAULT_DELIMITER);
 
1487
    }
 
1488
    else
 
1489
    {
 
1490
      /* Check that delimiter does not contain a backslash */
 
1491
      if (!strstr(argument, "\\"))
 
1492
      {
 
1493
        strmake(delimiter, argument, sizeof(delimiter) - 1);
 
1494
      }
 
1495
      else
 
1496
      {
 
1497
        put_info("DELIMITER cannot contain a backslash character",
 
1498
                 INFO_ERROR,0,0);
 
1499
        return 0;
 
1500
      }
 
1501
    }
 
1502
    delimiter_length= (uint)strlen(delimiter);
 
1503
    delimiter_str= delimiter;
 
1504
    break;
 
1505
  case OPT_LOCAL_INFILE:
 
1506
    using_opt_local_infile=1;
 
1507
    break;
 
1508
  case OPT_TEE:
 
1509
    if (argument == disabled_my_option)
 
1510
    {
 
1511
      if (opt_outfile)
 
1512
        end_tee();
 
1513
    }
 
1514
    else
 
1515
      init_tee(argument);
 
1516
    break;
 
1517
  case OPT_NOTEE:
 
1518
    printf("WARNING: option deprecated; use --disable-tee instead.\n");
 
1519
    if (opt_outfile)
 
1520
      end_tee();
 
1521
    break;
 
1522
  case OPT_PAGER:
 
1523
    if (argument == disabled_my_option)
 
1524
      opt_nopager= 1;
 
1525
    else
 
1526
    {
 
1527
      opt_nopager= 0;
 
1528
      if (argument && strlen(argument))
 
1529
      {
 
1530
        default_pager_set= 1;
 
1531
        strmake(pager, argument, sizeof(pager) - 1);
 
1532
        strmov(default_pager, pager);
 
1533
      }
 
1534
      else if (default_pager_set)
 
1535
        strmov(pager, default_pager);
 
1536
      else
 
1537
        opt_nopager= 1;
 
1538
    }
 
1539
    break;
 
1540
  case OPT_NOPAGER:
 
1541
    printf("WARNING: option deprecated; use --disable-pager instead.\n");
 
1542
    opt_nopager= 1;
 
1543
    break;
 
1544
  case OPT_MYSQL_PROTOCOL:
 
1545
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
1546
                                    opt->name);
 
1547
    break;
 
1548
  case OPT_SERVER_ARG:
 
1549
#ifdef EMBEDDED_LIBRARY
 
1550
    /*
 
1551
      When the embedded server is being tested, the client needs to be
 
1552
      able to pass command-line arguments to the embedded server so it can
 
1553
      locate the language files and data directory.
 
1554
    */
 
1555
    if (!embedded_server_arg_count)
 
1556
    {
 
1557
      embedded_server_arg_count= 1;
 
1558
      embedded_server_args[0]= (char*) "";
 
1559
    }
 
1560
    if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
 
1561
        !(embedded_server_args[embedded_server_arg_count++]=
 
1562
          g_strdup(argument)))
 
1563
    {
 
1564
      put_info("Can't use server argument", INFO_ERROR);
 
1565
      return 0;
 
1566
    }
 
1567
#else /*EMBEDDED_LIBRARY */
 
1568
    printf("WARNING: --server-arg option not supported in this configuration.\n");
 
1569
#endif
 
1570
    break;
 
1571
  case 'A':
 
1572
    opt_rehash= 0;
 
1573
    break;
 
1574
  case 'N':
 
1575
    column_names= 0;
 
1576
    break;
 
1577
  case 'e':
 
1578
    status.batch= 1;
 
1579
    status.add_to_history= 0;
 
1580
    if (!status.line_buff)
 
1581
      ignore_errors= 0;                         // do it for the first -e only
 
1582
    if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
 
1583
      return 1;
 
1584
    break;
 
1585
  case 'o':
 
1586
    if (argument == disabled_my_option)
 
1587
      one_database= 0;
 
1588
    else
 
1589
      one_database= skip_updates= 1;
 
1590
    break;
 
1591
  case 'p':
 
1592
    if (argument == disabled_my_option)
 
1593
      argument= (char*) "";                     // Don't require password
 
1594
    if (argument)
 
1595
    {
 
1596
      char *start= argument;
 
1597
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
 
1598
      opt_password= g_strdup(argument);
 
1599
      while (*argument) *argument++= 'x';               // Destroy argument
 
1600
      if (*start)
 
1601
        start[1]=0 ;
 
1602
      tty_password= 0;
 
1603
    }
 
1604
    else
 
1605
      tty_password= 1;
 
1606
    break;
 
1607
  case 's':
 
1608
    if (argument == disabled_my_option)
 
1609
      opt_silent= 0;
 
1610
    else
 
1611
      opt_silent++;
 
1612
    break;
 
1613
  case 'v':
 
1614
    if (argument == disabled_my_option)
 
1615
      verbose= 0;
 
1616
    else
 
1617
      verbose++;
 
1618
    break;
 
1619
  case 'B':
 
1620
    status.batch= 1;
 
1621
    status.add_to_history= 0;
 
1622
    set_if_bigger(opt_silent,1);                         // more silent
 
1623
    break;
 
1624
    break;
 
1625
  case 'V':
 
1626
    usage(1);
 
1627
    exit(0);
 
1628
  case 'I':
 
1629
  case '?':
 
1630
    usage(0);
 
1631
    exit(0);
 
1632
  }
 
1633
  return 0;
 
1634
}
 
1635
 
 
1636
 
 
1637
static int get_options(int argc, char **argv)
1946
1638
{
1947
1639
  char *tmp, *pagpoint;
1948
 
  
 
1640
  int ho_error;
 
1641
  MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
1949
1642
 
1950
 
  tmp= (char *) getenv("DRIZZLE_HOST");
 
1643
  tmp= (char *) getenv("MYSQL_HOST");
1951
1644
  if (tmp)
1952
 
    current_host.assign(tmp);
 
1645
    current_host= strdup(tmp);
1953
1646
 
1954
1647
  pagpoint= getenv("PAGER");
1955
1648
  if (!((char*) (pagpoint)))
1956
1649
  {
1957
 
    pager.assign("stdout");
 
1650
    strmov(pager, "stdout");
1958
1651
    opt_nopager= 1;
1959
1652
  }
1960
1653
  else
1961
 
  {
1962
 
    pager.assign(pagpoint);
1963
 
  }
1964
 
  default_pager.assign(pager);
1965
 
 
1966
 
  //
1967
 
 
1968
 
  if (status.getBatch()) /* disable pager and outfile in this case */
1969
 
  {
1970
 
    default_pager.assign("stdout");
1971
 
    pager.assign("stdout");
 
1654
    strmov(pager, pagpoint);
 
1655
  strmov(default_pager, pager);
 
1656
 
 
1657
  opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
 
1658
  opt_net_buffer_length= *mysql_params->p_net_buffer_length;
 
1659
 
 
1660
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
 
1661
    exit(ho_error);
 
1662
 
 
1663
  *mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
 
1664
  *mysql_params->p_net_buffer_length= opt_net_buffer_length;
 
1665
 
 
1666
  if (status.batch) /* disable pager and outfile in this case */
 
1667
  {
 
1668
    strmov(default_pager, "stdout");
 
1669
    strmov(pager, "stdout");
1972
1670
    opt_nopager= 1;
1973
1671
    default_pager_set= 0;
1974
1672
    opt_outfile= 0;
1975
1673
    opt_reconnect= 0;
1976
 
    connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
 
1674
    connect_flag= 0; /* Not in interactive mode */
1977
1675
  }
1978
1676
 
 
1677
  if (strcmp(default_charset, charset_info->csname) &&
 
1678
      !(charset_info= get_charset_by_csname(default_charset,
 
1679
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
1680
    exit(1);
 
1681
  if (argc > 1)
 
1682
  {
 
1683
    usage(0);
 
1684
    exit(1);
 
1685
  }
 
1686
  if (argc == 1)
 
1687
  {
 
1688
    skip_updates= 0;
 
1689
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
1690
    current_db= g_strdup(*argv);
 
1691
  }
1979
1692
  if (tty_password)
1980
 
    opt_password= client_get_tty_password(NULL);
 
1693
    opt_password= get_tty_password(NullS);
 
1694
  if (debug_info_flag)
 
1695
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
1696
  if (debug_check_flag)
 
1697
    my_end_arg= MY_CHECK_ERROR;
1981
1698
  return(0);
1982
1699
}
1983
1700
 
1985
1702
{
1986
1703
  char *line;
1987
1704
  char in_string=0;
1988
 
  uint32_t line_number=0;
 
1705
  ulong line_number=0;
1989
1706
  bool ml_comment= 0;
1990
 
  Commands *com;
1991
 
  status.setExitStatus(1);
 
1707
  COMMANDS *com;
 
1708
  status.exit_status=1;
1992
1709
 
1993
1710
  for (;;)
1994
1711
  {
1995
1712
    if (!interactive)
1996
1713
    {
1997
 
      if (status.getLineBuff())
1998
 
        line= status.getLineBuff()->readline();
1999
 
      else
2000
 
        line= 0;
2001
 
 
 
1714
      line=batch_readline(status.line_buff);
 
1715
      /*
 
1716
        Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
 
1717
        Editors like "notepad" put this marker in
 
1718
        the very beginning of a text file when
 
1719
        you save the file using "Unicode UTF-8" format.
 
1720
      */
 
1721
      if (!line_number &&
 
1722
          (uchar) line[0] == 0xEF &&
 
1723
          (uchar) line[1] == 0xBB &&
 
1724
          (uchar) line[2] == 0xBF)
 
1725
        line+= 3;
2002
1726
      line_number++;
2003
 
      if (show_progress_size > 0)
2004
 
      {
2005
 
        if ((line_number % show_progress_size) == 0)
2006
 
          fprintf(stderr, _("Processing line: %"PRIu32"\n"), line_number);
2007
 
      }
2008
 
      if (!glob_buffer->empty())
2009
 
        status.setQueryStartLine(line_number);
 
1727
      if (glob_buffer->len!=0)
 
1728
        status.query_start_line=line_number;
2010
1729
    }
2011
1730
    else
2012
1731
    {
2013
 
      string prompt(ml_comment
2014
 
                      ? "   /*> " 
2015
 
                      : glob_buffer->empty()
2016
 
                        ? construct_prompt()
2017
 
                        : not in_string
2018
 
                          ? "    -> "
2019
 
                          : in_string == '\''
2020
 
                            ? "    '> "
2021
 
                            : in_string == '`'
2022
 
                              ? "    `> "
2023
 
                              : "    \"> ");
2024
 
      if (opt_outfile && glob_buffer->empty())
 
1732
      char *prompt= (char*) (ml_comment ? "   /*> " :
 
1733
                             (glob_buffer->len == 0) ?  construct_prompt() :
 
1734
                             !in_string ? "    -> " :
 
1735
                             in_string == '\'' ?
 
1736
                             "    '> " : (in_string == '`' ?
 
1737
                                          "    `> " :
 
1738
                                          "    \"> "));
 
1739
      if (opt_outfile && (glob_buffer->len==0))
2025
1740
        fflush(OUTFILE);
2026
1741
 
2027
1742
      if (opt_outfile)
2028
 
        fputs(prompt.c_str(), OUTFILE);
2029
 
      line= readline(prompt.c_str());
 
1743
        fputs(prompt, OUTFILE);
 
1744
      line= readline(prompt);
2030
1745
      /*
2031
1746
        When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
2032
1747
        which may cause coredump.
2037
1752
    // End of file
2038
1753
    if (!line)
2039
1754
    {
2040
 
      status.setExitStatus(0);
 
1755
      status.exit_status=0;
2041
1756
      break;
2042
1757
    }
2043
1758
 
2044
1759
    /*
2045
 
      Check if line is a drizzle command line
 
1760
      Check if line is a mysql command line
2046
1761
      (We want to allow help, print and clear anywhere at line start
2047
1762
    */
2048
 
    if ((named_cmds || (glob_buffer->empty()))
 
1763
    if ((named_cmds || (glob_buffer->len==0))
2049
1764
        && !ml_comment && !in_string && (com=find_command(line,0)))
2050
1765
    {
2051
1766
      if ((*com->func)(glob_buffer,line) > 0)
2052
1767
        break;
2053
1768
      // If buffer was emptied
2054
 
      if (glob_buffer->empty())
 
1769
      if (glob_buffer->len==0)
2055
1770
        in_string=0;
2056
 
      if (interactive && status.getAddToHistory() && not_in_history(line))
 
1771
      if (interactive && status.add_to_history && not_in_history(line))
2057
1772
        add_history(line);
2058
1773
      continue;
2059
1774
    }
2062
1777
  }
2063
1778
  /* if in batch mode, send last query even if it doesn't end with \g or go */
2064
1779
 
2065
 
  if (!interactive && !status.getExitStatus())
 
1780
  if (!interactive && !status.exit_status)
2066
1781
  {
2067
1782
    remove_cntrl(glob_buffer);
2068
 
    if (!glob_buffer->empty())
 
1783
    if (glob_buffer->len != 0)
2069
1784
    {
2070
 
      status.setExitStatus(1);
 
1785
      status.exit_status=1;
2071
1786
      if (com_go(glob_buffer,line) <= 0)
2072
 
        status.setExitStatus(0);
 
1787
        status.exit_status=0;
2073
1788
    }
2074
1789
  }
2075
1790
 
2076
 
  return status.getExitStatus();
 
1791
  return status.exit_status;
2077
1792
}
2078
1793
 
2079
1794
 
2080
 
static Commands *find_command(const char *name,char cmd_char)
 
1795
static COMMANDS *find_command(char *name,char cmd_char)
2081
1796
{
2082
 
  uint32_t len;
2083
 
  const char *end;
 
1797
  uint len;
 
1798
  char *end;
2084
1799
 
2085
1800
  if (!name)
2086
1801
  {
2089
1804
  }
2090
1805
  else
2091
1806
  {
2092
 
    while (isspace(*name))
 
1807
    while (my_isspace(charset_info,*name))
2093
1808
      name++;
2094
1809
    /*
2095
1810
      If there is an \\g in the row or if the row has a delimiter but
2098
1813
    */
2099
1814
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
2100
1815
                                !(strlen(name) >= 9 &&
2101
 
                                  !strcmp(name, "delimiter"))))
2102
 
      return(NULL);
 
1816
                                  !my_strnncoll(charset_info,
 
1817
                                                (uchar*) name, 9,
 
1818
                                                (const uchar*) "delimiter",
 
1819
                                                9))))
 
1820
      return((COMMANDS *) 0);
2103
1821
    if ((end=strcont(name," \t")))
2104
1822
    {
2105
 
      len=(uint32_t) (end - name);
2106
 
      while (isspace(*end))
 
1823
      len=(uint) (end - name);
 
1824
      while (my_isspace(charset_info,*end))
2107
1825
        end++;
2108
1826
      if (!*end)
2109
 
        end=0;          // no arguments to function
 
1827
        end=0;                                  // no arguments to function
2110
1828
    }
2111
1829
    else
2112
 
      len=(uint32_t) strlen(name);
 
1830
      len=(uint) strlen(name);
2113
1831
  }
2114
1832
 
2115
 
  for (uint32_t i= 0; commands[i].getName(); i++)
 
1833
  for (uint i= 0; commands[i].name; i++)
2116
1834
  {
2117
1835
    if (commands[i].func &&
2118
 
        ((name && !strncmp(name, commands[i].getName(), len)
2119
 
          && !commands[i].getName()[len] && (!end || (end && commands[i].getTakesParams()))) || (!name && commands[i].getCmdChar() == cmd_char)))
 
1836
        ((name && !my_strnncoll(charset_info,(uchar*)name,len, (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
2120
1837
    {
2121
1838
      return(&commands[i]);
2122
1839
    }
2123
1840
  }
2124
 
  return(NULL);
 
1841
  return((COMMANDS *) 0);
2125
1842
}
2126
1843
 
2127
1844
 
2128
 
static bool add_line(string *buffer, char *line, char *in_string,
 
1845
static bool add_line(GString *buffer,char *line,char *in_string,
2129
1846
                        bool *ml_comment)
2130
1847
{
2131
 
  unsigned char inchar;
2132
 
  char *pos, *out;
2133
 
  Commands *com;
 
1848
  uchar inchar;
 
1849
  char buff[80], *pos, *out;
 
1850
  COMMANDS *com;
2134
1851
  bool need_space= 0;
2135
1852
  bool ss_comment= 0;
2136
1853
 
2137
1854
 
2138
 
  if (!line[0] && (buffer->empty()))
 
1855
  if (!line[0] && (buffer->len==0))
2139
1856
    return(0);
2140
 
  if (status.getAddToHistory() && line[0] && not_in_history(line))
 
1857
  if (status.add_to_history && line[0] && not_in_history(line))
2141
1858
    add_history(line);
2142
 
  char *end_of_line=line+(uint32_t) strlen(line);
 
1859
  char *end_of_line=line+(uint) strlen(line);
2143
1860
 
2144
 
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
 
1861
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
2145
1862
  {
2146
1863
    if (!preserve_comments)
2147
1864
    {
2148
1865
      // Skip spaces at the beggining of a statement
2149
 
      if (isspace(inchar) && (out == line) &&
2150
 
          (buffer->empty()))
 
1866
      if (my_isspace(charset_info,inchar) && (out == line) &&
 
1867
          (buffer->len==0))
2151
1868
        continue;
2152
1869
    }
2153
1870
 
 
1871
#ifdef USE_MB
2154
1872
    // Accept multi-byte characters as-is
2155
 
    if (not drizzled::utf8::is_single(*pos))
 
1873
    int length;
 
1874
    if (use_mb(charset_info) &&
 
1875
        (length= my_ismbchar(charset_info, pos, end_of_line)))
2156
1876
    {
2157
 
      int length;
2158
 
      if ((length= drizzled::utf8::sequence_length(*pos)))
 
1877
      if (!*ml_comment || preserve_comments)
2159
1878
      {
2160
 
        if (!*ml_comment || preserve_comments)
2161
 
        {
2162
 
          while (length--)
2163
 
            *out++ = *pos++;
2164
 
          pos--;
2165
 
        }
2166
 
        else
2167
 
          pos+= length - 1;
2168
 
        continue;
 
1879
        while (length--)
 
1880
          *out++ = *pos++;
 
1881
        pos--;
2169
1882
      }
 
1883
      else
 
1884
        pos+= length - 1;
 
1885
      continue;
2170
1886
    }
2171
 
    if (!*ml_comment && inchar == '\\' &&
2172
 
        !(*in_string && (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
 
1887
#endif
 
1888
        if (!*ml_comment && inchar == '\\' &&
 
1889
        !(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))
2173
1890
    {
2174
1891
      // Found possbile one character command like \c
2175
1892
 
2176
 
      if (!(inchar = (unsigned char) *++pos))
2177
 
        break;        // readline adds one '\'
2178
 
      if (*in_string || inchar == 'N')  // \N is short for NULL
2179
 
      {          // Don't allow commands in string
 
1893
      if (!(inchar = (uchar) *++pos))
 
1894
        break;                          // readline adds one '\'
 
1895
      if (*in_string || inchar == 'N')  // \N is short for NULL
 
1896
      {                                 // Don't allow commands in string
2180
1897
        *out++='\\';
2181
1898
        *out++= (char) inchar;
2182
1899
        continue;
2183
1900
      }
2184
 
      if ((com=find_command(NULL,(char) inchar)))
 
1901
      if ((com=find_command(NullS,(char) inchar)))
2185
1902
      {
2186
1903
        // Flush previously accepted characters
2187
1904
        if (out != line)
2188
1905
        {
2189
 
          buffer->append(line, (out-line));
 
1906
          g_string_append_len(buffer, line, (gssize) (out-line));
2190
1907
          out= line;
2191
1908
        }
2192
1909
 
2193
1910
        if ((*com->func)(buffer,pos-1) > 0)
2194
1911
          return(1);                       // Quit
2195
 
        if (com->getTakesParams())
 
1912
        if (com->takes_params)
2196
1913
        {
2197
1914
          if (ss_comment)
2198
1915
          {
2209
1926
          {
2210
1927
            for (pos++ ;
2211
1928
                 *pos && (*pos != *delimiter ||
2212
 
                          strncmp(pos + 1, delimiter + 1,
2213
 
                                  strlen(delimiter + 1))) ; pos++)
2214
 
              ;  // Remove parameters
 
1929
                          !is_prefix(pos + 1, delimiter + 1)) ; pos++)
 
1930
              ; // Remove parameters
2215
1931
            if (!*pos)
2216
1932
              pos--;
2217
1933
            else
2221
1937
      }
2222
1938
      else
2223
1939
      {
2224
 
        string buff(_("Unknown command: "));
2225
 
        buff.push_back('\'');
2226
 
        buff.push_back(inchar);
2227
 
        buff.push_back('\'');
2228
 
        buff.push_back('.');
2229
 
        if (put_info(buff.c_str(),INFO_ERROR,0,0) > 0)
 
1940
        sprintf(buff,"Unknown command '\\%c'.",inchar);
 
1941
        if (put_info(buff,INFO_ERROR,0,0) > 0)
2230
1942
          return(1);
2231
1943
        *out++='\\';
2232
1944
        *out++=(char) inchar;
2235
1947
    }
2236
1948
    else if (!*ml_comment && !*in_string &&
2237
1949
             (end_of_line - pos) >= 10 &&
2238
 
             !strncmp(pos, "delimiter ", 10))
 
1950
             !my_strnncoll(charset_info, (uchar*) pos, 10,
 
1951
                           (const uchar*) "delimiter ", 10))
2239
1952
    {
2240
1953
      // Flush previously accepted characters
2241
1954
      if (out != line)
2242
1955
      {
2243
 
        buffer->append(line, (out - line));
 
1956
        g_string_append_len(buffer, line, (gssize) (out - line));
2244
1957
        out= line;
2245
1958
      }
2246
1959
 
2247
1960
      // Flush possible comments in the buffer
2248
 
      if (!buffer->empty())
 
1961
      if (buffer->len != 0)
2249
1962
      {
2250
1963
        if (com_go(buffer, 0) > 0) // < 0 is not fatal
2251
1964
          return(1);
2252
1965
        assert(buffer!=NULL);
2253
 
        buffer->clear();
 
1966
        g_string_truncate(buffer,0);
2254
1967
      }
2255
1968
 
2256
1969
      /*
2257
1970
        Delimiter wants the get rest of the given line as argument to
2258
1971
        allow one to change ';' to ';;' and back
2259
1972
      */
2260
 
      buffer->append(pos);
 
1973
      g_string_append(buffer,pos);
2261
1974
      if (com_delimiter(buffer, pos) > 0)
2262
1975
        return(1);
2263
1976
 
2264
 
      buffer->clear();
 
1977
      g_string_truncate(buffer,0);
2265
1978
      break;
2266
1979
    }
2267
 
    else if (!*ml_comment && !*in_string && !strncmp(pos, delimiter,
2268
 
                                                     strlen(delimiter)))
 
1980
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
2269
1981
    {
2270
1982
      // Found a statement. Continue parsing after the delimiter
2271
1983
      pos+= delimiter_length;
2272
1984
 
2273
1985
      if (preserve_comments)
2274
1986
      {
2275
 
        while (isspace(*pos))
 
1987
        while (my_isspace(charset_info, *pos))
2276
1988
          *out++= *pos++;
2277
1989
      }
2278
1990
      // Flush previously accepted characters
2279
1991
      if (out != line)
2280
1992
      {
2281
 
        buffer->append(line, (out-line));
 
1993
        g_string_append_len(buffer, line, (gssize) (out-line));
2282
1994
        out= line;
2283
1995
      }
2284
1996
 
2285
1997
      if (preserve_comments && ((*pos == '#') ||
2286
1998
                                ((*pos == '-') &&
2287
1999
                                 (pos[1] == '-') &&
2288
 
                                 isspace(pos[2]))))
 
2000
                                 my_isspace(charset_info, pos[2]))))
2289
2001
      {
2290
2002
        // Add trailing single line comments to this statement
2291
 
        buffer->append(pos);
 
2003
        g_string_append(buffer, pos);
2292
2004
        pos+= strlen(pos);
2293
2005
      }
2294
2006
 
2295
2007
      pos--;
2296
2008
 
2297
 
      if ((com= find_command(buffer->c_str(), 0)))
 
2009
      if ((com= find_command(buffer->str, 0)))
2298
2010
      {
2299
2011
 
2300
 
        if ((*com->func)(buffer, buffer->c_str()) > 0)
 
2012
        if ((*com->func)(buffer, buffer->str) > 0)
2301
2013
          return(1);                       // Quit
2302
2014
      }
2303
2015
      else
2305
2017
        if (com_go(buffer, 0) > 0)             // < 0 is not fatal
2306
2018
          return(1);
2307
2019
      }
2308
 
      buffer->clear();
 
2020
      g_string_truncate(buffer,0);
2309
2021
    }
2310
2022
    else if (!*ml_comment
2311
2023
             && (!*in_string
2312
2024
                 && (inchar == '#'
2313
2025
                     || (inchar == '-'
2314
2026
                         && pos[1] == '-'
2315
 
                         && isspace(pos[2])))))
 
2027
                         && my_isspace(charset_info,pos[2])))))
2316
2028
    {
2317
2029
      // Flush previously accepted characters
2318
2030
      if (out != line)
2319
2031
      {
2320
 
        buffer->append(line, (out - line));
 
2032
        g_string_append_len(buffer, line, (gssize) (out - line));
2321
2033
        out= line;
2322
2034
      }
2323
2035
 
2324
2036
      // comment to end of line
2325
2037
      if (preserve_comments)
2326
 
        buffer->append(pos);
 
2038
        g_string_append(buffer,pos);
2327
2039
 
2328
2040
      break;
2329
2041
    }
2340
2052
      *ml_comment= 1;
2341
2053
      if (out != line)
2342
2054
      {
2343
 
        buffer->append(line, (out-line));
 
2055
        g_string_append_len(buffer, line, (gssize) (out-line));
2344
2056
        out=line;
2345
2057
      }
2346
2058
    }
2356
2068
      *ml_comment= 0;
2357
2069
      if (out != line)
2358
2070
      {
2359
 
        buffer->append(line, (out - line));
 
2071
        g_string_append_len(buffer, line, (gssize) (out - line));
2360
2072
        out= line;
2361
2073
      }
2362
2074
      // Consumed a 2 chars or more, and will add 1 at most,
2378
2090
        *in_string= (char) inchar;
2379
2091
      if (!*ml_comment || preserve_comments)
2380
2092
      {
2381
 
        if (need_space && !isspace((char)inchar))
 
2093
        if (need_space && !my_isspace(charset_info, (char)inchar))
2382
2094
          *out++= ' ';
2383
2095
        need_space= 0;
2384
2096
        *out++= (char) inchar;
2385
2097
      }
2386
2098
    }
2387
2099
  }
2388
 
  if (out != line || (buffer->length() > 0))
 
2100
  if (out != line || (buffer->len > 0))
2389
2101
  {
2390
2102
    *out++='\n';
2391
 
    uint32_t length=(uint32_t) (out-line);
2392
 
    if ((buffer->length() + length) > opt_max_input_line)
2393
 
    {
2394
 
      status.setExitStatus(1);
2395
 
      put_info(_("Not found a delimiter within max_input_line of input"), INFO_ERROR, 0, 0);
2396
 
      return 1;
2397
 
    }
2398
 
    if ((!*ml_comment || preserve_comments))
2399
 
      buffer->append(line, length);
 
2103
    uint length=(uint) (out-line);
 
2104
    if ((!*ml_comment || preserve_comments)
 
2105
        && (g_string_append_len(buffer, line, length) == NULL))
 
2106
      return(1);
2400
2107
  }
2401
2108
  return(0);
2402
2109
}
2406
2113
******************************************************************/
2407
2114
 
2408
2115
 
2409
 
static char **mysql_completion (const char *text, int start, int end);
2410
 
extern "C" char *new_command_generator(const char *text, int);
 
2116
static char *new_command_generator(const char *text, int);
 
2117
extern char **new_mysql_completion (const char *text, int start, int end);
2411
2118
 
2412
2119
/*
2413
2120
  Tell the GNU Readline library how to complete.  We want to try to complete
2414
2121
  on command names if this is the first word in the line, or on filenames
2415
2122
  if not.
2416
2123
*/
2417
 
static char *no_completion(const char *, int)
 
2124
 
 
2125
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE)
 
2126
extern char *no_completion(const char*,int);
 
2127
#else
 
2128
char *no_completion(void);
 
2129
char *no_completion(void)
2418
2130
{
2419
2131
  /* No filename completion */
2420
2132
  return 0;
2421
2133
}
2422
 
 
 
2134
#endif
2423
2135
 
2424
2136
/* glues pieces of history back together if in pieces   */
2425
 
static void fix_history(string *final_command)
 
2137
static void fix_history(GString *final_command)
2426
2138
{
2427
2139
  int total_lines = 1;
2428
 
  const char *ptr = final_command->c_str();
 
2140
  const char *ptr = final_command->str;
 
2141
  /* Converted buffer */
 
2142
  GString * fixed_buffer;
 
2143
  fixed_buffer = g_string_sized_new(16);
2429
2144
  char str_char = '\0';  /* Character if we are in a string or not */
2430
2145
 
2431
 
  /* Converted buffer */
2432
 
  string fixed_buffer;
2433
 
  fixed_buffer.reserve(512);
2434
 
 
2435
2146
  /* find out how many lines we have and remove newlines */
2436
2147
  while (*ptr != '\0')
2437
2148
  {
2445
2156
        str_char = *ptr;
2446
2157
      else if (str_char == *ptr)   /* close string */
2447
2158
        str_char = '\0';
2448
 
      fixed_buffer.append(ptr, 1);
 
2159
      g_string_append_len(fixed_buffer, ptr, 1);
2449
2160
      break;
2450
2161
    case '\n':
2451
2162
      /*
2452
2163
        not in string, change to space
2453
2164
        if in string, leave it alone
2454
2165
      */
2455
 
      fixed_buffer.append((str_char == '\0') ? " " : "\n");
 
2166
      g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2456
2167
      total_lines++;
2457
2168
      break;
2458
2169
    case '\\':
2459
 
      fixed_buffer.append("\\");
 
2170
      g_string_append_c(fixed_buffer, '\\');
2460
2171
      /* need to see if the backslash is escaping anything */
2461
2172
      if (str_char)
2462
2173
      {
2463
2174
        ptr++;
2464
2175
        /* special characters that need escaping */
2465
2176
        if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2466
 
          fixed_buffer.append(ptr, 1);
 
2177
          g_string_append_len(fixed_buffer, ptr, 1);
2467
2178
        else
2468
2179
          ptr--;
2469
2180
      }
2470
2181
      break;
2471
2182
    default:
2472
 
      fixed_buffer.append(ptr, 1);
 
2183
      g_string_append_len(fixed_buffer, ptr, 1);
2473
2184
    }
2474
2185
    ptr++;
2475
2186
  }
2476
2187
  if (total_lines > 1)
2477
 
    add_history(fixed_buffer.c_str());
 
2188
    add_history(fixed_buffer->str);
2478
2189
}
2479
2190
 
2480
2191
/*
2492
2203
  return 1;
2493
2204
}
2494
2205
 
2495
 
static void initialize_readline (char *name)
 
2206
static void initialize_readline (const char *name)
2496
2207
{
2497
2208
  /* Allow conditional parsing of the ~/.inputrc file. */
2498
2209
  rl_readline_name= name;
2499
2210
 
2500
2211
  /* Tell the completer that we want a crack first. */
2501
 
  rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
2502
 
  rl_completion_entry_function= (drizzle_compentry_func_t*)&no_completion;
 
2212
  rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
 
2213
  rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2503
2214
}
2504
2215
 
2505
 
 
2506
2216
/*
2507
2217
  Attempt to complete on the contents of TEXT.  START and END show the
2508
2218
  region of TEXT that contains the word to complete.  We can use the
2509
2219
  entire line in case we want to do some simple parsing.  Return the
2510
2220
  array of matches, or NULL if there aren't any.
2511
2221
*/
2512
 
char **mysql_completion (const char *text, int, int)
 
2222
 
 
2223
char **new_mysql_completion (const char *text,
 
2224
                             int start __attribute__((unused)),
 
2225
                             int end __attribute__((unused)))
2513
2226
{
2514
 
  if (!status.getBatch() && !quick)
 
2227
  if (!status.batch && !quick)
2515
2228
    return rl_completion_matches(text, new_command_generator);
2516
2229
  else
2517
2230
    return (char**) 0;
2518
2231
}
2519
2232
 
2520
 
inline string lower_string(const string &from_string)
2521
 
{
2522
 
  string to_string= from_string;
2523
 
  transform(to_string.begin(), to_string.end(),
2524
 
            to_string.begin(), ::tolower);
2525
 
  return to_string;
2526
 
}
2527
 
inline string lower_string(const char * from_string)
2528
 
{
2529
 
  string to_string= from_string;
2530
 
  return lower_string(to_string);
2531
 
}
2532
 
 
2533
 
template <class T>
2534
 
class CompletionMatch :
2535
 
  public unary_function<const string&, bool>
2536
 
{
2537
 
  string match_text; 
2538
 
  T match_func;
2539
 
public:
2540
 
  CompletionMatch(string text) : match_text(text) {}
2541
 
  inline bool operator() (const pair<string,string> &match_against) const
2542
 
  {
2543
 
    string sub_match=
2544
 
      lower_string(match_against.first.substr(0,match_text.size()));
2545
 
    return match_func(sub_match,match_text);
2546
 
  }
2547
 
};
2548
 
 
2549
 
 
2550
 
 
2551
 
extern "C"
2552
 
char *new_command_generator(const char *text, int state)
2553
 
{
 
2233
static char *new_command_generator(const char *text,int state)
 
2234
{
 
2235
  static int textlen;
 
2236
  char *ptr;
 
2237
  static Bucket *b;
 
2238
  static entry *e;
 
2239
  static uint i;
2554
2240
 
2555
2241
  if (!state)
2556
 
  {
2557
 
    completion_string= lower_string(text);
2558
 
    if (completion_string.size() == 0)
2559
 
    {
2560
 
      completion_iter= completion_map.begin();
2561
 
      completion_end= completion_map.end();
2562
 
    }
2563
 
    else
2564
 
    {
2565
 
      completion_iter= find_if(completion_map.begin(), completion_map.end(),
2566
 
                               CompletionMatch<equal_to<string> >(completion_string));
2567
 
      completion_end= find_if(completion_iter, completion_map.end(),
2568
 
                              CompletionMatch<not_equal_to<string> >(completion_string));
2569
 
    }
2570
 
  }
2571
 
  if (completion_iter == completion_end || (size_t)state > completion_map.size())
2572
 
    return NULL;
2573
 
  char *result= (char *)malloc((*completion_iter).second.size()+1);
2574
 
  strcpy(result, (*completion_iter).second.c_str());
2575
 
  completion_iter++;
2576
 
  return result;
 
2242
    textlen=(uint) strlen(text);
 
2243
 
 
2244
  if (textlen>0)
 
2245
  {                                             /* lookup in the hash */
 
2246
    if (!state)
 
2247
    {
 
2248
      uint len;
 
2249
 
 
2250
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
 
2251
      if (!b)
 
2252
        return NullS;
 
2253
      e = b->pData;
 
2254
    }
 
2255
 
 
2256
    if (e)
 
2257
    {
 
2258
      ptr= g_strdup(e->str);
 
2259
      e = e->pNext;
 
2260
      return ptr;
 
2261
    }
 
2262
  }
 
2263
  else
 
2264
  { /* traverse the entire hash, ugly but works */
 
2265
 
 
2266
    if (!state)
 
2267
    {
 
2268
      /* find the first used bucket */
 
2269
      for (i=0 ; i < ht.nTableSize ; i++)
 
2270
      {
 
2271
        if (ht.arBuckets[i])
 
2272
        {
 
2273
          b = ht.arBuckets[i];
 
2274
          e = b->pData;
 
2275
          break;
 
2276
        }
 
2277
      }
 
2278
    }
 
2279
    ptr= NullS;
 
2280
    while (e && !ptr)
 
2281
    {                                   /* find valid entry in bucket */
 
2282
      if ((uint) strlen(e->str) == b->nKeyLength)
 
2283
        ptr = g_strdup(e->str);
 
2284
      /* find the next used entry */
 
2285
      e = e->pNext;
 
2286
      if (!e)
 
2287
      { /* find the next used bucket */
 
2288
        b = b->pNext;
 
2289
        if (!b)
 
2290
        {
 
2291
          for (i++ ; i<ht.nTableSize; i++)
 
2292
          {
 
2293
            if (ht.arBuckets[i])
 
2294
            {
 
2295
              b = ht.arBuckets[i];
 
2296
              e = b->pData;
 
2297
              break;
 
2298
            }
 
2299
          }
 
2300
        }
 
2301
        else
 
2302
          e = b->pData;
 
2303
      }
 
2304
    }
 
2305
    if (ptr)
 
2306
      return ptr;
 
2307
  }
 
2308
  return NullS;
2577
2309
}
2578
2310
 
 
2311
 
2579
2312
/* Build up the completion hash */
2580
2313
 
2581
2314
static void build_completion_hash(bool rehash, bool write_info)
2582
2315
{
2583
 
  Commands *cmd=commands;
2584
 
  drizzle_return_t ret;
2585
 
  drizzle_result_st databases,tables,fields;
2586
 
  drizzle_row_t database_row,table_row;
2587
 
  string tmp_str, tmp_str_lower;
2588
 
  std::string query;
2589
 
 
2590
 
  if (status.getBatch() || quick || current_db.empty())
2591
 
    return;      // We don't need completion in batches
 
2316
  COMMANDS *cmd=commands;
 
2317
  MYSQL_RES *databases=0,*tables=0;
 
2318
  MYSQL_RES *fields;
 
2319
  static char ***field_names= 0;
 
2320
  MYSQL_ROW database_row,table_row;
 
2321
  MYSQL_FIELD *sql_field;
 
2322
  char buf[NAME_LEN*2+2];                // table name plus field name plus 2
 
2323
  int i,j,num_fields;
 
2324
 
 
2325
 
 
2326
  if (status.batch || quick || !current_db)
 
2327
    return;                     // We don't need completion in batches
2592
2328
  if (!rehash)
2593
2329
    return;
2594
2330
 
2595
 
  completion_map.clear();
 
2331
  /* Free old used memory */
 
2332
  if (field_names)
 
2333
    field_names=0;
 
2334
  completion_hash_clean(&ht);
 
2335
  free_root(&hash_mem_root,MYF(0));
2596
2336
 
2597
2337
  /* hash this file's known subset of SQL commands */
2598
 
  while (cmd->getName()) {
2599
 
    tmp_str= cmd->getName();
2600
 
    tmp_str_lower= lower_string(tmp_str);
2601
 
    completion_map[tmp_str_lower]= tmp_str;
 
2338
  while (cmd->name) {
 
2339
    add_word(&ht,(char*) cmd->name);
2602
2340
    cmd++;
2603
2341
  }
2604
2342
 
2605
2343
  /* hash Drizzle functions (to be implemented) */
2606
2344
 
2607
2345
  /* hash all database names */
2608
 
  if (drizzle_query_str(&con, &databases, "select schema_name from information_schema.schemata", &ret) != NULL)
2609
 
  {
2610
 
    if (ret == DRIZZLE_RETURN_OK)
2611
 
    {
2612
 
      if (drizzle_result_buffer(&databases) != DRIZZLE_RETURN_OK)
2613
 
        put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
2614
 
      else
2615
 
      {
2616
 
        while ((database_row=drizzle_row_next(&databases)))
2617
 
        {
2618
 
          tmp_str= database_row[0];
2619
 
          tmp_str_lower= lower_string(tmp_str);
2620
 
          completion_map[tmp_str_lower]= tmp_str;
2621
 
        }
2622
 
      }
2623
 
    }
2624
 
 
2625
 
    drizzle_result_free(&databases);
2626
 
  }
2627
 
 
2628
 
  query= "select table_name, column_name from information_schema.columns where table_schema='";
2629
 
  query.append(current_db);
2630
 
  query.append("' order by table_name");
2631
 
  
2632
 
  if (drizzle_query(&con, &fields, query.c_str(), query.length(),
2633
 
                    &ret) != NULL)
2634
 
  {
2635
 
    if (ret == DRIZZLE_RETURN_OK &&
2636
 
        drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
2637
 
    {
2638
 
      if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2639
 
      {
2640
 
        tee_fprintf(stdout,
2641
 
                    _("Reading table information for completion of "
2642
 
                      "table and column names\n"
2643
 
                      "You can turn off this feature to get a quicker "
2644
 
                      "startup with -A\n\n"));
2645
 
      }
2646
 
 
2647
 
      std::string table_name;
2648
 
      while ((table_row=drizzle_row_next(&fields)))
2649
 
      {
2650
 
        if (table_name.compare(table_row[0]) != 0)
2651
 
        {
2652
 
          tmp_str= table_row[0];
2653
 
          tmp_str_lower= lower_string(tmp_str);
2654
 
          completion_map[tmp_str_lower]= tmp_str;
2655
 
          table_name= table_row[0];
2656
 
        }
2657
 
        tmp_str= table_row[0];
2658
 
        tmp_str.append(".");
2659
 
        tmp_str.append(table_row[1]);
2660
 
        tmp_str_lower= lower_string(tmp_str);
2661
 
        completion_map[tmp_str_lower]= tmp_str;
2662
 
 
2663
 
        tmp_str= table_row[1];
2664
 
        tmp_str_lower= lower_string(tmp_str);
2665
 
        completion_map[tmp_str_lower]= tmp_str;
2666
 
      }
2667
 
    }
2668
 
  }
2669
 
  drizzle_result_free(&fields);
2670
 
  completion_iter= completion_map.begin();
 
2346
  if (mysql_query(&mysql,"show databases") == 0)
 
2347
  {
 
2348
    if (!(databases = mysql_store_result(&mysql)))
 
2349
      put_info(mysql_error(&mysql),INFO_INFO,0,0);
 
2350
    else
 
2351
    {
 
2352
      while ((database_row=mysql_fetch_row(databases)))
 
2353
      {
 
2354
        char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
 
2355
        if (str)
 
2356
          add_word(&ht,(char*) str);
 
2357
      }
 
2358
      mysql_free_result(databases);
 
2359
    }
 
2360
  }
 
2361
  /* hash all table names */
 
2362
  if (mysql_query(&mysql,"show tables")==0)
 
2363
  {
 
2364
    if (!(tables = mysql_store_result(&mysql)))
 
2365
      put_info(mysql_error(&mysql),INFO_INFO,0,0);
 
2366
    else
 
2367
    {
 
2368
      if (mysql_num_rows(tables) > 0 && !opt_silent && write_info)
 
2369
      {
 
2370
        tee_fprintf(stdout, "\
 
2371
Reading table information for completion of table and column names\n    \
 
2372
You can turn off this feature to get a quicker startup with -A\n\n");
 
2373
      }
 
2374
      while ((table_row=mysql_fetch_row(tables)))
 
2375
      {
 
2376
        char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
 
2377
        if (str &&
 
2378
            !completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
 
2379
          add_word(&ht,str);
 
2380
      }
 
2381
    }
 
2382
  }
 
2383
 
 
2384
  /* hash all field names, both with the table prefix and without it */
 
2385
  if (!tables)                                  /* no tables */
 
2386
  {
 
2387
    return;
 
2388
  }
 
2389
  mysql_data_seek(tables,0);
 
2390
  if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
 
2391
                                           (uint) (mysql_num_rows(tables)+1))))
 
2392
  {
 
2393
    mysql_free_result(tables);
 
2394
    return;
 
2395
  }
 
2396
  i=0;
 
2397
  while ((table_row=mysql_fetch_row(tables)))
 
2398
  {
 
2399
    if ((fields=mysql_list_fields(&mysql,(const char*) table_row[0],NullS)))
 
2400
    {
 
2401
      num_fields=mysql_num_fields(fields);
 
2402
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
 
2403
                                                  sizeof(char *) *
 
2404
                                                  (num_fields*2+1))))
 
2405
      {
 
2406
        mysql_free_result(fields);
 
2407
        break;
 
2408
      }
 
2409
      field_names[i][num_fields*2]= '\0';
 
2410
      j=0;
 
2411
      while ((sql_field=mysql_fetch_field(fields)))
 
2412
      {
 
2413
        sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name);
 
2414
        field_names[i][j] = strdup_root(&hash_mem_root,buf);
 
2415
        add_word(&ht,field_names[i][j]);
 
2416
        field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
 
2417
                                                   sql_field->name);
 
2418
        if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
 
2419
                                    (uint) strlen(field_names[i][num_fields+j])))
 
2420
          add_word(&ht,field_names[i][num_fields+j]);
 
2421
        j++;
 
2422
      }
 
2423
      mysql_free_result(fields);
 
2424
    }
 
2425
    else
 
2426
      field_names[i]= 0;
 
2427
 
 
2428
    i++;
 
2429
  }
 
2430
  mysql_free_result(tables);
 
2431
  field_names[i]=0;                             // End pointer
 
2432
  return;
2671
2433
}
2672
2434
 
2673
2435
/* for gnu readline */
2674
2436
 
 
2437
#ifndef HAVE_INDEX
 
2438
extern "C" {
 
2439
  extern char *index(const char *,int c),*rindex(const char *,int);
 
2440
 
 
2441
  char *index(const char *s,int c)
 
2442
  {
 
2443
    for (;;)
 
2444
    {
 
2445
      if (*s == (char) c) return (char*) s;
 
2446
      if (!*s++) return NullS;
 
2447
    }
 
2448
  }
 
2449
 
 
2450
  char *rindex(const char *s,int c)
 
2451
  {
 
2452
    register char *t;
 
2453
 
 
2454
    t = NullS;
 
2455
    do if (*s == (char) c) t = (char*) s; while (*s++);
 
2456
    return (char*) t;
 
2457
  }
 
2458
}
 
2459
#endif
 
2460
 
2675
2461
 
2676
2462
static int reconnect(void)
2677
2463
{
 
2464
  /* purecov: begin tested */
2678
2465
  if (opt_reconnect)
2679
2466
  {
2680
 
    put_info(_("No connection. Trying to reconnect..."),INFO_INFO,0,0);
2681
 
    (void) com_connect((string *)0, 0);
2682
 
    if (opt_rehash && connected)
 
2467
    put_info("No connection. Trying to reconnect...",INFO_INFO,0,0);
 
2468
    (void) com_connect((GString *) 0, 0);
 
2469
    if (opt_rehash)
2683
2470
      com_rehash(NULL, NULL);
2684
2471
  }
2685
 
  if (! connected)
2686
 
    return put_info(_("Can't connect to the server\n"),INFO_ERROR,0,0);
 
2472
  if (!connected)
 
2473
    return put_info("Can't connect to the server\n",INFO_ERROR,0,0);
 
2474
  /* purecov: end */
2687
2475
  return 0;
2688
2476
}
2689
2477
 
2690
2478
static void get_current_db(void)
2691
2479
{
2692
 
  drizzle_return_t ret;
2693
 
  drizzle_result_st res;
 
2480
  MYSQL_RES *res;
2694
2481
 
2695
 
  current_db.erase();
2696
 
  current_db= "";
 
2482
  my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
2483
  current_db= NULL;
2697
2484
  /* In case of error below current_db will be NULL */
2698
 
  if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
 
2485
  if (!mysql_query(&mysql, "SELECT DATABASE()") &&
 
2486
      (res= mysql_use_result(&mysql)))
2699
2487
  {
2700
 
    if (ret == DRIZZLE_RETURN_OK &&
2701
 
        drizzle_result_buffer(&res) == DRIZZLE_RETURN_OK)
2702
 
    {
2703
 
      drizzle_row_t row= drizzle_row_next(&res);
2704
 
      if (row[0])
2705
 
        current_db.assign(row[0]);
2706
 
      drizzle_result_free(&res);
2707
 
    }
 
2488
    MYSQL_ROW row= mysql_fetch_row(res);
 
2489
    if (row[0])
 
2490
      current_db= g_strdup(row[0]);
 
2491
    mysql_free_result(res);
2708
2492
  }
2709
2493
}
2710
2494
 
2712
2496
 The different commands
2713
2497
***************************************************************************/
2714
2498
 
2715
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
2716
 
                                      drizzle_result_st *result,
2717
 
                                      uint32_t *error_code)
 
2499
int mysql_real_query_for_lazy(const char *buf, int length)
2718
2500
{
2719
 
  drizzle_return_t ret;
2720
 
 
2721
 
  for (uint32_t retry=0;; retry++)
 
2501
  for (uint retry=0;; retry++)
2722
2502
  {
2723
2503
    int error;
2724
 
    if (drizzle_query(&con,result,buf,length,&ret) != NULL &&
2725
 
        ret == DRIZZLE_RETURN_OK)
2726
 
    {
 
2504
    if (!mysql_real_query(&mysql,buf,length))
2727
2505
      return 0;
2728
 
    }
2729
 
    error= put_error(&con, result);
2730
 
 
2731
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
2732
 
    {
2733
 
      *error_code= drizzle_result_error_code(result);
2734
 
      drizzle_result_free(result);
2735
 
    }
2736
 
 
2737
 
    if (ret != DRIZZLE_RETURN_SERVER_GONE || retry > 1 ||
 
2506
    error= put_error(&mysql);
 
2507
    if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
2738
2508
        !opt_reconnect)
2739
 
    {
2740
2509
      return error;
2741
 
    }
2742
 
 
2743
2510
    if (reconnect())
2744
2511
      return error;
2745
2512
  }
2746
2513
}
2747
2514
 
2748
 
int drizzleclient_store_result_for_lazy(drizzle_result_st *result)
 
2515
int mysql_store_result_for_lazy(MYSQL_RES **result)
2749
2516
{
2750
 
  if (drizzle_result_buffer(result) == DRIZZLE_RETURN_OK)
 
2517
  if ((*result=mysql_store_result(&mysql)))
2751
2518
    return 0;
2752
2519
 
2753
 
  if (drizzle_con_error(&con)[0])
2754
 
  {
2755
 
    int ret= put_error(&con, result);
2756
 
    drizzle_result_free(result);
2757
 
    return ret;
2758
 
  }
 
2520
  if (mysql_error(&mysql)[0])
 
2521
    return put_error(&mysql);
2759
2522
  return 0;
2760
2523
}
2761
2524
 
 
2525
static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *last_char)
 
2526
{
 
2527
  char ccat= (*cur)[num_cat][0];
 
2528
  if (*last_char != ccat)
 
2529
  {
 
2530
    put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO,0,0);
 
2531
    *last_char= ccat;
 
2532
  }
 
2533
  tee_fprintf(PAGER, "   %s\n", (*cur)[num_name]);
 
2534
}
 
2535
 
 
2536
 
 
2537
static int com_server_help(GString *buffer,
 
2538
                           char *line __attribute__((unused)),
 
2539
                           char *help_arg)
 
2540
{
 
2541
  MYSQL_ROW cur;
 
2542
  const char *server_cmd= buffer->str;
 
2543
  char cmd_buf[100];
 
2544
  MYSQL_RES *result;
 
2545
  int error;
 
2546
 
 
2547
  if (help_arg[0] != '\'')
 
2548
  {
 
2549
    char *end_arg= strend(help_arg);
 
2550
    if(--end_arg)
 
2551
    {
 
2552
      while (my_isspace(charset_info,*end_arg))
 
2553
        end_arg--;
 
2554
      *++end_arg= '\0';
 
2555
    }
 
2556
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
 
2557
    server_cmd= cmd_buf;
 
2558
  }
 
2559
 
 
2560
  if (!connected && reconnect())
 
2561
    return 1;
 
2562
 
 
2563
  if ((error= mysql_real_query_for_lazy(server_cmd,(int)strlen(server_cmd))) ||
 
2564
      (error= mysql_store_result_for_lazy(&result)))
 
2565
    return error;
 
2566
 
 
2567
  if (result)
 
2568
  {
 
2569
    unsigned int num_fields= mysql_num_fields(result);
 
2570
    uint64_t num_rows= mysql_num_rows(result);
 
2571
    mysql_fetch_fields(result);
 
2572
    if (num_fields==3 && num_rows==1)
 
2573
    {
 
2574
      if (!(cur= mysql_fetch_row(result)))
 
2575
      {
 
2576
        error= -1;
 
2577
        goto err;
 
2578
      }
 
2579
 
 
2580
      init_pager();
 
2581
      tee_fprintf(PAGER,   "Name: \'%s\'\n", cur[0]);
 
2582
      tee_fprintf(PAGER,   "Description:\n%s", cur[1]);
 
2583
      if (cur[2] && *((char*)cur[2]))
 
2584
        tee_fprintf(PAGER, "Examples:\n%s", cur[2]);
 
2585
      tee_fprintf(PAGER,   "\n");
 
2586
      end_pager();
 
2587
    }
 
2588
    else if (num_fields >= 2 && num_rows)
 
2589
    {
 
2590
      init_pager();
 
2591
      char last_char= 0;
 
2592
 
 
2593
      int num_name= 0, num_cat= 0;
 
2594
 
 
2595
      if (num_fields == 2)
 
2596
      {
 
2597
        put_info("Many help items for your request exist.", INFO_INFO,0,0);
 
2598
        put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO,0,0);
 
2599
        num_name= 0;
 
2600
        num_cat= 1;
 
2601
      }
 
2602
      else if ((cur= mysql_fetch_row(result)))
 
2603
      {
 
2604
        tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
 
2605
        put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO,0,0);
 
2606
        num_name= 1;
 
2607
        num_cat= 2;
 
2608
        print_help_item(&cur,1,2,&last_char);
 
2609
      }
 
2610
 
 
2611
      while ((cur= mysql_fetch_row(result)))
 
2612
        print_help_item(&cur,num_name,num_cat,&last_char);
 
2613
      tee_fprintf(PAGER, "\n");
 
2614
      end_pager();
 
2615
    }
 
2616
    else
 
2617
    {
 
2618
      put_info("\nNothing found", INFO_INFO,0,0);
 
2619
      put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO,0,0);
 
2620
    }
 
2621
  }
 
2622
 
 
2623
err:
 
2624
  mysql_free_result(result);
 
2625
  return error;
 
2626
}
 
2627
 
2762
2628
static int
2763
 
com_help(string *buffer, const char *)
 
2629
com_help(GString *buffer __attribute__((unused)),
 
2630
         char *line __attribute__((unused)))
2764
2631
{
2765
 
  int i, j;
2766
 
  char buff[32], *end;
2767
 
  std::vector<char> output_buff;
2768
 
  output_buff.resize(512);
 
2632
  register int i, j;
 
2633
  char * help_arg= strchr(line,' '), buff[32], *end;
 
2634
  if (help_arg)
 
2635
  {
 
2636
    while (my_isspace(charset_info,*help_arg))
 
2637
      help_arg++;
 
2638
    if (*help_arg)
 
2639
      return com_server_help(buffer,line,help_arg);
 
2640
  }
2769
2641
 
2770
 
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
 
2642
  put_info("List of all Drizzle commands:", INFO_INFO,0,0);
2771
2643
  if (!named_cmds)
2772
 
  {
2773
 
    snprintf(&output_buff[0], output_buff.size(),
2774
 
             _("Note that all text commands must be first on line and end with '%s' or \\g"),
2775
 
             delimiter);
2776
 
    put_info(&output_buff[0], INFO_INFO, 0, 0);
2777
 
  }
2778
 
  for (i = 0; commands[i].getName(); i++)
2779
 
  {
2780
 
    end= strcpy(buff, commands[i].getName());
2781
 
    end+= strlen(commands[i].getName());
2782
 
    for (j= (int)strlen(commands[i].getName()); j < 10; j++)
2783
 
      end= strcpy(end, " ")+1;
 
2644
    put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO,0,0);
 
2645
  for (i = 0; commands[i].name; i++)
 
2646
  {
 
2647
    end= strmov(buff, commands[i].name);
 
2648
    for (j= (int)strlen(commands[i].name); j < 10; j++)
 
2649
      end= strmov(end, " ");
2784
2650
    if (commands[i].func)
2785
2651
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2786
 
                  commands[i].getCmdChar(), _(commands[i].getDoc()));
 
2652
                  commands[i].cmd_char, commands[i].doc);
2787
2653
  }
2788
 
  tee_fprintf(stdout, "\n");
2789
 
  buffer->clear();
 
2654
  if (connected && mysql_get_server_version(&mysql) >= 40100)
 
2655
    put_info("\nFor server side help, type 'help contents'\n", INFO_INFO,0,0);
2790
2656
  return 0;
2791
2657
}
2792
2658
 
2793
2659
 
2794
2660
static int
2795
 
com_clear(string *buffer, const char *)
 
2661
com_clear(GString *buffer,char *line __attribute__((unused)))
2796
2662
{
2797
 
  if (status.getAddToHistory())
 
2663
  if (status.add_to_history)
2798
2664
    fix_history(buffer);
2799
 
  buffer->clear();
 
2665
  g_string_truncate(buffer, 0);
2800
2666
  return 0;
2801
2667
}
2802
2668
 
 
2669
static int
 
2670
com_charset(GString *buffer __attribute__((unused)), char *line)
 
2671
{
 
2672
  char buff[256], *param;
 
2673
  CHARSET_INFO * new_cs;
 
2674
  strmake(buff, line, sizeof(buff) - 1);
 
2675
  param= get_arg(buff, 0);
 
2676
  if (!param || !*param)
 
2677
  {
 
2678
    return put_info("Usage: \\C char_setname | charset charset_name",
 
2679
                    INFO_ERROR, 0, 0);
 
2680
  }
 
2681
  new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
 
2682
  if (new_cs)
 
2683
  {
 
2684
    charset_info= new_cs;
 
2685
    mysql_set_character_set(&mysql, charset_info->csname);
 
2686
    default_charset= (char *)charset_info->csname;
 
2687
    default_charset_used= 1;
 
2688
    put_info("Charset changed", INFO_INFO,0,0);
 
2689
  }
 
2690
  else put_info("Charset is not found", INFO_INFO,0,0);
 
2691
  return 0;
 
2692
}
2803
2693
 
2804
2694
/*
2805
2695
  Execute command
2808
2698
  1  if fatal error
2809
2699
*/
2810
2700
static int
2811
 
com_go(string *buffer, const char *)
 
2701
com_go(GString *buffer,
 
2702
       char *line __attribute__((unused)))
2812
2703
{
2813
2704
  char          buff[200]; /* about 110 chars used so far */
2814
 
  drizzle_result_st result;
2815
 
  drizzle_return_t ret;
2816
 
  uint32_t      warnings= 0;
2817
 
  boost::posix_time::ptime timer;
2818
 
  uint32_t      error= 0;
2819
 
  uint32_t      error_code= 0;
 
2705
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
 
2706
  MYSQL_RES     *result;
 
2707
  ulong         timer, warnings= 0;
 
2708
  uint          error= 0;
2820
2709
  int           err= 0;
2821
2710
 
2822
2711
  interrupted_query= 0;
2824
2713
  /* Remove garbage for nicer messages */
2825
2714
  remove_cntrl(buffer);
2826
2715
 
2827
 
  if (buffer->empty())
 
2716
  if (buffer->len == 0)
2828
2717
  {
2829
2718
    // Ignore empty quries
2830
 
    if (status.getBatch())
 
2719
    if (status.batch)
2831
2720
      return 0;
2832
 
    return put_info(_("No query specified\n"),INFO_ERROR,0,0);
 
2721
    return put_info("No query specified\n",INFO_ERROR,0,0);
2833
2722
 
2834
2723
  }
2835
2724
  if (!connected && reconnect())
2836
2725
  {
2837
2726
    // Remove query on error
2838
 
    buffer->clear();
 
2727
    g_string_truncate(buffer, 0);
2839
2728
    return opt_reconnect ? -1 : 1;          // Fatal error
2840
2729
  }
2841
2730
  if (verbose)
2842
2731
    (void) com_print(buffer, 0);
2843
2732
 
2844
2733
  if (skip_updates &&
2845
 
      ((buffer->length() < 4) || (buffer->find( "SET ") != 0)))
 
2734
      ((buffer->len < 4)
 
2735
      || g_string_equal(g_string_new_len(buffer->str,4),
 
2736
                        g_string_new("SET "))))
2846
2737
  {
2847
 
    (void) put_info(_("Ignoring query to other database"),INFO_INFO,0,0);
 
2738
    (void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2848
2739
    return 0;
2849
2740
  }
2850
2741
 
2851
2742
  timer=start_timer();
2852
2743
  executing_query= 1;
2853
 
  error= drizzleclient_real_query_for_lazy(buffer->c_str(),buffer->length(),&result, &error_code);
 
2744
  error= mysql_real_query_for_lazy(buffer->str,buffer->len);
2854
2745
 
2855
 
  if (status.getAddToHistory())
 
2746
  if (status.add_to_history)
2856
2747
  {
2857
 
    buffer->append(vertical ? "\\G" : delimiter);
 
2748
    g_string_append(buffer, vertical ? "\\G" : delimiter);
2858
2749
    /* Append final command onto history */
2859
2750
    fix_history(buffer);
2860
2751
  }
2861
2752
 
2862
 
  buffer->clear();
 
2753
  g_string_truncate(buffer, 0);
2863
2754
 
2864
2755
  if (error)
2865
2756
    goto end;
2870
2761
 
2871
2762
    if (quick)
2872
2763
    {
2873
 
      if (drizzle_column_buffer(&result) != DRIZZLE_RETURN_OK)
 
2764
      if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
2874
2765
      {
2875
 
        error= put_error(&con, &result);
 
2766
        error= put_error(&mysql);
2876
2767
        goto end;
2877
2768
      }
2878
2769
    }
2879
2770
    else
2880
2771
    {
2881
 
      error= drizzleclient_store_result_for_lazy(&result);
 
2772
      error= mysql_store_result_for_lazy(&result);
2882
2773
      if (error)
2883
2774
        goto end;
2884
2775
    }
2885
2776
 
2886
 
    string time_buff("");
2887
2777
    if (verbose >= 3 || !opt_silent)
2888
 
      drizzle_end_timer(timer,time_buff);
 
2778
      mysql_end_timer(timer,time_buff);
 
2779
    else
 
2780
      time_buff[0]= '\0';
2889
2781
 
2890
2782
    /* Every branch must truncate  buff . */
2891
 
    if (drizzle_result_column_count(&result) > 0)
 
2783
    if (result)
2892
2784
    {
2893
 
      if (!quick && drizzle_result_row_count(&result) == 0 &&
2894
 
          !column_types_flag)
 
2785
      if (!mysql_num_rows(result) && ! quick && !column_types_flag)
2895
2786
      {
2896
 
        strcpy(buff, _("Empty set"));
 
2787
        strmov(buff, "Empty set");
 
2788
        if (opt_xml)
 
2789
        {
 
2790
          /*
 
2791
            We must print XML header and footer
 
2792
            to produce a well-formed XML even if
 
2793
            the result set is empty (Bug#27608).
 
2794
          */
 
2795
          init_pager();
 
2796
          print_table_data_xml(result);
 
2797
          end_pager();
 
2798
        }
2897
2799
      }
2898
2800
      else
2899
2801
      {
2900
2802
        init_pager();
2901
 
        if (vertical || (auto_vertical_output &&
2902
 
                         (terminal_width < get_result_width(&result))))
2903
 
          print_table_data_vertically(&result);
 
2803
        if (opt_html)
 
2804
          print_table_data_html(result);
 
2805
        else if (opt_xml)
 
2806
          print_table_data_xml(result);
 
2807
        else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
 
2808
          print_table_data_vertically(result);
2904
2809
        else if (opt_silent && verbose <= 2 && !output_tables)
2905
 
          print_tab_data(&result);
 
2810
          print_tab_data(result);
2906
2811
        else
2907
 
          print_table_data(&result);
2908
 
        sprintf(buff,
2909
 
                ngettext("%ld row in set","%ld rows in set",
2910
 
                         (long) drizzle_result_row_count(&result)),
2911
 
                (long) drizzle_result_row_count(&result));
 
2812
          print_table_data(result);
 
2813
        sprintf(buff,"%ld %s in set",
 
2814
                (long) mysql_num_rows(result),
 
2815
                (long) mysql_num_rows(result) == 1 ? "row" : "rows");
2912
2816
        end_pager();
2913
 
        if (drizzle_result_error_code(&result))
2914
 
          error= put_error(&con, &result);
 
2817
        if (mysql_errno(&mysql))
 
2818
          error= put_error(&mysql);
2915
2819
      }
2916
2820
    }
2917
 
    else if (drizzle_result_affected_rows(&result) == ~(uint64_t) 0)
2918
 
      strcpy(buff,_("Query OK"));
 
2821
    else if (mysql_affected_rows(&mysql) == ~(uint64_t) 0)
 
2822
      strmov(buff,"Query OK");
2919
2823
    else
2920
 
      sprintf(buff, ngettext("Query OK, %ld row affected",
2921
 
                             "Query OK, %ld rows affected",
2922
 
                             (long) drizzle_result_affected_rows(&result)),
2923
 
              (long) drizzle_result_affected_rows(&result));
 
2824
      sprintf(buff,"Query OK, %ld %s affected",
 
2825
              (long) mysql_affected_rows(&mysql),
 
2826
              (long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows");
2924
2827
 
2925
 
    pos= strchr(buff, '\0');
2926
 
    if ((warnings= drizzle_result_warning_count(&result)))
 
2828
    pos=strend(buff);
 
2829
    if ((warnings= mysql_warning_count(&mysql)))
2927
2830
    {
2928
2831
      *pos++= ',';
2929
2832
      *pos++= ' ';
2930
 
      char warnings_buff[20];
2931
 
      memset(warnings_buff,0,20);
2932
 
      sprintf(warnings_buff, "%d", warnings);
2933
 
      strcpy(pos, warnings_buff);
2934
 
      pos+= strlen(warnings_buff);
2935
 
      pos= strcpy(pos, " warning")+8;
 
2833
      pos=int10_to_str(warnings, pos, 10);
 
2834
      pos=strmov(pos, " warning");
2936
2835
      if (warnings != 1)
2937
2836
        *pos++= 's';
2938
2837
    }
2939
 
    strcpy(pos, time_buff.c_str());
 
2838
    strmov(pos, time_buff);
2940
2839
    put_info(buff,INFO_RESULT,0,0);
2941
 
    if (strcmp(drizzle_result_info(&result), ""))
2942
 
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
2943
 
    put_info("",INFO_RESULT,0,0);      // Empty row
 
2840
    if (mysql_info(&mysql))
 
2841
      put_info(mysql_info(&mysql),INFO_RESULT,0,0);
 
2842
    put_info("",INFO_RESULT,0,0);                       // Empty row
2944
2843
 
2945
 
    if (unbuffered)
 
2844
    if (result && !mysql_eof(result))   /* Something wrong when using quick */
 
2845
      error= put_error(&mysql);
 
2846
    else if (unbuffered)
2946
2847
      fflush(stdout);
2947
 
    drizzle_result_free(&result);
2948
 
 
2949
 
    if (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS)
2950
 
    {
2951
 
      if (drizzle_result_read(&con, &result, &ret) == NULL ||
2952
 
          ret != DRIZZLE_RETURN_OK)
2953
 
      {
2954
 
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
2955
 
        {
2956
 
          error_code= drizzle_result_error_code(&result);
2957
 
          drizzle_result_free(&result);
2958
 
        }
2959
 
 
2960
 
        error= put_error(&con, NULL);
2961
 
        goto end;
2962
 
      }
2963
 
    }
2964
 
 
2965
 
  } while (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_MORE_RESULTS_EXISTS);
 
2848
    mysql_free_result(result);
 
2849
  } while (!(err= mysql_next_result(&mysql)));
2966
2850
  if (err >= 1)
2967
 
    error= put_error(&con, NULL);
 
2851
    error= put_error(&mysql);
2968
2852
 
2969
2853
end:
2970
2854
 
2971
2855
  /* Show warnings if any or error occured */
2972
2856
  if (show_warnings == 1 && (warnings >= 1 || error))
2973
 
    print_warnings(error_code);
 
2857
    print_warnings();
2974
2858
 
2975
 
  if (!error && !status.getBatch() &&
2976
 
      drizzle_con_status(&con) & DRIZZLE_CON_STATUS_DB_DROPPED)
2977
 
  {
 
2859
  if (!error && !status.batch &&
 
2860
      (mysql.server_status & SERVER_STATUS_DB_DROPPED))
2978
2861
    get_current_db();
2979
 
  }
2980
2862
 
2981
2863
  executing_query= 0;
2982
 
  return error;        /* New command follows */
 
2864
  return error;                         /* New command follows */
2983
2865
}
2984
2866
 
2985
2867
 
2987
2869
{
2988
2870
  if (!opt_nopager)
2989
2871
  {
2990
 
    if (!(PAGER= popen(pager.c_str(), "w")))
 
2872
    if (!(PAGER= popen(pager, "w")))
2991
2873
    {
2992
 
      tee_fprintf(stdout,_( "popen() failed! defaulting PAGER to stdout!\n"));
 
2874
      tee_fprintf(stdout, "popen() failed! defaulting PAGER to stdout!\n");
2993
2875
      PAGER= stdout;
2994
2876
    }
2995
2877
  }
3009
2891
  FILE* new_outfile;
3010
2892
  if (opt_outfile)
3011
2893
    end_tee();
3012
 
  if (!(new_outfile= fopen(file_name, "a")))
 
2894
  if (!(new_outfile= my_fopen(file_name, O_APPEND | O_WRONLY, MYF(MY_WME))))
3013
2895
  {
3014
 
    tee_fprintf(stdout, _("Error logging to file '%s'\n"), file_name);
 
2896
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
3015
2897
    return;
3016
2898
  }
3017
2899
  OUTFILE = new_outfile;
3018
 
  outfile.assign(file_name);
3019
 
  tee_fprintf(stdout, _("Logging to file '%s'\n"), file_name);
 
2900
  strmake(outfile, file_name, FN_REFLEN-1);
 
2901
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
3020
2902
  opt_outfile= 1;
3021
 
 
3022
2903
  return;
3023
2904
}
3024
2905
 
3025
2906
 
3026
2907
static void end_tee()
3027
2908
{
3028
 
  fclose(OUTFILE);
 
2909
  my_fclose(OUTFILE, MYF(0));
3029
2910
  OUTFILE= 0;
3030
2911
  opt_outfile= 0;
3031
2912
  return;
3033
2914
 
3034
2915
 
3035
2916
static int
3036
 
com_ego(string *buffer,const char *line)
 
2917
com_ego(GString *buffer,char *line)
3037
2918
{
3038
2919
  int result;
3039
2920
  bool oldvertical=vertical;
3044
2925
}
3045
2926
 
3046
2927
 
3047
 
static const char *fieldtype2str(drizzle_column_type_t type)
 
2928
static const char *fieldtype2str(enum enum_field_types type)
3048
2929
{
3049
2930
  switch (type) {
3050
 
    case DRIZZLE_COLUMN_TYPE_BLOB:        return "BLOB";
3051
 
    case DRIZZLE_COLUMN_TYPE_DATE:        return "DATE";
3052
 
    case DRIZZLE_COLUMN_TYPE_DATETIME:    return "DATETIME";
3053
 
    case DRIZZLE_COLUMN_TYPE_NEWDECIMAL:  return "DECIMAL";
3054
 
    case DRIZZLE_COLUMN_TYPE_DOUBLE:      return "DOUBLE";
3055
 
    case DRIZZLE_COLUMN_TYPE_ENUM:        return "ENUM";
3056
 
    case DRIZZLE_COLUMN_TYPE_LONG:        return "LONG";
3057
 
    case DRIZZLE_COLUMN_TYPE_LONGLONG:    return "LONGLONG";
3058
 
    case DRIZZLE_COLUMN_TYPE_NULL:        return "NULL";
3059
 
    case DRIZZLE_COLUMN_TYPE_TIMESTAMP:   return "TIMESTAMP";
 
2931
    case MYSQL_TYPE_BLOB:        return "BLOB";
 
2932
    case MYSQL_TYPE_NEWDATE:        return "DATE";
 
2933
    case MYSQL_TYPE_DATETIME:    return "DATETIME";
 
2934
    case MYSQL_TYPE_NEWDECIMAL:  return "DECIMAL";
 
2935
    case MYSQL_TYPE_DOUBLE:      return "DOUBLE";
 
2936
    case MYSQL_TYPE_ENUM:        return "ENUM";
 
2937
    case MYSQL_TYPE_LONG:        return "LONG";
 
2938
    case MYSQL_TYPE_LONGLONG:    return "LONGLONG";
 
2939
    case MYSQL_TYPE_NULL:        return "NULL";
 
2940
    case MYSQL_TYPE_SET:         return "SET";
 
2941
    case MYSQL_TYPE_SHORT:       return "SHORT";
 
2942
    case MYSQL_TYPE_STRING:      return "STRING";
 
2943
    case MYSQL_TYPE_TIME:        return "TIME";
 
2944
    case MYSQL_TYPE_TIMESTAMP:   return "TIMESTAMP";
 
2945
    case MYSQL_TYPE_TINY:        return "TINY";
 
2946
    case MYSQL_TYPE_VAR_STRING:  return "VAR_STRING";
 
2947
    case MYSQL_TYPE_YEAR:        return "YEAR";
3060
2948
    default:                     return "?-unknown-?";
3061
2949
  }
3062
2950
}
3063
2951
 
3064
 
static char *fieldflags2str(uint32_t f) {
 
2952
static char *fieldflags2str(uint f) {
3065
2953
  static char buf[1024];
3066
2954
  char *s=buf;
3067
2955
  *s=0;
3068
2956
#define ff2s_check_flag(X)                                              \
3069
 
  if (f & DRIZZLE_COLUMN_FLAGS_ ## X) { s=strcpy(s, # X " ")+strlen(# X " "); \
3070
 
                        f &= ~ DRIZZLE_COLUMN_FLAGS_ ## X; }
 
2957
  if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
3071
2958
  ff2s_check_flag(NOT_NULL);
3072
2959
  ff2s_check_flag(PRI_KEY);
3073
2960
  ff2s_check_flag(UNIQUE_KEY);
3074
2961
  ff2s_check_flag(MULTIPLE_KEY);
3075
2962
  ff2s_check_flag(BLOB);
3076
2963
  ff2s_check_flag(UNSIGNED);
 
2964
  ff2s_check_flag(ZEROFILL);
3077
2965
  ff2s_check_flag(BINARY);
3078
2966
  ff2s_check_flag(ENUM);
3079
2967
  ff2s_check_flag(AUTO_INCREMENT);
3093
2981
}
3094
2982
 
3095
2983
static void
3096
 
print_field_types(drizzle_result_st *result)
 
2984
print_field_types(MYSQL_RES *result)
3097
2985
{
3098
 
  drizzle_column_st   *field;
3099
 
  uint32_t i=0;
 
2986
  MYSQL_FIELD   *field;
 
2987
  uint i=0;
3100
2988
 
3101
 
  while ((field = drizzle_column_next(result)))
 
2989
  while ((field = mysql_fetch_field(result)))
3102
2990
  {
3103
 
    tee_fprintf(PAGER, _("Field %3u:  `%s`\n"
 
2991
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
3104
2992
                "Catalog:    `%s`\n"
3105
 
                "Schema:     `%s`\n"
 
2993
                "Database:   `%s`\n"
3106
2994
                "Table:      `%s`\n"
3107
2995
                "Org_table:  `%s`\n"
3108
 
                "Type:       UTF-8\n"
 
2996
                "Type:       %s\n"
3109
2997
                "Collation:  %s (%u)\n"
3110
2998
                "Length:     %lu\n"
3111
2999
                "Max_length: %lu\n"
3112
3000
                "Decimals:   %u\n"
3113
 
                "Flags:      %s\n\n"),
 
3001
                "Flags:      %s\n\n",
3114
3002
                ++i,
3115
 
                drizzle_column_name(field), drizzle_column_catalog(field),
3116
 
                drizzle_column_db(field), drizzle_column_table(field),
3117
 
                drizzle_column_orig_table(field),
3118
 
                fieldtype2str(drizzle_column_type(field)),
3119
 
                drizzle_column_charset(field), drizzle_column_size(field),
3120
 
                drizzle_column_max_size(field), drizzle_column_decimals(field),
3121
 
                fieldflags2str(drizzle_column_flags(field)));
 
3003
                field->name, field->catalog, field->db, field->table,
 
3004
                field->org_table, fieldtype2str(field->type),
 
3005
                get_charset_name(field->charsetnr), field->charsetnr,
 
3006
                field->length, field->max_length, field->decimals,
 
3007
                fieldflags2str(field->flags));
3122
3008
  }
3123
3009
  tee_puts("", PAGER);
3124
3010
}
3125
3011
 
 
3012
 
3126
3013
static void
3127
 
print_table_data(drizzle_result_st *result)
 
3014
print_table_data(MYSQL_RES *result)
3128
3015
{
3129
 
  drizzle_row_t cur;
3130
 
  drizzle_return_t ret;
3131
 
  drizzle_column_st *field;
3132
 
  std::vector<bool> num_flag;
3133
 
  std::vector<bool> boolean_flag;
3134
 
  std::vector<bool> ansi_boolean_flag;
3135
 
  string separator;
3136
 
 
3137
 
  separator.reserve(256);
3138
 
 
3139
 
  num_flag.resize(drizzle_result_column_count(result));
3140
 
  boolean_flag.resize(drizzle_result_column_count(result));
3141
 
  ansi_boolean_flag.resize(drizzle_result_column_count(result));
 
3016
  GString       *separator = g_string_sized_new(256);
 
3017
  MYSQL_ROW     cur;
 
3018
  MYSQL_FIELD   *field;
 
3019
  bool          *num_flag;
 
3020
 
 
3021
  num_flag=(bool*) my_malloc(sizeof(bool)*mysql_num_fields(result),
 
3022
                             MYF(MY_WME));
3142
3023
  if (column_types_flag)
3143
3024
  {
3144
3025
    print_field_types(result);
3145
 
    if (!drizzle_result_row_count(result))
 
3026
    if (!mysql_num_rows(result))
3146
3027
      return;
3147
 
    drizzle_column_seek(result,0);
 
3028
    mysql_field_seek(result,0);
3148
3029
  }
3149
 
  separator.append("+");
3150
 
  while ((field = drizzle_column_next(result)))
 
3030
  separator = g_string_append_c(separator, '+');
 
3031
  while ((field = mysql_fetch_field(result)))
3151
3032
  {
3152
 
    uint32_t x, length= 0;
3153
 
 
3154
 
    if (column_names)
3155
 
    {
3156
 
      uint32_t name_length= strlen(drizzle_column_name(field));
3157
 
 
3158
 
      /* Check if the max_byte value is really the maximum in terms
3159
 
         of visual length since multibyte characters can affect the
3160
 
         length of the separator. */
3161
 
      length= drizzled::utf8::char_length(drizzle_column_name(field));
3162
 
 
3163
 
      if (name_length == drizzle_column_max_size(field))
3164
 
      {
3165
 
        if (length < drizzle_column_max_size(field))
3166
 
          drizzle_column_set_max_size(field, length);
3167
 
      }
3168
 
      else
3169
 
      {
3170
 
        length= name_length;
3171
 
      }
3172
 
    }
3173
 
  
 
3033
    uint length= column_names ? field->name_length : 0;
3174
3034
    if (quick)
3175
 
      length=max(length,drizzle_column_size(field));
 
3035
      length=max(length,field->length);
3176
3036
    else
3177
 
      length=max(length,(uint32_t)drizzle_column_max_size(field));
3178
 
    if (length < 4 &&
3179
 
        !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
3180
 
    {
 
3037
      length=max(length,field->max_length);
 
3038
    if (length < 4 && !IS_NOT_NULL(field->flags))
3181
3039
      // Room for "NULL"
3182
3040
      length=4;
3183
 
    }
3184
 
    if ((length < 5) and 
3185
 
      (server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3186
 
      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY) and
3187
 
      (drizzle_column_type(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3188
 
    {
3189
 
      // Room for "FALSE"
3190
 
      length= 5;
3191
 
    }
3192
 
    drizzle_column_set_max_size(field, length);
3193
 
 
 
3041
    field->max_length=length;
 
3042
    uint x;
3194
3043
    for (x=0; x< (length+2); x++)
3195
 
      separator.append("-");
3196
 
    separator.append("+");
 
3044
      g_string_append_c(separator, '-');
 
3045
    g_string_append_c(separator, '+');
3197
3046
  }
 
3047
  // End marker for \0
 
3048
  // TODO: Huh? Do we need this with GString?
 
3049
  g_string_append_c(separator, '\0');
3198
3050
 
3199
 
  tee_puts((char*) separator.c_str(), PAGER);
 
3051
  tee_puts((char*) separator->str, PAGER);
3200
3052
  if (column_names)
3201
3053
  {
3202
 
    drizzle_column_seek(result,0);
 
3054
    mysql_field_seek(result,0);
3203
3055
    (void) tee_fputs("|", PAGER);
3204
 
    for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
 
3056
    for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
3205
3057
    {
3206
 
      uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
3207
 
      uint32_t numcells= drizzled::utf8::char_length(drizzle_column_name(field));
3208
 
      uint32_t display_length= drizzle_column_max_size(field) + name_length -
3209
 
                               numcells;
 
3058
      uint name_length= (uint) strlen(field->name);
 
3059
      uint numcells= charset_info->cset->numcells(charset_info,
 
3060
                                                  field->name,
 
3061
                                                  field->name + name_length);
 
3062
      uint display_length= field->max_length + name_length - numcells;
3210
3063
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3211
3064
                                             MAX_COLUMN_LENGTH),
3212
 
                  drizzle_column_name(field));
3213
 
      num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
3214
 
                      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_NEWDECIMAL));
3215
 
      if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3216
 
        (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3217
 
      {
3218
 
        if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3219
 
        {
3220
 
          ansi_boolean_flag[off]= true;
3221
 
        }
3222
 
        else
3223
 
        {
3224
 
          ansi_boolean_flag[off]= false;
3225
 
        }
3226
 
        boolean_flag[off]= true;
3227
 
        num_flag[off]= false;
3228
 
      }
3229
 
      else
3230
 
      {
3231
 
        boolean_flag[off]= false;
3232
 
      }
 
3065
                  field->name);
 
3066
      num_flag[off]= IS_NUM(field->type);
3233
3067
    }
3234
3068
    (void) tee_fputs("\n", PAGER);
3235
 
    tee_puts((char*) separator.c_str(), PAGER);
 
3069
    tee_puts((char*) separator->str, PAGER);
3236
3070
  }
3237
3071
 
3238
 
  while (1)
 
3072
  while ((cur= mysql_fetch_row(result)))
3239
3073
  {
3240
 
    if (quick)
3241
 
    {
3242
 
      cur= drizzle_row_buffer(result, &ret);
3243
 
      if (ret != DRIZZLE_RETURN_OK)
3244
 
      {
3245
 
        (void)put_error(&con, result);
3246
 
        break;
3247
 
      }
3248
 
    }
3249
 
    else
3250
 
      cur= drizzle_row_next(result);
3251
 
 
3252
 
    if (cur == NULL || interrupted_query)
 
3074
    if (interrupted_query)
3253
3075
      break;
3254
 
 
3255
 
    size_t *lengths= drizzle_row_field_sizes(result);
 
3076
    uint32_t *lengths= mysql_fetch_lengths(result);
3256
3077
    (void) tee_fputs("| ", PAGER);
3257
 
    drizzle_column_seek(result, 0);
3258
 
    for (uint32_t off= 0; off < drizzle_result_column_count(result); off++)
 
3078
    mysql_field_seek(result, 0);
 
3079
    for (uint off= 0; off < mysql_num_fields(result); off++)
3259
3080
    {
3260
3081
      const char *buffer;
3261
 
      uint32_t data_length;
3262
 
      uint32_t field_max_length;
3263
 
      uint32_t visible_length;
3264
 
      uint32_t extra_padding;
 
3082
      uint data_length;
 
3083
      uint field_max_length;
 
3084
      uint visible_length;
 
3085
      uint extra_padding;
3265
3086
 
3266
3087
      if (cur[off] == NULL)
3267
3088
      {
3268
3089
        buffer= "NULL";
3269
3090
        data_length= 4;
3270
3091
      }
3271
 
      else if (boolean_flag[off])
3272
 
      {
3273
 
        if (strncmp(cur[off],"1", 1) == 0)
3274
 
        {
3275
 
          if (ansi_boolean_flag[off])
3276
 
          {
3277
 
            buffer= "YES";
3278
 
            data_length= 3;
3279
 
          }
3280
 
          else
3281
 
          {
3282
 
            buffer= "TRUE";
3283
 
            data_length= 4;
3284
 
          }
3285
 
        }
3286
 
        else
3287
 
        {
3288
 
          if (ansi_boolean_flag[off])
3289
 
          {
3290
 
            buffer= "NO";
3291
 
            data_length= 2;
3292
 
          }
3293
 
          else
3294
 
          {
3295
 
            buffer= "FALSE";
3296
 
            data_length= 5;
3297
 
          }
3298
 
        }
3299
 
      }
3300
3092
      else
3301
3093
      {
3302
3094
        buffer= cur[off];
3303
 
        data_length= (uint32_t) lengths[off];
 
3095
        data_length= (uint) lengths[off];
3304
3096
      }
3305
3097
 
3306
 
      field= drizzle_column_next(result);
3307
 
      field_max_length= drizzle_column_max_size(field);
 
3098
      field= mysql_fetch_field(result);
 
3099
      field_max_length= field->max_length;
3308
3100
 
3309
3101
      /*
3310
3102
        How many text cells on the screen will this string span?  If it contains
3314
3106
        We need to find how much screen real-estate we will occupy to know how
3315
3107
        many extra padding-characters we should send with the printing function.
3316
3108
      */
3317
 
      visible_length= drizzled::utf8::char_length(buffer);
 
3109
      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
3318
3110
      extra_padding= data_length - visible_length;
3319
3111
 
3320
3112
      if (field_max_length > MAX_COLUMN_LENGTH)
3321
 
        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, false);
 
3113
        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
3322
3114
      else
3323
3115
      {
3324
3116
        if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
3325
 
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, true);
 
3117
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
3326
3118
        else
3327
3119
          tee_print_sized_data(buffer, data_length,
3328
 
                               field_max_length+extra_padding, false);
 
3120
                               field_max_length+extra_padding, FALSE);
3329
3121
      }
3330
3122
      tee_fputs(" | ", PAGER);
3331
3123
    }
3332
3124
    (void) tee_fputs("\n", PAGER);
3333
 
    if (quick)
3334
 
      drizzle_row_free(result, cur);
3335
3125
  }
3336
 
  tee_puts(separator.c_str(), PAGER);
 
3126
  tee_puts(separator->str, PAGER);
 
3127
  my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
3337
3128
}
3338
3129
 
3339
3130
/**
3352
3143
 
3353
3144
   @returns  number of character positions to be used, at most
3354
3145
*/
3355
 
static int get_field_disp_length(drizzle_column_st *field)
 
3146
static int get_field_disp_length(MYSQL_FIELD *field)
3356
3147
{
3357
 
  uint32_t length= column_names ? strlen(drizzle_column_name(field)) : 0;
 
3148
  uint length= column_names ? field->name_length : 0;
3358
3149
 
3359
3150
  if (quick)
3360
 
    length= max(length, drizzle_column_size(field));
 
3151
    length= max(length, field->length);
3361
3152
  else
3362
 
    length= max(length, (uint32_t)drizzle_column_max_size(field));
 
3153
    length= max(length, field->max_length);
3363
3154
 
3364
 
  if (length < 4 &&
3365
 
    !(drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_NOT_NULL))
3366
 
  {
3367
 
    length= 4;        /* Room for "NULL" */
3368
 
  }
 
3155
  if (length < 4 && !IS_NOT_NULL(field->flags))
 
3156
    length= 4;                          /* Room for "NULL" */
3369
3157
 
3370
3158
  return length;
3371
3159
}
3378
3166
 
3379
3167
   @returns  The max number of characters in any row of this result
3380
3168
*/
3381
 
static int get_result_width(drizzle_result_st *result)
 
3169
static int get_result_width(MYSQL_RES *result)
3382
3170
{
3383
3171
  unsigned int len= 0;
3384
 
  drizzle_column_st *field;
3385
 
  uint16_t offset;
 
3172
  MYSQL_FIELD *field;
 
3173
  MYSQL_FIELD_OFFSET offset;
3386
3174
 
3387
 
  offset= drizzle_column_current(result);
 
3175
  offset= mysql_field_tell(result);
3388
3176
  assert(offset == 0);
3389
3177
 
3390
 
  while ((field= drizzle_column_next(result)) != NULL)
 
3178
  while ((field= mysql_fetch_field(result)) != NULL)
3391
3179
    len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
3392
3180
 
3393
 
  (void) drizzle_column_seek(result, offset);
 
3181
  (void) mysql_field_seek(result, offset);
3394
3182
 
3395
3183
  return len + 1; /* plus final bar. */
3396
3184
}
3426
3214
 
3427
3215
 
3428
3216
static void
3429
 
print_table_data_vertically(drizzle_result_st *result)
3430
 
{
3431
 
  drizzle_row_t cur;
3432
 
  drizzle_return_t ret;
3433
 
  uint32_t max_length=0;
3434
 
  drizzle_column_st *field;
3435
 
 
3436
 
  while ((field = drizzle_column_next(result)))
3437
 
  {
3438
 
    uint32_t length= strlen(drizzle_column_name(field));
 
3217
print_table_data_html(MYSQL_RES *result)
 
3218
{
 
3219
  MYSQL_ROW     cur;
 
3220
  MYSQL_FIELD   *field;
 
3221
 
 
3222
  mysql_field_seek(result,0);
 
3223
  (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
 
3224
  if (column_names)
 
3225
  {
 
3226
    while((field = mysql_fetch_field(result)))
 
3227
    {
 
3228
      tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
 
3229
                                         (field->name[0] ? field->name :
 
3230
                                          " &nbsp; ") : "NULL"));
 
3231
    }
 
3232
    (void) tee_fputs("</TR>", PAGER);
 
3233
  }
 
3234
  while ((cur = mysql_fetch_row(result)))
 
3235
  {
 
3236
    if (interrupted_query)
 
3237
      break;
 
3238
    uint32_t *lengths=mysql_fetch_lengths(result);
 
3239
    (void) tee_fputs("<TR>", PAGER);
 
3240
    for (uint32_t i= 0; i < mysql_num_fields(result); i++)
 
3241
    {
 
3242
      (void) tee_fputs("<TD>", PAGER);
 
3243
      safe_put_field(cur[i],lengths[i]);
 
3244
      (void) tee_fputs("</TD>", PAGER);
 
3245
    }
 
3246
    (void) tee_fputs("</TR>", PAGER);
 
3247
  }
 
3248
  (void) tee_fputs("</TABLE>", PAGER);
 
3249
}
 
3250
 
 
3251
 
 
3252
static void
 
3253
print_table_data_xml(MYSQL_RES *result)
 
3254
{
 
3255
  MYSQL_ROW   cur;
 
3256
  MYSQL_FIELD *fields;
 
3257
 
 
3258
  mysql_field_seek(result,0);
 
3259
 
 
3260
  tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
 
3261
  xmlencode_print(glob_buffer->str, glob_buffer->len);
 
3262
  tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
 
3263
            PAGER);
 
3264
 
 
3265
  fields = mysql_fetch_fields(result);
 
3266
  while ((cur = mysql_fetch_row(result)))
 
3267
  {
 
3268
    if (interrupted_query)
 
3269
      break;
 
3270
    uint32_t *lengths=mysql_fetch_lengths(result);
 
3271
    (void) tee_fputs("\n  <row>\n", PAGER);
 
3272
    for (uint i=0; i < mysql_num_fields(result); i++)
 
3273
    {
 
3274
      tee_fprintf(PAGER, "\t<field name=\"");
 
3275
      xmlencode_print(fields[i].name, (uint) strlen(fields[i].name));
 
3276
      if (cur[i])
 
3277
      {
 
3278
        tee_fprintf(PAGER, "\">");
 
3279
        xmlencode_print(cur[i], lengths[i]);
 
3280
        tee_fprintf(PAGER, "</field>\n");
 
3281
      }
 
3282
      else
 
3283
        tee_fprintf(PAGER, "\" xsi:nil=\"true\" />\n");
 
3284
    }
 
3285
    (void) tee_fputs("  </row>\n", PAGER);
 
3286
  }
 
3287
  (void) tee_fputs("</resultset>\n", PAGER);
 
3288
}
 
3289
 
 
3290
 
 
3291
static void
 
3292
print_table_data_vertically(MYSQL_RES *result)
 
3293
{
 
3294
  MYSQL_ROW     cur;
 
3295
  uint          max_length=0;
 
3296
  MYSQL_FIELD   *field;
 
3297
 
 
3298
  while ((field = mysql_fetch_field(result)))
 
3299
  {
 
3300
    uint length= field->name_length;
3439
3301
    if (length > max_length)
3440
3302
      max_length= length;
3441
 
    drizzle_column_set_max_size(field, length);
 
3303
    field->max_length=length;
3442
3304
  }
3443
3305
 
3444
 
  for (uint32_t row_count=1;; row_count++)
 
3306
  mysql_field_seek(result,0);
 
3307
  for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
3445
3308
  {
3446
 
    if (quick)
3447
 
    {
3448
 
      cur= drizzle_row_buffer(result, &ret);
3449
 
      if (ret != DRIZZLE_RETURN_OK)
3450
 
      {
3451
 
        (void)put_error(&con, result);
3452
 
        break;
3453
 
      }
3454
 
    }
3455
 
    else
3456
 
      cur= drizzle_row_next(result);
3457
 
 
3458
 
    if (cur == NULL || interrupted_query)
 
3309
    if (interrupted_query)
3459
3310
      break;
3460
 
    drizzle_column_seek(result,0);
 
3311
    mysql_field_seek(result,0);
3461
3312
    tee_fprintf(PAGER,
3462
3313
                "*************************** %d. row ***************************\n", row_count);
3463
 
    for (uint32_t off=0; off < drizzle_result_column_count(result); off++)
 
3314
    for (uint off=0; off < mysql_num_fields(result); off++)
3464
3315
    {
3465
 
      field= drizzle_column_next(result);
3466
 
      tee_fprintf(PAGER, "%*s: ",(int) max_length,drizzle_column_name(field));
 
3316
      field= mysql_fetch_field(result);
 
3317
      tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
3467
3318
      tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
3468
3319
    }
3469
 
    if (quick)
3470
 
      drizzle_row_free(result, cur);
3471
3320
  }
3472
3321
}
3473
3322
 
3474
3323
 
3475
3324
/* print_warnings should be called right after executing a statement */
3476
3325
 
3477
 
static void print_warnings(uint32_t error_code)
 
3326
static void print_warnings()
3478
3327
{
3479
 
  const char *query;
3480
 
  drizzle_result_st result;
3481
 
  drizzle_row_t cur;
 
3328
  const char   *query;
 
3329
  MYSQL_RES    *result;
 
3330
  MYSQL_ROW    cur;
3482
3331
  uint64_t num_rows;
3483
 
  uint32_t new_code= 0;
3484
 
  FILE *out;
 
3332
  
 
3333
  /* Save current error before calling "show warnings" */
 
3334
  uint error= mysql_errno(&mysql);
3485
3335
 
3486
3336
  /* Get the warnings */
3487
3337
  query= "show warnings";
3488
 
  drizzleclient_real_query_for_lazy(query, strlen(query),&result,&new_code);
3489
 
  drizzleclient_store_result_for_lazy(&result);
 
3338
  mysql_real_query_for_lazy(query, strlen(query));
 
3339
  mysql_store_result_for_lazy(&result);
3490
3340
 
3491
3341
  /* Bail out when no warnings */
3492
 
  if (!(num_rows= drizzle_result_row_count(&result)))
 
3342
  if (!(num_rows= mysql_num_rows(result)))
3493
3343
    goto end;
3494
3344
 
3495
 
  cur= drizzle_row_next(&result);
 
3345
  cur= mysql_fetch_row(result);
3496
3346
 
3497
3347
  /*
3498
3348
    Don't print a duplicate of the current error.  It is possible for SHOW
3500
3350
    messages.  To be safe, skip printing the duplicate only if it is the only
3501
3351
    warning.
3502
3352
  */
3503
 
  if (!cur || (num_rows == 1 &&
3504
 
      error_code == (uint32_t) strtoul(cur[1], NULL, 10)))
3505
 
  {
 
3353
  if (!cur || (num_rows == 1 && error == (uint) strtoul(cur[1], NULL, 10)))
3506
3354
    goto end;
3507
 
  }
3508
3355
 
3509
3356
  /* Print the warnings */
3510
 
  if (status.getBatch()) 
3511
 
  {
3512
 
    out= stderr;
3513
 
  } 
3514
 
  else 
3515
 
  {
3516
 
    init_pager();
3517
 
    out= PAGER;
3518
 
  }
 
3357
  init_pager();
3519
3358
  do
3520
3359
  {
3521
 
    tee_fprintf(out, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3522
 
  } while ((cur= drizzle_row_next(&result)));
3523
 
 
3524
 
  if (not status.getBatch())
3525
 
    end_pager();
 
3360
    tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
 
3361
  } while ((cur= mysql_fetch_row(result)));
 
3362
  end_pager();
3526
3363
 
3527
3364
end:
3528
 
  drizzle_result_free(&result);
3529
 
}
3530
 
 
3531
 
 
3532
 
static void
3533
 
safe_put_field(const char *pos,uint32_t length)
 
3365
  mysql_free_result(result);
 
3366
}
 
3367
 
 
3368
 
 
3369
static const char *array_value(const char **array, char key)
 
3370
{
 
3371
  for (; *array; array+= 2)
 
3372
    if (**array == key)
 
3373
      return array[1];
 
3374
  return 0;
 
3375
}
 
3376
 
 
3377
 
 
3378
static void
 
3379
xmlencode_print(const char *src, uint length)
 
3380
{
 
3381
  if (!src)
 
3382
    tee_fputs("NULL", PAGER);
 
3383
  else
 
3384
  {
 
3385
    for (const char *p = src; *p && length; length--)
 
3386
    {
 
3387
      const char *t;
 
3388
      if ((t = array_value(xmlmeta, *p++)))
 
3389
        tee_fputs(t, PAGER);
 
3390
      else
 
3391
        tee_putc(*p, PAGER);
 
3392
    }
 
3393
  }
 
3394
}
 
3395
 
 
3396
 
 
3397
static void
 
3398
safe_put_field(const char *pos,ulong length)
3534
3399
{
3535
3400
  if (!pos)
3536
3401
    tee_fputs("NULL", PAGER);
3539
3404
    if (opt_raw_data)
3540
3405
      tee_fputs(pos, PAGER);
3541
3406
    else for (const char *end=pos+length ; pos != end ; pos++)
3542
 
    {
3543
 
      int l;
3544
 
      if ((l = drizzled::utf8::sequence_length(*pos)))
3545
 
      {
3546
 
        while (l--)
3547
 
          tee_putc(*pos++, PAGER);
3548
 
        pos--;
3549
 
        continue;
3550
 
      }
3551
 
      if (!*pos)
3552
 
        tee_fputs("\\0", PAGER); // This makes everything hard
3553
 
      else if (*pos == '\t')
3554
 
        tee_fputs("\\t", PAGER); // This would destroy tab format
3555
 
      else if (*pos == '\n')
3556
 
        tee_fputs("\\n", PAGER); // This too
3557
 
      else if (*pos == '\\')
3558
 
        tee_fputs("\\\\", PAGER);
3559
 
      else
3560
 
        tee_putc(*pos, PAGER);
3561
 
    }
 
3407
         {
 
3408
#ifdef USE_MB
 
3409
           int l;
 
3410
           if (use_mb(charset_info) &&
 
3411
               (l = my_ismbchar(charset_info, pos, end)))
 
3412
           {
 
3413
             while (l--)
 
3414
               tee_putc(*pos++, PAGER);
 
3415
             pos--;
 
3416
             continue;
 
3417
           }
 
3418
#endif
 
3419
           if (!*pos)
 
3420
             tee_fputs("\\0", PAGER); // This makes everything hard
 
3421
           else if (*pos == '\t')
 
3422
             tee_fputs("\\t", PAGER); // This would destroy tab format
 
3423
           else if (*pos == '\n')
 
3424
             tee_fputs("\\n", PAGER); // This too
 
3425
           else if (*pos == '\\')
 
3426
             tee_fputs("\\\\", PAGER);
 
3427
           else
 
3428
             tee_putc(*pos, PAGER);
 
3429
         }
3562
3430
  }
3563
3431
}
3564
3432
 
3565
3433
 
3566
3434
static void
3567
 
print_tab_data(drizzle_result_st *result)
 
3435
print_tab_data(MYSQL_RES *result)
3568
3436
{
3569
 
  drizzle_row_t cur;
3570
 
  drizzle_return_t ret;
3571
 
  drizzle_column_st *field;
3572
 
  size_t *lengths;
3573
 
  std::vector<bool> boolean_flag;
3574
 
  std::vector<bool> ansi_boolean_flag;
3575
 
 
3576
 
  boolean_flag.resize(drizzle_result_column_count(result));
3577
 
  ansi_boolean_flag.resize(drizzle_result_column_count(result));
3578
 
 
3579
 
  int first=0;
3580
 
  for (uint32_t off= 0; (field = drizzle_column_next(result)); off++)
 
3437
  MYSQL_ROW     cur;
 
3438
  MYSQL_FIELD   *field;
 
3439
  uint32_t              *lengths;
 
3440
 
 
3441
  if (opt_silent < 2 && column_names)
3581
3442
  {
3582
 
    if (opt_silent < 2 && column_names)
 
3443
    int first=0;
 
3444
    while ((field = mysql_fetch_field(result)))
3583
3445
    {
3584
3446
      if (first++)
3585
3447
        (void) tee_fputs("\t", PAGER);
3586
 
      (void) tee_fputs(drizzle_column_name(field), PAGER);
3587
 
    }
3588
 
    if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3589
 
      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3590
 
    {
3591
 
      if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3592
 
      {
3593
 
        ansi_boolean_flag[off]= true;
3594
 
      }
3595
 
      else
3596
 
      {
3597
 
        ansi_boolean_flag[off]= false;
3598
 
      }
3599
 
      boolean_flag[off]= true;
3600
 
    }
3601
 
    else
3602
 
    {
3603
 
      boolean_flag[off]= false;
3604
 
    }
3605
 
  }
3606
 
  if (opt_silent < 2 && column_names)
3607
 
  {
3608
 
    (void) tee_fputs("\n", PAGER);
3609
 
  }
3610
 
  while (1)
3611
 
  {
3612
 
    if (quick)
3613
 
    {
3614
 
      cur= drizzle_row_buffer(result, &ret);
3615
 
      if (ret != DRIZZLE_RETURN_OK)
3616
 
      {
3617
 
        (void)put_error(&con, result);
3618
 
        break;
3619
 
      }
3620
 
    }
3621
 
    else
3622
 
      cur= drizzle_row_next(result);
3623
 
 
3624
 
    if (cur == NULL)
3625
 
      break;
3626
 
 
3627
 
    lengths= drizzle_row_field_sizes(result);
3628
 
    drizzle_column_seek(result, 0);
3629
 
    for (uint32_t off=0 ; off < drizzle_result_column_count(result); off++)
3630
 
    {
3631
 
      if (off != 0)
3632
 
        (void) tee_fputs("\t", PAGER);
3633
 
      if (boolean_flag[off])
3634
 
      {
3635
 
        if (strncmp(cur[off],"1", 1) == 0)
3636
 
        {
3637
 
          if (ansi_boolean_flag[off])
3638
 
          {
3639
 
            safe_put_field("YES", 3);
3640
 
          }
3641
 
          else
3642
 
          {
3643
 
            safe_put_field("TRUE", 4);
3644
 
          }
3645
 
        }
3646
 
        else
3647
 
        {
3648
 
          if (ansi_boolean_flag[off])
3649
 
          {
3650
 
            safe_put_field("NO", 2);
3651
 
          }
3652
 
          else
3653
 
          {
3654
 
            safe_put_field("FALSE", 5);
3655
 
          }
3656
 
        }
3657
 
      }
3658
 
      else
3659
 
      {
3660
 
        safe_put_field(cur[off], lengths[off]);
3661
 
      }
3662
 
    }
3663
 
    (void) tee_fputs("\n", PAGER);
3664
 
    if (quick)
3665
 
      drizzle_row_free(result, cur);
 
3448
      (void) tee_fputs(field->name, PAGER);
 
3449
    }
 
3450
    (void) tee_fputs("\n", PAGER);
 
3451
  }
 
3452
  while ((cur = mysql_fetch_row(result)))
 
3453
  {
 
3454
    lengths= mysql_fetch_lengths(result);
 
3455
    safe_put_field(cur[0],lengths[0]);
 
3456
    for (uint off=1 ; off < mysql_num_fields(result); off++)
 
3457
    {
 
3458
      (void) tee_fputs("\t", PAGER);
 
3459
      safe_put_field(cur[off], lengths[off]);
 
3460
    }
 
3461
    (void) tee_fputs("\n", PAGER);
3666
3462
  }
3667
3463
}
3668
3464
 
3669
3465
static int
3670
 
com_tee(string *, const char *line )
 
3466
com_tee(GString *buffer __attribute__((__unused__)), char *line )
3671
3467
{
3672
 
  char file_name[FN_REFLEN], *end;
3673
 
  const char *param;
 
3468
  char file_name[FN_REFLEN], *end, *param;
3674
3469
 
3675
 
  if (status.getBatch())
 
3470
  if (status.batch)
3676
3471
    return 0;
3677
 
  while (isspace(*line))
 
3472
  while (my_isspace(charset_info,*line))
3678
3473
    line++;
3679
 
  if (!(param =strchr(line, ' '))) // if outfile wasn't given, use the default
 
3474
  if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
3680
3475
  {
3681
 
    if (outfile.empty())
 
3476
    if (!strlen(outfile))
3682
3477
    {
3683
 
      printf(_("No previous outfile available, you must give a filename!\n"));
 
3478
      printf("No previous outfile available, you must give a filename!\n");
3684
3479
      return 0;
3685
3480
    }
3686
3481
    else if (opt_outfile)
3687
3482
    {
3688
 
      tee_fprintf(stdout, _("Currently logging to file '%s'\n"), outfile.c_str());
 
3483
      tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
3689
3484
      return 0;
3690
3485
    }
3691
3486
    else
3692
 
      param= outfile.c_str();      //resume using the old outfile
 
3487
      param = outfile;                  //resume using the old outfile
3693
3488
  }
3694
3489
 
3695
 
  /* @TODO: Replace this with string methods */
3696
3490
  /* eliminate the spaces before the parameters */
3697
 
  while (isspace(*param))
 
3491
  while (my_isspace(charset_info,*param))
3698
3492
    param++;
3699
 
  strncpy(file_name, param, sizeof(file_name) - 1);
3700
 
  end= file_name + strlen(file_name);
 
3493
  end= strmake(file_name, param, sizeof(file_name) - 1);
3701
3494
  /* remove end space from command line */
3702
 
  while (end > file_name && (isspace(end[-1]) ||
3703
 
                             iscntrl(end[-1])))
 
3495
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
 
3496
                             my_iscntrl(charset_info,end[-1])))
3704
3497
    end--;
3705
3498
  end[0]= 0;
3706
3499
  if (end == file_name)
3707
3500
  {
3708
 
    printf(_("No outfile specified!\n"));
 
3501
    printf("No outfile specified!\n");
3709
3502
    return 0;
3710
3503
  }
3711
3504
  init_tee(file_name);
3714
3507
 
3715
3508
 
3716
3509
static int
3717
 
com_notee(string *, const char *)
 
3510
com_notee(GString *buffer __attribute__((unused)),
 
3511
          char *line __attribute__((unused)))
3718
3512
{
3719
3513
  if (opt_outfile)
3720
3514
    end_tee();
3721
 
  tee_fprintf(stdout, _("Outfile disabled.\n"));
 
3515
  tee_fprintf(stdout, "Outfile disabled.\n");
3722
3516
  return 0;
3723
3517
}
3724
3518
 
3727
3521
*/
3728
3522
 
3729
3523
static int
3730
 
com_pager(string *, const char *line)
 
3524
com_pager(GString *buffer __attribute__((__unused__)),
 
3525
          char *line __attribute__((unused)))
3731
3526
{
3732
 
  const char *param;
 
3527
  char pager_name[FN_REFLEN], *end, *param;
3733
3528
 
3734
 
  if (status.getBatch())
 
3529
  if (status.batch)
3735
3530
    return 0;
3736
3531
  /* Skip spaces in front of the pager command */
3737
 
  while (isspace(*line))
 
3532
  while (my_isspace(charset_info, *line))
3738
3533
    line++;
3739
3534
  /* Skip the pager command */
3740
3535
  param= strchr(line, ' ');
3741
3536
  /* Skip the spaces between the command and the argument */
3742
 
  while (param && isspace(*param))
 
3537
  while (param && my_isspace(charset_info, *param))
3743
3538
    param++;
3744
 
  if (!param || (*param == '\0')) // if pager was not given, use the default
 
3539
  if (!param || !strlen(param)) // if pager was not given, use the default
3745
3540
  {
3746
3541
    if (!default_pager_set)
3747
3542
    {
3748
 
      tee_fprintf(stdout, _("Default pager wasn't set, using stdout.\n"));
 
3543
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3749
3544
      opt_nopager=1;
3750
 
      pager.assign("stdout");
 
3545
      strmov(pager, "stdout");
3751
3546
      PAGER= stdout;
3752
3547
      return 0;
3753
3548
    }
3754
 
    pager.assign(default_pager);
 
3549
    strmov(pager, default_pager);
3755
3550
  }
3756
3551
  else
3757
3552
  {
3758
 
    string pager_name(param);
3759
 
    string::iterator end= pager_name.end();
3760
 
    while (end > pager_name.begin() &&
3761
 
           (isspace(*(end-1)) || iscntrl(*(end-1))))
3762
 
      --end;
3763
 
    pager_name.erase(end, pager_name.end());
3764
 
    pager.assign(pager_name);
3765
 
    default_pager.assign(pager_name);
 
3553
    end= strmake(pager_name, param, sizeof(pager_name)-1);
 
3554
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
 
3555
                                my_iscntrl(charset_info,end[-1])))
 
3556
      end--;
 
3557
    end[0]=0;
 
3558
    strmov(pager, pager_name);
 
3559
    strmov(default_pager, pager_name);
3766
3560
  }
3767
3561
  opt_nopager=0;
3768
 
  tee_fprintf(stdout, _("PAGER set to '%s'\n"), pager.c_str());
 
3562
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3769
3563
  return 0;
3770
3564
}
3771
3565
 
3772
3566
 
3773
3567
static int
3774
 
com_nopager(string *, const char *)
 
3568
com_nopager(GString *buffer __attribute__((unused)),
 
3569
            char *line __attribute__((unused)))
3775
3570
{
3776
 
  pager.assign("stdout");
 
3571
  strmov(pager, "stdout");
3777
3572
  opt_nopager=1;
3778
3573
  PAGER= stdout;
3779
 
  tee_fprintf(stdout, _("PAGER set to stdout\n"));
 
3574
  tee_fprintf(stdout, "PAGER set to stdout\n");
3780
3575
  return 0;
3781
3576
}
3782
3577
 
3783
3578
/* If arg is given, exit without errors. This happens on command 'quit' */
3784
3579
 
3785
3580
static int
3786
 
com_quit(string *, const char *)
 
3581
com_quit(GString *buffer __attribute__((unused)),
 
3582
         char *line __attribute__((unused)))
3787
3583
{
3788
3584
  /* let the screen auto close on a normal shutdown */
3789
 
  status.setExitStatus(0);
 
3585
  status.exit_status=0;
3790
3586
  return 1;
3791
3587
}
3792
3588
 
3793
3589
static int
3794
 
com_rehash(string *, const char *)
 
3590
com_rehash(GString *buffer __attribute__((unused)),
 
3591
           char *line __attribute__((unused)))
3795
3592
{
3796
3593
  build_completion_hash(1, 0);
3797
3594
  return 0;
3800
3597
 
3801
3598
 
3802
3599
static int
3803
 
com_print(string *buffer,const char *)
 
3600
com_print(GString *buffer,char *line __attribute__((unused)))
3804
3601
{
3805
3602
  tee_puts("--------------", stdout);
3806
 
  (void) tee_fputs(buffer->c_str(), stdout);
3807
 
  if ( (buffer->length() == 0)
3808
 
       || (buffer->c_str())[(buffer->length())-1] != '\n')
 
3603
  (void) tee_fputs(buffer->str, stdout);
 
3604
  if ( (buffer->len == 0)
 
3605
       || (buffer->str)[(buffer->len)-1] != '\n')
3809
3606
    tee_putc('\n', stdout);
3810
3607
  tee_puts("--------------\n", stdout);
3811
3608
  /* If empty buffer */
3814
3611
 
3815
3612
/* ARGSUSED */
3816
3613
static int
3817
 
com_connect(string *buffer, const char *line)
 
3614
com_connect(GString *buffer, char *line)
3818
3615
{
3819
3616
  char *tmp, buff[256];
3820
3617
  bool save_rehash= opt_rehash;
3821
3618
  int error;
3822
3619
 
3823
 
  memset(buff, 0, sizeof(buff));
 
3620
  bzero(buff, sizeof(buff));
3824
3621
  if (buffer)
3825
3622
  {
3826
3623
    /*
3827
3624
      Two null bytes are needed in the end of buff to allow
3828
3625
      get_arg to find end of string the second time it's called.
3829
3626
    */
3830
 
    tmp= strncpy(buff, line, sizeof(buff)-2);
 
3627
    tmp= strmake(buff, line, sizeof(buff)-2);
3831
3628
#ifdef EXTRA_DEBUG
3832
3629
    tmp[1]= 0;
3833
3630
#endif
3834
3631
    tmp= get_arg(buff, 0);
3835
3632
    if (tmp && *tmp)
3836
3633
    {
3837
 
      current_db.erase();
3838
 
      current_db.assign(tmp);
 
3634
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
3635
      current_db= g_strdup(tmp);
3839
3636
      tmp= get_arg(buff, 1);
3840
3637
      if (tmp)
3841
3638
      {
3842
 
        current_host.erase();
3843
 
        current_host=strdup(tmp);
 
3639
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
3640
        current_host=g_strdup(tmp);
3844
3641
      }
3845
3642
    }
3846
3643
    else
3847
3644
    {
3848
3645
      /* Quick re-connect */
3849
 
      opt_rehash= 0;
 
3646
      opt_rehash= 0;                            /* purecov: tested */
3850
3647
    }
3851
3648
    // command used
3852
3649
    assert(buffer!=NULL);
3853
 
    buffer->clear();
 
3650
    g_string_truncate(buffer, 0);
3854
3651
  }
3855
3652
  else
3856
3653
    opt_rehash= 0;
3857
 
  error=sql_connect(current_host, current_db, current_user, opt_password);
 
3654
  error=sql_connect(current_host,current_db,current_user,opt_password,0);
3858
3655
  opt_rehash= save_rehash;
3859
3656
 
3860
3657
  if (connected)
3861
3658
  {
3862
 
    sprintf(buff, _("Connection id:    %u"), drizzle_con_thread_id(&con));
 
3659
    sprintf(buff,"Connection id:    %u",mysql_thread_id(&mysql));
3863
3660
    put_info(buff,INFO_INFO,0,0);
3864
 
    sprintf(buff, _("Current schema: %.128s\n"),
3865
 
            !current_db.empty() ? current_db.c_str() : _("*** NONE ***"));
 
3661
    sprintf(buff,"Current database: %.128s\n",
 
3662
            current_db ? current_db : "*** NONE ***");
3866
3663
    put_info(buff,INFO_INFO,0,0);
3867
3664
  }
3868
3665
  return error;
3869
3666
}
3870
3667
 
3871
3668
 
3872
 
static int com_source(string *, const char *line)
 
3669
static int com_source(GString *buffer __attribute__((__unused__)), char *line)
3873
3670
{
3874
 
  char source_name[FN_REFLEN], *end;
3875
 
  const char *param;
3876
 
  LineBuffer *line_buff;
 
3671
  char source_name[FN_REFLEN], *end, *param;
 
3672
  LINE_BUFFER *line_buff;
3877
3673
  int error;
3878
 
  Status old_status;
 
3674
  STATUS old_status;
3879
3675
  FILE *sql_file;
3880
3676
 
3881
3677
  /* Skip space from file name */
3882
 
  while (isspace(*line))
 
3678
  while (my_isspace(charset_info,*line))
3883
3679
    line++;
3884
 
  if (!(param = strchr(line, ' ')))    // Skip command name
3885
 
    return put_info(_("Usage: \\. <filename> | source <filename>"),
 
3680
  if (!(param = strchr(line, ' ')))             // Skip command name
 
3681
    return put_info("Usage: \\. <filename> | source <filename>",
3886
3682
                    INFO_ERROR, 0,0);
3887
 
  while (isspace(*param))
 
3683
  while (my_isspace(charset_info,*param))
3888
3684
    param++;
3889
 
  end= strncpy(source_name,param,sizeof(source_name)-1);
3890
 
  end+= strlen(source_name);
3891
 
  while (end > source_name && (isspace(end[-1]) ||
3892
 
                               iscntrl(end[-1])))
 
3685
  end=strmake(source_name,param,sizeof(source_name)-1);
 
3686
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
 
3687
                               my_iscntrl(charset_info,end[-1])))
3893
3688
    end--;
3894
3689
  end[0]=0;
3895
 
 
 
3690
  unpack_filename(source_name,source_name);
3896
3691
  /* open file name */
3897
 
  if (!(sql_file = fopen(source_name, "r")))
 
3692
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
3898
3693
  {
3899
3694
    char buff[FN_REFLEN+60];
3900
 
    sprintf(buff, _("Failed to open file '%s', error: %d"), source_name,errno);
 
3695
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3901
3696
    return put_info(buff, INFO_ERROR, 0 ,0);
3902
3697
  }
3903
3698
 
3904
 
  line_buff= new(std::nothrow) LineBuffer(opt_max_input_line,sql_file);
3905
 
  if (line_buff == NULL)
 
3699
  if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file)))
3906
3700
  {
3907
 
    fclose(sql_file);
3908
 
    return put_info(_("Can't initialize LineBuffer"), INFO_ERROR, 0, 0);
 
3701
    my_fclose(sql_file,MYF(0));
 
3702
    return put_info("Can't initialize batch_readline", INFO_ERROR, 0 ,0);
3909
3703
  }
3910
3704
 
3911
3705
  /* Save old status */
3912
3706
  old_status=status;
3913
 
  memset(&status, 0, sizeof(status));
 
3707
  bfill((char*) &status,sizeof(status),(char) 0);
3914
3708
 
3915
3709
  // Run in batch mode
3916
 
  status.setBatch(old_status.getBatch());
3917
 
  status.setLineBuff(line_buff);
3918
 
  status.setFileName(source_name);
 
3710
  status.batch=old_status.batch;
 
3711
  status.line_buff=line_buff;
 
3712
  status.file_name=source_name;
3919
3713
  // Empty command buffer
3920
3714
  assert(glob_buffer!=NULL);
3921
 
  glob_buffer->clear();
 
3715
  g_string_truncate(glob_buffer, 0);
3922
3716
  error= read_and_execute(false);
3923
3717
  // Continue as before
3924
3718
  status=old_status;
3925
 
  fclose(sql_file);
3926
 
  delete status.getLineBuff();
3927
 
  line_buff=0;
3928
 
  status.setLineBuff(0);
 
3719
  my_fclose(sql_file,MYF(0));
 
3720
  batch_readline_end(line_buff);
3929
3721
  return error;
3930
3722
}
3931
3723
 
3932
3724
 
3933
3725
/* ARGSUSED */
3934
3726
static int
3935
 
com_delimiter(string *, const char *line)
 
3727
com_delimiter(GString *buffer __attribute__((unused)), char *line)
3936
3728
{
3937
3729
  char buff[256], *tmp;
3938
3730
 
3939
 
  strncpy(buff, line, sizeof(buff) - 1);
 
3731
  strmake(buff, line, sizeof(buff) - 1);
3940
3732
  tmp= get_arg(buff, 0);
3941
3733
 
3942
3734
  if (!tmp || !*tmp)
3943
3735
  {
3944
 
    put_info(_("DELIMITER must be followed by a 'delimiter' character or string"),
 
3736
    put_info("DELIMITER must be followed by a 'delimiter' character or string",
3945
3737
             INFO_ERROR, 0, 0);
3946
3738
    return 0;
3947
3739
  }
3949
3741
  {
3950
3742
    if (strstr(tmp, "\\"))
3951
3743
    {
3952
 
      put_info(_("DELIMITER cannot contain a backslash character"),
 
3744
      put_info("DELIMITER cannot contain a backslash character",
3953
3745
               INFO_ERROR, 0, 0);
3954
3746
      return 0;
3955
3747
    }
3956
3748
  }
3957
 
  strncpy(delimiter, tmp, sizeof(delimiter) - 1);
 
3749
  strmake(delimiter, tmp, sizeof(delimiter) - 1);
3958
3750
  delimiter_length= (int)strlen(delimiter);
3959
3751
  delimiter_str= delimiter;
3960
3752
  return 0;
3962
3754
 
3963
3755
/* ARGSUSED */
3964
3756
static int
3965
 
com_use(string *, const char *line)
 
3757
com_use(GString *buffer __attribute__((unused)), char *line)
3966
3758
{
3967
3759
  char *tmp, buff[FN_REFLEN + 1];
3968
3760
  int select_db;
3969
 
  drizzle_result_st result;
3970
 
  drizzle_return_t ret;
3971
3761
 
3972
 
  memset(buff, 0, sizeof(buff));
3973
 
  strncpy(buff, line, sizeof(buff) - 1);
 
3762
  bzero(buff, sizeof(buff));
 
3763
  strmake(buff, line, sizeof(buff) - 1);
3974
3764
  tmp= get_arg(buff, 0);
3975
3765
  if (!tmp || !*tmp)
3976
3766
  {
3977
 
    put_info(_("USE must be followed by a schema name"), INFO_ERROR, 0, 0);
 
3767
    put_info("USE must be followed by a database name", INFO_ERROR, 0, 0);
3978
3768
    return 0;
3979
3769
  }
3980
3770
  /*
3984
3774
  */
3985
3775
  get_current_db();
3986
3776
 
3987
 
  if (current_db.empty() || strcmp(current_db.c_str(),tmp))
 
3777
  if (!current_db || cmp_database(charset_info, current_db,tmp))
3988
3778
  {
3989
3779
    if (one_database)
3990
3780
    {
3991
3781
      skip_updates= 1;
3992
 
      select_db= 0;    // don't do drizzleclient_select_db()
 
3782
      select_db= 0;    // don't do mysql_select_db()
3993
3783
    }
3994
3784
    else
3995
 
      select_db= 2;    // do drizzleclient_select_db() and build_completion_hash()
 
3785
      select_db= 2;    // do mysql_select_db() and build_completion_hash()
3996
3786
  }
3997
3787
  else
3998
3788
  {
3999
3789
    /*
4000
3790
      USE to the current db specified.
4001
 
      We do need to send drizzleclient_select_db() to make server
 
3791
      We do need to send mysql_select_db() to make server
4002
3792
      update database level privileges, which might
4003
3793
      change since last USE (see bug#10979).
4004
3794
      For performance purposes, we'll skip rebuilding of completion hash.
4005
3795
    */
4006
3796
    skip_updates= 0;
4007
 
    select_db= 1;      // do only drizzleclient_select_db(), without completion
 
3797
    select_db= 1;      // do only mysql_select_db(), without completion
4008
3798
  }
4009
3799
 
4010
3800
  if (select_db)
4015
3805
    */
4016
3806
    if (!connected && reconnect())
4017
3807
      return opt_reconnect ? -1 : 1;                        // Fatal error
4018
 
    for (bool try_again= true; try_again; try_again= false)
 
3808
    if (mysql_select_db(&mysql,tmp))
4019
3809
    {
4020
 
      if (drizzle_select_db(&con,&result,tmp,&ret) == NULL ||
4021
 
          ret != DRIZZLE_RETURN_OK)
4022
 
      {
4023
 
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
4024
 
        {
4025
 
          int error= put_error(&con, &result);
4026
 
          drizzle_result_free(&result);
4027
 
          return error;
4028
 
        }
4029
 
 
4030
 
        if (ret != DRIZZLE_RETURN_SERVER_GONE || !try_again)
4031
 
          return put_error(&con, NULL);
4032
 
 
4033
 
        if (reconnect())
4034
 
          return opt_reconnect ? -1 : 1;                      // Fatal error
4035
 
      }
4036
 
      else
4037
 
        drizzle_result_free(&result);
 
3810
      if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR)
 
3811
        return put_error(&mysql);
 
3812
 
 
3813
      if (reconnect())
 
3814
        return opt_reconnect ? -1 : 1;                      // Fatal error
 
3815
      if (mysql_select_db(&mysql,tmp))
 
3816
        return put_error(&mysql);
4038
3817
    }
4039
 
    current_db.erase();
4040
 
    current_db.assign(tmp);
 
3818
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
3819
    current_db=g_strdup(tmp);
4041
3820
    if (select_db > 1)
4042
3821
      build_completion_hash(opt_rehash, 1);
4043
3822
  }
4044
3823
 
4045
 
  put_info(_("Schema changed"),INFO_INFO, 0, 0);
 
3824
  put_info("Database changed",INFO_INFO, 0, 0);
4046
3825
  return 0;
4047
3826
}
4048
3827
 
4049
 
static int com_shutdown(string *, const char *)
4050
 
{
4051
 
  drizzle_result_st result;
4052
 
  drizzle_return_t ret;
4053
 
 
4054
 
  if (verbose)
4055
 
  {
4056
 
    printf(_("shutting down drizzled"));
4057
 
    if (opt_drizzle_port > 0)
4058
 
      printf(_(" on port %d"), opt_drizzle_port);
4059
 
    printf("... ");
4060
 
  }
4061
 
 
4062
 
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
4063
 
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
4064
 
  {
4065
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
4066
 
    {
4067
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
4068
 
              drizzle_result_error(&result));
4069
 
      drizzle_result_free(&result);
4070
 
    }
4071
 
    else
4072
 
    {
4073
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
4074
 
              drizzle_con_error(&con));
4075
 
    }
4076
 
    return false;
4077
 
  }
4078
 
 
4079
 
  drizzle_result_free(&result);
4080
 
 
4081
 
  if (verbose)
4082
 
    printf(_("done\n"));
4083
 
 
4084
 
  return false;
4085
 
}
4086
 
 
4087
3828
static int
4088
 
com_warnings(string *, const char *)
 
3829
com_warnings(GString *buffer __attribute__((unused)),
 
3830
             char *line __attribute__((unused)))
4089
3831
{
4090
3832
  show_warnings = 1;
4091
 
  put_info(_("Show warnings enabled."),INFO_INFO, 0, 0);
 
3833
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
4092
3834
  return 0;
4093
3835
}
4094
3836
 
4095
3837
static int
4096
 
com_nowarnings(string *, const char *)
 
3838
com_nowarnings(GString *buffer __attribute__((unused)),
 
3839
               char *line __attribute__((unused)))
4097
3840
{
4098
3841
  show_warnings = 0;
4099
 
  put_info(_("Show warnings disabled."),INFO_INFO, 0, 0);
 
3842
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
4100
3843
  return 0;
4101
3844
}
4102
3845
 
4126
3869
  else
4127
3870
  {
4128
3871
    /* skip leading white spaces */
4129
 
    while (isspace(*ptr))
 
3872
    while (my_isspace(charset_info, *ptr))
4130
3873
      ptr++;
4131
3874
    if (*ptr == '\\') // short command was used
4132
3875
      ptr+= 2;
4133
3876
    else
4134
 
      while (*ptr &&!isspace(*ptr)) // skip command
 
3877
      while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
4135
3878
        ptr++;
4136
3879
  }
4137
3880
  if (!*ptr)
4138
 
    return NULL;
4139
 
  while (isspace(*ptr))
 
3881
    return NullS;
 
3882
  while (my_isspace(charset_info, *ptr))
4140
3883
    ptr++;
4141
3884
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
4142
3885
  {
4149
3892
    if (*ptr == '\\' && ptr[1]) // escaped character
4150
3893
    {
4151
3894
      // Remove the backslash
4152
 
      strcpy(ptr, ptr+1);
 
3895
      strmov(ptr, ptr+1);
4153
3896
    }
4154
3897
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
4155
3898
    {
4158
3901
    }
4159
3902
  }
4160
3903
  valid_arg= ptr != start;
4161
 
  return valid_arg ? start : NULL;
 
3904
  return valid_arg ? start : NullS;
4162
3905
}
4163
3906
 
4164
3907
 
4165
3908
static int
4166
 
sql_connect(const string &host, const string &database, const string &user, const string &password)
 
3909
sql_real_connect(char *host,char *database,char *user,char *password,
 
3910
                 uint silent)
4167
3911
{
4168
 
  drizzle_return_t ret;
4169
3912
  if (connected)
4170
3913
  {
4171
3914
    connected= 0;
4172
 
    drizzle_con_free(&con);
4173
 
    drizzle_free(&drizzle);
4174
 
  }
4175
 
  drizzle_create(&drizzle);
4176
 
 
4177
 
#ifdef DRIZZLE_ADMIN_TOOL
4178
 
  drizzle_con_options_t options= (drizzle_con_options_t) (DRIZZLE_CON_ADMIN | (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL));
4179
 
#else
4180
 
  drizzle_con_options_t options= (drizzle_con_options_t) (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
4181
 
#endif
4182
 
 
4183
 
  if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(),
4184
 
    opt_drizzle_port, (char *)user.c_str(),
4185
 
    (char *)password.c_str(), (char *)database.c_str(),
4186
 
    options) == NULL)
4187
 
  {
4188
 
    (void) put_error(&con, NULL);
4189
 
    (void) fflush(stdout);
4190
 
    return 1;
4191
 
  }
4192
 
 
4193
 
/* XXX add this back in
 
3915
    mysql_close(&mysql);
 
3916
  }
 
3917
  mysql_init(&mysql);
4194
3918
  if (opt_connect_timeout)
4195
3919
  {
4196
 
    uint32_t timeout=opt_connect_timeout;
4197
 
    drizzleclient_options(&drizzle,DRIZZLE_OPT_CONNECT_TIMEOUT,
 
3920
    uint timeout=opt_connect_timeout;
 
3921
    mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
4198
3922
                  (char*) &timeout);
4199
3923
  }
4200
 
*/
4201
 
 
4202
 
/* XXX Do we need this?
 
3924
  if (opt_compress)
 
3925
    mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
 
3926
  if (opt_secure_auth)
 
3927
    mysql_options(&mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
 
3928
  if (using_opt_local_infile)
 
3929
    mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
 
3930
  if (opt_protocol)
 
3931
    mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
4203
3932
  if (safe_updates)
4204
3933
  {
4205
3934
    char init_command[100];
4206
3935
    sprintf(init_command,
4207
 
            "SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
4208
 
            ",MAX_JOIN_SIZE=%"PRIu32,
4209
 
            select_limit, max_join_size);
4210
 
    drizzleclient_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
 
3936
                  "SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%"PRIu32
 
3937
            ",SQL_MAX_JOIN_SIZE=%"PRIu32,
 
3938
                  select_limit, max_join_size);
 
3939
    mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
4211
3940
  }
4212
 
*/
4213
 
  if ((ret= drizzle_con_connect(&con)) != DRIZZLE_RETURN_OK)
 
3941
  if (default_charset_used)
 
3942
    mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
 
3943
  if (!mysql_real_connect(&mysql, host, user, password,
 
3944
                          database, opt_mysql_port, opt_mysql_unix_port,
 
3945
                          connect_flag | CLIENT_MULTI_STATEMENTS))
4214
3946
  {
4215
 
 
4216
 
    if (opt_silent < 2)
 
3947
    if (!silent ||
 
3948
        (mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
 
3949
         mysql_errno(&mysql) != CR_CONNECTION_ERROR))
4217
3950
    {
4218
 
      (void) put_error(&con, NULL);
 
3951
      (void) put_error(&mysql);
4219
3952
      (void) fflush(stdout);
4220
 
      return ignore_errors ? -1 : 1;    // Abort
 
3953
      return ignore_errors ? -1 : 1;            // Abort
4221
3954
    }
4222
 
    return -1;          // Retryable
 
3955
    return -1;                                  // Retryable
4223
3956
  }
4224
3957
  connected=1;
4225
 
 
4226
 
  ServerDetect server_detect(&con);
4227
 
  server_type= server_detect.getServerType();
4228
 
 
 
3958
  mysql.reconnect= debug_info_flag; // We want to know if this happens
4229
3959
  build_completion_hash(opt_rehash, 1);
4230
3960
  return 0;
4231
3961
}
4232
3962
 
4233
3963
 
4234
3964
static int
4235
 
com_status(string *, const char *)
4236
 
{
4237
 
/*
 
3965
sql_connect(char *host,char *database,char *user,char *password,uint silent)
 
3966
{
 
3967
  bool message=0;
 
3968
  uint count=0;
 
3969
  int error;
 
3970
  for (;;)
 
3971
  {
 
3972
    if ((error=sql_real_connect(host,database,user,password,wait_flag)) >= 0)
 
3973
    {
 
3974
      if (count)
 
3975
      {
 
3976
        tee_fputs("\n", stderr);
 
3977
        (void) fflush(stderr);
 
3978
      }
 
3979
      return error;
 
3980
    }
 
3981
    if (!wait_flag)
 
3982
      return ignore_errors ? -1 : 1;
 
3983
    if (!message && !silent)
 
3984
    {
 
3985
      message=1;
 
3986
      tee_fputs("Waiting",stderr); (void) fflush(stderr);
 
3987
    }
 
3988
    (void) sleep(wait_time);
 
3989
    if (!silent)
 
3990
    {
 
3991
      putc('.',stderr); (void) fflush(stderr);
 
3992
      count++;
 
3993
    }
 
3994
  }
 
3995
}
 
3996
 
 
3997
 
 
3998
 
 
3999
static int
 
4000
com_status(GString *buffer __attribute__((unused)),
 
4001
           char *line __attribute__((unused)))
 
4002
{
 
4003
  const char *status_str;
4238
4004
  char buff[40];
4239
4005
  uint64_t id;
4240
 
*/
4241
 
  drizzle_result_st result;
4242
 
  drizzle_return_t ret;
 
4006
  MYSQL_RES *result;
4243
4007
 
4244
4008
  tee_puts("--------------", stdout);
4245
 
  printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
4246
 
         drizzle_version(), VERSION,
4247
 
         HOST_VENDOR, HOST_OS, HOST_CPU,
4248
 
         rl_library_version);
4249
 
 
 
4009
  usage(1);                                     /* Print version */
4250
4010
  if (connected)
4251
4011
  {
4252
 
    tee_fprintf(stdout, _("\nConnection id:\t\t%lu\n"),drizzle_con_thread_id(&con));
 
4012
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
4253
4013
    /*
4254
4014
      Don't remove "limit 1",
4255
4015
      it is protection againts SQL_SELECT_LIMIT=0
4256
4016
    */
4257
 
    if (drizzle_query_str(&con,&result,"select DATABASE(), USER() limit 1",
4258
 
                          &ret) != NULL && ret == DRIZZLE_RETURN_OK &&
4259
 
        drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
 
4017
    if (!mysql_query(&mysql,"select DATABASE(), USER() limit 1") &&
 
4018
        (result=mysql_use_result(&mysql)))
4260
4019
    {
4261
 
      drizzle_row_t cur=drizzle_row_next(&result);
 
4020
      MYSQL_ROW cur=mysql_fetch_row(result);
4262
4021
      if (cur)
4263
4022
      {
4264
 
        tee_fprintf(stdout, _("Current schema:\t%s\n"), cur[0] ? cur[0] : "");
4265
 
        tee_fprintf(stdout, _("Current user:\t\t%s\n"), cur[1]);
 
4023
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
 
4024
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
4266
4025
      }
4267
 
      drizzle_result_free(&result);
 
4026
      mysql_free_result(result);
4268
4027
    }
4269
 
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4270
 
      drizzle_result_free(&result);
4271
 
    tee_puts(_("SSL:\t\t\tNot in use"), stdout);
 
4028
    tee_puts("SSL:\t\t\tNot in use", stdout);
4272
4029
  }
4273
4030
  else
4274
4031
  {
4275
4032
    vidattr(A_BOLD);
4276
 
    tee_fprintf(stdout, _("\nNo connection\n"));
 
4033
    tee_fprintf(stdout, "\nNo connection\n");
4277
4034
    vidattr(A_NORMAL);
4278
4035
    return 0;
4279
4036
  }
4280
4037
  if (skip_updates)
4281
4038
  {
4282
4039
    vidattr(A_BOLD);
4283
 
    tee_fprintf(stdout, _("\nAll updates ignored to this schema\n"));
 
4040
    tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4284
4041
    vidattr(A_NORMAL);
4285
4042
  }
4286
 
  tee_fprintf(stdout, _("Current pager:\t\t%s\n"), pager.c_str());
4287
 
  tee_fprintf(stdout, _("Using outfile:\t\t'%s'\n"), opt_outfile ? outfile.c_str() : "");
4288
 
  tee_fprintf(stdout, _("Using delimiter:\t%s\n"), delimiter);
4289
 
  tee_fprintf(stdout, _("Server version:\t\t%s\n"), server_version_string(&con));
4290
 
  tee_fprintf(stdout, _("Protocol:\t\t%s\n"), opt_protocol.c_str());
4291
 
  tee_fprintf(stdout, _("Protocol version:\t%d\n"), drizzle_con_protocol_version(&con));
4292
 
  tee_fprintf(stdout, _("Connection:\t\t%s\n"), drizzle_con_host(&con));
4293
 
/* XXX need to save this from result
4294
 
  if ((id= drizzleclient_insert_id(&drizzle)))
4295
 
    tee_fprintf(stdout, "Insert id:\t\t%s\n", internal::llstr(id, buff));
4296
 
*/
4297
 
 
4298
 
  if (drizzle_con_uds(&con))
4299
 
    tee_fprintf(stdout, _("UNIX socket:\t\t%s\n"), drizzle_con_uds(&con));
4300
 
  else
4301
 
    tee_fprintf(stdout, _("TCP port:\t\t%d\n"), drizzle_con_port(&con));
4302
 
 
 
4043
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
 
4044
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
 
4045
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
 
4046
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&mysql));
 
4047
  tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql));
 
4048
  tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql));
 
4049
  if ((id= mysql_insert_id(&mysql)))
 
4050
    tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
 
4051
 
 
4052
  /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
 
4053
  if (!mysql_query(&mysql,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
 
4054
      (result=mysql_use_result(&mysql)))
 
4055
  {
 
4056
    MYSQL_ROW cur=mysql_fetch_row(result);
 
4057
    if (cur)
 
4058
    {
 
4059
      tee_fprintf(stdout, "Server characterset:\t%s\n", cur[2] ? cur[2] : "");
 
4060
      tee_fprintf(stdout, "Db     characterset:\t%s\n", cur[3] ? cur[3] : "");
 
4061
      tee_fprintf(stdout, "Client characterset:\t%s\n", cur[0] ? cur[0] : "");
 
4062
      tee_fprintf(stdout, "Conn.  characterset:\t%s\n", cur[1] ? cur[1] : "");
 
4063
    }
 
4064
    mysql_free_result(result);
 
4065
  }
 
4066
  else
 
4067
  {
 
4068
    /* Probably pre-4.1 server */
 
4069
    tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname);
 
4070
    tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname);
 
4071
  }
 
4072
 
 
4073
#ifndef EMBEDDED_LIBRARY
 
4074
  if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
 
4075
    tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
 
4076
  else
 
4077
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", mysql.unix_socket);
 
4078
  if (mysql.net.compress)
 
4079
    tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
 
4080
#endif
 
4081
 
 
4082
  if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
 
4083
  {
 
4084
    ulong sec;
 
4085
    const char *pos= strchr(status_str,' ');
 
4086
    /* print label */
 
4087
    tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str);
 
4088
    if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec)))
 
4089
    {
 
4090
      nice_time((double) sec,buff,0);
 
4091
      tee_puts(buff, stdout);                   /* print nice time */
 
4092
      while (*status_str == ' ')
 
4093
        status_str++;  /* to next info */
 
4094
      tee_putc('\n', stdout);
 
4095
      tee_puts(status_str, stdout);
 
4096
    }
 
4097
  }
4303
4098
  if (safe_updates)
4304
4099
  {
4305
4100
    vidattr(A_BOLD);
4306
 
    tee_fprintf(stdout, _("\nNote that you are running in safe_update_mode:\n"));
 
4101
    tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n");
4307
4102
    vidattr(A_NORMAL);
4308
 
    tee_fprintf(stdout, _("\
 
4103
    tee_fprintf(stdout, "\
4309
4104
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4310
4105
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n \
4311
4106
SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n             \
4312
 
Max number of examined row combination in a join is set to: %lu\n\n"),
 
4107
Max number of examined row combination in a join is set to: %lu\n\n",
4313
4108
                select_limit, max_join_size);
4314
4109
  }
4315
4110
  tee_puts("--------------\n", stdout);
4317
4112
}
4318
4113
 
4319
4114
static const char *
4320
 
server_version_string(drizzle_con_st *local_con)
 
4115
server_version_string(MYSQL *con)
4321
4116
{
4322
 
  static string buf("");
4323
 
  static bool server_version_string_reserved= false;
 
4117
  static char buf[MAX_SERVER_VERSION_LENGTH] = "";
4324
4118
 
4325
 
  if (!server_version_string_reserved)
4326
 
  {
4327
 
    buf.reserve(MAX_SERVER_VERSION_LENGTH);
4328
 
    server_version_string_reserved= true;
4329
 
  }
4330
4119
  /* Only one thread calls this, so no synchronization is needed */
4331
4120
  if (buf[0] == '\0')
4332
4121
  {
4333
 
    drizzle_result_st result;
4334
 
    drizzle_return_t ret;
 
4122
    char *bufp = buf;
 
4123
    MYSQL_RES *result;
4335
4124
 
4336
 
    buf.append(drizzle_con_server_version(local_con));
 
4125
    bufp= strnmov(buf, mysql_get_server_info(con), sizeof buf);
4337
4126
 
4338
4127
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
4339
 
    (void)drizzle_query_str(local_con, &result,
4340
 
                            "select @@version_comment limit 1", &ret);
4341
 
    if (ret == DRIZZLE_RETURN_OK &&
4342
 
        drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
 
4128
    if (!mysql_query(con, "select @@version_comment limit 1") &&
 
4129
        (result = mysql_use_result(con)))
4343
4130
    {
4344
 
      drizzle_row_t cur = drizzle_row_next(&result);
 
4131
      MYSQL_ROW cur = mysql_fetch_row(result);
4345
4132
      if (cur && cur[0])
4346
4133
      {
4347
 
        buf.append(" ");
4348
 
        buf.append(cur[0]);
 
4134
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
4349
4135
      }
4350
 
      drizzle_result_free(&result);
 
4136
      mysql_free_result(result);
4351
4137
    }
4352
 
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4353
 
      drizzle_result_free(&result);
 
4138
 
 
4139
    /* str*nmov doesn't guarantee NUL-termination */
 
4140
    if (bufp == buf + sizeof buf)
 
4141
      buf[sizeof buf - 1] = '\0';
4354
4142
  }
4355
4143
 
4356
 
  return buf.c_str();
 
4144
  return buf;
4357
4145
}
4358
4146
 
4359
4147
static int
4360
 
put_info(const char *str,INFO_TYPE info_type, uint32_t error, const char *sqlstate)
 
4148
put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
4361
4149
{
4362
4150
  FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
4363
4151
  static int inited=0;
4364
4152
 
4365
 
  if (status.getBatch())
 
4153
  if (status.batch)
4366
4154
  {
4367
4155
    if (info_type == INFO_ERROR)
4368
4156
    {
4369
4157
      (void) fflush(file);
4370
 
      fprintf(file,_("ERROR"));
 
4158
      fprintf(file,"ERROR");
4371
4159
      if (error)
4372
4160
      {
4373
4161
        if (sqlstate)
4375
4163
        else
4376
4164
          (void) fprintf(file," %d",error);
4377
4165
      }
4378
 
      if (status.getQueryStartLine() && line_numbers)
 
4166
      if (status.query_start_line && line_numbers)
4379
4167
      {
4380
 
        (void) fprintf(file," at line %"PRIu32,status.getQueryStartLine());
4381
 
        if (status.getFileName())
4382
 
          (void) fprintf(file," in file: '%s'", status.getFileName());
 
4168
        (void) fprintf(file," at line %"PRIu32,status.query_start_line);
 
4169
        if (status.file_name)
 
4170
          (void) fprintf(file," in file: '%s'", status.file_name);
4383
4171
      }
4384
4172
      (void) fprintf(file,": %s\n",str);
4385
4173
      (void) fflush(file);
4410
4198
      if (error)
4411
4199
      {
4412
4200
        if (sqlstate)
4413
 
          (void) tee_fprintf(file, _("ERROR %d (%s): "), error, sqlstate);
 
4201
          (void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate);
4414
4202
        else
4415
 
          (void) tee_fprintf(file, _("ERROR %d: "), error);
 
4203
          (void) tee_fprintf(file, "ERROR %d: ", error);
4416
4204
      }
4417
4205
      else
4418
 
        tee_puts(_("ERROR: "), file);
 
4206
        tee_puts("ERROR: ", file);
4419
4207
    }
4420
4208
    else
4421
4209
      vidattr(A_BOLD);
4429
4217
 
4430
4218
 
4431
4219
static int
4432
 
put_error(drizzle_con_st *local_con, drizzle_result_st *res)
 
4220
put_error(MYSQL *con)
4433
4221
{
4434
 
  const char *error;
4435
 
 
4436
 
  if (res != NULL)
4437
 
  {
4438
 
    error= drizzle_result_error(res);
4439
 
    if (!strcmp(error, ""))
4440
 
      error= drizzle_con_error(local_con);
4441
 
  }
4442
 
  else
4443
 
    error= drizzle_con_error(local_con);
4444
 
 
4445
 
  return put_info(error, INFO_ERROR,
4446
 
                  res == NULL ? drizzle_con_error_code(local_con) :
4447
 
                                drizzle_result_error_code(res),
4448
 
                  res == NULL ? drizzle_con_sqlstate(local_con) :
4449
 
                                drizzle_result_sqlstate(res));
 
4222
  return put_info(mysql_error(con), INFO_ERROR, mysql_errno(con),
 
4223
                  mysql_sqlstate(con));
4450
4224
}
4451
4225
 
4452
4226
 
4453
 
static void remove_cntrl(string *buffer)
 
4227
static void remove_cntrl(GString *buffer)
4454
4228
{
4455
 
  const char *start=  buffer->c_str();
4456
 
  const char *end= start + (buffer->length());
4457
 
  while (start < end && !isgraph(end[-1]))
 
4229
  char *start=  buffer->str;
 
4230
  char *end= start + (buffer->len);
 
4231
  while (start < end && !my_isgraph(charset_info,end[-1]))
4458
4232
    end--;
4459
 
  uint32_t pos_to_truncate= (end-start);
4460
 
  if (buffer->length() > pos_to_truncate)
4461
 
    buffer->erase(pos_to_truncate);
 
4233
  uint chars_to_truncate = end-start;
 
4234
  if (buffer->len > chars_to_truncate)
 
4235
    g_string_truncate(buffer, chars_to_truncate);
4462
4236
}
4463
4237
 
4464
4238
 
4506
4280
}
4507
4281
 
4508
4282
#include <sys/times.h>
4509
 
 
4510
 
static boost::posix_time::ptime start_timer(void)
4511
 
{
4512
 
  return boost::posix_time::microsec_clock::universal_time();
4513
 
}
4514
 
 
4515
 
static void nice_time(boost::posix_time::time_duration duration, string &buff)
4516
 
{
4517
 
  ostringstream tmp_buff_str;
4518
 
 
4519
 
  if (duration.hours() > 0)
4520
 
  {
4521
 
    tmp_buff_str << duration.hours();
4522
 
    if (duration.hours() > 1)
4523
 
      tmp_buff_str << _(" hours ");
4524
 
    else
4525
 
      tmp_buff_str << _(" hour ");
4526
 
  }
4527
 
  if (duration.hours() > 0 || duration.minutes() > 0)
4528
 
  {
4529
 
    tmp_buff_str << duration.minutes() << _(" min ");
4530
 
  }
4531
 
 
4532
 
  tmp_buff_str.precision(duration.num_fractional_digits());
4533
 
 
4534
 
  double seconds= duration.fractional_seconds();
4535
 
 
4536
 
  seconds/= pow(10.0,duration.num_fractional_digits());
4537
 
 
4538
 
  seconds+= duration.seconds();
4539
 
  tmp_buff_str << seconds << _(" sec");
4540
 
 
4541
 
  buff.append(tmp_buff_str.str());
4542
 
}
4543
 
 
4544
 
static void end_timer(boost::posix_time::ptime start_time, string &buff)
4545
 
{
4546
 
  boost::posix_time::ptime end_time= start_timer();
4547
 
  boost::posix_time::time_period duration(start_time, end_time);
4548
 
 
4549
 
  nice_time(duration.length(), buff);
4550
 
}
4551
 
 
4552
 
 
4553
 
static void drizzle_end_timer(boost::posix_time::ptime start_time, string &buff)
4554
 
{
4555
 
  buff.append(" (");
4556
 
  end_timer(start_time,buff);
4557
 
  buff.append(")");
 
4283
#ifdef _SC_CLK_TCK                              // For mit-pthreads
 
4284
#undef CLOCKS_PER_SEC
 
4285
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
 
4286
#endif
 
4287
 
 
4288
static ulong start_timer(void)
 
4289
{
 
4290
  struct tms tms_tmp;
 
4291
  return times(&tms_tmp);
 
4292
}
 
4293
 
 
4294
 
 
4295
/**
 
4296
   Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
 
4297
 
 
4298
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
 
4299
*/
 
4300
static void nice_time(double sec,char *buff,bool part_second)
 
4301
{
 
4302
  ulong tmp;
 
4303
  if (sec >= 3600.0*24)
 
4304
  {
 
4305
    tmp=(ulong) floor(sec/(3600.0*24));
 
4306
    sec-=3600.0*24*tmp;
 
4307
    buff=int10_to_str((long) tmp, buff, 10);
 
4308
    buff=strmov(buff,tmp > 1 ? " days " : " day ");
 
4309
  }
 
4310
  if (sec >= 3600.0)
 
4311
  {
 
4312
    tmp=(ulong) floor(sec/3600.0);
 
4313
    sec-=3600.0*tmp;
 
4314
    buff=int10_to_str((long) tmp, buff, 10);
 
4315
    buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
 
4316
  }
 
4317
  if (sec >= 60.0)
 
4318
  {
 
4319
    tmp=(ulong) floor(sec/60.0);
 
4320
    sec-=60.0*tmp;
 
4321
    buff=int10_to_str((long) tmp, buff, 10);
 
4322
    buff=strmov(buff," min ");
 
4323
  }
 
4324
  if (part_second)
 
4325
    sprintf(buff,"%.2f sec",sec);
 
4326
  else
 
4327
    sprintf(buff,"%d sec",(int) sec);
 
4328
}
 
4329
 
 
4330
 
 
4331
static void end_timer(ulong start_time,char *buff)
 
4332
{
 
4333
  nice_time((double) (start_timer() - start_time) /
 
4334
            CLOCKS_PER_SEC,buff,1);
 
4335
}
 
4336
 
 
4337
 
 
4338
static void mysql_end_timer(ulong start_time,char *buff)
 
4339
{
 
4340
  buff[0]=' ';
 
4341
  buff[1]='(';
 
4342
  end_timer(start_time,buff+2);
 
4343
  strmov(strend(buff),")");
4558
4344
}
4559
4345
 
4560
4346
static const char * construct_prompt()
4561
4347
{
4562
4348
  // Erase the old prompt
4563
4349
  assert(processed_prompt!=NULL);
4564
 
  processed_prompt->clear();
 
4350
  g_string_truncate(processed_prompt, 0);
4565
4351
 
4566
4352
  // Get the date struct
4567
4353
  time_t  lclock = time(NULL);
4568
4354
  struct tm *t = localtime(&lclock);
4569
4355
 
4570
4356
  /* parse thru the settings for the prompt */
4571
 
  string::iterator c= current_prompt.begin();
4572
 
  while (c != current_prompt.end())
 
4357
  for (char *c= current_prompt; *c; (void)*c++)
4573
4358
  {
4574
4359
    if (*c != PROMPT_CHAR)
4575
4360
    {
4576
 
      processed_prompt->push_back(*c);
 
4361
      g_string_append_c(processed_prompt, c[0]);
4577
4362
    }
4578
4363
    else
4579
4364
    {
4580
4365
      int getHour;
4581
4366
      int getYear;
4582
 
      /* Room for Dow MMM DD HH:MM:SS YYYY */ 
4583
 
      char dateTime[32];
 
4367
      char* dateTime= NULL;
4584
4368
      switch (*++c) {
4585
4369
      case '\0':
4586
4370
        // stop it from going beyond if ends with %
4587
 
        --c;
 
4371
        c--;
4588
4372
        break;
4589
4373
      case 'c':
4590
4374
        add_int_to_prompt(++prompt_counter);
4591
4375
        break;
4592
4376
      case 'v':
4593
4377
        if (connected)
4594
 
          processed_prompt->append(drizzle_con_server_version(&con));
 
4378
          g_string_append(processed_prompt, mysql_get_server_info(&mysql));
4595
4379
        else
4596
 
          processed_prompt->append("not_connected");
 
4380
          g_string_append(processed_prompt, "not_connected");
4597
4381
        break;
4598
4382
      case 'd':
4599
 
        processed_prompt->append(not current_db.empty() ? current_db : "(none)");
 
4383
        g_string_append(processed_prompt, current_db ? current_db : "(none)");
4600
4384
        break;
4601
4385
      case 'h':
4602
4386
      {
4603
 
        const char *prompt= connected ? drizzle_con_host(&con) : "not_connected";
 
4387
        const char *prompt;
 
4388
        prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4604
4389
        if (strstr(prompt, "Localhost"))
4605
 
          processed_prompt->append("localhost");
 
4390
          g_string_append(processed_prompt, "localhost");
4606
4391
        else
4607
4392
        {
4608
 
          const char *end=strrchr(prompt,' ');
4609
 
          if (end != NULL)
4610
 
            processed_prompt->append(prompt, (end-prompt));
 
4393
          const char *end=strcend(prompt,' ');
 
4394
          g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
4611
4395
        }
4612
4396
        break;
4613
4397
      }
4615
4399
      {
4616
4400
        if (!connected)
4617
4401
        {
4618
 
          processed_prompt->append("not_connected");
 
4402
          g_string_append(processed_prompt, "not_connected");
4619
4403
          break;
4620
4404
        }
4621
4405
 
4622
 
        if (drizzle_con_uds(&con))
 
4406
        const char *host_info = mysql_get_host_info(&mysql);
 
4407
        if (strstr(host_info, "memory"))
4623
4408
        {
4624
 
          const char *pos=strrchr(drizzle_con_uds(&con),'/');
4625
 
          processed_prompt->append(pos ? pos+1 : drizzle_con_uds(&con));
 
4409
          g_string_append(processed_prompt, mysql.host );
4626
4410
        }
 
4411
        else if (strstr(host_info,"TCP/IP") ||
 
4412
                 !mysql.unix_socket)
 
4413
          add_int_to_prompt(mysql.port);
4627
4414
        else
4628
 
          add_int_to_prompt(drizzle_con_port(&con));
 
4415
        {
 
4416
          char *pos=strrchr(mysql.unix_socket,'/');
 
4417
          g_string_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
 
4418
        }
4629
4419
      }
4630
4420
      break;
4631
4421
      case 'U':
4632
4422
        if (!full_username)
4633
4423
          init_username();
4634
 
        processed_prompt->append(full_username ? full_username :
4635
 
                                 (!current_user.empty() ?  current_user : "(unknown)"));
 
4424
        g_string_append(processed_prompt, full_username ? full_username :
 
4425
                        (current_user ?  current_user : "(unknown)"));
4636
4426
        break;
4637
4427
      case 'u':
4638
4428
        if (!full_username)
4639
4429
          init_username();
4640
 
        processed_prompt->append(part_username ? part_username :
4641
 
                                 (!current_user.empty() ?  current_user : _("(unknown)")));
 
4430
        g_string_append(processed_prompt, part_username ? part_username :
 
4431
                        (current_user ?  current_user : "(unknown)"));
4642
4432
        break;
4643
4433
      case PROMPT_CHAR:
4644
 
        {
4645
 
          processed_prompt->append(PROMPT_CHAR, 1);
4646
 
        }
 
4434
        g_string_append_c(processed_prompt, PROMPT_CHAR);
4647
4435
        break;
4648
4436
      case 'n':
4649
 
        {
4650
 
          processed_prompt->append('\n', 1);
4651
 
        }
 
4437
        g_string_append_c(processed_prompt, '\n');
4652
4438
        break;
4653
4439
      case ' ':
4654
4440
      case '_':
4655
 
        {
4656
 
          processed_prompt->append(' ', 1);
4657
 
        }
 
4441
        g_string_append_c(processed_prompt, ' ');
4658
4442
        break;
4659
4443
      case 'R':
4660
4444
        if (t->tm_hour < 10)
4661
 
          add_int_to_prompt(0);
 
4445
          g_string_append_c(processed_prompt, '0');
4662
4446
        add_int_to_prompt(t->tm_hour);
4663
4447
        break;
4664
4448
      case 'r':
4666
4450
        if (getHour == 0)
4667
4451
          getHour=12;
4668
4452
        if (getHour < 10)
4669
 
          add_int_to_prompt(0);
 
4453
          g_string_append_c(processed_prompt, '0');
4670
4454
        add_int_to_prompt(getHour);
4671
4455
        break;
4672
4456
      case 'm':
4673
4457
        if (t->tm_min < 10)
4674
 
          add_int_to_prompt(0);
 
4458
          g_string_append_c(processed_prompt, '0');
4675
4459
        add_int_to_prompt(t->tm_min);
4676
4460
        break;
4677
4461
      case 'y':
4678
4462
        getYear = t->tm_year % 100;
4679
4463
        if (getYear < 10)
4680
 
          add_int_to_prompt(0);
 
4464
          g_string_append_c(processed_prompt, '0');
4681
4465
        add_int_to_prompt(getYear);
4682
4466
        break;
4683
4467
      case 'Y':
4684
4468
        add_int_to_prompt(t->tm_year+1900);
4685
4469
        break;
4686
4470
      case 'D':
4687
 
        strftime(dateTime, 32, "%a %b %d %H:%M:%S %Y", localtime(&lclock));
4688
 
        processed_prompt->append(dateTime);
 
4471
        dateTime = ctime(&lclock);
 
4472
        g_string_append(processed_prompt, strtok(dateTime,"\n"));
4689
4473
        break;
4690
4474
      case 's':
4691
4475
        if (t->tm_sec < 10)
4692
 
          add_int_to_prompt(0);
 
4476
          g_string_append_c(processed_prompt, '0');
4693
4477
        add_int_to_prompt(t->tm_sec);
4694
4478
        break;
4695
4479
      case 'w':
4696
 
        processed_prompt->append(get_day_name(t->tm_wday));
 
4480
        g_string_append(processed_prompt, (day_names[t->tm_wday]));
4697
4481
        break;
4698
4482
      case 'P':
4699
 
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
 
4483
        g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4700
4484
        break;
4701
4485
      case 'o':
4702
4486
        add_int_to_prompt(t->tm_mon+1);
4703
4487
        break;
4704
4488
      case 'O':
4705
 
        processed_prompt->append(get_month_name(t->tm_mon));
 
4489
        g_string_append(processed_prompt, month_names[t->tm_mon]);
4706
4490
        break;
4707
4491
      case '\'':
4708
 
        processed_prompt->append("'");
 
4492
        g_string_append(processed_prompt, "'");
4709
4493
        break;
4710
4494
      case '"':
4711
 
        processed_prompt->append("\"");
 
4495
        g_string_append_c(processed_prompt, '"');
4712
4496
        break;
4713
4497
      case 'S':
4714
 
        processed_prompt->append(";");
 
4498
        g_string_append_c(processed_prompt, ';');
4715
4499
        break;
4716
4500
      case 't':
4717
 
        processed_prompt->append("\t");
 
4501
        g_string_append_c(processed_prompt, '\t');
4718
4502
        break;
4719
4503
      case 'l':
4720
 
        processed_prompt->append(delimiter_str);
 
4504
        g_string_append(processed_prompt, delimiter_str);
4721
4505
        break;
4722
4506
      default:
4723
 
        processed_prompt->push_back(*c);
 
4507
        g_string_append(processed_prompt, c);
4724
4508
      }
4725
4509
    }
4726
 
    ++c;
4727
4510
  }
4728
 
  return processed_prompt->c_str();
 
4511
  // TODO: Is this needed with GString?
 
4512
  g_string_append_c(processed_prompt, '\0');
 
4513
  return processed_prompt->str;
4729
4514
}
4730
4515
 
4731
4516
 
4732
4517
static void add_int_to_prompt(int toadd)
4733
4518
{
4734
 
  ostringstream buffer;
4735
 
  buffer << toadd;
4736
 
  processed_prompt->append(buffer.str().c_str());
 
4519
  char buffer[16];
 
4520
  int10_to_str(toadd,buffer,10);
 
4521
  g_string_append(processed_prompt, buffer);
4737
4522
}
4738
4523
 
4739
4524
static void init_username()
4740
4525
{
4741
 
/* XXX need this?
4742
 
  free(full_username);
4743
 
  free(part_username);
 
4526
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
4527
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
4744
4528
 
4745
 
  drizzle_result_st *result;
4746
 
  if (!drizzleclient_query(&drizzle,"select USER()") &&
4747
 
      (result=drizzleclient_use_result(&drizzle)))
 
4529
  MYSQL_RES *result;
 
4530
  if (!mysql_query(&mysql,"select USER()") &&
 
4531
      (result=mysql_use_result(&mysql)))
4748
4532
  {
4749
 
    drizzle_row_t cur=drizzleclient_fetch_row(result);
4750
 
    full_username= strdup(cur[0]);
4751
 
    part_username= strdup(strtok(cur[0],"@"));
4752
 
    (void) drizzleclient_fetch_row(result);        // Read eof
 
4533
    MYSQL_ROW cur=mysql_fetch_row(result);
 
4534
    full_username=g_strdup(cur[0]);
 
4535
    part_username=g_strdup(strtok(cur[0],"@"));
 
4536
    (void) mysql_fetch_row(result);             // Read eof
4753
4537
  }
4754
 
*/
4755
4538
}
4756
4539
 
4757
 
static int com_prompt(string *, const char *line)
 
4540
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
4758
4541
{
4759
 
  const char *ptr=strchr(line, ' ');
4760
 
  if (ptr == NULL)
4761
 
    tee_fprintf(stdout, _("Returning to default PROMPT of %s\n"),
4762
 
                default_prompt);
 
4542
  char *ptr=strchr(line, ' ');
4763
4543
  prompt_counter = 0;
4764
 
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
4765
 
  if (tmpptr == NULL)
4766
 
    tee_fprintf(stdout, _("Memory allocation error. Not changing prompt\n"));
 
4544
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
4545
  current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
 
4546
  if (!ptr)
 
4547
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
 
4548
                default_prompt->str);
4767
4549
  else
4768
 
  {
4769
 
    current_prompt.erase();
4770
 
    current_prompt= tmpptr;
4771
 
    tee_fprintf(stdout, _("PROMPT set to '%s'\n"), current_prompt.c_str());
4772
 
  }
 
4550
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4773
4551
  return 0;
4774
4552
}
4775
 
 
4776
 
/*
4777
 
    strcont(str, set) if str contanies any character in the string set.
4778
 
    The result is the position of the first found character in str, or NULL
4779
 
    if there isn't anything found.
4780
 
*/
4781
 
 
4782
 
static const char * strcont(const char *str, const char *set)
4783
 
{
4784
 
  const char * start = (const char *) set;
4785
 
 
4786
 
  while (*str)
4787
 
  {
4788
 
    while (*set)
4789
 
    {
4790
 
      if (*set++ == *str)
4791
 
        return ((const char*) str);
4792
 
    }
4793
 
    set=start; str++;
4794
 
  }
4795
 
  return NULL;
4796
 
} /* strcont */