~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-07-22 23:26:26 UTC
  • mto: (1039.5.43 replication)
  • mto: This revision was merged to the branch mainline in revision 1130.
  • Revision ID: osullivan.padraig@gmail.com-20090722232626-mu4khq7ho6dqcf7q
Created a simple filtered replicator that can filter by schema name or table
name.

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
34
33
 *
35
34
 **/
36
35
 
37
 
#include "config.h"
38
 
#include <libdrizzle/drizzle_client.h>
39
 
 
40
 
#include "client/get_password.h"
41
 
 
42
 
#include "boost/date_time/posix_time/posix_time.hpp"
43
 
 
44
 
#include <cerrno>
 
36
#include "client_priv.h"
45
37
#include <string>
46
 
#include <drizzled/gettext.h>
47
 
#include <iostream>
48
 
#include <fstream>
49
 
#include <map>
50
38
#include <algorithm>
51
 
#include <limits.h>
52
 
#include <cassert>
 
39
#include <mystrings/m_ctype.h>
53
40
#include <stdarg.h>
54
 
#include <math.h>
55
 
#include <memory>
56
 
#include "client/linebuffer.h"
 
41
#include "client/my_readline.h"
57
42
#include <signal.h>
58
43
#include <sys/ioctl.h>
59
44
#include <drizzled/configmake.h>
60
 
#include "drizzled/utf8/utf8.h"
61
 
#include <cstdlib>
62
45
 
63
46
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
64
47
#include <curses.h>
116
99
    /* no history */
117
100
#endif /* HAVE_READLINE_HISTORY */
118
101
 
 
102
#define DRIZZLE_DEFAULT_INPUT_LINE 65536
 
103
 
119
104
/**
120
105
 Make the old readline interface look like the new one.
121
106
*/
122
 
#ifndef HAVE_RL_COMPLETION
123
 
typedef char **rl_completion_func_t(const char *, int, int);
 
107
#ifndef USE_NEW_READLINE_INTERFACE
 
108
typedef CPPFunction rl_completion_func_t;
 
109
typedef Function rl_compentry_func_t;
124
110
#define rl_completion_matches(str, func) \
125
111
  completion_matches((char *)str, (CPFunction *)func)
126
112
#endif
127
113
 
128
 
#ifdef HAVE_RL_COMPENTRY
129
 
# ifdef HAVE_WORKING_RL_COMPENTRY
130
 
typedef rl_compentry_func_t drizzle_compentry_func_t;
131
 
# else
132
 
/* Snow Leopard ships an rl_compentry which cannot be assigned to
133
 
 * rl_completion_entry_function. We must undo the complete and total
134
 
 * ass-bagery.
135
 
 */
136
 
typedef Function drizzle_compentry_func_t;
137
 
# endif
138
 
#else
139
 
typedef Function drizzle_compentry_func_t;
140
 
#endif
141
 
 
142
114
#if defined(HAVE_LOCALE_H)
143
115
#include <locale.h>
144
116
#endif
145
117
 
 
118
#include <drizzled/gettext.h>
 
119
 
 
120
 
 
121
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
 
122
void sql_element_free(void *ptr);
146
123
 
147
124
 
148
125
#if !defined(HAVE_VIDATTR)
149
126
#undef vidattr
150
127
#define vidattr(A) {}      // Can't get this to work
151
128
#endif
152
 
#include <boost/program_options.hpp>
153
 
#include <boost/scoped_ptr.hpp>
154
 
#include "drizzled/program_options/config_file.h"
 
129
 
 
130
#include <iostream>
 
131
#include <map>
155
132
 
156
133
using namespace std;
157
 
namespace po=boost::program_options;
158
 
namespace dpo=drizzled::program_options;
159
134
 
 
135
const string VER("14.14");
160
136
/* Don't try to make a nice table if the data is too big */
161
137
const uint32_t MAX_COLUMN_LENGTH= 1024;
162
138
 
164
140
const int MAX_SERVER_VERSION_LENGTH= 128;
165
141
 
166
142
#define PROMPT_CHAR '\\'
 
143
#define DEFAULT_DELIMITER ";"
167
144
 
168
 
class Status
 
145
typedef struct st_status
169
146
{
170
 
public:
171
 
 
172
 
  Status(int in_exit_status, 
173
 
         uint32_t in_query_start_line,
174
 
         char *in_file_name,
175
 
         LineBuffer *in_line_buff,
176
 
         bool in_batch,
177
 
         bool in_add_to_history)
178
 
    :
179
 
    exit_status(in_exit_status),
180
 
    query_start_line(in_query_start_line),
181
 
    file_name(in_file_name),
182
 
    line_buff(in_line_buff),
183
 
    batch(in_batch),
184
 
    add_to_history(in_add_to_history)
185
 
    {}
186
 
 
187
 
  Status() :
188
 
    exit_status(0),
189
 
    query_start_line(0),
190
 
    file_name(NULL),
191
 
    line_buff(NULL),
192
 
    batch(false),        
193
 
    add_to_history(false)
194
 
  {}
195
 
  
196
 
  int getExitStatus() const
197
 
  {
198
 
    return exit_status;
199
 
  }
200
 
 
201
 
  uint32_t getQueryStartLine() const
202
 
  {
203
 
    return query_start_line;
204
 
  }
205
 
 
206
 
  const char *getFileName() const
207
 
  {
208
 
    return file_name;
209
 
  }
210
 
 
211
 
  LineBuffer *getLineBuff() const
212
 
  {
213
 
    return line_buff;
214
 
  }
215
 
 
216
 
  bool getBatch() const
217
 
  {
218
 
    return batch;
219
 
  }
220
 
 
221
 
  bool getAddToHistory() const
222
 
  {
223
 
    return add_to_history;
224
 
  }
225
 
 
226
 
  void setExitStatus(int in_exit_status)
227
 
  {
228
 
    exit_status= in_exit_status;
229
 
  }
230
 
 
231
 
  void setQueryStartLine(uint32_t in_query_start_line)
232
 
  {
233
 
    query_start_line= in_query_start_line;
234
 
  }
235
 
 
236
 
  void setFileName(char *in_file_name)
237
 
  {
238
 
    file_name= in_file_name;
239
 
  }
240
 
 
241
 
  void setLineBuff(int max_size, FILE *file=NULL)
242
 
  {
243
 
    line_buff= new(std::nothrow) LineBuffer(max_size, file);
244
 
  }
245
 
 
246
 
  void setLineBuff(LineBuffer *in_line_buff)
247
 
  {
248
 
    line_buff= in_line_buff;
249
 
  }
250
 
 
251
 
  void setBatch(bool in_batch)
252
 
  {
253
 
    batch= in_batch;
254
 
  }
255
 
 
256
 
  void setAddToHistory(bool in_add_to_history)
257
 
  {
258
 
    add_to_history= in_add_to_history;
259
 
  }
260
 
 
261
 
private:
262
147
  int exit_status;
263
148
  uint32_t query_start_line;
264
149
  char *file_name;
265
 
  LineBuffer *line_buff;
 
150
  LINE_BUFFER *line_buff;
266
151
  bool batch,add_to_history;
267
 
}; 
 
152
} STATUS;
 
153
 
268
154
 
269
155
static map<string, string>::iterator completion_iter;
270
156
static map<string, string>::iterator completion_end;
271
157
static map<string, string> completion_map;
272
158
static string completion_string;
273
159
 
 
160
static char **defaults_argv;
274
161
 
275
162
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
276
163
typedef enum enum_info_type INFO_TYPE;
281
168
  connected= false, opt_raw_data= false, unbuffered= false,
282
169
  output_tables= false, opt_rehash= true, skip_updates= false,
283
170
  safe_updates= false, one_database= false,
284
 
  opt_shutdown= false, opt_ping= false,
 
171
  opt_compress= false, opt_shutdown= false, opt_ping= false,
285
172
  vertical= false, line_numbers= true, column_names= true,
286
173
  opt_nopager= true, opt_outfile= false, named_cmds= false,
287
 
  opt_nobeep= false, opt_reconnect= true,
288
 
  opt_secure_auth= false,
 
174
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
175
  default_charset_used= false, opt_secure_auth= false,
289
176
  default_pager_set= false, opt_sigint_ignore= false,
290
177
  auto_vertical_output= false,
291
 
  show_warnings= false, executing_query= false, interrupted_query= false,
292
 
  use_drizzle_protocol= false, opt_local_infile;
293
 
static uint32_t show_progress_size= 0;
 
178
  show_warnings= false, executing_query= false, interrupted_query= false;
 
179
static uint32_t  show_progress_size= 0;
 
180
static bool debug_info_flag, debug_check_flag;
294
181
static bool column_types_flag;
295
182
static bool preserve_comments= false;
296
 
static uint32_t opt_max_input_line;
297
 
static uint32_t opt_drizzle_port= 0;
298
 
static int  opt_silent, verbose= 0;
 
183
static uint32_t opt_max_input_line, opt_drizzle_port= 0;
 
184
static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
 
185
static uint32_t my_end_arg;
 
186
static char * opt_drizzle_unix_port= NULL;
299
187
static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
 
188
static char *current_host, *current_db, *current_user= NULL,
 
189
  *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
300
190
static char *histfile;
301
191
static char *histfile_tmp;
302
192
static string *glob_buffer;
303
193
static string *processed_prompt= NULL;
304
194
static char *default_prompt= NULL;
305
195
static char *full_username= NULL,*part_username= NULL;
306
 
static Status status;
 
196
static STATUS status;
307
197
static uint32_t select_limit;
308
198
static uint32_t max_join_size;
309
199
static uint32_t opt_connect_timeout= 0;
310
 
std::string current_db,
311
 
  delimiter_str,  
312
 
  current_host,
313
 
  current_prompt,
314
 
  current_user,
315
 
  opt_verbose,
316
 
  current_password,
317
 
  opt_password,
318
 
  opt_protocol;
319
 
 
320
 
static const char* get_day_name(int day_of_week)
321
 
{
322
 
  switch(day_of_week)
323
 
  {
324
 
  case 0:
325
 
    return _("Sun");
326
 
  case 1:
327
 
    return _("Mon");
328
 
  case 2:
329
 
    return _("Tue");
330
 
  case 3:
331
 
    return _("Wed");
332
 
  case 4:
333
 
    return _("Thu");
334
 
  case 5:
335
 
    return _("Fri");
336
 
  case 6:
337
 
    return _("Sat");
338
 
  }
339
 
 
340
 
  return NULL;
341
 
}
342
 
 
343
 
static const char* get_month_name(int month)
344
 
{
345
 
  switch(month)
346
 
  {
347
 
  case 0:
348
 
    return _("Jan");
349
 
  case 1:
350
 
    return _("Feb");
351
 
  case 2:
352
 
    return _("Mar");
353
 
  case 3:
354
 
    return _("Apr");
355
 
  case 4:
356
 
    return _("May");
357
 
  case 5:
358
 
    return _("Jun");
359
 
  case 6:
360
 
    return _("Jul");
361
 
  case 7:
362
 
    return _("Aug");
363
 
  case 8:
364
 
    return _("Sep");
365
 
  case 9:
366
 
    return _("Oct");
367
 
  case 10:
368
 
    return _("Nov");
369
 
  case 11:
370
 
    return _("Dec");
371
 
  }
372
 
 
373
 
  return NULL;
374
 
}
375
 
 
376
 
/* @TODO: Remove this */
377
 
#define FN_REFLEN 512
378
 
 
379
 
static string default_pager("");
380
 
static string pager("");
381
 
static string outfile("");
 
200
// TODO: Need to i18n these
 
201
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
202
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
203
                                  "Aug","Sep","Oct","Nov","Dec"};
 
204
static char default_pager[FN_REFLEN];
 
205
static char pager[FN_REFLEN], outfile[FN_REFLEN];
382
206
static FILE *PAGER, *OUTFILE;
383
207
static uint32_t prompt_counter;
384
 
static char *delimiter= NULL;
 
208
static char delimiter[16]= DEFAULT_DELIMITER;
385
209
static uint32_t delimiter_length= 1;
386
210
unsigned short terminal_width= 80;
387
211
 
388
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
 
212
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
 
213
 
 
214
int drizzleclient_real_query_for_lazy(const char *buf, int length,
389
215
                                      drizzle_result_st *result,
390
216
                                      uint32_t *error_code);
391
217
int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
397
223
void tee_putc(int c, FILE *file);
398
224
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
399
225
/* The names of functions that actually do the manipulation. */
400
 
static int process_options(void);
 
226
static int get_options(int argc,char **argv);
 
227
extern "C" bool get_one_option(int optid, const struct my_option *opt,
 
228
                               char *argument);
401
229
static int com_quit(string *str,const char*),
402
230
  com_go(string *str,const char*), com_ego(string *str,const char*),
403
231
  com_print(string *str,const char*),
404
232
  com_help(string *str,const char*), com_clear(string *str,const char*),
405
233
  com_connect(string *str,const char*), com_status(string *str,const char*),
406
234
  com_use(string *str,const char*), com_source(string *str, const char*),
407
 
  com_shutdown(string *str,const char*),
408
235
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
409
236
  com_notee(string *str, const char*),
410
237
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
412
239
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
413
240
 
414
241
static int read_and_execute(bool interactive);
415
 
static int sql_connect(const string &host, const string &database, const string &user, const string &password);
 
242
static int sql_connect(char *host,char *database,char *user,char *password,
 
243
                       uint32_t silent);
416
244
static const char *server_version_string(drizzle_con_st *con);
417
245
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
418
246
                    const char *sql_state);
430
258
static int get_field_disp_length(drizzle_column_st * field);
431
259
static const char * strcont(register const char *str, register const char *set);
432
260
 
433
 
/* A class which contains information on the commands this program
 
261
/* A structure which contains information on the commands this program
434
262
   can understand. */
435
 
class Commands
436
 
{
437
 
private:
 
263
typedef struct {
438
264
  const char *name;        /* User printable name of the function. */
439
265
  char cmd_char;        /* msql command character */
440
 
public:
441
 
Commands(const char *in_name,
442
 
         char in_cmd_char,
443
 
         int (*in_func)(string *str,const char *name),
444
 
         bool in_takes_params,
445
 
         const char *in_doc)
446
 
  :
447
 
  name(in_name),
448
 
  cmd_char(in_cmd_char),
449
 
  func(in_func),
450
 
  takes_params(in_takes_params),
451
 
  doc(in_doc)
452
 
  {}
453
 
 
454
 
  Commands()
455
 
  :
456
 
  name(),
457
 
  cmd_char(),
458
 
  func(NULL),
459
 
  takes_params(false),
460
 
  doc()
461
 
  {}
462
 
 
463
 
  int (*func)(string *str,const char *);/* Function to call to do the job. */
464
 
 
465
 
  const char *getName() const
466
 
  {
467
 
    return name;
468
 
  }
469
 
 
470
 
  char getCmdChar() const
471
 
  {
472
 
    return cmd_char;
473
 
  }
474
 
 
475
 
  bool getTakesParams() const
476
 
  {
477
 
    return takes_params;
478
 
  }
479
 
 
480
 
  const char *getDoc() const
481
 
  {
482
 
    return doc;
483
 
  }
484
 
 
485
 
  void setName(const char *in_name)
486
 
  {
487
 
     name= in_name;
488
 
  }
489
 
 
490
 
  void setCmdChar(char in_cmd_char)
491
 
  {
492
 
    cmd_char= in_cmd_char;
493
 
  }
494
 
 
495
 
  void setTakesParams(bool in_takes_params)
496
 
  {
497
 
    takes_params= in_takes_params;
498
 
  }
499
 
 
500
 
  void setDoc(const char *in_doc)
501
 
  {
502
 
    doc= in_doc;
503
 
  }
504
 
 
505
 
private:
 
266
  int (*func)(string *str,const char *); /* Function to call to do the job. */
506
267
  bool takes_params;        /* Max parameters for command */
507
268
  const char *doc;        /* Documentation for this function.  */
508
 
}; 
509
 
 
510
 
 
511
 
static Commands commands[] = {
512
 
  Commands( "?",      '?', com_help,   0, N_("Synonym for `help'.") ),
513
 
  Commands( "clear",  'c', com_clear,  0, N_("Clear command.")),
514
 
  Commands( "connect",'r', com_connect,1,
515
 
    N_("Reconnect to the server. Optional arguments are db and host.")),
516
 
  Commands( "delimiter", 'd', com_delimiter,    1,
517
 
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") ),
518
 
  Commands( "ego",    'G', com_ego,    0,
519
 
    N_("Send command to drizzle server, display result vertically.")),
520
 
  Commands( "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")),
521
 
  Commands( "go",     'g', com_go,     0, N_("Send command to drizzle server.") ),
522
 
  Commands( "help",   'h', com_help,   0, N_("Display this help.") ),
523
 
  Commands( "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") ),
524
 
  Commands( "notee",  't', com_notee,  0, N_("Don't write into outfile.") ),
525
 
  Commands( "pager",  'P', com_pager,  1,
526
 
    N_("Set PAGER [to_pager]. Print the query results via PAGER.") ),
527
 
  Commands( "print",  'p', com_print,  0, N_("Print current command.") ),
528
 
  Commands( "prompt", 'R', com_prompt, 1, N_("Change your drizzle prompt.")),
529
 
  Commands( "quit",   'q', com_quit,   0, N_("Quit drizzle.") ),
530
 
  Commands( "rehash", '#', com_rehash, 0, N_("Rebuild completion hash.") ),
531
 
  Commands( "source", '.', com_source, 1,
532
 
    N_("Execute an SQL script file. Takes a file name as an argument.")),
533
 
  Commands( "status", 's', com_status, 0, N_("Get status information from the server.")),
534
 
  Commands( "tee",    'T', com_tee,    1,
535
 
    N_("Set outfile [to_outfile]. Append everything into given outfile.") ),
536
 
  Commands( "use",    'u', com_use,    1,
537
 
    N_("Use another schema. Takes schema name as argument.") ),
538
 
  Commands( "shutdown",    'u', com_shutdown,    1,
539
 
    N_("Shutdown the instance you are connected too.") ),
540
 
  Commands( "warnings", 'W', com_warnings,  0,
541
 
    N_("Show warnings after every statement.") ),
542
 
  Commands( "nowarning", 'w', com_nowarnings, 0,
543
 
    N_("Don't show warnings after every statement.") ),
 
269
} COMMANDS;
 
270
 
 
271
 
 
272
static COMMANDS commands[] = {
 
273
  { "?",      '?', com_help,   0, N_("Synonym for `help'.") },
 
274
  { "clear",  'c', com_clear,  0, N_("Clear command.")},
 
275
  { "connect",'r', com_connect,1,
 
276
    N_("Reconnect to the server. Optional arguments are db and host.")},
 
277
  { "delimiter", 'd', com_delimiter,    1,
 
278
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") },
 
279
  { "ego",    'G', com_ego,    0,
 
280
    N_("Send command to drizzle server, display result vertically.")},
 
281
  { "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")},
 
282
  { "go",     'g', com_go,     0, N_("Send command to drizzle server.") },
 
283
  { "help",   'h', com_help,   0, N_("Display this help.") },
 
284
  { "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") },
 
285
  { "notee",  't', com_notee,  0, N_("Don't write into outfile.") },
 
286
  { "pager",  'P', com_pager,  1,
 
287
    N_("Set PAGER [to_pager]. Print the query results via PAGER.") },
 
288
  { "print",  'p', com_print,  0, N_("Print current command.") },
 
289
  { "prompt", 'R', com_prompt, 1, N_("Change your drizzle prompt.")},
 
290
  { "quit",   'q', com_quit,   0, N_("Quit drizzle.") },
 
291
  { "rehash", '#', com_rehash, 0, N_("Rebuild completion hash.") },
 
292
  { "source", '.', com_source, 1,
 
293
    N_("Execute an SQL script file. Takes a file name as an argument.")},
 
294
  { "status", 's', com_status, 0, N_("Get status information from the server.")},
 
295
  { "tee",    'T', com_tee,    1,
 
296
    N_("Set outfile [to_outfile]. Append everything into given outfile.") },
 
297
  { "use",    'u', com_use,    1,
 
298
    N_("Use another database. Takes database name as argument.") },
 
299
  { "warnings", 'W', com_warnings,  0,
 
300
    N_("Show warnings after every statement.") },
 
301
  { "nowarning", 'w', com_nowarnings, 0,
 
302
    N_("Don't show warnings after every statement.") },
544
303
  /* Get bash-like expansion for some commands */
545
 
  Commands( "create table",     0, 0, 0, ""),
546
 
  Commands( "create database",  0, 0, 0, ""),
547
 
  Commands( "show databases",   0, 0, 0, ""),
548
 
  Commands( "show fields from", 0, 0, 0, ""),
549
 
  Commands( "show keys from",   0, 0, 0, ""),
550
 
  Commands( "show tables",      0, 0, 0, ""),
551
 
  Commands( "load data from",   0, 0, 0, ""),
552
 
  Commands( "alter table",      0, 0, 0, ""),
553
 
  Commands( "set option",       0, 0, 0, ""),
554
 
  Commands( "lock tables",      0, 0, 0, ""),
555
 
  Commands( "unlock tables",    0, 0, 0, ""),
 
304
  { "create table",     0, 0, 0, ""},
 
305
  { "create database",  0, 0, 0, ""},
 
306
  { "show databases",   0, 0, 0, ""},
 
307
  { "show fields from", 0, 0, 0, ""},
 
308
  { "show keys from",   0, 0, 0, ""},
 
309
  { "show tables",      0, 0, 0, ""},
 
310
  { "load data from",   0, 0, 0, ""},
 
311
  { "alter table",      0, 0, 0, ""},
 
312
  { "set option",       0, 0, 0, ""},
 
313
  { "lock tables",      0, 0, 0, ""},
 
314
  { "unlock tables",    0, 0, 0, ""},
556
315
  /* generated 2006-12-28.  Refresh occasionally from lexer. */
557
 
  Commands( "ACTION", 0, 0, 0, ""),
558
 
  Commands( "ADD", 0, 0, 0, ""),
559
 
  Commands( "AFTER", 0, 0, 0, ""),
560
 
  Commands( "AGAINST", 0, 0, 0, ""),
561
 
  Commands( "AGGREGATE", 0, 0, 0, ""),
562
 
  Commands( "ALL", 0, 0, 0, ""),
563
 
  Commands( "ALGORITHM", 0, 0, 0, ""),
564
 
  Commands( "ALTER", 0, 0, 0, ""),
565
 
  Commands( "ANALYZE", 0, 0, 0, ""),
566
 
  Commands( "AND", 0, 0, 0, ""),
567
 
  Commands( "ANY", 0, 0, 0, ""),
568
 
  Commands( "AS", 0, 0, 0, ""),
569
 
  Commands( "ASC", 0, 0, 0, ""),
570
 
  Commands( "ASCII", 0, 0, 0, ""),
571
 
  Commands( "ASENSITIVE", 0, 0, 0, ""),
572
 
  Commands( "AUTO_INCREMENT", 0, 0, 0, ""),
573
 
  Commands( "AVG", 0, 0, 0, ""),
574
 
  Commands( "AVG_ROW_LENGTH", 0, 0, 0, ""),
575
 
  Commands( "BEFORE", 0, 0, 0, ""),
576
 
  Commands( "BEGIN", 0, 0, 0, ""),
577
 
  Commands( "BETWEEN", 0, 0, 0, ""),
578
 
  Commands( "BIGINT", 0, 0, 0, ""),
579
 
  Commands( "BINARY", 0, 0, 0, ""),
580
 
  Commands( "BIT", 0, 0, 0, ""),
581
 
  Commands( "BLOB", 0, 0, 0, ""),
582
 
  Commands( "BOOL", 0, 0, 0, ""),
583
 
  Commands( "BOOLEAN", 0, 0, 0, ""),
584
 
  Commands( "BOTH", 0, 0, 0, ""),
585
 
  Commands( "BTREE", 0, 0, 0, ""),
586
 
  Commands( "BY", 0, 0, 0, ""),
587
 
  Commands( "BYTE", 0, 0, 0, ""),
588
 
  Commands( "CACHE", 0, 0, 0, ""),
589
 
  Commands( "CALL", 0, 0, 0, ""),
590
 
  Commands( "CASCADE", 0, 0, 0, ""),
591
 
  Commands( "CASCADED", 0, 0, 0, ""),
592
 
  Commands( "CASE", 0, 0, 0, ""),
593
 
  Commands( "CHAIN", 0, 0, 0, ""),
594
 
  Commands( "CHANGE", 0, 0, 0, ""),
595
 
  Commands( "CHANGED", 0, 0, 0, ""),
596
 
  Commands( "CHAR", 0, 0, 0, ""),
597
 
  Commands( "CHARACTER", 0, 0, 0, ""),
598
 
  Commands( "CHECK", 0, 0, 0, ""),
599
 
  Commands( "CHECKSUM", 0, 0, 0, ""),
600
 
  Commands( "CLIENT", 0, 0, 0, ""),
601
 
  Commands( "CLOSE", 0, 0, 0, ""),
602
 
  Commands( "COLLATE", 0, 0, 0, ""),
603
 
  Commands( "COLLATION", 0, 0, 0, ""),
604
 
  Commands( "COLUMN", 0, 0, 0, ""),
605
 
  Commands( "COLUMNS", 0, 0, 0, ""),
606
 
  Commands( "COMMENT", 0, 0, 0, ""),
607
 
  Commands( "COMMIT", 0, 0, 0, ""),
608
 
  Commands( "COMMITTED", 0, 0, 0, ""),
609
 
  Commands( "COMPACT", 0, 0, 0, ""),
610
 
  Commands( "COMPRESSED", 0, 0, 0, ""),
611
 
  Commands( "CONCURRENT", 0, 0, 0, ""),
612
 
  Commands( "CONDITION", 0, 0, 0, ""),
613
 
  Commands( "CONNECTION", 0, 0, 0, ""),
614
 
  Commands( "CONSISTENT", 0, 0, 0, ""),
615
 
  Commands( "CONSTRAINT", 0, 0, 0, ""),
616
 
  Commands( "CONTAINS", 0, 0, 0, ""),
617
 
  Commands( "CONTINUE", 0, 0, 0, ""),
618
 
  Commands( "CONVERT", 0, 0, 0, ""),
619
 
  Commands( "CREATE", 0, 0, 0, ""),
620
 
  Commands( "CROSS", 0, 0, 0, ""),
621
 
  Commands( "CUBE", 0, 0, 0, ""),
622
 
  Commands( "CURRENT_DATE", 0, 0, 0, ""),
623
 
  Commands( "CURRENT_TIMESTAMP", 0, 0, 0, ""),
624
 
  Commands( "CURRENT_USER", 0, 0, 0, ""),
625
 
  Commands( "CURSOR", 0, 0, 0, ""),
626
 
  Commands( "DATA", 0, 0, 0, ""),
627
 
  Commands( "DATABASE", 0, 0, 0, ""),
628
 
  Commands( "DATABASES", 0, 0, 0, ""),
629
 
  Commands( "DATE", 0, 0, 0, ""),
630
 
  Commands( "DATETIME", 0, 0, 0, ""),
631
 
  Commands( "DAY", 0, 0, 0, ""),
632
 
  Commands( "DAY_HOUR", 0, 0, 0, ""),
633
 
  Commands( "DAY_MICROSECOND", 0, 0, 0, ""),
634
 
  Commands( "DAY_MINUTE", 0, 0, 0, ""),
635
 
  Commands( "DAY_SECOND", 0, 0, 0, ""),
636
 
  Commands( "DEALLOCATE", 0, 0, 0, ""),
637
 
  Commands( "DEC", 0, 0, 0, ""),
638
 
  Commands( "DECIMAL", 0, 0, 0, ""),
639
 
  Commands( "DECLARE", 0, 0, 0, ""),
640
 
  Commands( "DEFAULT", 0, 0, 0, ""),
641
 
  Commands( "DEFINER", 0, 0, 0, ""),
642
 
  Commands( "DELAYED", 0, 0, 0, ""),
643
 
  Commands( "DELETE", 0, 0, 0, ""),
644
 
  Commands( "DESC", 0, 0, 0, ""),
645
 
  Commands( "DESCRIBE", 0, 0, 0, ""),
646
 
  Commands( "DETERMINISTIC", 0, 0, 0, ""),
647
 
  Commands( "DISABLE", 0, 0, 0, ""),
648
 
  Commands( "DISCARD", 0, 0, 0, ""),
649
 
  Commands( "DISTINCT", 0, 0, 0, ""),
650
 
  Commands( "DISTINCTROW", 0, 0, 0, ""),
651
 
  Commands( "DIV", 0, 0, 0, ""),
652
 
  Commands( "DOUBLE", 0, 0, 0, ""),
653
 
  Commands( "DROP", 0, 0, 0, ""),
654
 
  Commands( "DUMPFILE", 0, 0, 0, ""),
655
 
  Commands( "DUPLICATE", 0, 0, 0, ""),
656
 
  Commands( "DYNAMIC", 0, 0, 0, ""),
657
 
  Commands( "EACH", 0, 0, 0, ""),
658
 
  Commands( "ELSE", 0, 0, 0, ""),
659
 
  Commands( "ELSEIF", 0, 0, 0, ""),
660
 
  Commands( "ENABLE", 0, 0, 0, ""),
661
 
  Commands( "ENCLOSED", 0, 0, 0, ""),
662
 
  Commands( "END", 0, 0, 0, ""),
663
 
  Commands( "ENGINE", 0, 0, 0, ""),
664
 
  Commands( "ENGINES", 0, 0, 0, ""),
665
 
  Commands( "ENUM", 0, 0, 0, ""),
666
 
  Commands( "ERRORS", 0, 0, 0, ""),
667
 
  Commands( "ESCAPE", 0, 0, 0, ""),
668
 
  Commands( "ESCAPED", 0, 0, 0, ""),
669
 
  Commands( "EXISTS", 0, 0, 0, ""),
670
 
  Commands( "EXIT", 0, 0, 0, ""),
671
 
  Commands( "EXPLAIN", 0, 0, 0, ""),
672
 
  Commands( "EXTENDED", 0, 0, 0, ""),
673
 
  Commands( "FALSE", 0, 0, 0, ""),
674
 
  Commands( "FAST", 0, 0, 0, ""),
675
 
  Commands( "FETCH", 0, 0, 0, ""),
676
 
  Commands( "FIELDS", 0, 0, 0, ""),
677
 
  Commands( "FILE", 0, 0, 0, ""),
678
 
  Commands( "FIRST", 0, 0, 0, ""),
679
 
  Commands( "FIXED", 0, 0, 0, ""),
680
 
  Commands( "FLOAT", 0, 0, 0, ""),
681
 
  Commands( "FLOAT4", 0, 0, 0, ""),
682
 
  Commands( "FLOAT8", 0, 0, 0, ""),
683
 
  Commands( "FLUSH", 0, 0, 0, ""),
684
 
  Commands( "FOR", 0, 0, 0, ""),
685
 
  Commands( "FORCE", 0, 0, 0, ""),
686
 
  Commands( "FOREIGN", 0, 0, 0, ""),
687
 
  Commands( "FOUND", 0, 0, 0, ""),
688
 
  Commands( "FRAC_SECOND", 0, 0, 0, ""),
689
 
  Commands( "FROM", 0, 0, 0, ""),
690
 
  Commands( "FULL", 0, 0, 0, ""),
691
 
  Commands( "FUNCTION", 0, 0, 0, ""),
692
 
  Commands( "GLOBAL", 0, 0, 0, ""),
693
 
  Commands( "GRANT", 0, 0, 0, ""),
694
 
  Commands( "GRANTS", 0, 0, 0, ""),
695
 
  Commands( "GROUP", 0, 0, 0, ""),
696
 
  Commands( "HANDLER", 0, 0, 0, ""),
697
 
  Commands( "HASH", 0, 0, 0, ""),
698
 
  Commands( "HAVING", 0, 0, 0, ""),
699
 
  Commands( "HELP", 0, 0, 0, ""),
700
 
  Commands( "HIGH_PRIORITY", 0, 0, 0, ""),
701
 
  Commands( "HOSTS", 0, 0, 0, ""),
702
 
  Commands( "HOUR", 0, 0, 0, ""),
703
 
  Commands( "HOUR_MICROSECOND", 0, 0, 0, ""),
704
 
  Commands( "HOUR_MINUTE", 0, 0, 0, ""),
705
 
  Commands( "HOUR_SECOND", 0, 0, 0, ""),
706
 
  Commands( "IDENTIFIED", 0, 0, 0, ""),
707
 
  Commands( "IF", 0, 0, 0, ""),
708
 
  Commands( "IGNORE", 0, 0, 0, ""),
709
 
  Commands( "IMPORT", 0, 0, 0, ""),
710
 
  Commands( "IN", 0, 0, 0, ""),
711
 
  Commands( "INDEX", 0, 0, 0, ""),
712
 
  Commands( "INDEXES", 0, 0, 0, ""),
713
 
  Commands( "INFILE", 0, 0, 0, ""),
714
 
  Commands( "INNER", 0, 0, 0, ""),
715
 
  Commands( "INNOBASE", 0, 0, 0, ""),
716
 
  Commands( "INNODB", 0, 0, 0, ""),
717
 
  Commands( "INOUT", 0, 0, 0, ""),
718
 
  Commands( "INSENSITIVE", 0, 0, 0, ""),
719
 
  Commands( "INSERT", 0, 0, 0, ""),
720
 
  Commands( "INSERT_METHOD", 0, 0, 0, ""),
721
 
  Commands( "INT", 0, 0, 0, ""),
722
 
  Commands( "INT1", 0, 0, 0, ""),
723
 
  Commands( "INT2", 0, 0, 0, ""),
724
 
  Commands( "INT3", 0, 0, 0, ""),
725
 
  Commands( "INT4", 0, 0, 0, ""),
726
 
  Commands( "INT8", 0, 0, 0, ""),
727
 
  Commands( "INTEGER", 0, 0, 0, ""),
728
 
  Commands( "INTERVAL", 0, 0, 0, ""),
729
 
  Commands( "INTO", 0, 0, 0, ""),
730
 
  Commands( "IO_THREAD", 0, 0, 0, ""),
731
 
  Commands( "IS", 0, 0, 0, ""),
732
 
  Commands( "ISOLATION", 0, 0, 0, ""),
733
 
  Commands( "ISSUER", 0, 0, 0, ""),
734
 
  Commands( "ITERATE", 0, 0, 0, ""),
735
 
  Commands( "INVOKER", 0, 0, 0, ""),
736
 
  Commands( "JOIN", 0, 0, 0, ""),
737
 
  Commands( "KEY", 0, 0, 0, ""),
738
 
  Commands( "KEYS", 0, 0, 0, ""),
739
 
  Commands( "KILL", 0, 0, 0, ""),
740
 
  Commands( "LANGUAGE", 0, 0, 0, ""),
741
 
  Commands( "LAST", 0, 0, 0, ""),
742
 
  Commands( "LEADING", 0, 0, 0, ""),
743
 
  Commands( "LEAVE", 0, 0, 0, ""),
744
 
  Commands( "LEAVES", 0, 0, 0, ""),
745
 
  Commands( "LEFT", 0, 0, 0, ""),
746
 
  Commands( "LEVEL", 0, 0, 0, ""),
747
 
  Commands( "LIKE", 0, 0, 0, ""),
748
 
  Commands( "LIMIT", 0, 0, 0, ""),
749
 
  Commands( "LINES", 0, 0, 0, ""),
750
 
  Commands( "LINESTRING", 0, 0, 0, ""),
751
 
  Commands( "LOAD", 0, 0, 0, ""),
752
 
  Commands( "LOCAL", 0, 0, 0, ""),
753
 
  Commands( "LOCALTIMESTAMP", 0, 0, 0, ""),
754
 
  Commands( "LOCK", 0, 0, 0, ""),
755
 
  Commands( "LOCKS", 0, 0, 0, ""),
756
 
  Commands( "LOGS", 0, 0, 0, ""),
757
 
  Commands( "LONG", 0, 0, 0, ""),
758
 
  Commands( "LOOP", 0, 0, 0, ""),
759
 
  Commands( "MATCH", 0, 0, 0, ""),
760
 
  Commands( "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""),
761
 
  Commands( "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""),
762
 
  Commands( "MAX_ROWS", 0, 0, 0, ""),
763
 
  Commands( "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""),
764
 
  Commands( "MAX_USER_CONNECTIONS", 0, 0, 0, ""),
765
 
  Commands( "MEDIUM", 0, 0, 0, ""),
766
 
  Commands( "MERGE", 0, 0, 0, ""),
767
 
  Commands( "MICROSECOND", 0, 0, 0, ""),
768
 
  Commands( "MIGRATE", 0, 0, 0, ""),
769
 
  Commands( "MINUTE", 0, 0, 0, ""),
770
 
  Commands( "MINUTE_MICROSECOND", 0, 0, 0, ""),
771
 
  Commands( "MINUTE_SECOND", 0, 0, 0, ""),
772
 
  Commands( "MIN_ROWS", 0, 0, 0, ""),
773
 
  Commands( "MOD", 0, 0, 0, ""),
774
 
  Commands( "MODE", 0, 0, 0, ""),
775
 
  Commands( "MODIFIES", 0, 0, 0, ""),
776
 
  Commands( "MODIFY", 0, 0, 0, ""),
777
 
  Commands( "MONTH", 0, 0, 0, ""),
778
 
  Commands( "MULTILINESTRING", 0, 0, 0, ""),
779
 
  Commands( "MULTIPOINT", 0, 0, 0, ""),
780
 
  Commands( "MULTIPOLYGON", 0, 0, 0, ""),
781
 
  Commands( "MUTEX", 0, 0, 0, ""),
782
 
  Commands( "NAME", 0, 0, 0, ""),
783
 
  Commands( "NAMES", 0, 0, 0, ""),
784
 
  Commands( "NATIONAL", 0, 0, 0, ""),
785
 
  Commands( "NATURAL", 0, 0, 0, ""),
786
 
  Commands( "NCHAR", 0, 0, 0, ""),
787
 
  Commands( "NEW", 0, 0, 0, ""),
788
 
  Commands( "NEXT", 0, 0, 0, ""),
789
 
  Commands( "NO", 0, 0, 0, ""),
790
 
  Commands( "NONE", 0, 0, 0, ""),
791
 
  Commands( "NOT", 0, 0, 0, ""),
792
 
  Commands( "NULL", 0, 0, 0, ""),
793
 
  Commands( "NUMERIC", 0, 0, 0, ""),
794
 
  Commands( "NVARCHAR", 0, 0, 0, ""),
795
 
  Commands( "OFFSET", 0, 0, 0, ""),
796
 
  Commands( "ON", 0, 0, 0, ""),
797
 
  Commands( "ONE", 0, 0, 0, ""),
798
 
  Commands( "ONE_SHOT", 0, 0, 0, ""),
799
 
  Commands( "OPEN", 0, 0, 0, ""),
800
 
  Commands( "OPTIMIZE", 0, 0, 0, ""),
801
 
  Commands( "OPTION", 0, 0, 0, ""),
802
 
  Commands( "OPTIONALLY", 0, 0, 0, ""),
803
 
  Commands( "OR", 0, 0, 0, ""),
804
 
  Commands( "ORDER", 0, 0, 0, ""),
805
 
  Commands( "OUT", 0, 0, 0, ""),
806
 
  Commands( "OUTER", 0, 0, 0, ""),
807
 
  Commands( "OUTFILE", 0, 0, 0, ""),
808
 
  Commands( "PACK_KEYS", 0, 0, 0, ""),
809
 
  Commands( "PARTIAL", 0, 0, 0, ""),
810
 
  Commands( "PASSWORD", 0, 0, 0, ""),
811
 
  Commands( "PHASE", 0, 0, 0, ""),
812
 
  Commands( "PRECISION", 0, 0, 0, ""),
813
 
  Commands( "PREPARE", 0, 0, 0, ""),
814
 
  Commands( "PREV", 0, 0, 0, ""),
815
 
  Commands( "PRIMARY", 0, 0, 0, ""),
816
 
  Commands( "PRIVILEGES", 0, 0, 0, ""),
817
 
  Commands( "PROCEDURE", 0, 0, 0, ""),
818
 
  Commands( "PROCESS", 0, 0, 0, ""),
819
 
  Commands( "PROCESSLIST", 0, 0, 0, ""),
820
 
  Commands( "PURGE", 0, 0, 0, ""),
821
 
  Commands( "QUARTER", 0, 0, 0, ""),
822
 
  Commands( "QUERY", 0, 0, 0, ""),
823
 
  Commands( "QUICK", 0, 0, 0, ""),
824
 
  Commands( "READ", 0, 0, 0, ""),
825
 
  Commands( "READS", 0, 0, 0, ""),
826
 
  Commands( "REAL", 0, 0, 0, ""),
827
 
  Commands( "RECOVER", 0, 0, 0, ""),
828
 
  Commands( "REDUNDANT", 0, 0, 0, ""),
829
 
  Commands( "REFERENCES", 0, 0, 0, ""),
830
 
  Commands( "REGEXP", 0, 0, 0, ""),
831
 
  Commands( "RELEASE", 0, 0, 0, ""),
832
 
  Commands( "RELOAD", 0, 0, 0, ""),
833
 
  Commands( "RENAME", 0, 0, 0, ""),
834
 
  Commands( "REPAIR", 0, 0, 0, ""),
835
 
  Commands( "REPEATABLE", 0, 0, 0, ""),
836
 
  Commands( "REPLACE", 0, 0, 0, ""),
837
 
  Commands( "REPEAT", 0, 0, 0, ""),
838
 
  Commands( "REQUIRE", 0, 0, 0, ""),
839
 
  Commands( "RESET", 0, 0, 0, ""),
840
 
  Commands( "RESTORE", 0, 0, 0, ""),
841
 
  Commands( "RESTRICT", 0, 0, 0, ""),
842
 
  Commands( "RESUME", 0, 0, 0, ""),
843
 
  Commands( "RETURN", 0, 0, 0, ""),
844
 
  Commands( "RETURNS", 0, 0, 0, ""),
845
 
  Commands( "REVOKE", 0, 0, 0, ""),
846
 
  Commands( "RIGHT", 0, 0, 0, ""),
847
 
  Commands( "RLIKE", 0, 0, 0, ""),
848
 
  Commands( "ROLLBACK", 0, 0, 0, ""),
849
 
  Commands( "ROLLUP", 0, 0, 0, ""),
850
 
  Commands( "ROUTINE", 0, 0, 0, ""),
851
 
  Commands( "ROW", 0, 0, 0, ""),
852
 
  Commands( "ROWS", 0, 0, 0, ""),
853
 
  Commands( "ROW_FORMAT", 0, 0, 0, ""),
854
 
  Commands( "RTREE", 0, 0, 0, ""),
855
 
  Commands( "SAVEPOINT", 0, 0, 0, ""),
856
 
  Commands( "SCHEMA", 0, 0, 0, ""),
857
 
  Commands( "SCHEMAS", 0, 0, 0, ""),
858
 
  Commands( "SECOND", 0, 0, 0, ""),
859
 
  Commands( "SECOND_MICROSECOND", 0, 0, 0, ""),
860
 
  Commands( "SECURITY", 0, 0, 0, ""),
861
 
  Commands( "SELECT", 0, 0, 0, ""),
862
 
  Commands( "SENSITIVE", 0, 0, 0, ""),
863
 
  Commands( "SEPARATOR", 0, 0, 0, ""),
864
 
  Commands( "SERIAL", 0, 0, 0, ""),
865
 
  Commands( "SERIALIZABLE", 0, 0, 0, ""),
866
 
  Commands( "SESSION", 0, 0, 0, ""),
867
 
  Commands( "SET", 0, 0, 0, ""),
868
 
  Commands( "SHARE", 0, 0, 0, ""),
869
 
  Commands( "SHOW", 0, 0, 0, ""),
870
 
  Commands( "SHUTDOWN", 0, 0, 0, ""),
871
 
  Commands( "SIGNED", 0, 0, 0, ""),
872
 
  Commands( "SIMPLE", 0, 0, 0, ""),
873
 
  Commands( "SLAVE", 0, 0, 0, ""),
874
 
  Commands( "SNAPSHOT", 0, 0, 0, ""),
875
 
  Commands( "SOME", 0, 0, 0, ""),
876
 
  Commands( "SONAME", 0, 0, 0, ""),
877
 
  Commands( "SOUNDS", 0, 0, 0, ""),
878
 
  Commands( "SPATIAL", 0, 0, 0, ""),
879
 
  Commands( "SPECIFIC", 0, 0, 0, ""),
880
 
  Commands( "SQL", 0, 0, 0, ""),
881
 
  Commands( "SQLEXCEPTION", 0, 0, 0, ""),
882
 
  Commands( "SQLSTATE", 0, 0, 0, ""),
883
 
  Commands( "SQLWARNING", 0, 0, 0, ""),
884
 
  Commands( "SQL_BIG_RESULT", 0, 0, 0, ""),
885
 
  Commands( "SQL_BUFFER_RESULT", 0, 0, 0, ""),
886
 
  Commands( "SQL_CACHE", 0, 0, 0, ""),
887
 
  Commands( "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""),
888
 
  Commands( "SQL_NO_CACHE", 0, 0, 0, ""),
889
 
  Commands( "SQL_SMALL_RESULT", 0, 0, 0, ""),
890
 
  Commands( "SQL_THREAD", 0, 0, 0, ""),
891
 
  Commands( "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""),
892
 
  Commands( "SQL_TSI_SECOND", 0, 0, 0, ""),
893
 
  Commands( "SQL_TSI_MINUTE", 0, 0, 0, ""),
894
 
  Commands( "SQL_TSI_HOUR", 0, 0, 0, ""),
895
 
  Commands( "SQL_TSI_DAY", 0, 0, 0, ""),
896
 
  Commands( "SQL_TSI_WEEK", 0, 0, 0, ""),
897
 
  Commands( "SQL_TSI_MONTH", 0, 0, 0, ""),
898
 
  Commands( "SQL_TSI_QUARTER", 0, 0, 0, ""),
899
 
  Commands( "SQL_TSI_YEAR", 0, 0, 0, ""),
900
 
  Commands( "SSL", 0, 0, 0, ""),
901
 
  Commands( "START", 0, 0, 0, ""),
902
 
  Commands( "STARTING", 0, 0, 0, ""),
903
 
  Commands( "STATUS", 0, 0, 0, ""),
904
 
  Commands( "STOP", 0, 0, 0, ""),
905
 
  Commands( "STORAGE", 0, 0, 0, ""),
906
 
  Commands( "STRAIGHT_JOIN", 0, 0, 0, ""),
907
 
  Commands( "STRING", 0, 0, 0, ""),
908
 
  Commands( "STRIPED", 0, 0, 0, ""),
909
 
  Commands( "SUBJECT", 0, 0, 0, ""),
910
 
  Commands( "SUPER", 0, 0, 0, ""),
911
 
  Commands( "SUSPEND", 0, 0, 0, ""),
912
 
  Commands( "TABLE", 0, 0, 0, ""),
913
 
  Commands( "TABLES", 0, 0, 0, ""),
914
 
  Commands( "TABLESPACE", 0, 0, 0, ""),
915
 
  Commands( "TEMPORARY", 0, 0, 0, ""),
916
 
  Commands( "TEMPTABLE", 0, 0, 0, ""),
917
 
  Commands( "TERMINATED", 0, 0, 0, ""),
918
 
  Commands( "TEXT", 0, 0, 0, ""),
919
 
  Commands( "THEN", 0, 0, 0, ""),
920
 
  Commands( "TIMESTAMP", 0, 0, 0, ""),
921
 
  Commands( "TIMESTAMPADD", 0, 0, 0, ""),
922
 
  Commands( "TIMESTAMPDIFF", 0, 0, 0, ""),
923
 
  Commands( "TO", 0, 0, 0, ""),
924
 
  Commands( "TRAILING", 0, 0, 0, ""),
925
 
  Commands( "TRANSACTION", 0, 0, 0, ""),
926
 
  Commands( "TRUE", 0, 0, 0, ""),
927
 
  Commands( "TRUNCATE", 0, 0, 0, ""),
928
 
  Commands( "TYPE", 0, 0, 0, ""),
929
 
  Commands( "TYPES", 0, 0, 0, ""),
930
 
  Commands( "UNCOMMITTED", 0, 0, 0, ""),
931
 
  Commands( "UNDEFINED", 0, 0, 0, ""),
932
 
  Commands( "UNDO", 0, 0, 0, ""),
933
 
  Commands( "UNICODE", 0, 0, 0, ""),
934
 
  Commands( "UNION", 0, 0, 0, ""),
935
 
  Commands( "UNIQUE", 0, 0, 0, ""),
936
 
  Commands( "UNKNOWN", 0, 0, 0, ""),
937
 
  Commands( "UNLOCK", 0, 0, 0, ""),
938
 
  Commands( "UNTIL", 0, 0, 0, ""),
939
 
  Commands( "UPDATE", 0, 0, 0, ""),
940
 
  Commands( "UPGRADE", 0, 0, 0, ""),
941
 
  Commands( "USAGE", 0, 0, 0, ""),
942
 
  Commands( "USE", 0, 0, 0, ""),
943
 
  Commands( "USER", 0, 0, 0, ""),
944
 
  Commands( "USER_RESOURCES", 0, 0, 0, ""),
945
 
  Commands( "USING", 0, 0, 0, ""),
946
 
  Commands( "UTC_DATE", 0, 0, 0, ""),
947
 
  Commands( "UTC_TIMESTAMP", 0, 0, 0, ""),
948
 
  Commands( "VALUE", 0, 0, 0, ""),
949
 
  Commands( "VALUES", 0, 0, 0, ""),
950
 
  Commands( "VARBINARY", 0, 0, 0, ""),
951
 
  Commands( "VARCHAR", 0, 0, 0, ""),
952
 
  Commands( "VARCHARACTER", 0, 0, 0, ""),
953
 
  Commands( "VARIABLES", 0, 0, 0, ""),
954
 
  Commands( "VARYING", 0, 0, 0, ""),
955
 
  Commands( "WARNINGS", 0, 0, 0, ""),
956
 
  Commands( "WEEK", 0, 0, 0, ""),
957
 
  Commands( "WHEN", 0, 0, 0, ""),
958
 
  Commands( "WHERE", 0, 0, 0, ""),
959
 
  Commands( "WHILE", 0, 0, 0, ""),
960
 
  Commands( "VIEW", 0, 0, 0, ""),
961
 
  Commands( "WITH", 0, 0, 0, ""),
962
 
  Commands( "WORK", 0, 0, 0, ""),
963
 
  Commands( "WRITE", 0, 0, 0, ""),
964
 
  Commands( "XOR", 0, 0, 0, ""),
965
 
  Commands( "XA", 0, 0, 0, ""),
966
 
  Commands( "YEAR", 0, 0, 0, ""),
967
 
  Commands( "YEAR_MONTH", 0, 0, 0, ""),
968
 
  Commands( "ZEROFILL", 0, 0, 0, ""),
969
 
  Commands( "ABS", 0, 0, 0, ""),
970
 
  Commands( "ACOS", 0, 0, 0, ""),
971
 
  Commands( "ADDDATE", 0, 0, 0, ""),
972
 
  Commands( "AREA", 0, 0, 0, ""),
973
 
  Commands( "ASIN", 0, 0, 0, ""),
974
 
  Commands( "ASBINARY", 0, 0, 0, ""),
975
 
  Commands( "ASTEXT", 0, 0, 0, ""),
976
 
  Commands( "ATAN", 0, 0, 0, ""),
977
 
  Commands( "ATAN2", 0, 0, 0, ""),
978
 
  Commands( "BENCHMARK", 0, 0, 0, ""),
979
 
  Commands( "BIN", 0, 0, 0, ""),
980
 
  Commands( "BIT_OR", 0, 0, 0, ""),
981
 
  Commands( "BIT_AND", 0, 0, 0, ""),
982
 
  Commands( "BIT_XOR", 0, 0, 0, ""),
983
 
  Commands( "CAST", 0, 0, 0, ""),
984
 
  Commands( "CEIL", 0, 0, 0, ""),
985
 
  Commands( "CEILING", 0, 0, 0, ""),
986
 
  Commands( "CENTROID", 0, 0, 0, ""),
987
 
  Commands( "CHAR_LENGTH", 0, 0, 0, ""),
988
 
  Commands( "CHARACTER_LENGTH", 0, 0, 0, ""),
989
 
  Commands( "COALESCE", 0, 0, 0, ""),
990
 
  Commands( "COERCIBILITY", 0, 0, 0, ""),
991
 
  Commands( "COMPRESS", 0, 0, 0, ""),
992
 
  Commands( "CONCAT", 0, 0, 0, ""),
993
 
  Commands( "CONCAT_WS", 0, 0, 0, ""),
994
 
  Commands( "CONNECTION_ID", 0, 0, 0, ""),
995
 
  Commands( "CONV", 0, 0, 0, ""),
996
 
  Commands( "CONVERT_TZ", 0, 0, 0, ""),
997
 
  Commands( "COUNT", 0, 0, 0, ""),
998
 
  Commands( "COS", 0, 0, 0, ""),
999
 
  Commands( "COT", 0, 0, 0, ""),
1000
 
  Commands( "CRC32", 0, 0, 0, ""),
1001
 
  Commands( "CROSSES", 0, 0, 0, ""),
1002
 
  Commands( "CURDATE", 0, 0, 0, ""),
1003
 
  Commands( "DATE_ADD", 0, 0, 0, ""),
1004
 
  Commands( "DATEDIFF", 0, 0, 0, ""),
1005
 
  Commands( "DATE_FORMAT", 0, 0, 0, ""),
1006
 
  Commands( "DATE_SUB", 0, 0, 0, ""),
1007
 
  Commands( "DAYNAME", 0, 0, 0, ""),
1008
 
  Commands( "DAYOFMONTH", 0, 0, 0, ""),
1009
 
  Commands( "DAYOFWEEK", 0, 0, 0, ""),
1010
 
  Commands( "DAYOFYEAR", 0, 0, 0, ""),
1011
 
  Commands( "DECODE", 0, 0, 0, ""),
1012
 
  Commands( "DEGREES", 0, 0, 0, ""),
1013
 
  Commands( "DES_ENCRYPT", 0, 0, 0, ""),
1014
 
  Commands( "DES_DECRYPT", 0, 0, 0, ""),
1015
 
  Commands( "DIMENSION", 0, 0, 0, ""),
1016
 
  Commands( "DISJOINT", 0, 0, 0, ""),
1017
 
  Commands( "ELT", 0, 0, 0, ""),
1018
 
  Commands( "ENCODE", 0, 0, 0, ""),
1019
 
  Commands( "ENCRYPT", 0, 0, 0, ""),
1020
 
  Commands( "ENDPOINT", 0, 0, 0, ""),
1021
 
  Commands( "ENVELOPE", 0, 0, 0, ""),
1022
 
  Commands( "EQUALS", 0, 0, 0, ""),
1023
 
  Commands( "EXTERIORRING", 0, 0, 0, ""),
1024
 
  Commands( "EXTRACT", 0, 0, 0, ""),
1025
 
  Commands( "EXP", 0, 0, 0, ""),
1026
 
  Commands( "EXPORT_SET", 0, 0, 0, ""),
1027
 
  Commands( "FIELD", 0, 0, 0, ""),
1028
 
  Commands( "FIND_IN_SET", 0, 0, 0, ""),
1029
 
  Commands( "FLOOR", 0, 0, 0, ""),
1030
 
  Commands( "FORMAT", 0, 0, 0, ""),
1031
 
  Commands( "FOUND_ROWS", 0, 0, 0, ""),
1032
 
  Commands( "FROM_DAYS", 0, 0, 0, ""),
1033
 
  Commands( "FROM_UNIXTIME", 0, 0, 0, ""),
1034
 
  Commands( "GET_LOCK", 0, 0, 0, ""),
1035
 
  Commands( "GLENGTH", 0, 0, 0, ""),
1036
 
  Commands( "GREATEST", 0, 0, 0, ""),
1037
 
  Commands( "GROUP_CONCAT", 0, 0, 0, ""),
1038
 
  Commands( "GROUP_UNIQUE_USERS", 0, 0, 0, ""),
1039
 
  Commands( "HEX", 0, 0, 0, ""),
1040
 
  Commands( "IFNULL", 0, 0, 0, ""),
1041
 
  Commands( "INSTR", 0, 0, 0, ""),
1042
 
  Commands( "INTERIORRINGN", 0, 0, 0, ""),
1043
 
  Commands( "INTERSECTS", 0, 0, 0, ""),
1044
 
  Commands( "ISCLOSED", 0, 0, 0, ""),
1045
 
  Commands( "ISEMPTY", 0, 0, 0, ""),
1046
 
  Commands( "ISNULL", 0, 0, 0, ""),
1047
 
  Commands( "IS_FREE_LOCK", 0, 0, 0, ""),
1048
 
  Commands( "IS_USED_LOCK", 0, 0, 0, ""),
1049
 
  Commands( "LAST_INSERT_ID", 0, 0, 0, ""),
1050
 
  Commands( "ISSIMPLE", 0, 0, 0, ""),
1051
 
  Commands( "LAST_DAY", 0, 0, 0, ""),
1052
 
  Commands( "LCASE", 0, 0, 0, ""),
1053
 
  Commands( "LEAST", 0, 0, 0, ""),
1054
 
  Commands( "LENGTH", 0, 0, 0, ""),
1055
 
  Commands( "LN", 0, 0, 0, ""),
1056
 
  Commands( "LOAD_FILE", 0, 0, 0, ""),
1057
 
  Commands( "LOCATE", 0, 0, 0, ""),
1058
 
  Commands( "LOG", 0, 0, 0, ""),
1059
 
  Commands( "LOG2", 0, 0, 0, ""),
1060
 
  Commands( "LOG10", 0, 0, 0, ""),
1061
 
  Commands( "LOWER", 0, 0, 0, ""),
1062
 
  Commands( "LPAD", 0, 0, 0, ""),
1063
 
  Commands( "LTRIM", 0, 0, 0, ""),
1064
 
  Commands( "MAKE_SET", 0, 0, 0, ""),
1065
 
  Commands( "MAKEDATE", 0, 0, 0, ""),
1066
 
  Commands( "MASTER_POS_WAIT", 0, 0, 0, ""),
1067
 
  Commands( "MAX", 0, 0, 0, ""),
1068
 
  Commands( "MBRCONTAINS", 0, 0, 0, ""),
1069
 
  Commands( "MBRDISJOINT", 0, 0, 0, ""),
1070
 
  Commands( "MBREQUAL", 0, 0, 0, ""),
1071
 
  Commands( "MBRINTERSECTS", 0, 0, 0, ""),
1072
 
  Commands( "MBROVERLAPS", 0, 0, 0, ""),
1073
 
  Commands( "MBRTOUCHES", 0, 0, 0, ""),
1074
 
  Commands( "MBRWITHIN", 0, 0, 0, ""),
1075
 
  Commands( "MD5", 0, 0, 0, ""),
1076
 
  Commands( "MID", 0, 0, 0, ""),
1077
 
  Commands( "MIN", 0, 0, 0, ""),
1078
 
  Commands( "MONTHNAME", 0, 0, 0, ""),
1079
 
  Commands( "NAME_CONST", 0, 0, 0, ""),
1080
 
  Commands( "NOW", 0, 0, 0, ""),
1081
 
  Commands( "NULLIF", 0, 0, 0, ""),
1082
 
  Commands( "NUMPOINTS", 0, 0, 0, ""),
1083
 
  Commands( "OCTET_LENGTH", 0, 0, 0, ""),
1084
 
  Commands( "OCT", 0, 0, 0, ""),
1085
 
  Commands( "ORD", 0, 0, 0, ""),
1086
 
  Commands( "OVERLAPS", 0, 0, 0, ""),
1087
 
  Commands( "PERIOD_ADD", 0, 0, 0, ""),
1088
 
  Commands( "PERIOD_DIFF", 0, 0, 0, ""),
1089
 
  Commands( "PI", 0, 0, 0, ""),
1090
 
  Commands( "POINTN", 0, 0, 0, ""),
1091
 
  Commands( "POSITION", 0, 0, 0, ""),
1092
 
  Commands( "POW", 0, 0, 0, ""),
1093
 
  Commands( "POWER", 0, 0, 0, ""),
1094
 
  Commands( "QUOTE", 0, 0, 0, ""),
1095
 
  Commands( "RADIANS", 0, 0, 0, ""),
1096
 
  Commands( "RAND", 0, 0, 0, ""),
1097
 
  Commands( "RELEASE_LOCK", 0, 0, 0, ""),
1098
 
  Commands( "REVERSE", 0, 0, 0, ""),
1099
 
  Commands( "ROUND", 0, 0, 0, ""),
1100
 
  Commands( "ROW_COUNT", 0, 0, 0, ""),
1101
 
  Commands( "RPAD", 0, 0, 0, ""),
1102
 
  Commands( "RTRIM", 0, 0, 0, ""),
1103
 
  Commands( "SESSION_USER", 0, 0, 0, ""),
1104
 
  Commands( "SUBDATE", 0, 0, 0, ""),
1105
 
  Commands( "SIGN", 0, 0, 0, ""),
1106
 
  Commands( "SIN", 0, 0, 0, ""),
1107
 
  Commands( "SHA", 0, 0, 0, ""),
1108
 
  Commands( "SHA1", 0, 0, 0, ""),
1109
 
  Commands( "SLEEP", 0, 0, 0, ""),
1110
 
  Commands( "SOUNDEX", 0, 0, 0, ""),
1111
 
  Commands( "SPACE", 0, 0, 0, ""),
1112
 
  Commands( "SQRT", 0, 0, 0, ""),
1113
 
  Commands( "SRID", 0, 0, 0, ""),
1114
 
  Commands( "STARTPOINT", 0, 0, 0, ""),
1115
 
  Commands( "STD", 0, 0, 0, ""),
1116
 
  Commands( "STDDEV", 0, 0, 0, ""),
1117
 
  Commands( "STDDEV_POP", 0, 0, 0, ""),
1118
 
  Commands( "STDDEV_SAMP", 0, 0, 0, ""),
1119
 
  Commands( "STR_TO_DATE", 0, 0, 0, ""),
1120
 
  Commands( "STRCMP", 0, 0, 0, ""),
1121
 
  Commands( "SUBSTR", 0, 0, 0, ""),
1122
 
  Commands( "SUBSTRING", 0, 0, 0, ""),
1123
 
  Commands( "SUBSTRING_INDEX", 0, 0, 0, ""),
1124
 
  Commands( "SUM", 0, 0, 0, ""),
1125
 
  Commands( "SYSDATE", 0, 0, 0, ""),
1126
 
  Commands( "SYSTEM_USER", 0, 0, 0, ""),
1127
 
  Commands( "TAN", 0, 0, 0, ""),
1128
 
  Commands( "TIME_FORMAT", 0, 0, 0, ""),
1129
 
  Commands( "TO_DAYS", 0, 0, 0, ""),
1130
 
  Commands( "TOUCHES", 0, 0, 0, ""),
1131
 
  Commands( "TRIM", 0, 0, 0, ""),
1132
 
  Commands( "UCASE", 0, 0, 0, ""),
1133
 
  Commands( "UNCOMPRESS", 0, 0, 0, ""),
1134
 
  Commands( "UNCOMPRESSED_LENGTH", 0, 0, 0, ""),
1135
 
  Commands( "UNHEX", 0, 0, 0, ""),
1136
 
  Commands( "UNIQUE_USERS", 0, 0, 0, ""),
1137
 
  Commands( "UNIX_TIMESTAMP", 0, 0, 0, ""),
1138
 
  Commands( "UPPER", 0, 0, 0, ""),
1139
 
  Commands( "UUID", 0, 0, 0, ""),
1140
 
  Commands( "VARIANCE", 0, 0, 0, ""),
1141
 
  Commands( "VAR_POP", 0, 0, 0, ""),
1142
 
  Commands( "VAR_SAMP", 0, 0, 0, ""),
1143
 
  Commands( "VERSION", 0, 0, 0, ""),
1144
 
  Commands( "WEEKDAY", 0, 0, 0, ""),
1145
 
  Commands( "WEEKOFYEAR", 0, 0, 0, ""),
1146
 
  Commands( "WITHIN", 0, 0, 0, ""),
1147
 
  Commands( "X", 0, 0, 0, ""),
1148
 
  Commands( "Y", 0, 0, 0, ""),
1149
 
  Commands( "YEARWEEK", 0, 0, 0, ""),
 
316
  { "ACTION", 0, 0, 0, ""},
 
317
  { "ADD", 0, 0, 0, ""},
 
318
  { "AFTER", 0, 0, 0, ""},
 
319
  { "AGAINST", 0, 0, 0, ""},
 
320
  { "AGGREGATE", 0, 0, 0, ""},
 
321
  { "ALL", 0, 0, 0, ""},
 
322
  { "ALGORITHM", 0, 0, 0, ""},
 
323
  { "ALTER", 0, 0, 0, ""},
 
324
  { "ANALYZE", 0, 0, 0, ""},
 
325
  { "AND", 0, 0, 0, ""},
 
326
  { "ANY", 0, 0, 0, ""},
 
327
  { "AS", 0, 0, 0, ""},
 
328
  { "ASC", 0, 0, 0, ""},
 
329
  { "ASCII", 0, 0, 0, ""},
 
330
  { "ASENSITIVE", 0, 0, 0, ""},
 
331
  { "AUTO_INCREMENT", 0, 0, 0, ""},
 
332
  { "AVG", 0, 0, 0, ""},
 
333
  { "AVG_ROW_LENGTH", 0, 0, 0, ""},
 
334
  { "BACKUP", 0, 0, 0, ""},
 
335
  { "BDB", 0, 0, 0, ""},
 
336
  { "BEFORE", 0, 0, 0, ""},
 
337
  { "BEGIN", 0, 0, 0, ""},
 
338
  { "BERKELEYDB", 0, 0, 0, ""},
 
339
  { "BETWEEN", 0, 0, 0, ""},
 
340
  { "BIGINT", 0, 0, 0, ""},
 
341
  { "BINARY", 0, 0, 0, ""},
 
342
  { "BINLOG", 0, 0, 0, ""},
 
343
  { "BIT", 0, 0, 0, ""},
 
344
  { "BLOB", 0, 0, 0, ""},
 
345
  { "BOOL", 0, 0, 0, ""},
 
346
  { "BOOLEAN", 0, 0, 0, ""},
 
347
  { "BOTH", 0, 0, 0, ""},
 
348
  { "BTREE", 0, 0, 0, ""},
 
349
  { "BY", 0, 0, 0, ""},
 
350
  { "BYTE", 0, 0, 0, ""},
 
351
  { "CACHE", 0, 0, 0, ""},
 
352
  { "CALL", 0, 0, 0, ""},
 
353
  { "CASCADE", 0, 0, 0, ""},
 
354
  { "CASCADED", 0, 0, 0, ""},
 
355
  { "CASE", 0, 0, 0, ""},
 
356
  { "CHAIN", 0, 0, 0, ""},
 
357
  { "CHANGE", 0, 0, 0, ""},
 
358
  { "CHANGED", 0, 0, 0, ""},
 
359
  { "CHAR", 0, 0, 0, ""},
 
360
  { "CHARACTER", 0, 0, 0, ""},
 
361
  { "CHARSET", 0, 0, 0, ""},
 
362
  { "CHECK", 0, 0, 0, ""},
 
363
  { "CHECKSUM", 0, 0, 0, ""},
 
364
  { "CIPHER", 0, 0, 0, ""},
 
365
  { "CLIENT", 0, 0, 0, ""},
 
366
  { "CLOSE", 0, 0, 0, ""},
 
367
  { "CODE", 0, 0, 0, ""},
 
368
  { "COLLATE", 0, 0, 0, ""},
 
369
  { "COLLATION", 0, 0, 0, ""},
 
370
  { "COLUMN", 0, 0, 0, ""},
 
371
  { "COLUMNS", 0, 0, 0, ""},
 
372
  { "COMMENT", 0, 0, 0, ""},
 
373
  { "COMMIT", 0, 0, 0, ""},
 
374
  { "COMMITTED", 0, 0, 0, ""},
 
375
  { "COMPACT", 0, 0, 0, ""},
 
376
  { "COMPRESSED", 0, 0, 0, ""},
 
377
  { "CONCURRENT", 0, 0, 0, ""},
 
378
  { "CONDITION", 0, 0, 0, ""},
 
379
  { "CONNECTION", 0, 0, 0, ""},
 
380
  { "CONSISTENT", 0, 0, 0, ""},
 
381
  { "CONSTRAINT", 0, 0, 0, ""},
 
382
  { "CONTAINS", 0, 0, 0, ""},
 
383
  { "CONTINUE", 0, 0, 0, ""},
 
384
  { "CONVERT", 0, 0, 0, ""},
 
385
  { "CREATE", 0, 0, 0, ""},
 
386
  { "CROSS", 0, 0, 0, ""},
 
387
  { "CUBE", 0, 0, 0, ""},
 
388
  { "CURRENT_DATE", 0, 0, 0, ""},
 
389
  { "CURRENT_TIMESTAMP", 0, 0, 0, ""},
 
390
  { "CURRENT_USER", 0, 0, 0, ""},
 
391
  { "CURSOR", 0, 0, 0, ""},
 
392
  { "DATA", 0, 0, 0, ""},
 
393
  { "DATABASE", 0, 0, 0, ""},
 
394
  { "DATABASES", 0, 0, 0, ""},
 
395
  { "DATE", 0, 0, 0, ""},
 
396
  { "DATETIME", 0, 0, 0, ""},
 
397
  { "DAY", 0, 0, 0, ""},
 
398
  { "DAY_HOUR", 0, 0, 0, ""},
 
399
  { "DAY_MICROSECOND", 0, 0, 0, ""},
 
400
  { "DAY_MINUTE", 0, 0, 0, ""},
 
401
  { "DAY_SECOND", 0, 0, 0, ""},
 
402
  { "DEALLOCATE", 0, 0, 0, ""},
 
403
  { "DEC", 0, 0, 0, ""},
 
404
  { "DECIMAL", 0, 0, 0, ""},
 
405
  { "DECLARE", 0, 0, 0, ""},
 
406
  { "DEFAULT", 0, 0, 0, ""},
 
407
  { "DEFINER", 0, 0, 0, ""},
 
408
  { "DELAYED", 0, 0, 0, ""},
 
409
  { "DELAY_KEY_WRITE", 0, 0, 0, ""},
 
410
  { "DELETE", 0, 0, 0, ""},
 
411
  { "DESC", 0, 0, 0, ""},
 
412
  { "DESCRIBE", 0, 0, 0, ""},
 
413
  { "DES_KEY_FILE", 0, 0, 0, ""},
 
414
  { "DETERMINISTIC", 0, 0, 0, ""},
 
415
  { "DIRECTORY", 0, 0, 0, ""},
 
416
  { "DISABLE", 0, 0, 0, ""},
 
417
  { "DISCARD", 0, 0, 0, ""},
 
418
  { "DISTINCT", 0, 0, 0, ""},
 
419
  { "DISTINCTROW", 0, 0, 0, ""},
 
420
  { "DIV", 0, 0, 0, ""},
 
421
  { "DO", 0, 0, 0, ""},
 
422
  { "DOUBLE", 0, 0, 0, ""},
 
423
  { "DROP", 0, 0, 0, ""},
 
424
  { "DUAL", 0, 0, 0, ""},
 
425
  { "DUMPFILE", 0, 0, 0, ""},
 
426
  { "DUPLICATE", 0, 0, 0, ""},
 
427
  { "DYNAMIC", 0, 0, 0, ""},
 
428
  { "EACH", 0, 0, 0, ""},
 
429
  { "ELSE", 0, 0, 0, ""},
 
430
  { "ELSEIF", 0, 0, 0, ""},
 
431
  { "ENABLE", 0, 0, 0, ""},
 
432
  { "ENCLOSED", 0, 0, 0, ""},
 
433
  { "END", 0, 0, 0, ""},
 
434
  { "ENGINE", 0, 0, 0, ""},
 
435
  { "ENGINES", 0, 0, 0, ""},
 
436
  { "ENUM", 0, 0, 0, ""},
 
437
  { "ERRORS", 0, 0, 0, ""},
 
438
  { "ESCAPE", 0, 0, 0, ""},
 
439
  { "ESCAPED", 0, 0, 0, ""},
 
440
  { "EVENTS", 0, 0, 0, ""},
 
441
  { "EXECUTE", 0, 0, 0, ""},
 
442
  { "EXISTS", 0, 0, 0, ""},
 
443
  { "EXIT", 0, 0, 0, ""},
 
444
  { "EXPANSION", 0, 0, 0, ""},
 
445
  { "EXPLAIN", 0, 0, 0, ""},
 
446
  { "EXTENDED", 0, 0, 0, ""},
 
447
  { "FALSE", 0, 0, 0, ""},
 
448
  { "FAST", 0, 0, 0, ""},
 
449
  { "FETCH", 0, 0, 0, ""},
 
450
  { "FIELDS", 0, 0, 0, ""},
 
451
  { "FILE", 0, 0, 0, ""},
 
452
  { "FIRST", 0, 0, 0, ""},
 
453
  { "FIXED", 0, 0, 0, ""},
 
454
  { "FLOAT", 0, 0, 0, ""},
 
455
  { "FLOAT4", 0, 0, 0, ""},
 
456
  { "FLOAT8", 0, 0, 0, ""},
 
457
  { "FLUSH", 0, 0, 0, ""},
 
458
  { "FOR", 0, 0, 0, ""},
 
459
  { "FORCE", 0, 0, 0, ""},
 
460
  { "FOREIGN", 0, 0, 0, ""},
 
461
  { "FOUND", 0, 0, 0, ""},
 
462
  { "FRAC_SECOND", 0, 0, 0, ""},
 
463
  { "FROM", 0, 0, 0, ""},
 
464
  { "FULL", 0, 0, 0, ""},
 
465
  { "FULLTEXT", 0, 0, 0, ""},
 
466
  { "FUNCTION", 0, 0, 0, ""},
 
467
  { "GLOBAL", 0, 0, 0, ""},
 
468
  { "GRANT", 0, 0, 0, ""},
 
469
  { "GRANTS", 0, 0, 0, ""},
 
470
  { "GROUP", 0, 0, 0, ""},
 
471
  { "HANDLER", 0, 0, 0, ""},
 
472
  { "HASH", 0, 0, 0, ""},
 
473
  { "HAVING", 0, 0, 0, ""},
 
474
  { "HELP", 0, 0, 0, ""},
 
475
  { "HIGH_PRIORITY", 0, 0, 0, ""},
 
476
  { "HOSTS", 0, 0, 0, ""},
 
477
  { "HOUR", 0, 0, 0, ""},
 
478
  { "HOUR_MICROSECOND", 0, 0, 0, ""},
 
479
  { "HOUR_MINUTE", 0, 0, 0, ""},
 
480
  { "HOUR_SECOND", 0, 0, 0, ""},
 
481
  { "IDENTIFIED", 0, 0, 0, ""},
 
482
  { "IF", 0, 0, 0, ""},
 
483
  { "IGNORE", 0, 0, 0, ""},
 
484
  { "IMPORT", 0, 0, 0, ""},
 
485
  { "IN", 0, 0, 0, ""},
 
486
  { "INDEX", 0, 0, 0, ""},
 
487
  { "INDEXES", 0, 0, 0, ""},
 
488
  { "INFILE", 0, 0, 0, ""},
 
489
  { "INNER", 0, 0, 0, ""},
 
490
  { "INNOBASE", 0, 0, 0, ""},
 
491
  { "INNODB", 0, 0, 0, ""},
 
492
  { "INOUT", 0, 0, 0, ""},
 
493
  { "INSENSITIVE", 0, 0, 0, ""},
 
494
  { "INSERT", 0, 0, 0, ""},
 
495
  { "INSERT_METHOD", 0, 0, 0, ""},
 
496
  { "INT", 0, 0, 0, ""},
 
497
  { "INT1", 0, 0, 0, ""},
 
498
  { "INT2", 0, 0, 0, ""},
 
499
  { "INT3", 0, 0, 0, ""},
 
500
  { "INT4", 0, 0, 0, ""},
 
501
  { "INT8", 0, 0, 0, ""},
 
502
  { "INTEGER", 0, 0, 0, ""},
 
503
  { "INTERVAL", 0, 0, 0, ""},
 
504
  { "INTO", 0, 0, 0, ""},
 
505
  { "IO_THREAD", 0, 0, 0, ""},
 
506
  { "IS", 0, 0, 0, ""},
 
507
  { "ISOLATION", 0, 0, 0, ""},
 
508
  { "ISSUER", 0, 0, 0, ""},
 
509
  { "ITERATE", 0, 0, 0, ""},
 
510
  { "INVOKER", 0, 0, 0, ""},
 
511
  { "JOIN", 0, 0, 0, ""},
 
512
  { "KEY", 0, 0, 0, ""},
 
513
  { "KEYS", 0, 0, 0, ""},
 
514
  { "KILL", 0, 0, 0, ""},
 
515
  { "LANGUAGE", 0, 0, 0, ""},
 
516
  { "LAST", 0, 0, 0, ""},
 
517
  { "LEADING", 0, 0, 0, ""},
 
518
  { "LEAVE", 0, 0, 0, ""},
 
519
  { "LEAVES", 0, 0, 0, ""},
 
520
  { "LEFT", 0, 0, 0, ""},
 
521
  { "LEVEL", 0, 0, 0, ""},
 
522
  { "LIKE", 0, 0, 0, ""},
 
523
  { "LIMIT", 0, 0, 0, ""},
 
524
  { "LINES", 0, 0, 0, ""},
 
525
  { "LINESTRING", 0, 0, 0, ""},
 
526
  { "LOAD", 0, 0, 0, ""},
 
527
  { "LOCAL", 0, 0, 0, ""},
 
528
  { "LOCALTIMESTAMP", 0, 0, 0, ""},
 
529
  { "LOCK", 0, 0, 0, ""},
 
530
  { "LOCKS", 0, 0, 0, ""},
 
531
  { "LOGS", 0, 0, 0, ""},
 
532
  { "LONG", 0, 0, 0, ""},
 
533
  { "LONGTEXT", 0, 0, 0, ""},
 
534
  { "LOOP", 0, 0, 0, ""},
 
535
  { "LOW_PRIORITY", 0, 0, 0, ""},
 
536
  { "MASTER", 0, 0, 0, ""},
 
537
  { "MASTER_CONNECT_RETRY", 0, 0, 0, ""},
 
538
  { "MASTER_HOST", 0, 0, 0, ""},
 
539
  { "MASTER_LOG_FILE", 0, 0, 0, ""},
 
540
  { "MASTER_LOG_POS", 0, 0, 0, ""},
 
541
  { "MASTER_PASSWORD", 0, 0, 0, ""},
 
542
  { "MASTER_PORT", 0, 0, 0, ""},
 
543
  { "MASTER_SERVER_ID", 0, 0, 0, ""},
 
544
  { "MASTER_SSL", 0, 0, 0, ""},
 
545
  { "MASTER_SSL_CA", 0, 0, 0, ""},
 
546
  { "MASTER_SSL_CAPATH", 0, 0, 0, ""},
 
547
  { "MASTER_SSL_CERT", 0, 0, 0, ""},
 
548
  { "MASTER_SSL_CIPHER", 0, 0, 0, ""},
 
549
  { "MASTER_SSL_KEY", 0, 0, 0, ""},
 
550
  { "MASTER_USER", 0, 0, 0, ""},
 
551
  { "MATCH", 0, 0, 0, ""},
 
552
  { "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""},
 
553
  { "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""},
 
554
  { "MAX_ROWS", 0, 0, 0, ""},
 
555
  { "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""},
 
556
  { "MAX_USER_CONNECTIONS", 0, 0, 0, ""},
 
557
  { "MEDIUM", 0, 0, 0, ""},
 
558
  { "MEDIUMTEXT", 0, 0, 0, ""},
 
559
  { "MERGE", 0, 0, 0, ""},
 
560
  { "MICROSECOND", 0, 0, 0, ""},
 
561
  { "MIDDLEINT", 0, 0, 0, ""},
 
562
  { "MIGRATE", 0, 0, 0, ""},
 
563
  { "MINUTE", 0, 0, 0, ""},
 
564
  { "MINUTE_MICROSECOND", 0, 0, 0, ""},
 
565
  { "MINUTE_SECOND", 0, 0, 0, ""},
 
566
  { "MIN_ROWS", 0, 0, 0, ""},
 
567
  { "MOD", 0, 0, 0, ""},
 
568
  { "MODE", 0, 0, 0, ""},
 
569
  { "MODIFIES", 0, 0, 0, ""},
 
570
  { "MODIFY", 0, 0, 0, ""},
 
571
  { "MONTH", 0, 0, 0, ""},
 
572
  { "MULTILINESTRING", 0, 0, 0, ""},
 
573
  { "MULTIPOINT", 0, 0, 0, ""},
 
574
  { "MULTIPOLYGON", 0, 0, 0, ""},
 
575
  { "MUTEX", 0, 0, 0, ""},
 
576
  { "NAME", 0, 0, 0, ""},
 
577
  { "NAMES", 0, 0, 0, ""},
 
578
  { "NATIONAL", 0, 0, 0, ""},
 
579
  { "NATURAL", 0, 0, 0, ""},
 
580
  { "NDB", 0, 0, 0, ""},
 
581
  { "NDBCLUSTER", 0, 0, 0, ""},
 
582
  { "NCHAR", 0, 0, 0, ""},
 
583
  { "NEW", 0, 0, 0, ""},
 
584
  { "NEXT", 0, 0, 0, ""},
 
585
  { "NO", 0, 0, 0, ""},
 
586
  { "NONE", 0, 0, 0, ""},
 
587
  { "NOT", 0, 0, 0, ""},
 
588
  { "NO_WRITE_TO_BINLOG", 0, 0, 0, ""},
 
589
  { "NULL", 0, 0, 0, ""},
 
590
  { "NUMERIC", 0, 0, 0, ""},
 
591
  { "NVARCHAR", 0, 0, 0, ""},
 
592
  { "OFFSET", 0, 0, 0, ""},
 
593
  { "OLD_PASSWORD", 0, 0, 0, ""},
 
594
  { "ON", 0, 0, 0, ""},
 
595
  { "ONE", 0, 0, 0, ""},
 
596
  { "ONE_SHOT", 0, 0, 0, ""},
 
597
  { "OPEN", 0, 0, 0, ""},
 
598
  { "OPTIMIZE", 0, 0, 0, ""},
 
599
  { "OPTION", 0, 0, 0, ""},
 
600
  { "OPTIONALLY", 0, 0, 0, ""},
 
601
  { "OR", 0, 0, 0, ""},
 
602
  { "ORDER", 0, 0, 0, ""},
 
603
  { "OUT", 0, 0, 0, ""},
 
604
  { "OUTER", 0, 0, 0, ""},
 
605
  { "OUTFILE", 0, 0, 0, ""},
 
606
  { "PACK_KEYS", 0, 0, 0, ""},
 
607
  { "PARTIAL", 0, 0, 0, ""},
 
608
  { "PASSWORD", 0, 0, 0, ""},
 
609
  { "PHASE", 0, 0, 0, ""},
 
610
  { "POINT", 0, 0, 0, ""},
 
611
  { "POLYGON", 0, 0, 0, ""},
 
612
  { "PRECISION", 0, 0, 0, ""},
 
613
  { "PREPARE", 0, 0, 0, ""},
 
614
  { "PREV", 0, 0, 0, ""},
 
615
  { "PRIMARY", 0, 0, 0, ""},
 
616
  { "PRIVILEGES", 0, 0, 0, ""},
 
617
  { "PROCEDURE", 0, 0, 0, ""},
 
618
  { "PROCESS", 0, 0, 0, ""},
 
619
  { "PROCESSLIST", 0, 0, 0, ""},
 
620
  { "PURGE", 0, 0, 0, ""},
 
621
  { "QUARTER", 0, 0, 0, ""},
 
622
  { "QUERY", 0, 0, 0, ""},
 
623
  { "QUICK", 0, 0, 0, ""},
 
624
  { "READ", 0, 0, 0, ""},
 
625
  { "READS", 0, 0, 0, ""},
 
626
  { "REAL", 0, 0, 0, ""},
 
627
  { "RECOVER", 0, 0, 0, ""},
 
628
  { "REDUNDANT", 0, 0, 0, ""},
 
629
  { "REFERENCES", 0, 0, 0, ""},
 
630
  { "REGEXP", 0, 0, 0, ""},
 
631
  { "RELAY_LOG_FILE", 0, 0, 0, ""},
 
632
  { "RELAY_LOG_POS", 0, 0, 0, ""},
 
633
  { "RELAY_THREAD", 0, 0, 0, ""},
 
634
  { "RELEASE", 0, 0, 0, ""},
 
635
  { "RELOAD", 0, 0, 0, ""},
 
636
  { "RENAME", 0, 0, 0, ""},
 
637
  { "REPAIR", 0, 0, 0, ""},
 
638
  { "REPEATABLE", 0, 0, 0, ""},
 
639
  { "REPLACE", 0, 0, 0, ""},
 
640
  { "REPLICATION", 0, 0, 0, ""},
 
641
  { "REPEAT", 0, 0, 0, ""},
 
642
  { "REQUIRE", 0, 0, 0, ""},
 
643
  { "RESET", 0, 0, 0, ""},
 
644
  { "RESTORE", 0, 0, 0, ""},
 
645
  { "RESTRICT", 0, 0, 0, ""},
 
646
  { "RESUME", 0, 0, 0, ""},
 
647
  { "RETURN", 0, 0, 0, ""},
 
648
  { "RETURNS", 0, 0, 0, ""},
 
649
  { "REVOKE", 0, 0, 0, ""},
 
650
  { "RIGHT", 0, 0, 0, ""},
 
651
  { "RLIKE", 0, 0, 0, ""},
 
652
  { "ROLLBACK", 0, 0, 0, ""},
 
653
  { "ROLLUP", 0, 0, 0, ""},
 
654
  { "ROUTINE", 0, 0, 0, ""},
 
655
  { "ROW", 0, 0, 0, ""},
 
656
  { "ROWS", 0, 0, 0, ""},
 
657
  { "ROW_FORMAT", 0, 0, 0, ""},
 
658
  { "RTREE", 0, 0, 0, ""},
 
659
  { "SAVEPOINT", 0, 0, 0, ""},
 
660
  { "SCHEMA", 0, 0, 0, ""},
 
661
  { "SCHEMAS", 0, 0, 0, ""},
 
662
  { "SECOND", 0, 0, 0, ""},
 
663
  { "SECOND_MICROSECOND", 0, 0, 0, ""},
 
664
  { "SECURITY", 0, 0, 0, ""},
 
665
  { "SELECT", 0, 0, 0, ""},
 
666
  { "SENSITIVE", 0, 0, 0, ""},
 
667
  { "SEPARATOR", 0, 0, 0, ""},
 
668
  { "SERIAL", 0, 0, 0, ""},
 
669
  { "SERIALIZABLE", 0, 0, 0, ""},
 
670
  { "SESSION", 0, 0, 0, ""},
 
671
  { "SET", 0, 0, 0, ""},
 
672
  { "SHARE", 0, 0, 0, ""},
 
673
  { "SHOW", 0, 0, 0, ""},
 
674
  { "SHUTDOWN", 0, 0, 0, ""},
 
675
  { "SIGNED", 0, 0, 0, ""},
 
676
  { "SIMPLE", 0, 0, 0, ""},
 
677
  { "SLAVE", 0, 0, 0, ""},
 
678
  { "SNAPSHOT", 0, 0, 0, ""},
 
679
  { "SMALLINT", 0, 0, 0, ""},
 
680
  { "SOME", 0, 0, 0, ""},
 
681
  { "SONAME", 0, 0, 0, ""},
 
682
  { "SOUNDS", 0, 0, 0, ""},
 
683
  { "SPATIAL", 0, 0, 0, ""},
 
684
  { "SPECIFIC", 0, 0, 0, ""},
 
685
  { "SQL", 0, 0, 0, ""},
 
686
  { "SQLEXCEPTION", 0, 0, 0, ""},
 
687
  { "SQLSTATE", 0, 0, 0, ""},
 
688
  { "SQLWARNING", 0, 0, 0, ""},
 
689
  { "SQL_BIG_RESULT", 0, 0, 0, ""},
 
690
  { "SQL_BUFFER_RESULT", 0, 0, 0, ""},
 
691
  { "SQL_CACHE", 0, 0, 0, ""},
 
692
  { "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""},
 
693
  { "SQL_NO_CACHE", 0, 0, 0, ""},
 
694
  { "SQL_SMALL_RESULT", 0, 0, 0, ""},
 
695
  { "SQL_THREAD", 0, 0, 0, ""},
 
696
  { "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
 
697
  { "SQL_TSI_SECOND", 0, 0, 0, ""},
 
698
  { "SQL_TSI_MINUTE", 0, 0, 0, ""},
 
699
  { "SQL_TSI_HOUR", 0, 0, 0, ""},
 
700
  { "SQL_TSI_DAY", 0, 0, 0, ""},
 
701
  { "SQL_TSI_WEEK", 0, 0, 0, ""},
 
702
  { "SQL_TSI_MONTH", 0, 0, 0, ""},
 
703
  { "SQL_TSI_QUARTER", 0, 0, 0, ""},
 
704
  { "SQL_TSI_YEAR", 0, 0, 0, ""},
 
705
  { "SSL", 0, 0, 0, ""},
 
706
  { "START", 0, 0, 0, ""},
 
707
  { "STARTING", 0, 0, 0, ""},
 
708
  { "STATUS", 0, 0, 0, ""},
 
709
  { "STOP", 0, 0, 0, ""},
 
710
  { "STORAGE", 0, 0, 0, ""},
 
711
  { "STRAIGHT_JOIN", 0, 0, 0, ""},
 
712
  { "STRING", 0, 0, 0, ""},
 
713
  { "STRIPED", 0, 0, 0, ""},
 
714
  { "SUBJECT", 0, 0, 0, ""},
 
715
  { "SUPER", 0, 0, 0, ""},
 
716
  { "SUSPEND", 0, 0, 0, ""},
 
717
  { "TABLE", 0, 0, 0, ""},
 
718
  { "TABLES", 0, 0, 0, ""},
 
719
  { "TABLESPACE", 0, 0, 0, ""},
 
720
  { "TEMPORARY", 0, 0, 0, ""},
 
721
  { "TEMPTABLE", 0, 0, 0, ""},
 
722
  { "TERMINATED", 0, 0, 0, ""},
 
723
  { "TEXT", 0, 0, 0, ""},
 
724
  { "THEN", 0, 0, 0, ""},
 
725
  { "TIMESTAMP", 0, 0, 0, ""},
 
726
  { "TIMESTAMPADD", 0, 0, 0, ""},
 
727
  { "TIMESTAMPDIFF", 0, 0, 0, ""},
 
728
  { "TINYINT", 0, 0, 0, ""},
 
729
  { "TINYTEXT", 0, 0, 0, ""},
 
730
  { "TO", 0, 0, 0, ""},
 
731
  { "TRAILING", 0, 0, 0, ""},
 
732
  { "TRANSACTION", 0, 0, 0, ""},
 
733
  { "TRIGGER", 0, 0, 0, ""},
 
734
  { "TRIGGERS", 0, 0, 0, ""},
 
735
  { "TRUE", 0, 0, 0, ""},
 
736
  { "TRUNCATE", 0, 0, 0, ""},
 
737
  { "TYPE", 0, 0, 0, ""},
 
738
  { "TYPES", 0, 0, 0, ""},
 
739
  { "UNCOMMITTED", 0, 0, 0, ""},
 
740
  { "UNDEFINED", 0, 0, 0, ""},
 
741
  { "UNDO", 0, 0, 0, ""},
 
742
  { "UNICODE", 0, 0, 0, ""},
 
743
  { "UNION", 0, 0, 0, ""},
 
744
  { "UNIQUE", 0, 0, 0, ""},
 
745
  { "UNKNOWN", 0, 0, 0, ""},
 
746
  { "UNLOCK", 0, 0, 0, ""},
 
747
  { "UNSIGNED", 0, 0, 0, ""},
 
748
  { "UNTIL", 0, 0, 0, ""},
 
749
  { "UPDATE", 0, 0, 0, ""},
 
750
  { "UPGRADE", 0, 0, 0, ""},
 
751
  { "USAGE", 0, 0, 0, ""},
 
752
  { "USE", 0, 0, 0, ""},
 
753
  { "USER", 0, 0, 0, ""},
 
754
  { "USER_RESOURCES", 0, 0, 0, ""},
 
755
  { "USE_FRM", 0, 0, 0, ""},
 
756
  { "USING", 0, 0, 0, ""},
 
757
  { "UTC_DATE", 0, 0, 0, ""},
 
758
  { "UTC_TIMESTAMP", 0, 0, 0, ""},
 
759
  { "VALUE", 0, 0, 0, ""},
 
760
  { "VALUES", 0, 0, 0, ""},
 
761
  { "VARBINARY", 0, 0, 0, ""},
 
762
  { "VARCHAR", 0, 0, 0, ""},
 
763
  { "VARCHARACTER", 0, 0, 0, ""},
 
764
  { "VARIABLES", 0, 0, 0, ""},
 
765
  { "VARYING", 0, 0, 0, ""},
 
766
  { "WARNINGS", 0, 0, 0, ""},
 
767
  { "WEEK", 0, 0, 0, ""},
 
768
  { "WHEN", 0, 0, 0, ""},
 
769
  { "WHERE", 0, 0, 0, ""},
 
770
  { "WHILE", 0, 0, 0, ""},
 
771
  { "VIEW", 0, 0, 0, ""},
 
772
  { "WITH", 0, 0, 0, ""},
 
773
  { "WORK", 0, 0, 0, ""},
 
774
  { "WRITE", 0, 0, 0, ""},
 
775
  { "X509", 0, 0, 0, ""},
 
776
  { "XOR", 0, 0, 0, ""},
 
777
  { "XA", 0, 0, 0, ""},
 
778
  { "YEAR", 0, 0, 0, ""},
 
779
  { "YEAR_MONTH", 0, 0, 0, ""},
 
780
  { "ZEROFILL", 0, 0, 0, ""},
 
781
  { "ABS", 0, 0, 0, ""},
 
782
  { "ACOS", 0, 0, 0, ""},
 
783
  { "ADDDATE", 0, 0, 0, ""},
 
784
  { "AES_ENCRYPT", 0, 0, 0, ""},
 
785
  { "AES_DECRYPT", 0, 0, 0, ""},
 
786
  { "AREA", 0, 0, 0, ""},
 
787
  { "ASIN", 0, 0, 0, ""},
 
788
  { "ASBINARY", 0, 0, 0, ""},
 
789
  { "ASTEXT", 0, 0, 0, ""},
 
790
  { "ASWKB", 0, 0, 0, ""},
 
791
  { "ASWKT", 0, 0, 0, ""},
 
792
  { "ATAN", 0, 0, 0, ""},
 
793
  { "ATAN2", 0, 0, 0, ""},
 
794
  { "BENCHMARK", 0, 0, 0, ""},
 
795
  { "BIN", 0, 0, 0, ""},
 
796
  { "BIT_OR", 0, 0, 0, ""},
 
797
  { "BIT_AND", 0, 0, 0, ""},
 
798
  { "BIT_XOR", 0, 0, 0, ""},
 
799
  { "CAST", 0, 0, 0, ""},
 
800
  { "CEIL", 0, 0, 0, ""},
 
801
  { "CEILING", 0, 0, 0, ""},
 
802
  { "CENTROID", 0, 0, 0, ""},
 
803
  { "CHAR_LENGTH", 0, 0, 0, ""},
 
804
  { "CHARACTER_LENGTH", 0, 0, 0, ""},
 
805
  { "COALESCE", 0, 0, 0, ""},
 
806
  { "COERCIBILITY", 0, 0, 0, ""},
 
807
  { "COMPRESS", 0, 0, 0, ""},
 
808
  { "CONCAT", 0, 0, 0, ""},
 
809
  { "CONCAT_WS", 0, 0, 0, ""},
 
810
  { "CONNECTION_ID", 0, 0, 0, ""},
 
811
  { "CONV", 0, 0, 0, ""},
 
812
  { "CONVERT_TZ", 0, 0, 0, ""},
 
813
  { "COUNT", 0, 0, 0, ""},
 
814
  { "COS", 0, 0, 0, ""},
 
815
  { "COT", 0, 0, 0, ""},
 
816
  { "CRC32", 0, 0, 0, ""},
 
817
  { "CROSSES", 0, 0, 0, ""},
 
818
  { "CURDATE", 0, 0, 0, ""},
 
819
  { "DATE_ADD", 0, 0, 0, ""},
 
820
  { "DATEDIFF", 0, 0, 0, ""},
 
821
  { "DATE_FORMAT", 0, 0, 0, ""},
 
822
  { "DATE_SUB", 0, 0, 0, ""},
 
823
  { "DAYNAME", 0, 0, 0, ""},
 
824
  { "DAYOFMONTH", 0, 0, 0, ""},
 
825
  { "DAYOFWEEK", 0, 0, 0, ""},
 
826
  { "DAYOFYEAR", 0, 0, 0, ""},
 
827
  { "DECODE", 0, 0, 0, ""},
 
828
  { "DEGREES", 0, 0, 0, ""},
 
829
  { "DES_ENCRYPT", 0, 0, 0, ""},
 
830
  { "DES_DECRYPT", 0, 0, 0, ""},
 
831
  { "DIMENSION", 0, 0, 0, ""},
 
832
  { "DISJOINT", 0, 0, 0, ""},
 
833
  { "ELT", 0, 0, 0, ""},
 
834
  { "ENCODE", 0, 0, 0, ""},
 
835
  { "ENCRYPT", 0, 0, 0, ""},
 
836
  { "ENDPOINT", 0, 0, 0, ""},
 
837
  { "ENVELOPE", 0, 0, 0, ""},
 
838
  { "EQUALS", 0, 0, 0, ""},
 
839
  { "EXTERIORRING", 0, 0, 0, ""},
 
840
  { "EXTRACT", 0, 0, 0, ""},
 
841
  { "EXP", 0, 0, 0, ""},
 
842
  { "EXPORT_SET", 0, 0, 0, ""},
 
843
  { "FIELD", 0, 0, 0, ""},
 
844
  { "FIND_IN_SET", 0, 0, 0, ""},
 
845
  { "FLOOR", 0, 0, 0, ""},
 
846
  { "FORMAT", 0, 0, 0, ""},
 
847
  { "FOUND_ROWS", 0, 0, 0, ""},
 
848
  { "FROM_DAYS", 0, 0, 0, ""},
 
849
  { "FROM_UNIXTIME", 0, 0, 0, ""},
 
850
  { "GET_LOCK", 0, 0, 0, ""},
 
851
  { "GLENGTH", 0, 0, 0, ""},
 
852
  { "GREATEST", 0, 0, 0, ""},
 
853
  { "GROUP_CONCAT", 0, 0, 0, ""},
 
854
  { "GROUP_UNIQUE_USERS", 0, 0, 0, ""},
 
855
  { "HEX", 0, 0, 0, ""},
 
856
  { "IFNULL", 0, 0, 0, ""},
 
857
  { "INET_ATON", 0, 0, 0, ""},
 
858
  { "INET_NTOA", 0, 0, 0, ""},
 
859
  { "INSTR", 0, 0, 0, ""},
 
860
  { "INTERIORRINGN", 0, 0, 0, ""},
 
861
  { "INTERSECTS", 0, 0, 0, ""},
 
862
  { "ISCLOSED", 0, 0, 0, ""},
 
863
  { "ISEMPTY", 0, 0, 0, ""},
 
864
  { "ISNULL", 0, 0, 0, ""},
 
865
  { "IS_FREE_LOCK", 0, 0, 0, ""},
 
866
  { "IS_USED_LOCK", 0, 0, 0, ""},
 
867
  { "LAST_INSERT_ID", 0, 0, 0, ""},
 
868
  { "ISSIMPLE", 0, 0, 0, ""},
 
869
  { "LAST_DAY", 0, 0, 0, ""},
 
870
  { "LCASE", 0, 0, 0, ""},
 
871
  { "LEAST", 0, 0, 0, ""},
 
872
  { "LENGTH", 0, 0, 0, ""},
 
873
  { "LN", 0, 0, 0, ""},
 
874
  { "LINEFROMTEXT", 0, 0, 0, ""},
 
875
  { "LINEFROMWKB", 0, 0, 0, ""},
 
876
  { "LINESTRINGFROMTEXT", 0, 0, 0, ""},
 
877
  { "LINESTRINGFROMWKB", 0, 0, 0, ""},
 
878
  { "LOAD_FILE", 0, 0, 0, ""},
 
879
  { "LOCATE", 0, 0, 0, ""},
 
880
  { "LOG", 0, 0, 0, ""},
 
881
  { "LOG2", 0, 0, 0, ""},
 
882
  { "LOG10", 0, 0, 0, ""},
 
883
  { "LOWER", 0, 0, 0, ""},
 
884
  { "LPAD", 0, 0, 0, ""},
 
885
  { "LTRIM", 0, 0, 0, ""},
 
886
  { "MAKE_SET", 0, 0, 0, ""},
 
887
  { "MAKEDATE", 0, 0, 0, ""},
 
888
  { "MASTER_POS_WAIT", 0, 0, 0, ""},
 
889
  { "MAX", 0, 0, 0, ""},
 
890
  { "MBRCONTAINS", 0, 0, 0, ""},
 
891
  { "MBRDISJOINT", 0, 0, 0, ""},
 
892
  { "MBREQUAL", 0, 0, 0, ""},
 
893
  { "MBRINTERSECTS", 0, 0, 0, ""},
 
894
  { "MBROVERLAPS", 0, 0, 0, ""},
 
895
  { "MBRTOUCHES", 0, 0, 0, ""},
 
896
  { "MBRWITHIN", 0, 0, 0, ""},
 
897
  { "MD5", 0, 0, 0, ""},
 
898
  { "MID", 0, 0, 0, ""},
 
899
  { "MIN", 0, 0, 0, ""},
 
900
  { "MLINEFROMTEXT", 0, 0, 0, ""},
 
901
  { "MLINEFROMWKB", 0, 0, 0, ""},
 
902
  { "MPOINTFROMTEXT", 0, 0, 0, ""},
 
903
  { "MPOINTFROMWKB", 0, 0, 0, ""},
 
904
  { "MPOLYFROMTEXT", 0, 0, 0, ""},
 
905
  { "MPOLYFROMWKB", 0, 0, 0, ""},
 
906
  { "MONTHNAME", 0, 0, 0, ""},
 
907
  { "MULTILINESTRINGFROMTEXT", 0, 0, 0, ""},
 
908
  { "MULTILINESTRINGFROMWKB", 0, 0, 0, ""},
 
909
  { "MULTIPOINTFROMTEXT", 0, 0, 0, ""},
 
910
  { "MULTIPOINTFROMWKB", 0, 0, 0, ""},
 
911
  { "MULTIPOLYGONFROMTEXT", 0, 0, 0, ""},
 
912
  { "MULTIPOLYGONFROMWKB", 0, 0, 0, ""},
 
913
  { "NAME_CONST", 0, 0, 0, ""},
 
914
  { "NOW", 0, 0, 0, ""},
 
915
  { "NULLIF", 0, 0, 0, ""},
 
916
  { "NUMINTERIORRINGS", 0, 0, 0, ""},
 
917
  { "NUMPOINTS", 0, 0, 0, ""},
 
918
  { "OCTET_LENGTH", 0, 0, 0, ""},
 
919
  { "OCT", 0, 0, 0, ""},
 
920
  { "ORD", 0, 0, 0, ""},
 
921
  { "OVERLAPS", 0, 0, 0, ""},
 
922
  { "PERIOD_ADD", 0, 0, 0, ""},
 
923
  { "PERIOD_DIFF", 0, 0, 0, ""},
 
924
  { "PI", 0, 0, 0, ""},
 
925
  { "POINTFROMTEXT", 0, 0, 0, ""},
 
926
  { "POINTFROMWKB", 0, 0, 0, ""},
 
927
  { "POINTN", 0, 0, 0, ""},
 
928
  { "POLYFROMTEXT", 0, 0, 0, ""},
 
929
  { "POLYFROMWKB", 0, 0, 0, ""},
 
930
  { "POLYGONFROMTEXT", 0, 0, 0, ""},
 
931
  { "POLYGONFROMWKB", 0, 0, 0, ""},
 
932
  { "POSITION", 0, 0, 0, ""},
 
933
  { "POW", 0, 0, 0, ""},
 
934
  { "POWER", 0, 0, 0, ""},
 
935
  { "QUOTE", 0, 0, 0, ""},
 
936
  { "RADIANS", 0, 0, 0, ""},
 
937
  { "RAND", 0, 0, 0, ""},
 
938
  { "RELEASE_LOCK", 0, 0, 0, ""},
 
939
  { "REVERSE", 0, 0, 0, ""},
 
940
  { "ROUND", 0, 0, 0, ""},
 
941
  { "ROW_COUNT", 0, 0, 0, ""},
 
942
  { "RPAD", 0, 0, 0, ""},
 
943
  { "RTRIM", 0, 0, 0, ""},
 
944
  { "SESSION_USER", 0, 0, 0, ""},
 
945
  { "SUBDATE", 0, 0, 0, ""},
 
946
  { "SIGN", 0, 0, 0, ""},
 
947
  { "SIN", 0, 0, 0, ""},
 
948
  { "SHA", 0, 0, 0, ""},
 
949
  { "SHA1", 0, 0, 0, ""},
 
950
  { "SLEEP", 0, 0, 0, ""},
 
951
  { "SOUNDEX", 0, 0, 0, ""},
 
952
  { "SPACE", 0, 0, 0, ""},
 
953
  { "SQRT", 0, 0, 0, ""},
 
954
  { "SRID", 0, 0, 0, ""},
 
955
  { "STARTPOINT", 0, 0, 0, ""},
 
956
  { "STD", 0, 0, 0, ""},
 
957
  { "STDDEV", 0, 0, 0, ""},
 
958
  { "STDDEV_POP", 0, 0, 0, ""},
 
959
  { "STDDEV_SAMP", 0, 0, 0, ""},
 
960
  { "STR_TO_DATE", 0, 0, 0, ""},
 
961
  { "STRCMP", 0, 0, 0, ""},
 
962
  { "SUBSTR", 0, 0, 0, ""},
 
963
  { "SUBSTRING", 0, 0, 0, ""},
 
964
  { "SUBSTRING_INDEX", 0, 0, 0, ""},
 
965
  { "SUM", 0, 0, 0, ""},
 
966
  { "SYSDATE", 0, 0, 0, ""},
 
967
  { "SYSTEM_USER", 0, 0, 0, ""},
 
968
  { "TAN", 0, 0, 0, ""},
 
969
  { "TIME_FORMAT", 0, 0, 0, ""},
 
970
  { "TO_DAYS", 0, 0, 0, ""},
 
971
  { "TOUCHES", 0, 0, 0, ""},
 
972
  { "TRIM", 0, 0, 0, ""},
 
973
  { "UCASE", 0, 0, 0, ""},
 
974
  { "UNCOMPRESS", 0, 0, 0, ""},
 
975
  { "UNCOMPRESSED_LENGTH", 0, 0, 0, ""},
 
976
  { "UNHEX", 0, 0, 0, ""},
 
977
  { "UNIQUE_USERS", 0, 0, 0, ""},
 
978
  { "UNIX_TIMESTAMP", 0, 0, 0, ""},
 
979
  { "UPPER", 0, 0, 0, ""},
 
980
  { "UUID", 0, 0, 0, ""},
 
981
  { "VARIANCE", 0, 0, 0, ""},
 
982
  { "VAR_POP", 0, 0, 0, ""},
 
983
  { "VAR_SAMP", 0, 0, 0, ""},
 
984
  { "VERSION", 0, 0, 0, ""},
 
985
  { "WEEKDAY", 0, 0, 0, ""},
 
986
  { "WEEKOFYEAR", 0, 0, 0, ""},
 
987
  { "WITHIN", 0, 0, 0, ""},
 
988
  { "X", 0, 0, 0, ""},
 
989
  { "Y", 0, 0, 0, ""},
 
990
  { "YEARWEEK", 0, 0, 0, ""},
1150
991
  /* end sentinel */
1151
 
  Commands((char *)NULL,       0, 0, 0, "")
 
992
  { (char *)NULL,       0, 0, 0, ""}
1152
993
};
1153
994
 
 
995
static const char *load_default_groups[]= { "drizzle","client",0 };
1154
996
 
1155
997
int history_length;
1156
998
static int not_in_history(const char *line);
1157
999
static void initialize_readline (char *name);
1158
1000
static void fix_history(string *final_command);
1159
1001
 
1160
 
static Commands *find_command(const char *name,char cmd_name);
 
1002
static COMMANDS *find_command(const char *name,char cmd_name);
1161
1003
static bool add_line(string *buffer,char *line,char *in_string,
1162
1004
                     bool *ml_comment);
1163
1005
static void remove_cntrl(string *buffer);
1165
1007
static void print_tab_data(drizzle_result_st *result);
1166
1008
static void print_table_data_vertically(drizzle_result_st *result);
1167
1009
static void print_warnings(uint32_t error_code);
1168
 
static boost::posix_time::ptime start_timer(void);
1169
 
static void end_timer(boost::posix_time::ptime, string &buff);
1170
 
static void drizzle_end_timer(boost::posix_time::ptime, string &buff);
1171
 
static void nice_time(boost::posix_time::time_duration duration, string &buff);
 
1010
static uint32_t start_timer(void);
 
1011
static void end_timer(uint32_t start_time,char *buff);
 
1012
static void drizzle_end_timer(uint32_t start_time,char *buff);
 
1013
static void nice_time(double sec,char *buff,bool part_second);
1172
1014
extern "C" void drizzle_end(int sig);
1173
1015
extern "C" void handle_sigint(int sig);
1174
1016
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1175
1017
static void window_resize(int sig);
1176
1018
#endif
1177
1019
 
 
1020
static inline int is_prefix(const char *s, const char *t)
 
1021
{
 
1022
  while (*t)
 
1023
    if (*s++ != *t++) return 0;
 
1024
  return 1;                                     /* WRONG */
 
1025
}
 
1026
 
1178
1027
/**
1179
1028
  Shutdown the server that we are currently connected to.
1180
1029
 
1190
1039
 
1191
1040
  if (verbose)
1192
1041
  {
1193
 
    printf(_("shutting down drizzled"));
 
1042
    printf("shutting down drizzled");
1194
1043
    if (opt_drizzle_port > 0)
1195
 
      printf(_(" on port %d"), opt_drizzle_port);
 
1044
      printf(" on port %d", opt_drizzle_port);
1196
1045
    printf("... ");
1197
1046
  }
1198
1047
 
1201
1050
  {
1202
1051
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1203
1052
    {
1204
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1053
      fprintf(stderr, "shutdown failed; error: '%s'",
1205
1054
              drizzle_result_error(&result));
1206
1055
      drizzle_result_free(&result);
1207
1056
    }
1208
1057
    else
1209
1058
    {
1210
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1059
      fprintf(stderr, "shutdown failed; error: '%s'",
1211
1060
              drizzle_con_error(&con));
1212
1061
    }
1213
1062
    return false;
1216
1065
  drizzle_result_free(&result);
1217
1066
 
1218
1067
  if (verbose)
1219
 
    printf(_("done\n"));
 
1068
    printf("done\n");
1220
1069
 
1221
1070
  return true;
1222
1071
}
1237
1086
  if (drizzle_ping(&con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
1238
1087
  {
1239
1088
    if (opt_silent < 2)
1240
 
      printf(_("drizzled is alive\n"));
 
1089
      printf("drizzled is alive\n");
1241
1090
  }
1242
1091
  else
1243
1092
  {
1244
1093
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1245
1094
    {
1246
 
      fprintf(stderr, _("ping failed; error: '%s'"),
 
1095
      fprintf(stderr, "ping failed; error: '%s'",
1247
1096
              drizzle_result_error(&result));
1248
1097
      drizzle_result_free(&result);
1249
1098
    }
1250
1099
    else
1251
1100
    {
1252
 
      fprintf(stderr, _("drizzled won't answer to ping, error: '%s'"),
 
1101
      fprintf(stderr, "drizzled won't answer to ping, error: '%s'",
1253
1102
              drizzle_con_error(&con));
1254
1103
    }
1255
1104
    return false;
1293
1142
  return executed;
1294
1143
}
1295
1144
 
1296
 
static void check_timeout_value(uint32_t in_connect_timeout)
1297
 
{
1298
 
  opt_connect_timeout= 0;
1299
 
  if (in_connect_timeout > 3600*12)
1300
 
  {
1301
 
    cout << _("Error: Invalid Value for connect_timeout"); 
1302
 
    exit(-1);
1303
 
  }
1304
 
  opt_connect_timeout= in_connect_timeout;
1305
 
}
1306
 
 
1307
 
static void check_max_input_line(uint32_t in_max_input_line)
1308
 
{
1309
 
  opt_max_input_line= 0;
1310
 
  if (in_max_input_line < 4096 || in_max_input_line > (int64_t)2*1024L*1024L*1024L)
1311
 
  {
1312
 
    cout << _("Error: Invalid Value for max_input_line");
1313
 
    exit(-1);
1314
 
  }
1315
 
  opt_max_input_line= in_max_input_line - (in_max_input_line % 1024);
1316
 
}
1317
 
 
1318
1145
int main(int argc,char *argv[])
1319
1146
{
1320
 
try
1321
 
{
 
1147
  char buff[80];
1322
1148
 
1323
1149
#if defined(ENABLE_NLS)
1324
1150
# if defined(HAVE_LOCALE_H)
1325
1151
  setlocale(LC_ALL, "");
1326
1152
# endif
1327
 
  bindtextdomain("drizzle7", LOCALEDIR);
1328
 
  textdomain("drizzle7");
1329
 
#endif
1330
 
 
1331
 
  po::options_description commandline_options(_("Options used only in command line"));
1332
 
  commandline_options.add_options()
1333
 
  ("help,?",_("Displays this help and exit."))
1334
 
  ("batch,B",_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1335
 
  ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1336
 
  _("Display column type information."))
1337
 
  ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
1338
 
  _("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1339
 
  ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1340
 
  _("Print the output of a query (rows) vertically."))
1341
 
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1342
 
  _("Continue even if we get an sql error."))
1343
 
  ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
1344
 
  _("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."))
1345
 
  ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
1346
 
  _("Turn off beep on error."))
1347
 
  ("disable-line-numbers", _("Do not write line numbers for errors."))
1348
 
  ("disable-column-names", _("Do not write column names in results."))
1349
 
  ("skip-column-names,N", 
1350
 
  _("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1351
 
  ("set-variable,O", po::value<string>(),
1352
 
  _("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1353
 
  ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1354
 
  _("Output in table format.")) 
1355
 
  ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1356
 
  _("Only allow UPDATE and DELETE that uses keys."))
1357
 
  ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1358
 
  _("Synonym for option --safe-updates, -U."))
1359
 
  ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
1360
 
  _("-v vvv implies that verbose= 3, Used to specify verbose"))
1361
 
  ("version,V", _("Output version information and exit."))
1362
 
  ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
1363
 
  _("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1364
 
  ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1365
 
  _("Show warnings after every statement."))
1366
 
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1367
 
  _("Number of lines before each import progress report."))
1368
 
  ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1369
 
  _("Ping the server to check if it's alive."))
1370
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1371
 
  _("Configuration file defaults are not used if no-defaults is set"))
1372
 
  ;
1373
 
 
1374
 
  po::options_description drizzle_options(_("Options specific to the drizzle client"));
1375
 
  drizzle_options.add_options()
1376
 
  ("disable-auto-rehash,A",
1377
 
  _("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."))
1378
 
  ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
1379
 
  _("Automatically switch to vertical output mode if the result is wider than the terminal width."))
1380
 
  ("database,D", po::value<string>(&current_db)->default_value(""),
1381
 
  _("Database to use."))
1382
 
  ("default-character-set",po::value<string>(),
1383
 
  _("(not used)"))
1384
 
  ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1385
 
  _("Delimiter to be used."))
1386
 
  ("execute,e", po::value<string>(),
1387
 
  _("Execute command and quit. (Disables --force and history file)"))
1388
 
  ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1389
 
  _("Enable LOAD DATA LOCAL INFILE."))
1390
 
  ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1391
 
  _("Flush buffer after each query."))
1392
 
  ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1393
 
  _("Ignore SIGINT (CTRL-C)"))
1394
 
  ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
1395
 
  _("Only update the default database. This is useful for skipping updates to other database in the update log."))
1396
 
  ("pager", po::value<string>(),
1397
 
  _("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."))
1398
 
  ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1399
 
  _("Disable pager and print to stdout. See interactive help (\\h) also."))
1400
 
  ("prompt", po::value<string>(&current_prompt)->default_value(""),  
1401
 
  _("Set the drizzle prompt to this value."))
1402
 
  ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
1403
 
  _("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."))
1404
 
  ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
1405
 
  _("Write fields without conversion. Used with --batch.")) 
1406
 
  ("disable-reconnect", _("Do not reconnect if the connection is lost."))
1407
 
  ("shutdown", po::value<bool>()->zero_tokens(),
1408
 
  _("Shutdown the server"))
1409
 
  ("silent,s", _("Be more silent. Print results with a tab as separator, each row on new line."))
1410
 
  ("tee", po::value<string>(),
1411
 
  _("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."))
1412
 
  ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(), 
1413
 
  _("Disable outfile. See interactive help (\\h) also."))
1414
 
  ("connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1415
 
  _("Number of seconds before connection timeout."))
1416
 
  ("max-input-line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1417
 
  _("Max length of input line"))
1418
 
  ("select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1419
 
  _("Automatic limit for SELECT when using --safe-updates"))
1420
 
  ("max-join-size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1421
 
  _("Automatic limit for rows in a join when using --safe-updates"))
1422
 
  ;
1423
 
 
1424
 
  po::options_description client_options(_("Options specific to the client"));
1425
 
  client_options.add_options()
1426
 
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1427
 
  _("Connect to host"))
1428
 
  ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
1429
 
  _("Password to use when connecting to server. If password is not given it's asked from the tty."))
1430
 
  ("port,p", po::value<uint32_t>()->default_value(0),
1431
 
  _("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1432
 
#ifdef DRIZZLE_ADMIN_TOOL
1433
 
  ("user,u", po::value<string>(&current_user)->default_value("root"),
1434
 
#else
1435
 
  ("user,u", po::value<string>(&current_user)->default_value(""),
1436
 
#endif
1437
 
  _("User for login if not current user."))
1438
 
  ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
1439
 
  _("The protocol of connection (mysql or drizzle)."))
1440
 
  ;
1441
 
 
1442
 
  po::options_description long_options(_("Allowed Options"));
1443
 
  long_options.add(commandline_options).add(drizzle_options).add(client_options);
1444
 
 
1445
 
  std::string system_config_dir_drizzle(SYSCONFDIR); 
1446
 
  system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
1447
 
 
1448
 
  std::string system_config_dir_client(SYSCONFDIR); 
1449
 
  system_config_dir_client.append("/drizzle/client.cnf");
1450
 
 
1451
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
1452
 
 
1453
 
  if (user_config_dir.compare(0, 2, "~/") == 0)
1454
 
  {
1455
 
    char *homedir;
1456
 
    homedir= getenv("HOME");
1457
 
    if (homedir != NULL)
1458
 
      user_config_dir.replace(0, 1, homedir);
1459
 
  }
1460
 
 
1461
 
  po::variables_map vm;
1462
 
 
1463
 
  po::positional_options_description p;
1464
 
  p.add("database", 1);
1465
 
 
1466
 
  // Disable allow_guessing
1467
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1468
 
 
1469
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
1470
 
            style(style).positional(p).extra_parser(parse_password_arg).run(),
1471
 
            vm);
1472
 
 
1473
 
  if (! vm["no-defaults"].as<bool>())
1474
 
  {
1475
 
    std::string user_config_dir_drizzle(user_config_dir);
1476
 
    user_config_dir_drizzle.append("/drizzle/drizzle.cnf"); 
1477
 
 
1478
 
    std::string user_config_dir_client(user_config_dir);
1479
 
    user_config_dir_client.append("/drizzle/client.cnf");
1480
 
 
1481
 
    ifstream user_drizzle_ifs(user_config_dir_drizzle.c_str());
1482
 
    po::store(dpo::parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1483
 
 
1484
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
1485
 
    po::store(dpo::parse_config_file(user_client_ifs, client_options), vm);
1486
 
 
1487
 
    ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1488
 
    store(dpo::parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1489
 
 
1490
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
1491
 
    po::store(dpo::parse_config_file(system_client_ifs, client_options), vm);
1492
 
  }
1493
 
 
1494
 
  po::notify(vm);
1495
 
 
1496
 
#ifdef DRIZZLE_ADMIN_TOOL
1497
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1498
 
                         getenv("DRIZZLE_PS1") :
1499
 
                         "drizzleadmin> ");
1500
 
#else
 
1153
  bindtextdomain("drizzle", LOCALEDIR);
 
1154
  textdomain("drizzle");
 
1155
#endif
 
1156
 
 
1157
  MY_INIT(argv[0]);
 
1158
  delimiter_str= delimiter;
1501
1159
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1502
1160
                         getenv("DRIZZLE_PS1") :
1503
1161
                         "drizzle> ");
1504
 
#endif
 
1162
  
1505
1163
  if (default_prompt == NULL)
1506
1164
  {
1507
1165
    fprintf(stderr, _("Memory allocation error while constructing initial "
1508
1166
                      "prompt. Aborting.\n"));
1509
1167
    exit(ENOMEM);
1510
1168
  }
1511
 
 
1512
 
  if (current_prompt.empty())
1513
 
    current_prompt= strdup(default_prompt);
1514
 
 
1515
 
  if (current_prompt.empty())
 
1169
  current_prompt= strdup(default_prompt);
 
1170
  if (current_prompt == NULL)
1516
1171
  {
1517
1172
    fprintf(stderr, _("Memory allocation error while constructing initial "
1518
1173
                      "prompt. Aborting.\n"));
1523
1178
 
1524
1179
  prompt_counter=0;
1525
1180
 
1526
 
  outfile.clear();      // no (default) outfile
1527
 
  pager.assign("stdout");  // the default, if --pager wasn't given
 
1181
  outfile[0]=0;      // no (default) outfile
 
1182
  strcpy(pager, "stdout");  // the default, if --pager wasn't given
1528
1183
  {
1529
 
    const char *tmp= getenv("PAGER");
 
1184
    char *tmp=getenv("PAGER");
1530
1185
    if (tmp && strlen(tmp))
1531
1186
    {
1532
1187
      default_pager_set= 1;
1533
 
      default_pager.assign(tmp);
 
1188
      strcpy(default_pager, tmp);
1534
1189
    }
1535
1190
  }
1536
 
  if (! isatty(0) || ! isatty(1))
 
1191
  if (!isatty(0) || !isatty(1))
1537
1192
  {
1538
 
    status.setBatch(1); opt_silent=1;
 
1193
    status.batch=1; opt_silent=1;
 
1194
    ignore_errors=0;
1539
1195
  }
1540
1196
  else
1541
 
    status.setAddToHistory(1);
1542
 
  status.setExitStatus(1);
 
1197
    status.add_to_history=1;
 
1198
  status.exit_status=1;
1543
1199
 
1544
1200
  {
1545
1201
    /*
1555
1211
      close(stdout_fileno_copy);             /* Clean up dup(). */
1556
1212
  }
1557
1213
 
1558
 
  /* Inverted Booleans */
1559
 
 
1560
 
  line_numbers= (vm.count("disable-line-numbers")) ? false : true;
1561
 
  column_names= (vm.count("disable-column-names")) ? false : true;
1562
 
  opt_rehash= (vm.count("disable-auto-rehash")) ? false : true;
1563
 
  opt_reconnect= (vm.count("disable-reconnect")) ? false : true;
1564
 
 
1565
 
  /* Don't rehash with --shutdown */
1566
 
  if (vm.count("shutdown"))
1567
 
  {
1568
 
    opt_rehash= false;
1569
 
    opt_shutdown= true;
1570
 
  }
1571
 
 
1572
 
  if (vm.count("delimiter"))
1573
 
  {
1574
 
    /* Check that delimiter does not contain a backslash */
1575
 
    if (! strstr(delimiter_str.c_str(), "\\"))
1576
 
    {
1577
 
      delimiter= (char *)delimiter_str.c_str();  
1578
 
    }
1579
 
    else
1580
 
    {
1581
 
      put_info(_("DELIMITER cannot contain a backslash character"),
1582
 
      INFO_ERROR,0,0);
1583
 
      exit(-1);
1584
 
    }
1585
 
   
1586
 
    delimiter_length= (uint32_t)strlen(delimiter);
1587
 
  }
1588
 
  if (vm.count("tee"))
1589
 
  { 
1590
 
    if (vm["tee"].as<string>().empty())
1591
 
    {
1592
 
      if (opt_outfile)
1593
 
        end_tee();
1594
 
    }
1595
 
    else
1596
 
      init_tee(vm["tee"].as<string>().c_str());
1597
 
  }
1598
 
  if (vm["disable-tee"].as<bool>() == true)
1599
 
  {
1600
 
    if (opt_outfile)
1601
 
      end_tee();
1602
 
  }
1603
 
  if (vm.count("pager"))
1604
 
  {
1605
 
    if (vm["pager"].as<string>().empty())
1606
 
      opt_nopager= 1;
1607
 
    else
1608
 
    {
1609
 
      opt_nopager= 0;
1610
 
      if (vm[pager].as<string>().length())
1611
 
      {
1612
 
        default_pager_set= 1;
1613
 
        pager.assign(vm["pager"].as<string>());
1614
 
        default_pager.assign(pager);
1615
 
      }
1616
 
      else if (default_pager_set)
1617
 
        pager.assign(default_pager);
1618
 
      else
1619
 
        opt_nopager= 1;
1620
 
    }
1621
 
  }
1622
 
  if (vm.count("disable-pager"))
1623
 
  {
1624
 
    opt_nopager= 1;
1625
 
  }
1626
 
 
1627
 
  if (vm.count("no-auto-rehash"))
1628
 
    opt_rehash= 0;
1629
 
 
1630
 
  if (vm.count("skip-column-names"))
1631
 
    column_names= 0;
1632
 
    
1633
 
  if (vm.count("execute"))
1634
 
  {  
1635
 
    status.setBatch(1);
1636
 
    status.setAddToHistory(1);
1637
 
    if (status.getLineBuff() == NULL)
1638
 
      status.setLineBuff(opt_max_input_line,NULL);
1639
 
    if (status.getLineBuff() == NULL)
1640
 
    {
1641
 
      exit(1);
1642
 
    }
1643
 
    status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
1644
 
  }
1645
 
 
1646
 
  if (one_database)
1647
 
    skip_updates= true;
1648
 
 
1649
 
  if (vm.count("protocol"))
1650
 
  {
1651
 
    std::transform(opt_protocol.begin(), opt_protocol.end(), 
1652
 
      opt_protocol.begin(), ::tolower);
1653
 
 
1654
 
    if (not opt_protocol.compare("mysql"))
1655
 
      use_drizzle_protocol=false;
1656
 
    else if (not opt_protocol.compare("drizzle"))
1657
 
      use_drizzle_protocol=true;
1658
 
    else
1659
 
    {
1660
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1661
 
      exit(-1);
1662
 
    }
1663
 
  }
1664
 
 
1665
 
  if (vm.count("port"))
1666
 
  {
1667
 
    opt_drizzle_port= vm["port"].as<uint32_t>();
1668
 
 
1669
 
    /* If the port number is > 65535 it is not a valid port
1670
 
       This also helps with potential data loss casting unsigned long to a
1671
 
       uint32_t. */
1672
 
    if (opt_drizzle_port > 65535)
1673
 
    {
1674
 
      printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
1675
 
      exit(-1);
1676
 
    }
1677
 
  }
1678
 
 
1679
 
  if (vm.count("password"))
1680
 
  {
1681
 
    if (!opt_password.empty())
1682
 
      opt_password.erase();
1683
 
    if (current_password == PASSWORD_SENTINEL)
1684
 
    {
1685
 
      opt_password= "";
1686
 
    }
1687
 
    else
1688
 
    {
1689
 
      opt_password= current_password;
1690
 
      tty_password= false;
1691
 
    }
1692
 
  }
1693
 
  else
1694
 
  {
1695
 
      tty_password= true;
1696
 
  }
1697
 
  
1698
 
 
1699
 
  if (!opt_verbose.empty())
1700
 
  {
1701
 
    verbose= opt_verbose.length();
1702
 
  }
1703
 
 
1704
 
  if (vm.count("batch"))
1705
 
  {
1706
 
    status.setBatch(1);
1707
 
    status.setAddToHistory(0);
1708
 
    if (opt_silent < 1)
1709
 
    {
1710
 
      opt_silent= 1;
1711
 
    }
1712
 
  }
1713
 
  if (vm.count("silent"))
1714
 
  {
1715
 
    opt_silent= 2;
1716
 
  }
1717
 
  
1718
 
  if (vm.count("help") || vm.count("version"))
1719
 
  {
1720
 
    printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
1721
 
           drizzle_version(), VERSION,
1722
 
           HOST_VENDOR, HOST_OS, HOST_CPU,
1723
 
           rl_library_version);
1724
 
    if (vm.count("version"))
1725
 
      exit(0);
1726
 
    printf(_("Copyright (C) 2008 Sun Microsystems\n"
1727
 
           "This software comes with ABSOLUTELY NO WARRANTY. "
1728
 
           "This is free software,\n"
1729
 
           "and you are welcome to modify and redistribute it "
1730
 
           "under the GPL license\n"));
1731
 
    printf(_("Usage: drizzle [OPTIONS] [schema]\n"));
1732
 
    cout << long_options;
1733
 
    exit(0);
1734
 
  }
1735
 
 
1736
 
 
1737
 
  if (process_options())
1738
 
  {
 
1214
  load_defaults("drizzle",load_default_groups,&argc,&argv);
 
1215
  defaults_argv=argv;
 
1216
  if (get_options(argc, (char **) argv))
 
1217
  {
 
1218
    free_defaults(defaults_argv);
 
1219
    my_end(0);
1739
1220
    exit(1);
1740
1221
  }
1741
1222
 
1742
1223
  memset(&drizzle, 0, sizeof(drizzle));
1743
 
  if (sql_connect(current_host, current_db, current_user, opt_password))
 
1224
  if (sql_connect(current_host,current_db,current_user,opt_password,
 
1225
                  opt_silent))
1744
1226
  {
1745
1227
    quick= 1;          // Avoid history
1746
 
    status.setExitStatus(1);
 
1228
    status.exit_status= 1;
1747
1229
    drizzle_end(-1);
1748
1230
  }
1749
1231
 
1751
1233
  if (execute_commands(&command_error) != false)
1752
1234
  {
1753
1235
    /* we've executed a command so exit before we go into readline mode */
 
1236
    free_defaults(defaults_argv);
 
1237
    my_end(0);
1754
1238
    exit(command_error);
1755
1239
  }
1756
1240
 
1757
 
  if (status.getBatch() && !status.getLineBuff())
 
1241
  if (status.batch && !status.line_buff)
1758
1242
  {
1759
 
    status.setLineBuff(opt_max_input_line, stdin);
1760
 
    if (status.getLineBuff() == NULL)
 
1243
    status.line_buff =batch_readline_init(opt_max_input_line+512, stdin);
 
1244
    if (status.line_buff == NULL)
1761
1245
    {
 
1246
      free_defaults(defaults_argv);
 
1247
      my_end(0);
1762
1248
      exit(1);
1763
1249
    }
1764
1250
  }
1765
1251
 
1766
 
  if (!status.getBatch())
 
1252
  if (!status.batch)
1767
1253
    ignore_errors=1;        // Don't abort monitor
1768
1254
 
1769
1255
  if (opt_sigint_ignore)
1778
1264
  /* call the SIGWINCH handler to get the default term width */
1779
1265
  window_resize(0);
1780
1266
#endif
1781
 
  std::vector<char> output_buff;
1782
 
  output_buff.resize(512);
1783
 
 
1784
 
  snprintf(&output_buff[0], output_buff.size(), 
1785
 
           _("Welcome to the Drizzle client..  Commands end with %s or \\g."), 
1786
 
           delimiter);
1787
 
 
1788
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
 
1267
 
 
1268
  put_info(_("Welcome to the Drizzle client..  Commands end with ; or \\g."),
 
1269
           INFO_INFO,0,0);
1789
1270
 
1790
1271
  glob_buffer= new string();
1791
1272
  glob_buffer->reserve(512);
1792
1273
 
1793
 
  snprintf(&output_buff[0], output_buff.size(),
1794
 
          _("Your Drizzle connection id is %u\nConnection protocol: %s\nServer version: %s\n"),
 
1274
  char * output_buff= (char *)malloc(512);
 
1275
  memset(output_buff, '\0', 512);
 
1276
 
 
1277
  sprintf(output_buff,
 
1278
          _("Your Drizzle connection id is %u\nServer version: %s\n"),
1795
1279
          drizzle_con_thread_id(&con),
1796
 
          opt_protocol.c_str(),
1797
1280
          server_version_string(&con));
1798
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
1799
 
 
1800
 
 
1801
 
  initialize_readline((char *)current_prompt.c_str());
1802
 
  if (!status.getBatch() && !quick)
 
1281
  put_info(output_buff, INFO_INFO, 0, 0);
 
1282
 
 
1283
  initialize_readline(current_prompt);
 
1284
  if (!status.batch && !quick)
1803
1285
  {
1804
1286
    /* read-history from file, default ~/.drizzle_history*/
1805
1287
    if (getenv("DRIZZLE_HISTFILE"))
1835
1317
      sprintf(histfile_tmp, "%s.TMP", histfile);
1836
1318
    }
1837
1319
  }
 
1320
  sprintf(buff, "%s",
 
1321
          _("Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n"));
1838
1322
 
1839
 
  put_info(_("Type 'help;' or '\\h' for help. "
1840
 
             "Type '\\c' to clear the buffer.\n"),INFO_INFO,0,0);
1841
 
  status.setExitStatus(read_and_execute(!status.getBatch()));
 
1323
  put_info(buff,INFO_INFO,0,0);
 
1324
  status.exit_status= read_and_execute(!status.batch);
1842
1325
  if (opt_outfile)
1843
1326
    end_tee();
1844
1327
  drizzle_end(0);
1845
 
}
1846
1328
 
1847
 
  catch(exception &err)
1848
 
  {
1849
 
    cerr << _("Error:") << err.what() << endl;
1850
 
  }
1851
1329
  return(0);        // Keep compiler happy
1852
1330
}
1853
1331
 
1855
1333
{
1856
1334
  drizzle_con_free(&con);
1857
1335
  drizzle_free(&drizzle);
1858
 
  if (!status.getBatch() && !quick && histfile)
 
1336
  if (!status.batch && !quick && histfile)
1859
1337
  {
1860
1338
    /* write-history */
1861
1339
    if (verbose)
1862
1340
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
1863
1341
    if (!write_history(histfile_tmp))
1864
 
      rename(histfile_tmp, histfile);
 
1342
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1865
1343
  }
1866
 
  delete status.getLineBuff();
1867
 
  status.setLineBuff(0);
 
1344
  batch_readline_end(status.line_buff);
1868
1345
 
1869
1346
  if (sig >= 0)
1870
1347
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1871
 
  delete glob_buffer;
1872
 
  delete processed_prompt;
1873
 
  opt_password.erase();
 
1348
  if (glob_buffer)
 
1349
    delete glob_buffer;
 
1350
  if (processed_prompt)
 
1351
    delete processed_prompt;
 
1352
  free(opt_password);
 
1353
  free(opt_drizzle_unix_port);
1874
1354
  free(histfile);
1875
1355
  free(histfile_tmp);
1876
 
  current_db.erase();
1877
 
  current_host.erase();
1878
 
  current_user.erase();
 
1356
  free(current_db);
 
1357
  free(current_host);
 
1358
  free(current_user);
1879
1359
  free(full_username);
1880
1360
  free(part_username);
1881
1361
  free(default_prompt);
1882
 
  current_prompt.erase();
1883
 
  exit(status.getExitStatus());
 
1362
  free(current_prompt);
 
1363
  free_defaults(defaults_argv);
 
1364
  my_end(my_end_arg);
 
1365
  exit(status.exit_status);
1884
1366
}
1885
1367
 
1886
1368
 
1893
1375
void handle_sigint(int sig)
1894
1376
{
1895
1377
  char kill_buffer[40];
1896
 
  boost::scoped_ptr<drizzle_con_st> kill_drizzle(new drizzle_con_st);
 
1378
  drizzle_con_st kill_drizzle;
1897
1379
  drizzle_result_st res;
1898
1380
  drizzle_return_t ret;
1899
1381
 
1902
1384
    goto err;
1903
1385
  }
1904
1386
 
1905
 
  if (drizzle_con_add_tcp(&drizzle, kill_drizzle.get(), current_host.c_str(),
1906
 
    opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
1907
 
    use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
 
1387
  if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host,
 
1388
                          opt_drizzle_port, current_user, opt_password, NULL,
 
1389
                          DRIZZLE_CON_NONE) == NULL)
1908
1390
  {
1909
1391
    goto err;
1910
1392
  }
1913
1395
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u",
1914
1396
          drizzle_con_thread_id(&con));
1915
1397
 
1916
 
  if (drizzle_query_str(kill_drizzle.get(), &res, kill_buffer, &ret) != NULL)
 
1398
  if (drizzle_query_str(&kill_drizzle, &res, kill_buffer, &ret) != NULL)
1917
1399
    drizzle_result_free(&res);
1918
1400
 
1919
 
  drizzle_con_free(kill_drizzle.get());
 
1401
  drizzle_con_free(&kill_drizzle);
1920
1402
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
1921
1403
 
1922
1404
  interrupted_query= 1;
1938
1420
}
1939
1421
#endif
1940
1422
 
1941
 
 
1942
 
 
1943
 
static int process_options(void)
 
1423
static struct my_option my_long_options[] =
 
1424
{
 
1425
  {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1426
   0, 0, 0, 0, 0},
 
1427
  {"help", 'I', N_("Synonym for -?"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1428
   0, 0, 0, 0, 0},
 
1429
  {"auto-rehash", OPT_AUTO_REHASH,
 
1430
   N_("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."),
 
1431
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
 
1432
   0, 0},
 
1433
  {"no-auto-rehash", 'A',
 
1434
   N_("No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of drizzle_st and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead."),
 
1435
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1436
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
 
1437
   N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
 
1438
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1439
  {"batch", 'B',
 
1440
   N_("Don't use history file. Disable interactive behavior. (Enables --silent)"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1441
  {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
 
1442
   (char**) &column_types_flag, (char**) &column_types_flag,
 
1443
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1444
  {"comments", 'c', N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"),
 
1445
   (char**) &preserve_comments, (char**) &preserve_comments,
 
1446
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1447
  {"compress", 'C', N_("Use compression in server/client protocol."),
 
1448
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1449
   0, 0, 0},
 
1450
  {"debug-check", OPT_DEBUG_CHECK, N_("Check memory and open file usage at exit ."),
 
1451
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
1452
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1453
  {"debug-info", 'T', N_("Print some debug info at exit."), (char**) &debug_info_flag,
 
1454
   (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1455
  {"database", 'D', N_("Database to use."), (char**) &current_db,
 
1456
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1457
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
1458
   N_("(not used)"), 0,
 
1459
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1460
  {"delimiter", OPT_DELIMITER, N_("Delimiter to be used."), (char**) &delimiter_str,
 
1461
   (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1462
  {"execute", 'e', N_("Execute command and quit. (Disables --force and history file)"), 0,
 
1463
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1464
  {"vertical", 'E', N_("Print the output of a query (rows) vertically."),
 
1465
   (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
1466
   0},
 
1467
  {"force", 'f', N_("Continue even if we get an sql error."),
 
1468
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
1469
   0, 0, 0, 0},
 
1470
  {"named-commands", 'G',
 
1471
   N_("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. Disable with --disable-named-commands. This option is disabled by default."),
 
1472
   (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
1473
   0, 0},
 
1474
  {"no-named-commands", 'g',
 
1475
   N_("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."),
 
1476
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1477
  {"ignore-spaces", 'i', N_("Ignore space after function names."), 0, 0, 0,
 
1478
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1479
  {"local-infile", OPT_LOCAL_INFILE, N_("Enable/disable LOAD DATA LOCAL INFILE."),
 
1480
   (char**) &opt_local_infile,
 
1481
   (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1482
  {"no-beep", 'b', N_("Turn off beep on error."), (char**) &opt_nobeep,
 
1483
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1484
  {"host", 'h', N_("Connect to host."), (char**) &current_host,
 
1485
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1486
  {"line-numbers", OPT_LINE_NUMBERS, N_("Write line numbers for errors."),
 
1487
   (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
 
1488
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1489
  {"skip-line-numbers", 'L', N_("Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead."), 0, 0, 0, GET_NO_ARG,
 
1490
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1491
  {"unbuffered", 'n', N_("Flush buffer after each query."), (char**) &unbuffered,
 
1492
   (char**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1493
  {"column-names", OPT_COLUMN_NAMES, N_("Write column names in results."),
 
1494
   (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
 
1495
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1496
  {"skip-column-names", 'N',
 
1497
   N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."),
 
1498
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1499
  {"set-variable", 'O',
 
1500
   N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."),
 
1501
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1502
  {"sigint-ignore", OPT_SIGINT_IGNORE, N_("Ignore SIGINT (CTRL-C)"),
 
1503
   (char**) &opt_sigint_ignore,  (char**) &opt_sigint_ignore, 0, GET_BOOL,
 
1504
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1505
  {"one-database", 'o',
 
1506
   N_("Only update the default database. This is useful for skipping updates to other database in the update log."),
 
1507
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1508
  {"pager", OPT_PAGER,
 
1509
   N_("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."),
 
1510
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1511
  {"no-pager", OPT_NOPAGER,
 
1512
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
 
1513
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1514
  {"password", 'P',
 
1515
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
 
1516
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1517
  {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
 
1518
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
1519
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1520
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
 
1521
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
 
1522
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1523
  {"quick", 'q',
 
1524
   N_("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."),
 
1525
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1526
  {"raw", 'r', N_("Write fields without conversion. Used with --batch."),
 
1527
   (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1528
   0, 0, 0},
 
1529
  {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
 
1530
   (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
1531
  {"shutdown", OPT_SHUTDOWN, N_("Shutdown the server."),
 
1532
   (char**) &opt_shutdown, (char**) &opt_shutdown, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1533
  {"silent", 's', N_("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,
 
1534
   0, 0},
 
1535
  {"socket", 'S', N_("Socket file to use for connection."),
 
1536
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR_ALLOC,
 
1537
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1538
  {"table", 't', N_("Output in table format."), (char**) &output_tables,
 
1539
   (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1540
  {"tee", OPT_TEE,
 
1541
   N_("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."),
 
1542
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1543
  {"no-tee", OPT_NOTEE, N_("Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead"), 0, 0, 0, GET_NO_ARG,
 
1544
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1545
  {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
 
1546
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1547
  {"safe-updates", 'U', N_("Only allow UPDATE and DELETE that uses keys."),
 
1548
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1549
   0, 0, 0, 0},
 
1550
  {"i-am-a-dummy", 'U', N_("Synonym for option --safe-updates, -U."),
 
1551
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1552
   0, 0, 0, 0},
 
1553
  {"verbose", 'v', N_("Write more. (-v -v -v gives the table output format)."), 0,
 
1554
   0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1555
  {"version", 'V', N_("Output version information and exit."), 0, 0, 0,
 
1556
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1557
  {"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_NO_ARG,
 
1558
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1559
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
 
1560
   N_("Number of seconds before connection timeout."),
 
1561
   (char**) &opt_connect_timeout,
 
1562
   (char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 3600*12, 0,
 
1563
   0, 0},
 
1564
  {"max_input_line", OPT_MAX_INPUT_LINE,
 
1565
   N_("Max length of input line"),
 
1566
   (char**) &opt_max_input_line, (char**) &opt_max_input_line, 0,
 
1567
   GET_UINT32, REQUIRED_ARG, 16 *1024L*1024L, 4096,
 
1568
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1569
  {"select_limit", OPT_SELECT_LIMIT,
 
1570
   N_("Automatic limit for SELECT when using --safe-updates"),
 
1571
   (char**) &select_limit,
 
1572
   (char**) &select_limit, 0, GET_UINT32, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
 
1573
   0, 1, 0},
 
1574
  {"max_join_size", OPT_MAX_JOIN_SIZE,
 
1575
   N_("Automatic limit for rows in a join when using --safe-updates"),
 
1576
   (char**) &max_join_size,
 
1577
   (char**) &max_join_size, 0, GET_UINT32, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
 
1578
   0, 1, 0},
 
1579
  {"secure-auth", OPT_SECURE_AUTH, N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"), (char**) &opt_secure_auth,
 
1580
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1581
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
 
1582
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
 
1583
   0, 0, 0, 0, 0, 0},
 
1584
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
 
1585
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
 
1586
   0, 0, 0, 0, 0, 0},
 
1587
  {"ping", OPT_PING, N_("Ping the server to check if it's alive."),
 
1588
   (char**) &opt_ping, (char**) &opt_ping, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1589
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1590
};
 
1591
 
 
1592
 
 
1593
static void usage(int version)
 
1594
{
 
1595
  const char* readline= "readline";
 
1596
 
 
1597
  printf(_("%s  Ver %s Distrib %s, for %s-%s (%s) using %s %s\n"),
 
1598
         my_progname, VER.c_str(), drizzle_version(),
 
1599
         HOST_VENDOR, HOST_OS, HOST_CPU,
 
1600
         readline, rl_library_version);
 
1601
 
 
1602
  if (version)
 
1603
    return;
 
1604
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
 
1605
           "This software comes with ABSOLUTELY NO WARRANTY. "
 
1606
           "This is free software,\n"
 
1607
           "and you are welcome to modify and redistribute it "
 
1608
           "under the GPL license\n"));
 
1609
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
 
1610
  my_print_help(my_long_options);
 
1611
  print_defaults("drizzle", load_default_groups);
 
1612
  my_print_variables(my_long_options);
 
1613
}
 
1614
 
 
1615
 
 
1616
extern "C" bool
 
1617
get_one_option(int optid, const struct my_option *, char *argument)
 
1618
{
 
1619
  char *endchar= NULL;
 
1620
  uint64_t temp_drizzle_port= 0;
 
1621
 
 
1622
  switch(optid) {
 
1623
  case  OPT_DEFAULT_CHARSET:
 
1624
    default_charset_used= 1;
 
1625
    break;
 
1626
  case OPT_DELIMITER:
 
1627
    if (argument == disabled_my_option)
 
1628
    {
 
1629
      strcpy(delimiter, DEFAULT_DELIMITER);
 
1630
    }
 
1631
    else
 
1632
    {
 
1633
      /* Check that delimiter does not contain a backslash */
 
1634
      if (!strstr(argument, "\\"))
 
1635
      {
 
1636
        strncpy(delimiter, argument, sizeof(delimiter) - 1);
 
1637
      }
 
1638
      else
 
1639
      {
 
1640
        put_info(_("DELIMITER cannot contain a backslash character"),
 
1641
                 INFO_ERROR,0,0);
 
1642
        return false;
 
1643
      }
 
1644
    }
 
1645
    delimiter_length= (uint32_t)strlen(delimiter);
 
1646
    delimiter_str= delimiter;
 
1647
    break;
 
1648
  case OPT_TEE:
 
1649
    if (argument == disabled_my_option)
 
1650
    {
 
1651
      if (opt_outfile)
 
1652
        end_tee();
 
1653
    }
 
1654
    else
 
1655
      init_tee(argument);
 
1656
    break;
 
1657
  case OPT_NOTEE:
 
1658
    printf(_("WARNING: option deprecated; use --disable-tee instead.\n"));
 
1659
    if (opt_outfile)
 
1660
      end_tee();
 
1661
    break;
 
1662
  case OPT_PAGER:
 
1663
    if (argument == disabled_my_option)
 
1664
      opt_nopager= 1;
 
1665
    else
 
1666
    {
 
1667
      opt_nopager= 0;
 
1668
      if (argument && strlen(argument))
 
1669
      {
 
1670
        default_pager_set= 1;
 
1671
        strncpy(pager, argument, sizeof(pager) - 1);
 
1672
        strcpy(default_pager, pager);
 
1673
      }
 
1674
      else if (default_pager_set)
 
1675
        strcpy(pager, default_pager);
 
1676
      else
 
1677
        opt_nopager= 1;
 
1678
    }
 
1679
    break;
 
1680
  case OPT_NOPAGER:
 
1681
    printf(_("WARNING: option deprecated; use --disable-pager instead.\n"));
 
1682
    opt_nopager= 1;
 
1683
    break;
 
1684
  case OPT_SERVER_ARG:
 
1685
    printf(_("WARNING: --server-arg option not supported in this configuration.\n"));
 
1686
    break;
 
1687
  case 'A':
 
1688
    opt_rehash= 0;
 
1689
    break;
 
1690
  case 'N':
 
1691
    column_names= 0;
 
1692
    break;
 
1693
  case 'e':
 
1694
    status.batch= 1;
 
1695
    status.add_to_history= 0;
 
1696
    if (!status.line_buff)
 
1697
      ignore_errors= 0;                         // do it for the first -e only
 
1698
    if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
 
1699
      return 1;
 
1700
    break;
 
1701
  case 'o':
 
1702
    if (argument == disabled_my_option)
 
1703
      one_database= 0;
 
1704
    else
 
1705
      one_database= skip_updates= 1;
 
1706
    break;
 
1707
  case 'p':
 
1708
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1709
    /* if there is an alpha character this is not a valid port */
 
1710
    if (strlen(endchar) != 0)
 
1711
    {
 
1712
      put_info(_("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
 
1713
      return false;
 
1714
    }
 
1715
    /* If the port number is > 65535 it is not a valid port
 
1716
       This also helps with potential data loss casting unsigned long to a
 
1717
       uint32_t. */
 
1718
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1719
    {
 
1720
      put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
 
1721
      return false;
 
1722
    }
 
1723
    else
 
1724
    {
 
1725
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1726
    }
 
1727
    break;
 
1728
  case 'P':
 
1729
    /* Don't require password */
 
1730
    if (argument == disabled_my_option)
 
1731
    {
 
1732
      argument= (char*) "";
 
1733
    }
 
1734
    if (argument)
 
1735
    {
 
1736
      char *start= argument;
 
1737
      free(opt_password);
 
1738
      opt_password= strdup(argument);
 
1739
      while (*argument)
 
1740
      {
 
1741
        /* Overwriting password with 'x' */
 
1742
        *argument++= 'x';
 
1743
      }
 
1744
      if (*start)
 
1745
      {
 
1746
        start[1]= 0;
 
1747
      }
 
1748
      tty_password= 0;
 
1749
    }
 
1750
    else
 
1751
    {
 
1752
      tty_password= 1;
 
1753
    }
 
1754
    break;
 
1755
  case 's':
 
1756
    if (argument == disabled_my_option)
 
1757
      opt_silent= 0;
 
1758
    else
 
1759
      opt_silent++;
 
1760
    break;
 
1761
  case 'v':
 
1762
    if (argument == disabled_my_option)
 
1763
      verbose= 0;
 
1764
    else
 
1765
      verbose++;
 
1766
    break;
 
1767
  case 'B':
 
1768
    status.batch= 1;
 
1769
    status.add_to_history= 0;
 
1770
    set_if_bigger(opt_silent,1);                         // more silent
 
1771
    break;
 
1772
  case 'V':
 
1773
    usage(1);
 
1774
    exit(0);
 
1775
  case 'I':
 
1776
  case '?':
 
1777
    usage(0);
 
1778
    exit(0);
 
1779
  }
 
1780
  return 0;
 
1781
}
 
1782
 
 
1783
 
 
1784
static int get_options(int argc, char **argv)
1944
1785
{
1945
1786
  char *tmp, *pagpoint;
1946
 
  
 
1787
  int ho_error;
1947
1788
 
1948
1789
  tmp= (char *) getenv("DRIZZLE_HOST");
1949
1790
  if (tmp)
1950
 
    current_host.assign(tmp);
 
1791
    current_host= strdup(tmp);
1951
1792
 
1952
1793
  pagpoint= getenv("PAGER");
1953
1794
  if (!((char*) (pagpoint)))
1954
1795
  {
1955
 
    pager.assign("stdout");
 
1796
    strcpy(pager, "stdout");
1956
1797
    opt_nopager= 1;
1957
1798
  }
1958
1799
  else
1959
 
  {
1960
 
    pager.assign(pagpoint);
1961
 
  }
1962
 
  default_pager.assign(pager);
1963
 
 
1964
 
  //
1965
 
 
1966
 
  if (status.getBatch()) /* disable pager and outfile in this case */
1967
 
  {
1968
 
    default_pager.assign("stdout");
1969
 
    pager.assign("stdout");
 
1800
    strcpy(pager, pagpoint);
 
1801
  strcpy(default_pager, pager);
 
1802
 
 
1803
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
 
1804
    exit(ho_error);
 
1805
 
 
1806
  if (status.batch) /* disable pager and outfile in this case */
 
1807
  {
 
1808
    strcpy(default_pager, "stdout");
 
1809
    strcpy(pager, "stdout");
1970
1810
    opt_nopager= 1;
1971
1811
    default_pager_set= 0;
1972
1812
    opt_outfile= 0;
1974
1814
    connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1975
1815
  }
1976
1816
 
 
1817
  if (argc > 1)
 
1818
  {
 
1819
    usage(0);
 
1820
    exit(1);
 
1821
  }
 
1822
  if (argc == 1)
 
1823
  {
 
1824
    skip_updates= 0;
 
1825
    free(current_db);
 
1826
    current_db= strdup(*argv);
 
1827
  }
1977
1828
  if (tty_password)
1978
1829
    opt_password= client_get_tty_password(NULL);
 
1830
  if (debug_info_flag)
 
1831
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
1832
  if (debug_check_flag)
 
1833
    my_end_arg= MY_CHECK_ERROR;
1979
1834
  return(0);
1980
1835
}
1981
1836
 
1985
1840
  char in_string=0;
1986
1841
  uint32_t line_number=0;
1987
1842
  bool ml_comment= 0;
1988
 
  Commands *com;
1989
 
  status.setExitStatus(1);
 
1843
  COMMANDS *com;
 
1844
  status.exit_status=1;
1990
1845
 
1991
1846
  for (;;)
1992
1847
  {
1993
1848
    if (!interactive)
1994
1849
    {
1995
 
      if (status.getLineBuff())
1996
 
        line= status.getLineBuff()->readline();
1997
 
      else
1998
 
        line= 0;
1999
 
 
 
1850
      line=batch_readline(status.line_buff);
 
1851
      /*
 
1852
        Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
 
1853
        Editors like "notepad" put this marker in
 
1854
        the very beginning of a text file when
 
1855
        you save the file using "Unicode UTF-8" format.
 
1856
      */
 
1857
      if (!line_number &&
 
1858
          (unsigned char) line[0] == 0xEF &&
 
1859
          (unsigned char) line[1] == 0xBB &&
 
1860
          (unsigned char) line[2] == 0xBF)
 
1861
        line+= 3;
2000
1862
      line_number++;
2001
1863
      if (show_progress_size > 0)
2002
1864
      {
2004
1866
          fprintf(stderr, _("Processing line: %"PRIu32"\n"), line_number);
2005
1867
      }
2006
1868
      if (!glob_buffer->empty())
2007
 
        status.setQueryStartLine(line_number);
 
1869
        status.query_start_line=line_number;
2008
1870
    }
2009
1871
    else
2010
1872
    {
2011
 
      string prompt(ml_comment
2012
 
                      ? "   /*> " 
2013
 
                      : glob_buffer->empty()
2014
 
                        ? construct_prompt()
2015
 
                        : not in_string
2016
 
                          ? "    -> "
2017
 
                          : in_string == '\''
2018
 
                            ? "    '> "
2019
 
                            : in_string == '`'
2020
 
                              ? "    `> "
2021
 
                              : "    \"> ");
 
1873
      const char *prompt= (const char*) (ml_comment ? "   /*> " :
 
1874
                                         (glob_buffer->empty())
 
1875
                                         ?  construct_prompt()
 
1876
                                         : !in_string ? "    -> " :
 
1877
                                         in_string == '\'' ?
 
1878
                                         "    '> " : (in_string == '`' ?
 
1879
                                                      "    `> " :
 
1880
                                                      "    \"> "));
2022
1881
      if (opt_outfile && glob_buffer->empty())
2023
1882
        fflush(OUTFILE);
2024
1883
 
2025
1884
      if (opt_outfile)
2026
 
        fputs(prompt.c_str(), OUTFILE);
2027
 
      line= readline(prompt.c_str());
 
1885
        fputs(prompt, OUTFILE);
 
1886
      line= readline(prompt);
2028
1887
      /*
2029
1888
        When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
2030
1889
        which may cause coredump.
2035
1894
    // End of file
2036
1895
    if (!line)
2037
1896
    {
2038
 
      status.setExitStatus(0);
 
1897
      status.exit_status=0;
2039
1898
      break;
2040
1899
    }
2041
1900
 
2051
1910
      // If buffer was emptied
2052
1911
      if (glob_buffer->empty())
2053
1912
        in_string=0;
2054
 
      if (interactive && status.getAddToHistory() && not_in_history(line))
 
1913
      if (interactive && status.add_to_history && not_in_history(line))
2055
1914
        add_history(line);
2056
1915
      continue;
2057
1916
    }
2060
1919
  }
2061
1920
  /* if in batch mode, send last query even if it doesn't end with \g or go */
2062
1921
 
2063
 
  if (!interactive && !status.getExitStatus())
 
1922
  if (!interactive && !status.exit_status)
2064
1923
  {
2065
1924
    remove_cntrl(glob_buffer);
2066
1925
    if (!glob_buffer->empty())
2067
1926
    {
2068
 
      status.setExitStatus(1);
 
1927
      status.exit_status=1;
2069
1928
      if (com_go(glob_buffer,line) <= 0)
2070
 
        status.setExitStatus(0);
 
1929
        status.exit_status=0;
2071
1930
    }
2072
1931
  }
2073
1932
 
2074
 
  return status.getExitStatus();
 
1933
  return status.exit_status;
2075
1934
}
2076
1935
 
2077
1936
 
2078
 
static Commands *find_command(const char *name,char cmd_char)
 
1937
static COMMANDS *find_command(const char *name,char cmd_char)
2079
1938
{
2080
1939
  uint32_t len;
2081
1940
  const char *end;
2087
1946
  }
2088
1947
  else
2089
1948
  {
2090
 
    while (isspace(*name))
 
1949
    while (my_isspace(charset_info,*name))
2091
1950
      name++;
2092
1951
    /*
2093
1952
      If there is an \\g in the row or if the row has a delimiter but
2096
1955
    */
2097
1956
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
2098
1957
                                !(strlen(name) >= 9 &&
2099
 
                                  !strcmp(name, "delimiter"))))
2100
 
      return(NULL);
 
1958
                                  !my_strnncoll(charset_info,
 
1959
                                                (unsigned char*) name, 9,
 
1960
                                                (const unsigned char*) "delimiter",
 
1961
                                                9))))
 
1962
      return((COMMANDS *) 0);
2101
1963
    if ((end=strcont(name," \t")))
2102
1964
    {
2103
1965
      len=(uint32_t) (end - name);
2104
 
      while (isspace(*end))
 
1966
      while (my_isspace(charset_info,*end))
2105
1967
        end++;
2106
1968
      if (!*end)
2107
1969
        end=0;          // no arguments to function
2110
1972
      len=(uint32_t) strlen(name);
2111
1973
  }
2112
1974
 
2113
 
  for (uint32_t i= 0; commands[i].getName(); i++)
 
1975
  for (uint32_t i= 0; commands[i].name; i++)
2114
1976
  {
2115
1977
    if (commands[i].func &&
2116
 
        ((name && !strncmp(name, commands[i].getName(), len)
2117
 
          && !commands[i].getName()[len] && (!end || (end && commands[i].getTakesParams()))) || (!name && commands[i].getCmdChar() == cmd_char)))
 
1978
        ((name && !my_strnncoll(charset_info,(const unsigned char*)name,len, (const unsigned char*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
2118
1979
    {
2119
1980
      return(&commands[i]);
2120
1981
    }
2121
1982
  }
2122
 
  return(NULL);
 
1983
  return((COMMANDS *) 0);
2123
1984
}
2124
1985
 
2125
1986
 
2127
1988
                        bool *ml_comment)
2128
1989
{
2129
1990
  unsigned char inchar;
2130
 
  char *pos, *out;
2131
 
  Commands *com;
 
1991
  char buff[80], *pos, *out;
 
1992
  COMMANDS *com;
2132
1993
  bool need_space= 0;
2133
1994
  bool ss_comment= 0;
2134
1995
 
2135
1996
 
2136
1997
  if (!line[0] && (buffer->empty()))
2137
1998
    return(0);
2138
 
  if (status.getAddToHistory() && line[0] && not_in_history(line))
 
1999
  if (status.add_to_history && line[0] && not_in_history(line))
2139
2000
    add_history(line);
2140
2001
  char *end_of_line=line+(uint32_t) strlen(line);
2141
2002
 
2144
2005
    if (!preserve_comments)
2145
2006
    {
2146
2007
      // Skip spaces at the beggining of a statement
2147
 
      if (isspace(inchar) && (out == line) &&
 
2008
      if (my_isspace(charset_info,inchar) && (out == line) &&
2148
2009
          (buffer->empty()))
2149
2010
        continue;
2150
2011
    }
2151
2012
 
2152
2013
    // Accept multi-byte characters as-is
2153
 
    if (not drizzled::utf8::is_single(*pos))
 
2014
    int length;
 
2015
    if (use_mb(charset_info) &&
 
2016
        (length= my_ismbchar(charset_info, pos, end_of_line)))
2154
2017
    {
2155
 
      int length;
2156
 
      if ((length= drizzled::utf8::sequence_length(*pos)))
 
2018
      if (!*ml_comment || preserve_comments)
2157
2019
      {
2158
 
        if (!*ml_comment || preserve_comments)
2159
 
        {
2160
 
          while (length--)
2161
 
            *out++ = *pos++;
2162
 
          pos--;
2163
 
        }
2164
 
        else
2165
 
          pos+= length - 1;
2166
 
        continue;
 
2020
        while (length--)
 
2021
          *out++ = *pos++;
 
2022
        pos--;
2167
2023
      }
 
2024
      else
 
2025
        pos+= length - 1;
 
2026
      continue;
2168
2027
    }
2169
2028
    if (!*ml_comment && inchar == '\\' &&
2170
2029
        !(*in_string && (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
2190
2049
 
2191
2050
        if ((*com->func)(buffer,pos-1) > 0)
2192
2051
          return(1);                       // Quit
2193
 
        if (com->getTakesParams())
 
2052
        if (com->takes_params)
2194
2053
        {
2195
2054
          if (ss_comment)
2196
2055
          {
2219
2078
      }
2220
2079
      else
2221
2080
      {
2222
 
        string buff(_("Unknown command: "));
2223
 
        buff.push_back('\'');
2224
 
        buff.push_back(inchar);
2225
 
        buff.push_back('\'');
2226
 
        buff.push_back('.');
2227
 
        if (put_info(buff.c_str(),INFO_ERROR,0,0) > 0)
 
2081
        sprintf(buff,_("Unknown command '\\%c'."),inchar);
 
2082
        if (put_info(buff,INFO_ERROR,0,0) > 0)
2228
2083
          return(1);
2229
2084
        *out++='\\';
2230
2085
        *out++=(char) inchar;
2233
2088
    }
2234
2089
    else if (!*ml_comment && !*in_string &&
2235
2090
             (end_of_line - pos) >= 10 &&
2236
 
             !strncmp(pos, "delimiter ", 10))
 
2091
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
 
2092
                           (const unsigned char*) "delimiter ", 10))
2237
2093
    {
2238
2094
      // Flush previously accepted characters
2239
2095
      if (out != line)
2270
2126
 
2271
2127
      if (preserve_comments)
2272
2128
      {
2273
 
        while (isspace(*pos))
 
2129
        while (my_isspace(charset_info, *pos))
2274
2130
          *out++= *pos++;
2275
2131
      }
2276
2132
      // Flush previously accepted characters
2283
2139
      if (preserve_comments && ((*pos == '#') ||
2284
2140
                                ((*pos == '-') &&
2285
2141
                                 (pos[1] == '-') &&
2286
 
                                 isspace(pos[2]))))
 
2142
                                 my_isspace(charset_info, pos[2]))))
2287
2143
      {
2288
2144
        // Add trailing single line comments to this statement
2289
2145
        buffer->append(pos);
2310
2166
                 && (inchar == '#'
2311
2167
                     || (inchar == '-'
2312
2168
                         && pos[1] == '-'
2313
 
                         && isspace(pos[2])))))
 
2169
                         && my_isspace(charset_info,pos[2])))))
2314
2170
    {
2315
2171
      // Flush previously accepted characters
2316
2172
      if (out != line)
2376
2232
        *in_string= (char) inchar;
2377
2233
      if (!*ml_comment || preserve_comments)
2378
2234
      {
2379
 
        if (need_space && !isspace((char)inchar))
 
2235
        if (need_space && !my_isspace(charset_info, (char)inchar))
2380
2236
          *out++= ' ';
2381
2237
        need_space= 0;
2382
2238
        *out++= (char) inchar;
2387
2243
  {
2388
2244
    *out++='\n';
2389
2245
    uint32_t length=(uint32_t) (out-line);
2390
 
    if ((buffer->length() + length) > opt_max_input_line)
2391
 
    {
2392
 
      status.setExitStatus(1);
2393
 
      put_info(_("Not found a delimiter within max_input_line of input"), INFO_ERROR, 0, 0);
2394
 
      return 1;
2395
 
    }
2396
2246
    if ((!*ml_comment || preserve_comments))
2397
2247
      buffer->append(line, length);
2398
2248
  }
2497
2347
 
2498
2348
  /* Tell the completer that we want a crack first. */
2499
2349
  rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
2500
 
  rl_completion_entry_function= (drizzle_compentry_func_t*)&no_completion;
 
2350
  rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2501
2351
}
2502
2352
 
2503
2353
 
2509
2359
*/
2510
2360
char **mysql_completion (const char *text, int, int)
2511
2361
{
2512
 
  if (!status.getBatch() && !quick)
 
2362
  if (!status.batch && !quick)
2513
2363
    return rl_completion_matches(text, new_command_generator);
2514
2364
  else
2515
2365
    return (char**) 0;
2578
2428
 
2579
2429
static void build_completion_hash(bool rehash, bool write_info)
2580
2430
{
2581
 
  Commands *cmd=commands;
 
2431
  COMMANDS *cmd=commands;
2582
2432
  drizzle_return_t ret;
2583
2433
  drizzle_result_st databases,tables,fields;
2584
2434
  drizzle_row_t database_row,table_row;
 
2435
  drizzle_column_st *sql_field;
2585
2436
  string tmp_str, tmp_str_lower;
2586
 
  std::string query;
2587
2437
 
2588
 
  if (status.getBatch() || quick || current_db.empty())
 
2438
  if (status.batch || quick || !current_db)
2589
2439
    return;      // We don't need completion in batches
2590
2440
  if (!rehash)
2591
2441
    return;
2593
2443
  completion_map.clear();
2594
2444
 
2595
2445
  /* hash this file's known subset of SQL commands */
2596
 
  while (cmd->getName()) {
2597
 
    tmp_str= cmd->getName();
 
2446
  while (cmd->name) {
 
2447
    tmp_str= cmd->name;
2598
2448
    tmp_str_lower= lower_string(tmp_str);
2599
2449
    completion_map[tmp_str_lower]= tmp_str;
2600
2450
    cmd++;
2603
2453
  /* hash Drizzle functions (to be implemented) */
2604
2454
 
2605
2455
  /* hash all database names */
2606
 
  if (drizzle_query_str(&con, &databases, "select schema_name from information_schema.schemata", &ret) != NULL)
 
2456
  if (drizzle_query_str(&con, &databases, "show databases", &ret) != NULL)
2607
2457
  {
2608
2458
    if (ret == DRIZZLE_RETURN_OK)
2609
2459
    {
2623
2473
    drizzle_result_free(&databases);
2624
2474
  }
2625
2475
 
2626
 
  query= "select table_name, column_name from information_schema.columns where table_schema='";
2627
 
  query.append(current_db);
2628
 
  query.append("' order by table_name");
2629
 
  
2630
 
  if (drizzle_query(&con, &fields, query.c_str(), query.length(),
2631
 
                    &ret) != NULL)
 
2476
  /* hash all table names */
 
2477
  if (drizzle_query_str(&con, &tables, "show tables", &ret) != NULL)
2632
2478
  {
2633
 
    if (ret == DRIZZLE_RETURN_OK &&
2634
 
        drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2479
    if (ret != DRIZZLE_RETURN_OK)
 
2480
    {
 
2481
      drizzle_result_free(&tables);
 
2482
      return;
 
2483
    }
 
2484
 
 
2485
    if (drizzle_result_buffer(&tables) != DRIZZLE_RETURN_OK)
 
2486
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2487
    else
2635
2488
    {
2636
2489
      if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2637
2490
      {
2638
 
        tee_fprintf(stdout,
2639
 
                    _("Reading table information for completion of "
2640
 
                      "table and column names\n"
2641
 
                      "You can turn off this feature to get a quicker "
2642
 
                      "startup with -A\n\n"));
 
2491
        tee_fprintf(stdout, _("\
 
2492
Reading table information for completion of table and column names\n    \
 
2493
You can turn off this feature to get a quicker startup with -A\n\n"));
2643
2494
      }
2644
 
 
2645
 
      std::string table_name;
2646
 
      while ((table_row=drizzle_row_next(&fields)))
 
2495
      while ((table_row=drizzle_row_next(&tables)))
2647
2496
      {
2648
 
        if (table_name.compare(table_row[0]) != 0)
2649
 
        {
2650
 
          tmp_str= table_row[0];
2651
 
          tmp_str_lower= lower_string(tmp_str);
2652
 
          completion_map[tmp_str_lower]= tmp_str;
2653
 
          table_name= table_row[0];
2654
 
        }
2655
2497
        tmp_str= table_row[0];
2656
 
        tmp_str.append(".");
2657
 
        tmp_str.append(table_row[1]);
2658
 
        tmp_str_lower= lower_string(tmp_str);
2659
 
        completion_map[tmp_str_lower]= tmp_str;
2660
 
 
2661
 
        tmp_str= table_row[1];
2662
 
        tmp_str_lower= lower_string(tmp_str);
2663
 
        completion_map[tmp_str_lower]= tmp_str;
2664
 
      }
2665
 
    }
2666
 
  }
2667
 
  drizzle_result_free(&fields);
 
2498
        tmp_str_lower= lower_string(tmp_str);
 
2499
        completion_map[tmp_str_lower]= tmp_str;
 
2500
      }
 
2501
    }
 
2502
  }
 
2503
  else
 
2504
    return;
 
2505
 
 
2506
  /* hash all field names, both with the table prefix and without it */
 
2507
  if (drizzle_result_row_count(&tables) == 0)
 
2508
  {
 
2509
    drizzle_result_free(&tables);
 
2510
    return;
 
2511
  }
 
2512
 
 
2513
  drizzle_row_seek(&tables, 0);
 
2514
 
 
2515
  while ((table_row=drizzle_row_next(&tables)))
 
2516
  {
 
2517
    string query;
 
2518
 
 
2519
    query.append("show fields in '");
 
2520
    query.append(table_row[0]);
 
2521
    query.append("'");
 
2522
    
 
2523
    if (drizzle_query(&con, &fields, query.c_str(), query.length(),
 
2524
                      &ret) != NULL)
 
2525
    {
 
2526
      if (ret == DRIZZLE_RETURN_OK &&
 
2527
          drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2528
      {
 
2529
        while ((sql_field=drizzle_column_next(&fields)))
 
2530
        {
 
2531
          tmp_str=table_row[0];
 
2532
          tmp_str.append(".");
 
2533
          tmp_str.append(drizzle_column_name(sql_field));
 
2534
          tmp_str_lower= lower_string(tmp_str);
 
2535
          completion_map[tmp_str_lower]= tmp_str;
 
2536
 
 
2537
          tmp_str=drizzle_column_name(sql_field);
 
2538
          tmp_str_lower= lower_string(tmp_str);
 
2539
          completion_map[tmp_str_lower]= tmp_str;
 
2540
        }
 
2541
      }
 
2542
      drizzle_result_free(&fields);
 
2543
    }
 
2544
  }
 
2545
  drizzle_result_free(&tables);
2668
2546
  completion_iter= completion_map.begin();
2669
2547
}
2670
2548
 
2671
2549
/* for gnu readline */
2672
2550
 
 
2551
#ifndef HAVE_INDEX
 
2552
extern "C" {
 
2553
  extern char *index(const char *,int c),*rindex(const char *,int);
 
2554
 
 
2555
  char *index(const char *s,int c)
 
2556
  {
 
2557
    for (;;)
 
2558
    {
 
2559
      if (*s == (char) c) return (char*) s;
 
2560
      if (!*s++) return NULL;
 
2561
    }
 
2562
  }
 
2563
 
 
2564
  char *rindex(const char *s,int c)
 
2565
  {
 
2566
    register char *t;
 
2567
 
 
2568
    t = NULL;
 
2569
    do if (*s == (char) c) t = (char*) s; while (*s++);
 
2570
    return (char*) t;
 
2571
  }
 
2572
}
 
2573
#endif
 
2574
 
2673
2575
 
2674
2576
static int reconnect(void)
2675
2577
{
 
2578
  /* purecov: begin tested */
2676
2579
  if (opt_reconnect)
2677
2580
  {
2678
2581
    put_info(_("No connection. Trying to reconnect..."),INFO_INFO,0,0);
2679
2582
    (void) com_connect((string *)0, 0);
2680
 
    if (opt_rehash && connected)
 
2583
    if (opt_rehash)
2681
2584
      com_rehash(NULL, NULL);
2682
2585
  }
2683
 
  if (! connected)
 
2586
  if (!connected)
2684
2587
    return put_info(_("Can't connect to the server\n"),INFO_ERROR,0,0);
 
2588
  /* purecov: end */
2685
2589
  return 0;
2686
2590
}
2687
2591
 
2690
2594
  drizzle_return_t ret;
2691
2595
  drizzle_result_st res;
2692
2596
 
2693
 
  current_db.erase();
2694
 
  current_db= "";
 
2597
  free(current_db);
 
2598
  current_db= NULL;
2695
2599
  /* In case of error below current_db will be NULL */
2696
2600
  if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
2697
2601
  {
2700
2604
    {
2701
2605
      drizzle_row_t row= drizzle_row_next(&res);
2702
2606
      if (row[0])
2703
 
        current_db.assign(row[0]);
2704
 
      drizzle_result_free(&res);
 
2607
        current_db= strdup(row[0]);
2705
2608
    }
 
2609
    drizzle_result_free(&res);
2706
2610
  }
2707
2611
}
2708
2612
 
2710
2614
 The different commands
2711
2615
***************************************************************************/
2712
2616
 
2713
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
 
2617
int drizzleclient_real_query_for_lazy(const char *buf, int length,
2714
2618
                                      drizzle_result_st *result,
2715
2619
                                      uint32_t *error_code)
2716
2620
{
2749
2653
    return 0;
2750
2654
 
2751
2655
  if (drizzle_con_error(&con)[0])
2752
 
  {
2753
 
    int ret= put_error(&con, result);
2754
 
    drizzle_result_free(result);
2755
 
    return ret;
2756
 
  }
 
2656
    return put_error(&con, result);
2757
2657
  return 0;
2758
2658
}
2759
2659
 
2762
2662
{
2763
2663
  register int i, j;
2764
2664
  char buff[32], *end;
2765
 
  std::vector<char> output_buff;
2766
 
  output_buff.resize(512);
2767
2665
 
2768
2666
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
2769
2667
  if (!named_cmds)
2770
 
  {
2771
 
    snprintf(&output_buff[0], output_buff.size(),
2772
 
             _("Note that all text commands must be first on line and end with '%s' or \\g"),
2773
 
             delimiter);
2774
 
    put_info(&output_buff[0], INFO_INFO, 0, 0);
2775
 
  }
2776
 
  for (i = 0; commands[i].getName(); i++)
2777
 
  {
2778
 
    end= strcpy(buff, commands[i].getName());
2779
 
    end+= strlen(commands[i].getName());
2780
 
    for (j= (int)strlen(commands[i].getName()); j < 10; j++)
 
2668
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
 
2669
  for (i = 0; commands[i].name; i++)
 
2670
  {
 
2671
    end= strcpy(buff, commands[i].name);
 
2672
    end+= strlen(commands[i].name);
 
2673
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2781
2674
      end= strcpy(end, " ")+1;
2782
2675
    if (commands[i].func)
2783
2676
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2784
 
                  commands[i].getCmdChar(), _(commands[i].getDoc()));
 
2677
                  commands[i].cmd_char, _(commands[i].doc));
2785
2678
  }
2786
2679
  tee_fprintf(stdout, "\n");
2787
2680
  buffer->clear();
2792
2685
static int
2793
2686
com_clear(string *buffer, const char *)
2794
2687
{
2795
 
  if (status.getAddToHistory())
 
2688
  if (status.add_to_history)
2796
2689
    fix_history(buffer);
2797
2690
  buffer->clear();
2798
2691
  return 0;
2809
2702
com_go(string *buffer, const char *)
2810
2703
{
2811
2704
  char          buff[200]; /* about 110 chars used so far */
 
2705
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2812
2706
  drizzle_result_st result;
2813
2707
  drizzle_return_t ret;
2814
 
  uint32_t      warnings= 0;
2815
 
  boost::posix_time::ptime timer;
 
2708
  uint32_t      timer, warnings= 0;
2816
2709
  uint32_t      error= 0;
2817
2710
  uint32_t      error_code= 0;
2818
2711
  int           err= 0;
2825
2718
  if (buffer->empty())
2826
2719
  {
2827
2720
    // Ignore empty quries
2828
 
    if (status.getBatch())
 
2721
    if (status.batch)
2829
2722
      return 0;
2830
2723
    return put_info(_("No query specified\n"),INFO_ERROR,0,0);
2831
2724
 
2850
2743
  executing_query= 1;
2851
2744
  error= drizzleclient_real_query_for_lazy(buffer->c_str(),buffer->length(),&result, &error_code);
2852
2745
 
2853
 
  if (status.getAddToHistory())
 
2746
  if (status.add_to_history)
2854
2747
  {
2855
2748
    buffer->append(vertical ? "\\G" : delimiter);
2856
2749
    /* Append final command onto history */
2881
2774
        goto end;
2882
2775
    }
2883
2776
 
2884
 
    string time_buff("");
2885
2777
    if (verbose >= 3 || !opt_silent)
2886
2778
      drizzle_end_timer(timer,time_buff);
 
2779
    else
 
2780
      time_buff[0]= '\0';
2887
2781
 
2888
2782
    /* Every branch must truncate  buff . */
2889
2783
    if (drizzle_result_column_count(&result) > 0)
2934
2828
      if (warnings != 1)
2935
2829
        *pos++= 's';
2936
2830
    }
2937
 
    strcpy(pos, time_buff.c_str());
 
2831
    strcpy(pos, time_buff);
2938
2832
    put_info(buff,INFO_RESULT,0,0);
2939
2833
    if (strcmp(drizzle_result_info(&result), ""))
2940
2834
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
2970
2864
  if (show_warnings == 1 && (warnings >= 1 || error))
2971
2865
    print_warnings(error_code);
2972
2866
 
2973
 
  if (!error && !status.getBatch() &&
 
2867
  if (!error && !status.batch &&
2974
2868
      drizzle_con_status(&con) & DRIZZLE_CON_STATUS_DB_DROPPED)
2975
2869
  {
2976
2870
    get_current_db();
2985
2879
{
2986
2880
  if (!opt_nopager)
2987
2881
  {
2988
 
    if (!(PAGER= popen(pager.c_str(), "w")))
 
2882
    if (!(PAGER= popen(pager, "w")))
2989
2883
    {
2990
 
      tee_fprintf(stdout,_( "popen() failed! defaulting PAGER to stdout!\n"));
 
2884
      tee_fprintf(stdout, "popen() failed! defaulting PAGER to stdout!\n");
2991
2885
      PAGER= stdout;
2992
2886
    }
2993
2887
  }
3009
2903
    end_tee();
3010
2904
  if (!(new_outfile= fopen(file_name, "a")))
3011
2905
  {
3012
 
    tee_fprintf(stdout, _("Error logging to file '%s'\n"), file_name);
 
2906
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
3013
2907
    return;
3014
2908
  }
3015
2909
  OUTFILE = new_outfile;
3016
 
  outfile.assign(file_name);
3017
 
  tee_fprintf(stdout, _("Logging to file '%s'\n"), file_name);
 
2910
  strncpy(outfile, file_name, FN_REFLEN-1);
 
2911
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
3018
2912
  opt_outfile= 1;
3019
2913
 
3020
2914
  return;
3055
2949
    case DRIZZLE_COLUMN_TYPE_LONGLONG:    return "LONGLONG";
3056
2950
    case DRIZZLE_COLUMN_TYPE_NULL:        return "NULL";
3057
2951
    case DRIZZLE_COLUMN_TYPE_TIMESTAMP:   return "TIMESTAMP";
 
2952
    case DRIZZLE_COLUMN_TYPE_TINY:        return "TINY";
 
2953
    case DRIZZLE_COLUMN_TYPE_VIRTUAL:     return "VIRTUAL";
3058
2954
    default:                     return "?-unknown-?";
3059
2955
  }
3060
2956
}
3098
2994
 
3099
2995
  while ((field = drizzle_column_next(result)))
3100
2996
  {
3101
 
    tee_fprintf(PAGER, _("Field %3u:  `%s`\n"
 
2997
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
3102
2998
                "Catalog:    `%s`\n"
3103
 
                "Schema:     `%s`\n"
 
2999
                "Database:   `%s`\n"
3104
3000
                "Table:      `%s`\n"
3105
3001
                "Org_table:  `%s`\n"
3106
 
                "Type:       UTF-8\n"
 
3002
                "Type:       %s\n"
3107
3003
                "Collation:  %s (%u)\n"
3108
3004
                "Length:     %lu\n"
3109
3005
                "Max_length: %lu\n"
3110
3006
                "Decimals:   %u\n"
3111
 
                "Flags:      %s\n\n"),
 
3007
                "Flags:      %s\n\n",
3112
3008
                ++i,
3113
3009
                drizzle_column_name(field), drizzle_column_catalog(field),
3114
3010
                drizzle_column_db(field), drizzle_column_table(field),
3115
3011
                drizzle_column_orig_table(field),
3116
3012
                fieldtype2str(drizzle_column_type(field)),
 
3013
                get_charset_name(drizzle_column_charset(field)),
3117
3014
                drizzle_column_charset(field), drizzle_column_size(field),
3118
3015
                drizzle_column_max_size(field), drizzle_column_decimals(field),
3119
3016
                fieldflags2str(drizzle_column_flags(field)));
3121
3018
  tee_puts("", PAGER);
3122
3019
}
3123
3020
 
 
3021
 
3124
3022
static void
3125
3023
print_table_data(drizzle_result_st *result)
3126
3024
{
3127
3025
  drizzle_row_t cur;
3128
3026
  drizzle_return_t ret;
3129
3027
  drizzle_column_st *field;
3130
 
  std::vector<bool> num_flag;
 
3028
  bool *num_flag;
3131
3029
  string separator;
3132
3030
 
3133
3031
  separator.reserve(256);
3134
3032
 
3135
 
  num_flag.resize(drizzle_result_column_count(result));
 
3033
  num_flag=(bool*) malloc(sizeof(bool)*drizzle_result_column_count(result));
3136
3034
  if (column_types_flag)
3137
3035
  {
3138
3036
    print_field_types(result);
3152
3050
      /* Check if the max_byte value is really the maximum in terms
3153
3051
         of visual length since multibyte characters can affect the
3154
3052
         length of the separator. */
3155
 
      length= drizzled::utf8::char_length(drizzle_column_name(field));
 
3053
      length= charset_info->cset->numcells(charset_info,
 
3054
                                           drizzle_column_name(field),
 
3055
                                           drizzle_column_name(field) +
 
3056
                                           name_length);
3156
3057
 
3157
3058
      if (name_length == drizzle_column_max_size(field))
3158
3059
      {
3190
3091
    for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
3191
3092
    {
3192
3093
      uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
3193
 
      uint32_t numcells= drizzled::utf8::char_length(drizzle_column_name(field));
 
3094
      uint32_t numcells= charset_info->cset->numcells(charset_info,
 
3095
                                                  drizzle_column_name(field),
 
3096
                                                  drizzle_column_name(field) +
 
3097
                                                  name_length);
3194
3098
      uint32_t display_length= drizzle_column_max_size(field) + name_length -
3195
3099
                               numcells;
3196
3100
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3253
3157
        We need to find how much screen real-estate we will occupy to know how
3254
3158
        many extra padding-characters we should send with the printing function.
3255
3159
      */
3256
 
      visible_length= drizzled::utf8::char_length(buffer);
 
3160
      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
3257
3161
      extra_padding= data_length - visible_length;
3258
3162
 
3259
3163
      if (field_max_length > MAX_COLUMN_LENGTH)
3273
3177
      drizzle_row_free(result, cur);
3274
3178
  }
3275
3179
  tee_puts(separator.c_str(), PAGER);
 
3180
  free(num_flag);
3276
3181
}
3277
3182
 
3278
3183
/**
3420
3325
  drizzle_row_t cur;
3421
3326
  uint64_t num_rows;
3422
3327
  uint32_t new_code= 0;
3423
 
  FILE *out;
3424
3328
 
3425
3329
  /* Get the warnings */
3426
3330
  query= "show warnings";
3446
3350
  }
3447
3351
 
3448
3352
  /* Print the warnings */
3449
 
  if (status.getBatch()) 
3450
 
  {
3451
 
    out= stderr;
3452
 
  } 
3453
 
  else 
3454
 
  {
3455
 
    init_pager();
3456
 
    out= PAGER;
3457
 
  }
 
3353
  init_pager();
3458
3354
  do
3459
3355
  {
3460
 
    tee_fprintf(out, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
 
3356
    tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3461
3357
  } while ((cur= drizzle_row_next(&result)));
3462
 
 
3463
 
  if (not status.getBatch())
3464
 
    end_pager();
 
3358
  end_pager();
3465
3359
 
3466
3360
end:
3467
3361
  drizzle_result_free(&result);
3480
3374
    else for (const char *end=pos+length ; pos != end ; pos++)
3481
3375
    {
3482
3376
      int l;
3483
 
      if ((l = drizzled::utf8::sequence_length(*pos)))
 
3377
      if (use_mb(charset_info) &&
 
3378
          (l = my_ismbchar(charset_info, pos, end)))
3484
3379
      {
3485
3380
        while (l--)
3486
3381
          tee_putc(*pos++, PAGER);
3557
3452
  char file_name[FN_REFLEN], *end;
3558
3453
  const char *param;
3559
3454
 
3560
 
  if (status.getBatch())
 
3455
  if (status.batch)
3561
3456
    return 0;
3562
 
  while (isspace(*line))
 
3457
  while (my_isspace(charset_info,*line))
3563
3458
    line++;
3564
 
  if (!(param =strchr(line, ' '))) // if outfile wasn't given, use the default
 
3459
  if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
3565
3460
  {
3566
 
    if (outfile.empty())
 
3461
    if (!strlen(outfile))
3567
3462
    {
3568
 
      printf(_("No previous outfile available, you must give a filename!\n"));
 
3463
      printf("No previous outfile available, you must give a filename!\n");
3569
3464
      return 0;
3570
3465
    }
3571
3466
    else if (opt_outfile)
3572
3467
    {
3573
 
      tee_fprintf(stdout, _("Currently logging to file '%s'\n"), outfile.c_str());
 
3468
      tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
3574
3469
      return 0;
3575
3470
    }
3576
3471
    else
3577
 
      param= outfile.c_str();      //resume using the old outfile
 
3472
      param = outfile;      //resume using the old outfile
3578
3473
  }
3579
3474
 
3580
 
  /* @TODO: Replace this with string methods */
3581
3475
  /* eliminate the spaces before the parameters */
3582
 
  while (isspace(*param))
 
3476
  while (my_isspace(charset_info,*param))
3583
3477
    param++;
3584
3478
  strncpy(file_name, param, sizeof(file_name) - 1);
3585
3479
  end= file_name + strlen(file_name);
3586
3480
  /* remove end space from command line */
3587
 
  while (end > file_name && (isspace(end[-1]) ||
3588
 
                             iscntrl(end[-1])))
 
3481
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
 
3482
                             my_iscntrl(charset_info,end[-1])))
3589
3483
    end--;
3590
3484
  end[0]= 0;
3591
3485
  if (end == file_name)
3592
3486
  {
3593
 
    printf(_("No outfile specified!\n"));
 
3487
    printf("No outfile specified!\n");
3594
3488
    return 0;
3595
3489
  }
3596
3490
  init_tee(file_name);
3603
3497
{
3604
3498
  if (opt_outfile)
3605
3499
    end_tee();
3606
 
  tee_fprintf(stdout, _("Outfile disabled.\n"));
 
3500
  tee_fprintf(stdout, "Outfile disabled.\n");
3607
3501
  return 0;
3608
3502
}
3609
3503
 
3614
3508
static int
3615
3509
com_pager(string *, const char *line)
3616
3510
{
 
3511
  char pager_name[FN_REFLEN], *end;
3617
3512
  const char *param;
3618
3513
 
3619
 
  if (status.getBatch())
 
3514
  if (status.batch)
3620
3515
    return 0;
3621
3516
  /* Skip spaces in front of the pager command */
3622
 
  while (isspace(*line))
 
3517
  while (my_isspace(charset_info, *line))
3623
3518
    line++;
3624
3519
  /* Skip the pager command */
3625
3520
  param= strchr(line, ' ');
3626
3521
  /* Skip the spaces between the command and the argument */
3627
 
  while (param && isspace(*param))
 
3522
  while (param && my_isspace(charset_info, *param))
3628
3523
    param++;
3629
 
  if (!param || (*param == '\0')) // if pager was not given, use the default
 
3524
  if (!param || !strlen(param)) // if pager was not given, use the default
3630
3525
  {
3631
3526
    if (!default_pager_set)
3632
3527
    {
3633
 
      tee_fprintf(stdout, _("Default pager wasn't set, using stdout.\n"));
 
3528
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3634
3529
      opt_nopager=1;
3635
 
      pager.assign("stdout");
 
3530
      strcpy(pager, "stdout");
3636
3531
      PAGER= stdout;
3637
3532
      return 0;
3638
3533
    }
3639
 
    pager.assign(default_pager);
 
3534
    strcpy(pager, default_pager);
3640
3535
  }
3641
3536
  else
3642
3537
  {
3643
 
    string pager_name(param);
3644
 
    string::iterator end= pager_name.end();
3645
 
    while (end > pager_name.begin() &&
3646
 
           (isspace(*(end-1)) || iscntrl(*(end-1))))
3647
 
      --end;
3648
 
    pager_name.erase(end, pager_name.end());
3649
 
    pager.assign(pager_name);
3650
 
    default_pager.assign(pager_name);
 
3538
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3539
    end+= strlen(pager_name);
 
3540
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
 
3541
                                my_iscntrl(charset_info,end[-1])))
 
3542
      end--;
 
3543
    end[0]=0;
 
3544
    strcpy(pager, pager_name);
 
3545
    strcpy(default_pager, pager_name);
3651
3546
  }
3652
3547
  opt_nopager=0;
3653
 
  tee_fprintf(stdout, _("PAGER set to '%s'\n"), pager.c_str());
 
3548
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3654
3549
  return 0;
3655
3550
}
3656
3551
 
3658
3553
static int
3659
3554
com_nopager(string *, const char *)
3660
3555
{
3661
 
  pager.assign("stdout");
 
3556
  strcpy(pager, "stdout");
3662
3557
  opt_nopager=1;
3663
3558
  PAGER= stdout;
3664
 
  tee_fprintf(stdout, _("PAGER set to stdout\n"));
 
3559
  tee_fprintf(stdout, "PAGER set to stdout\n");
3665
3560
  return 0;
3666
3561
}
3667
3562
 
3671
3566
com_quit(string *, const char *)
3672
3567
{
3673
3568
  /* let the screen auto close on a normal shutdown */
3674
 
  status.setExitStatus(0);
 
3569
  status.exit_status=0;
3675
3570
  return 1;
3676
3571
}
3677
3572
 
3719
3614
    tmp= get_arg(buff, 0);
3720
3615
    if (tmp && *tmp)
3721
3616
    {
3722
 
      current_db.erase();
3723
 
      current_db.assign(tmp);
 
3617
      free(current_db);
 
3618
      current_db= strdup(tmp);
3724
3619
      tmp= get_arg(buff, 1);
3725
3620
      if (tmp)
3726
3621
      {
3727
 
        current_host.erase();
 
3622
        free(current_host);
3728
3623
        current_host=strdup(tmp);
3729
3624
      }
3730
3625
    }
3731
3626
    else
3732
3627
    {
3733
3628
      /* Quick re-connect */
3734
 
      opt_rehash= 0;
 
3629
      opt_rehash= 0;                            /* purecov: tested */
3735
3630
    }
3736
3631
    // command used
3737
3632
    assert(buffer!=NULL);
3739
3634
  }
3740
3635
  else
3741
3636
    opt_rehash= 0;
3742
 
  error=sql_connect(current_host, current_db, current_user, opt_password);
 
3637
  error=sql_connect(current_host,current_db,current_user,opt_password,0);
3743
3638
  opt_rehash= save_rehash;
3744
3639
 
3745
3640
  if (connected)
3746
3641
  {
3747
 
    sprintf(buff, _("Connection id:    %u"), drizzle_con_thread_id(&con));
 
3642
    sprintf(buff,"Connection id:    %u",drizzle_con_thread_id(&con));
3748
3643
    put_info(buff,INFO_INFO,0,0);
3749
 
    sprintf(buff, _("Current schema: %.128s\n"),
3750
 
            !current_db.empty() ? current_db.c_str() : _("*** NONE ***"));
 
3644
    sprintf(buff,"Current database: %.128s\n",
 
3645
            current_db ? current_db : "*** NONE ***");
3751
3646
    put_info(buff,INFO_INFO,0,0);
3752
3647
  }
3753
3648
  return error;
3758
3653
{
3759
3654
  char source_name[FN_REFLEN], *end;
3760
3655
  const char *param;
3761
 
  LineBuffer *line_buff;
 
3656
  LINE_BUFFER *line_buff;
3762
3657
  int error;
3763
 
  Status old_status;
 
3658
  STATUS old_status;
3764
3659
  FILE *sql_file;
3765
3660
 
3766
3661
  /* Skip space from file name */
3767
 
  while (isspace(*line))
 
3662
  while (my_isspace(charset_info,*line))
3768
3663
    line++;
3769
3664
  if (!(param = strchr(line, ' ')))    // Skip command name
3770
 
    return put_info(_("Usage: \\. <filename> | source <filename>"),
 
3665
    return put_info("Usage: \\. <filename> | source <filename>",
3771
3666
                    INFO_ERROR, 0,0);
3772
 
  while (isspace(*param))
 
3667
  while (my_isspace(charset_info,*param))
3773
3668
    param++;
3774
3669
  end= strncpy(source_name,param,sizeof(source_name)-1);
3775
3670
  end+= strlen(source_name);
3776
 
  while (end > source_name && (isspace(end[-1]) ||
3777
 
                               iscntrl(end[-1])))
 
3671
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
 
3672
                               my_iscntrl(charset_info,end[-1])))
3778
3673
    end--;
3779
3674
  end[0]=0;
3780
 
 
 
3675
  unpack_filename(source_name,source_name);
3781
3676
  /* open file name */
3782
3677
  if (!(sql_file = fopen(source_name, "r")))
3783
3678
  {
3784
3679
    char buff[FN_REFLEN+60];
3785
 
    sprintf(buff, _("Failed to open file '%s', error: %d"), source_name,errno);
 
3680
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3786
3681
    return put_info(buff, INFO_ERROR, 0 ,0);
3787
3682
  }
3788
3683
 
3789
 
  line_buff= new(std::nothrow) LineBuffer(opt_max_input_line,sql_file);
3790
 
  if (line_buff == NULL)
 
3684
  if (!(line_buff=batch_readline_init(opt_max_input_line+512,sql_file)))
3791
3685
  {
3792
3686
    fclose(sql_file);
3793
 
    return put_info(_("Can't initialize LineBuffer"), INFO_ERROR, 0, 0);
 
3687
    return put_info("Can't initialize batch_readline", INFO_ERROR, 0 ,0);
3794
3688
  }
3795
3689
 
3796
3690
  /* Save old status */
3798
3692
  memset(&status, 0, sizeof(status));
3799
3693
 
3800
3694
  // Run in batch mode
3801
 
  status.setBatch(old_status.getBatch());
3802
 
  status.setLineBuff(line_buff);
3803
 
  status.setFileName(source_name);
 
3695
  status.batch=old_status.batch;
 
3696
  status.line_buff=line_buff;
 
3697
  status.file_name=source_name;
3804
3698
  // Empty command buffer
3805
3699
  assert(glob_buffer!=NULL);
3806
3700
  glob_buffer->clear();
3808
3702
  // Continue as before
3809
3703
  status=old_status;
3810
3704
  fclose(sql_file);
3811
 
  delete status.getLineBuff();
3812
 
  line_buff=0;
3813
 
  status.setLineBuff(0);
 
3705
  batch_readline_end(line_buff);
3814
3706
  return error;
3815
3707
}
3816
3708
 
3826
3718
 
3827
3719
  if (!tmp || !*tmp)
3828
3720
  {
3829
 
    put_info(_("DELIMITER must be followed by a 'delimiter' character or string"),
 
3721
    put_info("DELIMITER must be followed by a 'delimiter' character or string",
3830
3722
             INFO_ERROR, 0, 0);
3831
3723
    return 0;
3832
3724
  }
3834
3726
  {
3835
3727
    if (strstr(tmp, "\\"))
3836
3728
    {
3837
 
      put_info(_("DELIMITER cannot contain a backslash character"),
 
3729
      put_info("DELIMITER cannot contain a backslash character",
3838
3730
               INFO_ERROR, 0, 0);
3839
3731
      return 0;
3840
3732
    }
3859
3751
  tmp= get_arg(buff, 0);
3860
3752
  if (!tmp || !*tmp)
3861
3753
  {
3862
 
    put_info(_("USE must be followed by a schema name"), INFO_ERROR, 0, 0);
 
3754
    put_info("USE must be followed by a database name", INFO_ERROR, 0, 0);
3863
3755
    return 0;
3864
3756
  }
3865
3757
  /*
3869
3761
  */
3870
3762
  get_current_db();
3871
3763
 
3872
 
  if (current_db.empty() || strcmp(current_db.c_str(),tmp))
 
3764
  if (!current_db || strcmp(current_db,tmp))
3873
3765
  {
3874
3766
    if (one_database)
3875
3767
    {
3921
3813
      else
3922
3814
        drizzle_result_free(&result);
3923
3815
    }
3924
 
    current_db.erase();
3925
 
    current_db.assign(tmp);
 
3816
    free(current_db);
 
3817
    current_db= strdup(tmp);
3926
3818
    if (select_db > 1)
3927
3819
      build_completion_hash(opt_rehash, 1);
3928
3820
  }
3929
3821
 
3930
 
  put_info(_("Schema changed"),INFO_INFO, 0, 0);
 
3822
  put_info("Database changed",INFO_INFO, 0, 0);
3931
3823
  return 0;
3932
3824
}
3933
3825
 
3934
 
static int com_shutdown(string *, const char *)
3935
 
{
3936
 
  drizzle_result_st result;
3937
 
  drizzle_return_t ret;
3938
 
 
3939
 
  if (verbose)
3940
 
  {
3941
 
    printf(_("shutting down drizzled"));
3942
 
    if (opt_drizzle_port > 0)
3943
 
      printf(_(" on port %d"), opt_drizzle_port);
3944
 
    printf("... ");
3945
 
  }
3946
 
 
3947
 
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
3948
 
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
3949
 
  {
3950
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3951
 
    {
3952
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
3953
 
              drizzle_result_error(&result));
3954
 
      drizzle_result_free(&result);
3955
 
    }
3956
 
    else
3957
 
    {
3958
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
3959
 
              drizzle_con_error(&con));
3960
 
    }
3961
 
    return false;
3962
 
  }
3963
 
 
3964
 
  drizzle_result_free(&result);
3965
 
 
3966
 
  if (verbose)
3967
 
    printf(_("done\n"));
3968
 
 
3969
 
  return false;
3970
 
}
3971
 
 
3972
3826
static int
3973
3827
com_warnings(string *, const char *)
3974
3828
{
3975
3829
  show_warnings = 1;
3976
 
  put_info(_("Show warnings enabled."),INFO_INFO, 0, 0);
 
3830
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3977
3831
  return 0;
3978
3832
}
3979
3833
 
3981
3835
com_nowarnings(string *, const char *)
3982
3836
{
3983
3837
  show_warnings = 0;
3984
 
  put_info(_("Show warnings disabled."),INFO_INFO, 0, 0);
 
3838
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3985
3839
  return 0;
3986
3840
}
3987
3841
 
4011
3865
  else
4012
3866
  {
4013
3867
    /* skip leading white spaces */
4014
 
    while (isspace(*ptr))
 
3868
    while (my_isspace(charset_info, *ptr))
4015
3869
      ptr++;
4016
3870
    if (*ptr == '\\') // short command was used
4017
3871
      ptr+= 2;
4018
3872
    else
4019
 
      while (*ptr &&!isspace(*ptr)) // skip command
 
3873
      while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
4020
3874
        ptr++;
4021
3875
  }
4022
3876
  if (!*ptr)
4023
3877
    return NULL;
4024
 
  while (isspace(*ptr))
 
3878
  while (my_isspace(charset_info, *ptr))
4025
3879
    ptr++;
4026
3880
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
4027
3881
  {
4048
3902
 
4049
3903
 
4050
3904
static int
4051
 
sql_connect(const string &host, const string &database, const string &user, const string &password)
 
3905
sql_connect(char *host,char *database,char *user,char *password,
 
3906
                 uint32_t silent)
4052
3907
{
4053
3908
  drizzle_return_t ret;
 
3909
 
4054
3910
  if (connected)
4055
3911
  {
4056
3912
    connected= 0;
4058
3914
    drizzle_free(&drizzle);
4059
3915
  }
4060
3916
  drizzle_create(&drizzle);
4061
 
 
4062
 
#ifdef DRIZZLE_ADMIN_TOOL
4063
 
  drizzle_con_options_t options= (drizzle_con_options_t) (DRIZZLE_CON_ADMIN | (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL));
4064
 
#else
4065
 
  drizzle_con_options_t options= (drizzle_con_options_t) (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
4066
 
#endif
4067
 
 
4068
 
  if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(),
4069
 
    opt_drizzle_port, (char *)user.c_str(),
4070
 
    (char *)password.c_str(), (char *)database.c_str(),
4071
 
    options) == NULL)
 
3917
  if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,
 
3918
                          password, database, DRIZZLE_CON_NONE) == NULL)
4072
3919
  {
4073
3920
    (void) put_error(&con, NULL);
4074
3921
    (void) fflush(stdout);
4097
3944
*/
4098
3945
  if ((ret= drizzle_con_connect(&con)) != DRIZZLE_RETURN_OK)
4099
3946
  {
4100
 
 
4101
 
    if (opt_silent < 2)
 
3947
    if (!silent || (ret != DRIZZLE_RETURN_GETADDRINFO &&
 
3948
                    ret != DRIZZLE_RETURN_COULD_NOT_CONNECT))
4102
3949
    {
4103
3950
      (void) put_error(&con, NULL);
4104
3951
      (void) fflush(stdout);
4107
3954
    return -1;          // Retryable
4108
3955
  }
4109
3956
  connected=1;
4110
 
 
 
3957
/* XXX hmm?
 
3958
  drizzle.reconnect= debug_info_flag; // We want to know if this happens
 
3959
*/
4111
3960
  build_completion_hash(opt_rehash, 1);
4112
3961
  return 0;
4113
3962
}
4124
3973
  drizzle_return_t ret;
4125
3974
 
4126
3975
  tee_puts("--------------", stdout);
4127
 
  printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
4128
 
         drizzle_version(), VERSION,
4129
 
         HOST_VENDOR, HOST_OS, HOST_CPU,
4130
 
         rl_library_version);
4131
 
 
 
3976
  usage(1);          /* Print version */
4132
3977
  if (connected)
4133
3978
  {
4134
 
    tee_fprintf(stdout, _("\nConnection id:\t\t%lu\n"),drizzle_con_thread_id(&con));
 
3979
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
4135
3980
    /*
4136
3981
      Don't remove "limit 1",
4137
3982
      it is protection againts SQL_SELECT_LIMIT=0
4143
3988
      drizzle_row_t cur=drizzle_row_next(&result);
4144
3989
      if (cur)
4145
3990
      {
4146
 
        tee_fprintf(stdout, _("Current schema:\t%s\n"), cur[0] ? cur[0] : "");
4147
 
        tee_fprintf(stdout, _("Current user:\t\t%s\n"), cur[1]);
 
3991
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
 
3992
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
4148
3993
      }
4149
3994
      drizzle_result_free(&result);
4150
3995
    }
4151
3996
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4152
3997
      drizzle_result_free(&result);
4153
 
    tee_puts(_("SSL:\t\t\tNot in use"), stdout);
 
3998
    tee_puts("SSL:\t\t\tNot in use", stdout);
4154
3999
  }
4155
4000
  else
4156
4001
  {
4157
4002
    vidattr(A_BOLD);
4158
 
    tee_fprintf(stdout, _("\nNo connection\n"));
 
4003
    tee_fprintf(stdout, "\nNo connection\n");
4159
4004
    vidattr(A_NORMAL);
4160
4005
    return 0;
4161
4006
  }
4162
4007
  if (skip_updates)
4163
4008
  {
4164
4009
    vidattr(A_BOLD);
4165
 
    tee_fprintf(stdout, _("\nAll updates ignored to this schema\n"));
 
4010
    tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4166
4011
    vidattr(A_NORMAL);
4167
4012
  }
4168
 
  tee_fprintf(stdout, _("Current pager:\t\t%s\n"), pager.c_str());
4169
 
  tee_fprintf(stdout, _("Using outfile:\t\t'%s'\n"), opt_outfile ? outfile.c_str() : "");
4170
 
  tee_fprintf(stdout, _("Using delimiter:\t%s\n"), delimiter);
4171
 
  tee_fprintf(stdout, _("Server version:\t\t%s\n"), server_version_string(&con));
4172
 
  tee_fprintf(stdout, _("Protocol:\t\t%s\n"), opt_protocol.c_str());
4173
 
  tee_fprintf(stdout, _("Protocol version:\t%d\n"), drizzle_con_protocol_version(&con));
4174
 
  tee_fprintf(stdout, _("Connection:\t\t%s\n"), drizzle_con_host(&con));
 
4013
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
 
4014
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
 
4015
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
 
4016
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&con));
 
4017
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_con_protocol_version(&con));
 
4018
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_con_host(&con));
4175
4019
/* XXX need to save this from result
4176
4020
  if ((id= drizzleclient_insert_id(&drizzle)))
4177
 
    tee_fprintf(stdout, "Insert id:\t\t%s\n", internal::llstr(id, buff));
 
4021
    tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
4178
4022
*/
4179
4023
 
4180
 
  if (drizzle_con_uds(&con))
4181
 
    tee_fprintf(stdout, _("UNIX socket:\t\t%s\n"), drizzle_con_uds(&con));
 
4024
  if (strcmp(drizzle_con_uds(&con), ""))
 
4025
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle_con_uds(&con));
4182
4026
  else
4183
 
    tee_fprintf(stdout, _("TCP port:\t\t%d\n"), drizzle_con_port(&con));
 
4027
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle_con_port(&con));
4184
4028
 
4185
4029
  if (safe_updates)
4186
4030
  {
4187
4031
    vidattr(A_BOLD);
4188
 
    tee_fprintf(stdout, _("\nNote that you are running in safe_update_mode:\n"));
 
4032
    tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n");
4189
4033
    vidattr(A_NORMAL);
4190
 
    tee_fprintf(stdout, _("\
 
4034
    tee_fprintf(stdout, "\
4191
4035
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4192
4036
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n \
4193
4037
SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n             \
4194
 
Max number of examined row combination in a join is set to: %lu\n\n"),
 
4038
Max number of examined row combination in a join is set to: %lu\n\n",
4195
4039
                select_limit, max_join_size);
4196
4040
  }
4197
4041
  tee_puts("--------------\n", stdout);
4244
4088
  FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
4245
4089
  static int inited=0;
4246
4090
 
4247
 
  if (status.getBatch())
 
4091
  if (status.batch)
4248
4092
  {
4249
4093
    if (info_type == INFO_ERROR)
4250
4094
    {
4251
4095
      (void) fflush(file);
4252
 
      fprintf(file,_("ERROR"));
 
4096
      fprintf(file,"ERROR");
4253
4097
      if (error)
4254
4098
      {
4255
4099
        if (sqlstate)
4257
4101
        else
4258
4102
          (void) fprintf(file," %d",error);
4259
4103
      }
4260
 
      if (status.getQueryStartLine() && line_numbers)
 
4104
      if (status.query_start_line && line_numbers)
4261
4105
      {
4262
 
        (void) fprintf(file," at line %"PRIu32,status.getQueryStartLine());
4263
 
        if (status.getFileName())
4264
 
          (void) fprintf(file," in file: '%s'", status.getFileName());
 
4106
        (void) fprintf(file," at line %"PRIu32,status.query_start_line);
 
4107
        if (status.file_name)
 
4108
          (void) fprintf(file," in file: '%s'", status.file_name);
4265
4109
      }
4266
4110
      (void) fprintf(file,": %s\n",str);
4267
4111
      (void) fflush(file);
4292
4136
      if (error)
4293
4137
      {
4294
4138
        if (sqlstate)
4295
 
          (void) tee_fprintf(file, _("ERROR %d (%s): "), error, sqlstate);
 
4139
          (void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate);
4296
4140
        else
4297
 
          (void) tee_fprintf(file, _("ERROR %d: "), error);
 
4141
          (void) tee_fprintf(file, "ERROR %d: ", error);
4298
4142
      }
4299
4143
      else
4300
 
        tee_puts(_("ERROR: "), file);
 
4144
        tee_puts("ERROR: ", file);
4301
4145
    }
4302
4146
    else
4303
4147
      vidattr(A_BOLD);
4336
4180
{
4337
4181
  const char *start=  buffer->c_str();
4338
4182
  const char *end= start + (buffer->length());
4339
 
  while (start < end && !isgraph(end[-1]))
 
4183
  while (start < end && !my_isgraph(charset_info,end[-1]))
4340
4184
    end--;
4341
4185
  uint32_t pos_to_truncate= (end-start);
4342
4186
  if (buffer->length() > pos_to_truncate)
4388
4232
}
4389
4233
 
4390
4234
#include <sys/times.h>
 
4235
#ifdef _SC_CLK_TCK        // For mit-pthreads
 
4236
#undef CLOCKS_PER_SEC
 
4237
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
 
4238
#endif
4391
4239
 
4392
 
static boost::posix_time::ptime start_timer(void)
 
4240
static uint32_t start_timer(void)
4393
4241
{
4394
 
  return boost::posix_time::microsec_clock::universal_time();
 
4242
  struct tms tms_tmp;
 
4243
  return times(&tms_tmp);
4395
4244
}
4396
4245
 
4397
 
static void nice_time(boost::posix_time::time_duration duration, string &buff)
 
4246
 
 
4247
/**
 
4248
   Write as many as 52+1 bytes to buff, in the form of a legible
 
4249
   duration of time.
 
4250
 
 
4251
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
 
4252
*/
 
4253
static void nice_time(double sec,char *buff,bool part_second)
4398
4254
{
 
4255
  uint32_t tmp;
4399
4256
  ostringstream tmp_buff_str;
4400
4257
 
4401
 
  if (duration.hours() > 0)
4402
 
  {
4403
 
    tmp_buff_str << duration.hours();
4404
 
    if (duration.hours() > 1)
4405
 
      tmp_buff_str << _(" hours ");
4406
 
    else
4407
 
      tmp_buff_str << _(" hour ");
4408
 
  }
4409
 
  if (duration.hours() > 0 || duration.minutes() > 0)
4410
 
  {
4411
 
    tmp_buff_str << duration.minutes() << _(" min ");
4412
 
  }
4413
 
 
4414
 
  tmp_buff_str.precision(duration.num_fractional_digits());
4415
 
 
4416
 
  double seconds= duration.fractional_seconds();
4417
 
 
4418
 
  seconds/= pow(10.0,duration.num_fractional_digits());
4419
 
 
4420
 
  seconds+= duration.seconds();
4421
 
  tmp_buff_str << seconds << _(" sec");
4422
 
 
4423
 
  buff.append(tmp_buff_str.str());
4424
 
}
4425
 
 
4426
 
static void end_timer(boost::posix_time::ptime start_time, string &buff)
4427
 
{
4428
 
  boost::posix_time::ptime end_time= start_timer();
4429
 
  boost::posix_time::time_period duration(start_time, end_time);
4430
 
 
4431
 
  nice_time(duration.length(), buff);
4432
 
}
4433
 
 
4434
 
 
4435
 
static void drizzle_end_timer(boost::posix_time::ptime start_time, string &buff)
4436
 
{
4437
 
  buff.append(" (");
4438
 
  end_timer(start_time,buff);
4439
 
  buff.append(")");
 
4258
  if (sec >= 3600.0*24)
 
4259
  {
 
4260
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4261
    sec-= 3600.0*24*tmp;
 
4262
    tmp_buff_str << tmp;
 
4263
 
 
4264
    if (tmp > 1)
 
4265
      tmp_buff_str << " days ";
 
4266
    else
 
4267
      tmp_buff_str << " day ";
 
4268
 
 
4269
  }
 
4270
  if (sec >= 3600.0)
 
4271
  {
 
4272
    tmp=(uint32_t) floor(sec/3600.0);
 
4273
    sec-=3600.0*tmp;
 
4274
    tmp_buff_str << tmp;
 
4275
 
 
4276
    if (tmp > 1)
 
4277
      tmp_buff_str << " hours ";
 
4278
    else
 
4279
      tmp_buff_str << " hour ";
 
4280
  }
 
4281
  if (sec >= 60.0)
 
4282
  {
 
4283
    tmp=(uint32_t) floor(sec/60.0);
 
4284
    sec-=60.0*tmp;
 
4285
    tmp_buff_str << tmp << " min ";
 
4286
  }
 
4287
  if (part_second)
 
4288
    tmp_buff_str.precision(2);
 
4289
  else
 
4290
    tmp_buff_str.precision(0);
 
4291
  tmp_buff_str << sec << " sec";
 
4292
  strcpy(buff, tmp_buff_str.str().c_str());
 
4293
}
 
4294
 
 
4295
 
 
4296
static void end_timer(uint32_t start_time,char *buff)
 
4297
{
 
4298
  nice_time((double) (start_timer() - start_time) /
 
4299
            CLOCKS_PER_SEC,buff,1);
 
4300
}
 
4301
 
 
4302
 
 
4303
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4304
{
 
4305
  buff[0]=' ';
 
4306
  buff[1]='(';
 
4307
  end_timer(start_time,buff+2);
 
4308
  strcpy(strchr(buff, '\0'),")");
4440
4309
}
4441
4310
 
4442
4311
static const char * construct_prompt()
4450
4319
  struct tm *t = localtime(&lclock);
4451
4320
 
4452
4321
  /* parse thru the settings for the prompt */
4453
 
  string::iterator c= current_prompt.begin();
4454
 
  while (c != current_prompt.end())
 
4322
  for (char *c= current_prompt; *c; (void)*c++)
4455
4323
  {
4456
4324
    if (*c != PROMPT_CHAR)
4457
4325
    {
4458
 
      processed_prompt->push_back(*c);
 
4326
      processed_prompt->append(c, 1);
4459
4327
    }
4460
4328
    else
4461
4329
    {
4466
4334
      switch (*++c) {
4467
4335
      case '\0':
4468
4336
        // stop it from going beyond if ends with %
4469
 
        --c;
 
4337
        c--;
4470
4338
        break;
4471
4339
      case 'c':
4472
4340
        add_int_to_prompt(++prompt_counter);
4478
4346
          processed_prompt->append("not_connected");
4479
4347
        break;
4480
4348
      case 'd':
4481
 
        processed_prompt->append(not current_db.empty() ? current_db : "(none)");
 
4349
        processed_prompt->append(current_db ? current_db : "(none)");
4482
4350
        break;
4483
4351
      case 'h':
4484
4352
      {
4485
 
        const char *prompt= connected ? drizzle_con_host(&con) : "not_connected";
 
4353
        const char *prompt;
 
4354
        prompt= connected ? drizzle_con_host(&con) : "not_connected";
4486
4355
        if (strstr(prompt, "Localhost"))
4487
4356
          processed_prompt->append("localhost");
4488
4357
        else
4501
4370
          break;
4502
4371
        }
4503
4372
 
4504
 
        if (drizzle_con_uds(&con))
 
4373
        if (strcmp(drizzle_con_uds(&con), ""))
4505
4374
        {
4506
4375
          const char *pos=strrchr(drizzle_con_uds(&con),'/');
4507
4376
          processed_prompt->append(pos ? pos+1 : drizzle_con_uds(&con));
4514
4383
        if (!full_username)
4515
4384
          init_username();
4516
4385
        processed_prompt->append(full_username ? full_username :
4517
 
                                 (!current_user.empty() ?  current_user : "(unknown)"));
 
4386
                                 (current_user ?  current_user : "(unknown)"));
4518
4387
        break;
4519
4388
      case 'u':
4520
4389
        if (!full_username)
4521
4390
          init_username();
4522
4391
        processed_prompt->append(part_username ? part_username :
4523
 
                                 (!current_user.empty() ?  current_user : _("(unknown)")));
 
4392
                                 (current_user ?  current_user : "(unknown)"));
4524
4393
        break;
4525
4394
      case PROMPT_CHAR:
4526
4395
        {
4575
4444
        add_int_to_prompt(t->tm_sec);
4576
4445
        break;
4577
4446
      case 'w':
4578
 
        processed_prompt->append(get_day_name(t->tm_wday));
 
4447
        processed_prompt->append(day_names[t->tm_wday]);
4579
4448
        break;
4580
4449
      case 'P':
4581
4450
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
4584
4453
        add_int_to_prompt(t->tm_mon+1);
4585
4454
        break;
4586
4455
      case 'O':
4587
 
        processed_prompt->append(get_month_name(t->tm_mon));
 
4456
        processed_prompt->append(month_names[t->tm_mon]);
4588
4457
        break;
4589
4458
      case '\'':
4590
4459
        processed_prompt->append("'");
4602
4471
        processed_prompt->append(delimiter_str);
4603
4472
        break;
4604
4473
      default:
4605
 
        processed_prompt->push_back(*c);
 
4474
        processed_prompt->append(c, 1);
4606
4475
      }
4607
4476
    }
4608
 
    ++c;
4609
4477
  }
4610
4478
  return processed_prompt->c_str();
4611
4479
}
4640
4508
{
4641
4509
  const char *ptr=strchr(line, ' ');
4642
4510
  if (ptr == NULL)
4643
 
    tee_fprintf(stdout, _("Returning to default PROMPT of %s\n"),
 
4511
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4644
4512
                default_prompt);
4645
4513
  prompt_counter = 0;
4646
4514
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
4647
4515
  if (tmpptr == NULL)
4648
 
    tee_fprintf(stdout, _("Memory allocation error. Not changing prompt\n"));
 
4516
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4649
4517
  else
4650
4518
  {
4651
 
    current_prompt.erase();
 
4519
    free(current_prompt);
4652
4520
    current_prompt= tmpptr;
4653
 
    tee_fprintf(stdout, _("PROMPT set to '%s'\n"), current_prompt.c_str());
 
4521
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4654
4522
  }
4655
4523
  return 0;
4656
4524
}