~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Monty Taylor
  • Date: 2008-10-14 21:20:42 UTC
  • mto: (511.1.4 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081014212042-tef3njx3368b6lwt
Override copy ctr and op= because we have pointer members.

Show diffs side-by-side

added added

removed removed

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