~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Jay Pipes
  • Date: 2008-12-18 15:55:03 UTC
  • mto: This revision was merged to the branch mainline in revision 717.
  • Revision ID: jpipes@serialcoder-20081218155503-u45ygyunrdyyvquq
Fix for Bug#308457.  Gave UTF8 enclosure and escape character on LOAD DATA INFILE and changed the error message to be more descriptive

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