~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Daniel Nichter
  • Date: 2011-10-23 16:01:37 UTC
  • mto: This revision was merged to the branch mainline in revision 2448.
  • Revision ID: daniel@percona.com-20111023160137-7ac3blgz8z4tf8za
Add Administration Getting Started and Logging.  Capitalize SQL clause keywords.

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