~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.c

  • Committer: Patrick Galbraith
  • Date: 2008-07-24 16:57:40 UTC
  • mto: (202.2.4 rename-mysql-to-drizzle)
  • mto: This revision was merged to the branch mainline in revision 212.
  • Revision ID: patg@ishvara-20080724165740-x58yw6zs6d9o17lf
Most everything working with client rename
mysqlslap test still fails... can't connect to the server

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 *   Michael 'Monty' Widenius
26
26
 *   Andi Gutmans  <andi@zend.com>
27
27
 *   Zeev Suraski  <zeev@zend.com>
28
 
 *   Jani Tolonen  <jani@mysql.com>
29
 
 *   Matt Wagner   <matt@mysql.com>
30
 
 *   Jeremy Cole   <jcole@mysql.com>
31
 
 *   Tonu Samuel   <tonu@mysql.com>
32
 
 *   Harrison Fisk <harrison@mysql.com>
 
28
 *   Jani Tolonen  <jani@drizzle.com>
 
29
 *   Matt Wagner   <matt@drizzle.com>
 
30
 *   Jeremy Cole   <jcole@drizzle.com>
 
31
 *   Tonu Samuel   <tonu@drizzle.com>
 
32
 *   Harrison Fisk <harrison@drizzle.com>
33
33
 *
34
34
 **/
35
35
 
36
 
#include "config.h"
37
 
 
38
 
#include <string>
39
 
 
40
36
#include "client_priv.h"
41
 
#include <mystrings/m_ctype.h>
 
37
#include <m_ctype.h>
42
38
#include <stdarg.h>
 
39
#include <my_dir.h>
43
40
#ifndef __GNU_LIBRARY__
44
41
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
45
42
#endif
46
43
#include <readline/history.h>
47
44
#include "my_readline.h"
48
45
#include <signal.h>
49
 
#include <sys/ioctl.h>
50
 
 
51
 
 
52
 
#if defined(HAVE_LOCALE_H)
 
46
#include <violite.h>
 
47
 
 
48
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
53
49
#include <locale.h>
54
50
#endif
55
51
 
56
 
#include <libdrizzle/gettext.h>
 
52
#include <glib.h>
57
53
 
58
54
const char *VER= "14.14";
59
55
 
60
56
/* Don't try to make a nice table if the data is too big */
61
 
#define MAX_COLUMN_LENGTH       (uint32_t)1024
 
57
#define MAX_COLUMN_LENGTH       1024
62
58
 
63
59
/* Buffer to hold 'version' and 'version_comment' */
64
60
#define MAX_SERVER_VERSION_LENGTH     128
69
65
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
70
66
void sql_element_free(void *ptr);
71
67
 
72
 
 
73
68
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
74
69
#include <curses.h>
75
 
#ifdef __sun
76
 
#undef clear
77
 
#undef erase
78
 
#endif
79
70
#include <term.h>
80
71
#else
81
72
#if defined(HAVE_TERMIOS_H)
86
77
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
87
78
#include <asm/termbits.h>    // Standard linux
88
79
#endif
 
80
#undef VOID
89
81
#if defined(HAVE_TERMCAP_H)
90
82
#include <termcap.h>
91
83
#else
99
91
#endif
100
92
#endif
101
93
 
102
 
#undef bcmp                             // Fix problem with new readline
 
94
#undef bcmp        // Fix problem with new readline
103
95
 
104
 
#ifdef HAVE_READLINE_HISTORY_H
105
 
#include <readline/history.h>
106
 
#endif
107
96
#include <readline/readline.h>
108
97
 
109
 
/**
110
 
 Make the old readline interface look like the new one.
111
 
*/
112
 
#ifndef USE_NEW_READLINE_INTERFACE
113
 
typedef CPPFunction rl_completion_func_t;
114
 
typedef Function rl_compentry_func_t;
115
 
#define rl_completion_matches(str, func) \
116
 
  completion_matches((char *)str, (CPFunction *)func)
117
 
#endif
118
 
 
119
98
 
120
99
#if !defined(HAVE_VIDATTR)
121
100
#undef vidattr
130
109
 
131
110
#include "completion_hash.h"
132
111
 
133
 
using namespace std;
134
 
 
135
112
#define PROMPT_CHAR '\\'
136
113
#define DEFAULT_DELIMITER ";"
137
114
 
156
133
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
157
134
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
158
135
  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,
 
136
  vertical=0, line_numbers=1, column_names=1,opt_html=0,
 
137
  opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
161
138
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
162
139
  default_charset_used= 0, opt_secure_auth= 0,
163
140
  default_pager_set= 0, opt_sigint_ignore= 0,
166
143
static bool debug_info_flag, debug_check_flag;
167
144
static bool column_types_flag;
168
145
static bool preserve_comments= 0;
169
 
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
 
146
static ulong opt_max_allowed_packet, opt_net_buffer_length;
170
147
static int verbose=0,opt_silent=0,opt_drizzle_port=0, opt_local_infile=0;
171
148
static uint my_end_arg;
172
149
static char * opt_drizzle_unix_port=0;
173
150
static int connect_flag=CLIENT_INTERACTIVE;
174
151
static char *current_host,*current_db,*current_user=0,*opt_password=0,
175
 
  *delimiter_str= 0,* current_prompt= 0;
 
152
  *delimiter_str= 0,*current_prompt=0,
 
153
  *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
176
154
static char *histfile;
177
155
static char *histfile_tmp;
178
 
static string *glob_buffer;
179
 
static string *processed_prompt= NULL;
180
 
static char *default_prompt= NULL;
 
156
static GString *glob_buffer;
 
157
static GString *processed_prompt= NULL;
 
158
static GString *default_prompt= NULL;
181
159
static char *full_username=0,*part_username=0;
182
160
static STATUS status;
183
161
static uint32_t select_limit;
184
162
static uint32_t max_join_size;
185
 
static uint32_t opt_connect_timeout= 0;
 
163
static ulong opt_connect_timeout= 0;
186
164
static char drizzle_charsets_dir[FN_REFLEN+1];
187
 
// TODO: Need to i18n these
 
165
static const char *xmlmeta[] = {
 
166
  "&", "&amp;",
 
167
  "<", "&lt;",
 
168
  ">", "&gt;",
 
169
  "\"", "&quot;",
 
170
  0, 0
 
171
};
188
172
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
189
173
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
190
174
                                  "Aug","Sep","Oct","Nov","Dec"};
197
181
static uint delimiter_length= 1;
198
182
unsigned short terminal_width= 80;
199
183
 
200
 
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
 
184
static uint opt_protocol= DRIZZLE_PROTOCOL_TCP;
 
185
static CHARSET_INFO *charset_info= &my_charset_latin1;
201
186
 
 
187
const char *default_dbug_option="d:t:o,/tmp/drizzle.trace";
202
188
int drizzle_real_query_for_lazy(const char *buf, int length);
203
189
int drizzle_store_result_for_lazy(DRIZZLE_RES **result);
204
190
 
212
198
static int get_options(int argc,char **argv);
213
199
bool get_one_option(int optid, const struct my_option *opt,
214
200
                    char *argument);
215
 
static int com_quit(string *str,const char*),
216
 
  com_go(string *str,const char*), com_ego(string *str,const char*),
217
 
  com_print(string *str,const char*),
218
 
  com_help(string *str,const char*), com_clear(string *str,const char*),
219
 
  com_connect(string *str,const char*), com_status(string *str,const char*),
220
 
  com_use(string *str,const char*), com_source(string *str, const char*),
221
 
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
222
 
  com_notee(string *str, const char*),
223
 
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
224
 
  com_warnings(string *str, const char*), com_nowarnings(string *str, const char*),
225
 
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
 
201
static int com_quit(GString *str,char*),
 
202
  com_go(GString *str,char*), com_ego(GString *str,char*),
 
203
  com_print(GString *str,char*),
 
204
  com_help(GString *str,char*), com_clear(GString *str,char*),
 
205
  com_connect(GString *str,char*), com_status(GString *str,char*),
 
206
  com_use(GString *str,char*), com_source(GString *str, char*),
 
207
  com_rehash(GString *str, char*), com_tee(GString *str, char*),
 
208
  com_notee(GString *str, char*), com_charset(GString *str,char*),
 
209
  com_prompt(GString *str, char*), com_delimiter(GString *str, char*),
 
210
  com_warnings(GString *str, char*), com_nowarnings(GString *str, char*),
 
211
  com_nopager(GString *str, char*), com_pager(GString *str, char*);
226
212
 
227
213
static int read_and_execute(bool interactive);
228
214
static int sql_connect(char *host,char *database,char *user,char *password,
231
217
static int put_info(const char *str,INFO_TYPE info,uint error,
232
218
                    const char *sql_state);
233
219
static int put_error(DRIZZLE *drizzle);
234
 
static void safe_put_field(const char *pos,uint32_t length);
 
220
static void safe_put_field(const char *pos,ulong length);
 
221
static void xmlencode_print(const char *src, uint length);
235
222
static void init_pager(void);
236
223
static void end_pager(void);
237
224
static void init_tee(const char *);
242
229
static void add_int_to_prompt(int toadd);
243
230
static int get_result_width(DRIZZLE_RES *res);
244
231
static int get_field_disp_length(DRIZZLE_FIELD * field);
245
 
static const char * strcont(register const char *str, register const char *set);
246
232
 
247
233
/* A structure which contains information on the commands this program
248
234
   can understand. */
249
235
typedef struct {
250
 
  const char *name;        /* User printable name of the function. */
251
 
  char cmd_char;        /* msql command character */
252
 
  int (*func)(string *str,const char *); /* Function to call to do the job. */
253
 
  bool takes_params;        /* Max parameters for command */
254
 
  const char *doc;        /* Documentation for this function.  */
 
236
  const char *name;    /* User printable name of the function. */
 
237
  char cmd_char;    /* msql command character */
 
238
  int (*func)(GString *str,char *); /* Function to call to do the job. */
 
239
  bool takes_params;    /* Max parameters for command */
 
240
  const char *doc;    /* Documentation for this function.  */
255
241
} COMMANDS;
256
242
 
257
243
 
258
244
static COMMANDS commands[] = {
259
 
  { "?",      '?', com_help,   1, N_("Synonym for `help'.") },
260
 
  { "clear",  'c', com_clear,  0, N_("Clear command.")},
 
245
  { "?",      '?', com_help,   1, "Synonym for `help'." },
 
246
  { "clear",  'c', com_clear,  0, "Clear command."},
261
247
  { "connect",'r', com_connect,1,
262
 
    N_("Reconnect to the server. Optional arguments are db and host." }),
 
248
    "Reconnect to the server. Optional arguments are db and host." },
263
249
  { "delimiter", 'd', com_delimiter,    1,
264
 
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") },
 
250
    "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
265
251
  { "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.") },
 
252
    "Send command to drizzle server, display result vertically."},
 
253
  { "exit",   'q', com_quit,   0, "Exit drizzle. Same as quit."},
 
254
  { "go",     'g', com_go,     0, "Send command to drizzle server." },
 
255
  { "help",   'h', com_help,   1, "Display this help." },
 
256
  { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
 
257
  { "notee",  't', com_notee,  0, "Don't write into outfile." },
272
258
  { "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.") },
 
259
    "Set PAGER [to_pager]. Print the query results via PAGER." },
 
260
  { "print",  'p', com_print,  0, "Print current command." },
 
261
  { "prompt", 'R', com_prompt, 1, "Change your drizzle prompt."},
 
262
  { "quit",   'q', com_quit,   0, "Quit drizzle." },
 
263
  { "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
278
264
  { "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.")},
 
265
    "Execute an SQL script file. Takes a file name as an argument."},
 
266
  { "status", 's', com_status, 0, "Get status information from the server."},
281
267
  { "tee",    'T', com_tee,    1,
282
 
    N_("Set outfile [to_outfile]. Append everything into given outfile.") },
 
268
    "Set outfile [to_outfile]. Append everything into given outfile." },
283
269
  { "use",    'u', com_use,    1,
284
 
    N_("Use another database. Takes database name as argument.") },
 
270
    "Use another database. Takes database name as argument." },
 
271
  { "charset",    'C', com_charset,    1,
 
272
    "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." },
285
273
  { "warnings", 'W', com_warnings,  0,
286
 
    N_("Show warnings after every statement.") },
 
274
    "Show warnings after every statement." },
287
275
  { "nowarning", 'w', com_nowarnings, 0,
288
 
    N_("Don't show warnings after every statement.") },
 
276
    "Don't show warnings after every statement." },
289
277
  /* Get bash-like expansion for some commands */
290
278
  { "create table",     0, 0, 0, ""},
291
279
  { "create database",  0, 0, 0, ""},
610
598
  { "QUARTER", 0, 0, 0, ""},
611
599
  { "QUERY", 0, 0, 0, ""},
612
600
  { "QUICK", 0, 0, 0, ""},
 
601
  { "RAID0", 0, 0, 0, ""},
 
602
  { "RAID_CHUNKS", 0, 0, 0, ""},
 
603
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
 
604
  { "RAID_TYPE", 0, 0, 0, ""},
613
605
  { "READ", 0, 0, 0, ""},
614
606
  { "READS", 0, 0, 0, ""},
615
607
  { "REAL", 0, 0, 0, ""},
994
986
 
995
987
static const char *load_default_groups[]= { "drizzle","client",0 };
996
988
 
 
989
static int         embedded_server_arg_count= 0;
 
990
static char       *embedded_server_args[MAX_SERVER_ARGS];
 
991
static const char *embedded_server_groups[]=
 
992
{ "server", "DRIZZLE_SERVER", 0 };
 
993
 
997
994
int history_length;
998
995
static int not_in_history(const char *line);
999
 
static void initialize_readline (char *name);
1000
 
static void fix_history(string *final_command);
 
996
static void initialize_readline (const char *name);
 
997
static void fix_history(GString *final_command);
1001
998
 
1002
 
static COMMANDS *find_command(const char *name,char cmd_name);
1003
 
static bool add_line(string *buffer,char *line,char *in_string,
 
999
static COMMANDS *find_command(char *name,char cmd_name);
 
1000
static bool add_line(GString *buffer,char *line,char *in_string,
1004
1001
                     bool *ml_comment);
1005
 
static void remove_cntrl(string *buffer);
 
1002
static void remove_cntrl(GString *buffer);
1006
1003
static void print_table_data(DRIZZLE_RES *result);
 
1004
static void print_table_data_html(DRIZZLE_RES *result);
 
1005
static void print_table_data_xml(DRIZZLE_RES *result);
1007
1006
static void print_tab_data(DRIZZLE_RES *result);
1008
1007
static void print_table_data_vertically(DRIZZLE_RES *result);
1009
1008
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);
 
1009
static ulong start_timer(void);
 
1010
static void end_timer(ulong start_time,char *buff);
 
1011
static void drizzle_end_timer(ulong start_time,char *buff);
1013
1012
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);
 
1013
extern sig_handler drizzle_end(int sig);
 
1014
extern sig_handler handle_sigint(int sig);
1016
1015
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1017
 
static RETSIGTYPE window_resize(int sig);
 
1016
static sig_handler window_resize(int sig);
1018
1017
#endif
1019
1018
 
1020
1019
int main(int argc,char *argv[])
1021
1020
{
1022
1021
  char buff[80];
1023
1022
 
1024
 
#if defined(ENABLE_NLS)
1025
 
# if defined(HAVE_LOCALE_H)
1026
 
  setlocale(LC_ALL, "");
1027
 
# endif
1028
 
  bindtextdomain("drizzle", LOCALEDIR);
1029
 
  textdomain("drizzle");
1030
 
#endif
1031
 
 
1032
1023
  MY_INIT(argv[0]);
1033
1024
  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));
1038
 
  processed_prompt= new string();
1039
 
  processed_prompt->reserve(32);
1040
 
 
 
1025
  default_prompt = g_string_new(g_strdup(getenv("DRIZZLE_PS1") ?
 
1026
                                         getenv("DRIZZLE_PS1") :
 
1027
                                         "drizzle>> "));
 
1028
  current_prompt = g_strdup(default_prompt->str);
 
1029
  processed_prompt = g_string_sized_new(16);
1041
1030
  prompt_counter=0;
1042
1031
 
1043
1032
  outfile[0]=0;      // no (default) outfile
1044
 
  my_stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1033
  strmov(pager, "stdout");  // the default, if --pager wasn't given
1045
1034
  {
1046
1035
    char *tmp=getenv("PAGER");
1047
1036
    if (tmp && strlen(tmp))
1048
1037
    {
1049
1038
      default_pager_set= 1;
1050
 
      my_stpcpy(default_pager, tmp);
 
1039
      strmov(default_pager, tmp);
1051
1040
    }
1052
1041
  }
1053
1042
  if (!isatty(0) || !isatty(1))
1088
1077
    my_end(0);
1089
1078
    exit(1);
1090
1079
  }
 
1080
  if (drizzle_server_init(embedded_server_arg_count, embedded_server_args,
 
1081
                        (char**) embedded_server_groups))
 
1082
  {
 
1083
    put_error(NULL);
 
1084
    free_defaults(defaults_argv);
 
1085
    my_end(0);
 
1086
    exit(1);
 
1087
  }
1091
1088
  completion_hash_init(&ht, 128);
1092
1089
  init_alloc_root(&hash_mem_root, 16384, 0);
1093
 
  memset(&drizzle, 0, sizeof(drizzle));
 
1090
  bzero((char*) &drizzle, sizeof(drizzle));
1094
1091
  if (sql_connect(current_host,current_db,current_user,opt_password,
1095
1092
                  opt_silent))
1096
1093
  {
1114
1111
  window_resize(0);
1115
1112
#endif
1116
1113
 
1117
 
  put_info(_("Welcome to the Drizzle client..  Commands end with ; or \\g."),
 
1114
  put_info("Welcome to the Drizzle client..  Commands end with ; or \\g.",
1118
1115
           INFO_INFO,0,0);
1119
 
 
1120
 
  glob_buffer= new string();
1121
 
  glob_buffer->reserve(512);
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)
 
1116
  glob_buffer = g_string_sized_new(512);
 
1117
  g_string_printf(glob_buffer,
 
1118
                  "Your Drizzle connection id is %u\nServer version: %s\n",
 
1119
                  drizzle_thread_id(&drizzle), server_version_string(&drizzle));
 
1120
  put_info(glob_buffer->str,INFO_INFO,0,0);
 
1121
  g_string_truncate(glob_buffer,0);
 
1122
 
 
1123
  initialize_readline(my_progname);
 
1124
  if (!status.batch && !quick && !opt_html && !opt_xml)
1134
1125
  {
1135
1126
    /* read-history from file, default ~/.drizzle_history*/
1136
 
    if (getenv("DRIZZLE_HISTFILE"))
1137
 
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
 
1127
    if (getenv("MYSQL_HISTFILE"))
 
1128
      histfile=g_strdup(getenv("MYSQL_HISTFILE"));
1138
1129
    else if (getenv("HOME"))
1139
1130
    {
1140
1131
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1147
1138
          strncmp(link_name, "/dev/null", 10) == 0)
1148
1139
      {
1149
1140
        /* The .drizzle_history file is a symlink to /dev/null, don't use it */
1150
 
        free(histfile);
 
1141
        my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
1151
1142
        histfile= 0;
1152
1143
      }
1153
1144
    }
1154
1145
    if (histfile)
1155
1146
    {
1156
1147
      if (verbose)
1157
 
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
 
1148
        tee_fprintf(stdout, "Reading history-file %s\n",histfile);
1158
1149
      read_history(histfile);
1159
1150
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1160
1151
                                            MYF(MY_WME))))
1161
1152
      {
1162
 
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
 
1153
        fprintf(stderr, "Couldn't allocate memory for temp histfile!\n");
1163
1154
        exit(1);
1164
1155
      }
1165
1156
      sprintf(histfile_tmp, "%s.TMP", histfile);
1166
1157
    }
1167
1158
  }
1168
1159
  sprintf(buff, "%s",
1169
 
          _("Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n"));
 
1160
          "Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
1170
1161
 
1171
1162
  put_info(buff,INFO_INFO,0,0);
1172
1163
  status.exit_status= read_and_execute(!status.batch);
1173
1164
  if (opt_outfile)
1174
1165
    end_tee();
1175
1166
  drizzle_end(0);
1176
 
 
 
1167
#ifndef _lint
1177
1168
  return(0);        // Keep compiler happy
 
1169
#endif
1178
1170
}
1179
1171
 
1180
 
RETSIGTYPE drizzle_end(int sig)
 
1172
sig_handler drizzle_end(int sig)
1181
1173
{
1182
1174
  drizzle_close(&drizzle);
1183
 
  if (!status.batch && !quick && histfile)
 
1175
  if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
1184
1176
  {
1185
1177
    /* write-history */
1186
1178
    if (verbose)
1187
 
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
 
1179
      tee_fprintf(stdout, "Writing history-file %s\n",histfile);
1188
1180
    if (!write_history(histfile_tmp))
1189
1181
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1190
1182
  }
1193
1185
  free_root(&hash_mem_root,MYF(0));
1194
1186
 
1195
1187
  if (sig >= 0)
1196
 
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
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);
1203
 
  free(histfile);
1204
 
  free(histfile_tmp);
1205
 
  free(current_db);
1206
 
  free(current_host);
1207
 
  free(current_user);
1208
 
  free(full_username);
1209
 
  free(part_username);
1210
 
  free(default_prompt);
1211
 
  free(current_prompt);
 
1188
    put_info(sig ? "Aborted" : "Bye", INFO_RESULT,0,0);
 
1189
  assert(glob_buffer != NULL);
 
1190
  g_string_free(glob_buffer,true);
 
1191
  assert(processed_prompt != NULL);
 
1192
  g_string_free(processed_prompt,true);
 
1193
  assert(default_prompt != NULL);
 
1194
  g_string_free(default_prompt,true);
 
1195
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
1196
  my_free(opt_drizzle_unix_port,MYF(MY_ALLOW_ZERO_PTR));
 
1197
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
 
1198
  my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
 
1199
  my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
1200
  my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
1201
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
 
1202
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
1203
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
 
1204
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1205
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1206
  while (embedded_server_arg_count > 1)
 
1207
    my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
 
1208
  drizzle_server_end();
1212
1209
  free_defaults(defaults_argv);
1213
1210
  my_end(my_end_arg);
1214
1211
  exit(status.exit_status);
1220
1217
  If query is in process, kill query
1221
1218
  no query in process, terminate like previous behavior
1222
1219
*/
1223
 
RETSIGTYPE handle_sigint(int sig)
 
1220
sig_handler handle_sigint(int sig)
1224
1221
{
1225
1222
  char kill_buffer[40];
1226
1223
  DRIZZLE *kill_drizzle= NULL;
1230
1227
    goto err;
1231
1228
  }
1232
1229
 
1233
 
  kill_drizzle= drizzle_create(kill_drizzle);
 
1230
  kill_drizzle= drizzle_init(kill_drizzle);
1234
1231
  if (!drizzle_connect(kill_drizzle,current_host, current_user, opt_password,
1235
1232
                          "", opt_drizzle_port, opt_drizzle_unix_port,0))
1236
1233
  {
1241
1238
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u", drizzle_thread_id(&drizzle));
1242
1239
  drizzle_real_query(kill_drizzle, kill_buffer, strlen(kill_buffer));
1243
1240
  drizzle_close(kill_drizzle);
1244
 
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
 
1241
  tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
1245
1242
 
1246
1243
  interrupted_query= 1;
1247
1244
 
1253
1250
 
1254
1251
 
1255
1252
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1256
 
RETSIGTYPE window_resize(int sig __attribute__((unused)))
 
1253
sig_handler window_resize(int sig __attribute__((__unused__)))
1257
1254
{
1258
1255
  struct winsize window_size;
1259
1256
 
1264
1261
 
1265
1262
static struct my_option my_long_options[] =
1266
1263
{
1267
 
  {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1264
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1268
1265
   0, 0, 0, 0, 0},
1269
 
  {"help", 'I', N_("Synonym for -?"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1266
  {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1270
1267
   0, 0, 0, 0, 0},
1271
1268
  {"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."),
 
1269
   "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
1270
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
1274
1271
   0, 0},
1275
1272
  {"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."),
 
1273
   "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
1274
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1278
1275
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1279
 
   N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
 
1276
   "Automatically switch to vertical output mode if the result is wider than the terminal width.",
1280
1277
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1281
1278
  {"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},
 
1279
   "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
1280
  {"character-sets-dir", OPT_CHARSETS_DIR,
1284
 
   N_("Directory where character sets are."), (char**) &charsets_dir,
 
1281
   "Directory where character sets are.", (char**) &charsets_dir,
1285
1282
   (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."),
 
1283
  {"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
1287
1284
   (char**) &column_types_flag, (char**) &column_types_flag,
1288
1285
   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"),
 
1286
  {"comments", 'c', "Preserve comments. Send comments to the server."
 
1287
   " The default is --skip-comments (discard comments), enable with --comments",
1290
1288
   (char**) &preserve_comments, (char**) &preserve_comments,
1291
1289
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1292
 
  {"compress", 'C', N_("Use compression in server/client protocol."),
 
1290
  {"compress", 'C', "Use compression in server/client protocol.",
1293
1291
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1294
1292
   0, 0, 0},
1295
 
  {"debug-check", OPT_DEBUG_CHECK, N_("Check memory and open file usage at exit ."),
 
1293
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
1296
1294
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
1297
1295
   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,
 
1296
  {"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
1299
1297
   (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,
 
1298
  {"database", 'D', "Database to use.", (char**) &current_db,
1301
1299
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1302
1300
  {"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,
 
1301
   "Set the default character set.", (char**) &default_charset,
 
1302
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1303
  {"delimiter", OPT_DELIMITER, "Delimiter to be used.", (char**) &delimiter_str,
1306
1304
   (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,
 
1305
  {"execute", 'e', "Execute command and quit. (Disables --force and history file)", 0,
1308
1306
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1309
 
  {"vertical", 'E', N_("Print the output of a query (rows) vertically."),
 
1307
  {"vertical", 'E', "Print the output of a query (rows) vertically.",
1310
1308
   (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1311
1309
   0},
1312
 
  {"force", 'f', N_("Continue even if we get an sql error."),
 
1310
  {"force", 'f', "Continue even if we get an sql error.",
1313
1311
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1314
1312
   0, 0, 0, 0},
1315
1313
  {"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."),
 
1314
   "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
1315
   (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1318
1316
   0, 0},
1319
1317
  {"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."),
 
1318
   "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
1319
   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,
 
1320
  {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
1323
1321
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1324
 
  {"local-infile", OPT_LOCAL_INFILE, N_("Enable/disable LOAD DATA LOCAL INFILE."),
 
1322
  {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
1325
1323
   (char**) &opt_local_infile,
1326
1324
   (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,
 
1325
  {"no-beep", 'b', "Turn off beep on error.", (char**) &opt_nobeep,
1328
1326
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1329
 
  {"host", 'h', N_("Connect to host."), (char**) &current_host,
 
1327
  {"host", 'h', "Connect to host.", (char**) &current_host,
1330
1328
   (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."),
 
1329
  {"html", 'H', "Produce HTML output.", (char**) &opt_html, (char**) &opt_html,
 
1330
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1331
  {"xml", 'X', "Produce XML output", (char**) &opt_xml, (char**) &opt_xml, 0,
 
1332
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1333
  {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
1332
1334
   (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
1333
1335
   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,
 
1336
  {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
1335
1337
   NO_ARG, 0, 0, 0, 0, 0, 0},
1336
 
  {"unbuffered", 'n', N_("Flush buffer after each query."), (char**) &unbuffered,
 
1338
  {"unbuffered", 'n', "Flush buffer after each query.", (char**) &unbuffered,
1337
1339
   (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."),
 
1340
  {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
1339
1341
   (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
1340
1342
   NO_ARG, 1, 0, 0, 0, 0, 0},
1341
1343
  {"skip-column-names", 'N',
1342
 
   N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."),
 
1344
   "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
1343
1345
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1344
1346
  {"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."),
 
1347
   "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
1346
1348
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1347
 
  {"sigint-ignore", OPT_SIGINT_IGNORE, N_("Ignore SIGINT (CTRL-C)"),
 
1349
  {"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C)",
1348
1350
   (char**) &opt_sigint_ignore,  (char**) &opt_sigint_ignore, 0, GET_BOOL,
1349
1351
   NO_ARG, 0, 0, 0, 0, 0, 0},
1350
1352
  {"one-database", 'o',
1351
 
   N_("Only update the default database. This is useful for skipping updates to other database in the update log."),
 
1353
   "Only update the default database. This is useful for skipping updates to other database in the update log.",
1352
1354
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1353
1355
  {"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."),
 
1356
   "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
1357
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1356
1358
  {"no-pager", OPT_NOPAGER,
1357
 
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
 
1359
   "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
1358
1360
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1359
1361
  {"password", 'p',
1360
 
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
 
1362
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
1361
1363
   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
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
1365
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
1366
#if MYSQL_PORT_DEFAULT == 0
 
1367
   "/etc/services, "
 
1368
#endif
 
1369
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
1364
1370
   (char**) &opt_drizzle_port,
1365
1371
   (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."),
 
1372
  {"prompt", OPT_PROMPT, "Set the drizzle prompt to this value.",
1367
1373
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
1368
1374
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1369
 
  {"protocol", OPT_DRIZZLE_PROTOCOL, N_("The protocol of connection (tcp,socket,pipe,memory)."),
 
1375
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1370
1376
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1371
1377
  {"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."),
 
1378
   "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
1379
   (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."),
 
1380
  {"raw", 'r', "Write fields without conversion. Used with --batch.",
1375
1381
   (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1376
1382
   0, 0, 0},
1377
 
  {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
 
1383
  {"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
1378
1384
   (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,
 
1385
  {"silent", 's', "Be more silent. Print results with a tab as separator, each row on new line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
1380
1386
   0, 0},
1381
 
  {"socket", 'S', N_("Socket file to use for connection."),
 
1387
  {"socket", 'S', "Socket file to use for connection.",
1382
1388
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR_ALLOC,
1383
1389
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1384
 
  {"table", 't', N_("Output in table format."), (char**) &output_tables,
 
1390
  {"table", 't', "Output in table format.", (char**) &output_tables,
1385
1391
   (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1386
1392
  {"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."),
 
1393
   "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
1394
   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,
 
1395
  {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
1390
1396
   NO_ARG, 0, 0, 0, 0, 0, 0},
1391
1397
#ifndef DONT_ALLOW_USER_CHANGE
1392
 
  {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
 
1398
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
1393
1399
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1394
1400
#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,
 
1401
  {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
 
1402
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1403
   0, 0, 0, 0},
 
1404
  {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
 
1405
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1406
   0, 0, 0, 0},
 
1407
  {"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
1402
1408
   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,
 
1409
  {"version", 'V', "Output version information and exit.", 0, 0, 0,
1404
1410
   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,
 
1411
  {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
1406
1412
   NO_ARG, 0, 0, 0, 0, 0, 0},
1407
1413
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
1408
 
   N_("Number of seconds before connection timeout."),
 
1414
   "Number of seconds before connection timeout.",
1409
1415
   (char**) &opt_connect_timeout,
1410
1416
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
1411
1417
   0, 0},
1412
1418
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1413
 
   N_("Max packet length to send to, or receive from server"),
 
1419
   "Max packet length to send to, or receive from server",
1414
1420
   (char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
1415
1421
   GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
1416
1422
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1417
1423
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
1418
 
   N_("Buffer for TCP/IP and socket communication"),
 
1424
   "Buffer for TCP/IP and socket communication",
1419
1425
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_ULONG,
1420
1426
   REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
1421
1427
  {"select_limit", OPT_SELECT_LIMIT,
1422
 
   N_("Automatic limit for SELECT when using --safe-updates"),
 
1428
   "Automatic limit for SELECT when using --safe-updates",
1423
1429
   (char**) &select_limit,
1424
1430
   (char**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
1425
1431
   0, 1, 0},
1426
1432
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1427
 
   N_("Automatic limit for rows in a join when using --safe-updates"),
 
1433
   "Automatic limit for rows in a join when using --safe-updates",
1428
1434
   (char**) &max_join_size,
1429
1435
   (char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1430
1436
   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,
 
1437
  {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
 
1438
   " uses old (pre-4.1.1) protocol", (char**) &opt_secure_auth,
1432
1439
   (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."),
 
1440
  {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.",
 
1441
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1442
  {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
1434
1443
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1435
1444
   0, 0, 0, 0, 0, 0},
1436
1445
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1441
1450
{
1442
1451
  const char* readline= "readline";
1443
1452
 
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,
 
1453
  printf("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n",
 
1454
         my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
1447
1455
         readline, rl_library_version);
1448
1456
 
1449
1457
  if (version)
1450
1458
    return;
1451
 
  printf(_("\
1452
 
Copyright (C) 2000-2008 MySQL AB\n                                      \
 
1459
  printf("\
 
1460
Copyright (C) 2000-2008 Drizzle AB\n                                      \
1453
1461
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);
 
1462
and you are welcome to modify and redistribute it under the GPL license\n");
 
1463
  printf("Usage: %s [OPTIONS] [database]\n", my_progname);
1456
1464
  my_print_help(my_long_options);
1457
1465
  print_defaults("my", load_default_groups);
1458
1466
  my_print_variables(my_long_options);
1474
1482
  case OPT_DELIMITER:
1475
1483
    if (argument == disabled_my_option)
1476
1484
    {
1477
 
      my_stpcpy(delimiter, DEFAULT_DELIMITER);
 
1485
      strmov(delimiter, DEFAULT_DELIMITER);
1478
1486
    }
1479
1487
    else
1480
1488
    {
1485
1493
      }
1486
1494
      else
1487
1495
      {
1488
 
        put_info(_("DELIMITER cannot contain a backslash character"),
 
1496
        put_info("DELIMITER cannot contain a backslash character",
1489
1497
                 INFO_ERROR,0,0);
1490
1498
        return 0;
1491
1499
      }
1506
1514
      init_tee(argument);
1507
1515
    break;
1508
1516
  case OPT_NOTEE:
1509
 
    printf(_("WARNING: option deprecated; use --disable-tee instead.\n"));
 
1517
    printf("WARNING: option deprecated; use --disable-tee instead.\n");
1510
1518
    if (opt_outfile)
1511
1519
      end_tee();
1512
1520
    break;
1520
1528
      {
1521
1529
        default_pager_set= 1;
1522
1530
        strmake(pager, argument, sizeof(pager) - 1);
1523
 
        my_stpcpy(default_pager, pager);
 
1531
        strmov(default_pager, pager);
1524
1532
      }
1525
1533
      else if (default_pager_set)
1526
 
        my_stpcpy(pager, default_pager);
 
1534
        strmov(pager, default_pager);
1527
1535
      else
1528
1536
        opt_nopager= 1;
1529
1537
    }
1530
1538
    break;
1531
1539
  case OPT_NOPAGER:
1532
 
    printf(_("WARNING: option deprecated; use --disable-pager instead.\n"));
 
1540
    printf("WARNING: option deprecated; use --disable-pager instead.\n");
1533
1541
    opt_nopager= 1;
1534
1542
    break;
 
1543
  case OPT_DRIZZLE_PROTOCOL:
 
1544
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
1545
                                    opt->name);
 
1546
    break;
1535
1547
  case OPT_SERVER_ARG:
1536
 
    printf(_("WARNING: --server-arg option not supported in this configuration.\n"));
 
1548
#ifdef EMBEDDED_LIBRARY
 
1549
    /*
 
1550
      When the embedded server is being tested, the client needs to be
 
1551
      able to pass command-line arguments to the embedded server so it can
 
1552
      locate the language files and data directory.
 
1553
    */
 
1554
    if (!embedded_server_arg_count)
 
1555
    {
 
1556
      embedded_server_arg_count= 1;
 
1557
      embedded_server_args[0]= (char*) "";
 
1558
    }
 
1559
    if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
 
1560
        !(embedded_server_args[embedded_server_arg_count++]=
 
1561
          g_strdup(argument)))
 
1562
    {
 
1563
      put_info("Can't use server argument", INFO_ERROR);
 
1564
      return 0;
 
1565
    }
 
1566
#else /*EMBEDDED_LIBRARY */
 
1567
    printf("WARNING: --server-arg option not supported in this configuration.\n");
 
1568
#endif
1537
1569
    break;
1538
1570
  case 'A':
1539
1571
    opt_rehash= 0;
1561
1593
    if (argument)
1562
1594
    {
1563
1595
      char *start= argument;
1564
 
      free(opt_password);
1565
 
      opt_password= strdup(argument);
1566
 
      while (*argument) *argument++= 'x';        // Destroy argument
 
1596
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
 
1597
      opt_password= g_strdup(argument);
 
1598
      while (*argument) *argument++= 'x';    // Destroy argument
1567
1599
      if (*start)
1568
1600
        start[1]=0 ;
1569
1601
      tty_password= 0;
1605
1637
{
1606
1638
  char *tmp, *pagpoint;
1607
1639
  int ho_error;
1608
 
  const DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
 
1640
  DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
1609
1641
 
1610
 
  tmp= (char *) getenv("DRIZZLE_HOST");
 
1642
  tmp= (char *) getenv("MYSQL_HOST");
1611
1643
  if (tmp)
1612
1644
    current_host= strdup(tmp);
1613
1645
 
1614
1646
  pagpoint= getenv("PAGER");
1615
1647
  if (!((char*) (pagpoint)))
1616
1648
  {
1617
 
    my_stpcpy(pager, "stdout");
 
1649
    strmov(pager, "stdout");
1618
1650
    opt_nopager= 1;
1619
1651
  }
1620
1652
  else
1621
 
    my_stpcpy(pager, pagpoint);
1622
 
  my_stpcpy(default_pager, pager);
 
1653
    strmov(pager, pagpoint);
 
1654
  strmov(default_pager, pager);
1623
1655
 
1624
1656
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1625
1657
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
1632
1664
 
1633
1665
  if (status.batch) /* disable pager and outfile in this case */
1634
1666
  {
1635
 
    my_stpcpy(default_pager, "stdout");
1636
 
    my_stpcpy(pager, "stdout");
 
1667
    strmov(default_pager, "stdout");
 
1668
    strmov(pager, "stdout");
1637
1669
    opt_nopager= 1;
1638
1670
    default_pager_set= 0;
1639
1671
    opt_outfile= 0;
1641
1673
    connect_flag= 0; /* Not in interactive mode */
1642
1674
  }
1643
1675
 
 
1676
  if (strcmp(default_charset, charset_info->csname) &&
 
1677
      !(charset_info= get_charset_by_csname(default_charset,
 
1678
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
1679
    exit(1);
1644
1680
  if (argc > 1)
1645
1681
  {
1646
1682
    usage(0);
1649
1685
  if (argc == 1)
1650
1686
  {
1651
1687
    skip_updates= 0;
1652
 
    free(current_db);
1653
 
    current_db= strdup(*argv);
 
1688
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
1689
    current_db= g_strdup(*argv);
1654
1690
  }
1655
1691
  if (tty_password)
1656
 
    opt_password= get_tty_password(NULL);
 
1692
    opt_password= get_tty_password(NullS);
1657
1693
  if (debug_info_flag)
1658
1694
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1659
1695
  if (debug_check_flag)
1665
1701
{
1666
1702
  char *line;
1667
1703
  char in_string=0;
1668
 
  uint32_t line_number=0;
 
1704
  ulong line_number=0;
1669
1705
  bool ml_comment= 0;
1670
1706
  COMMANDS *com;
1671
1707
  status.exit_status=1;
1682
1718
        you save the file using "Unicode UTF-8" format.
1683
1719
      */
1684
1720
      if (!line_number &&
1685
 
          (unsigned char) line[0] == 0xEF &&
1686
 
          (unsigned char) line[1] == 0xBB &&
1687
 
          (unsigned char) line[2] == 0xBF)
 
1721
          (uchar) line[0] == 0xEF &&
 
1722
          (uchar) line[1] == 0xBB &&
 
1723
          (uchar) line[2] == 0xBF)
1688
1724
        line+= 3;
1689
1725
      line_number++;
1690
 
      if (!glob_buffer->empty())
 
1726
      if (glob_buffer->len!=0)
1691
1727
        status.query_start_line=line_number;
1692
1728
    }
1693
1729
    else
1694
1730
    {
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
 
                                                      "    \"> "));
1703
 
      if (opt_outfile && glob_buffer->empty())
 
1731
      char *prompt= (char*) (ml_comment ? "   /*> " :
 
1732
                             (glob_buffer->len == 0) ?  construct_prompt() :
 
1733
                             !in_string ? "    -> " :
 
1734
                             in_string == '\'' ?
 
1735
                             "    '> " : (in_string == '`' ?
 
1736
                                          "    `> " :
 
1737
                                          "    \"> "));
 
1738
      if (opt_outfile && (glob_buffer->len==0))
1704
1739
        fflush(OUTFILE);
1705
1740
 
1706
1741
      if (opt_outfile)
1724
1759
      Check if line is a drizzle command line
1725
1760
      (We want to allow help, print and clear anywhere at line start
1726
1761
    */
1727
 
    if ((named_cmds || (glob_buffer->empty()))
 
1762
    if ((named_cmds || (glob_buffer->len==0))
1728
1763
        && !ml_comment && !in_string && (com=find_command(line,0)))
1729
1764
    {
1730
1765
      if ((*com->func)(glob_buffer,line) > 0)
1731
1766
        break;
1732
1767
      // If buffer was emptied
1733
 
      if (glob_buffer->empty())
 
1768
      if (glob_buffer->len==0)
1734
1769
        in_string=0;
1735
1770
      if (interactive && status.add_to_history && not_in_history(line))
1736
1771
        add_history(line);
1744
1779
  if (!interactive && !status.exit_status)
1745
1780
  {
1746
1781
    remove_cntrl(glob_buffer);
1747
 
    if (!glob_buffer->empty())
 
1782
    if (glob_buffer->len != 0)
1748
1783
    {
1749
1784
      status.exit_status=1;
1750
1785
      if (com_go(glob_buffer,line) <= 0)
1756
1791
}
1757
1792
 
1758
1793
 
1759
 
static COMMANDS *find_command(const char *name,char cmd_char)
 
1794
static COMMANDS *find_command(char *name,char cmd_char)
1760
1795
{
1761
1796
  uint len;
1762
 
  const char *end;
 
1797
  char *end;
1763
1798
 
1764
1799
  if (!name)
1765
1800
  {
1778
1813
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
1779
1814
                                !(strlen(name) >= 9 &&
1780
1815
                                  !my_strnncoll(charset_info,
1781
 
                                                (unsigned char*) name, 9,
1782
 
                                                (const unsigned char*) "delimiter",
 
1816
                                                (uchar*) name, 9,
 
1817
                                                (const uchar*) "delimiter",
1783
1818
                                                9))))
1784
1819
      return((COMMANDS *) 0);
1785
1820
    if ((end=strcont(name," \t")))
1797
1832
  for (uint i= 0; commands[i].name; i++)
1798
1833
  {
1799
1834
    if (commands[i].func &&
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)))
 
1835
        ((name && !my_strnncoll(charset_info,(uchar*)name,len, (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
1801
1836
    {
1802
1837
      return(&commands[i]);
1803
1838
    }
1806
1841
}
1807
1842
 
1808
1843
 
1809
 
static bool add_line(string *buffer, char *line, char *in_string,
 
1844
static bool add_line(GString *buffer,char *line,char *in_string,
1810
1845
                        bool *ml_comment)
1811
1846
{
1812
 
  unsigned char inchar;
 
1847
  uchar inchar;
1813
1848
  char buff[80], *pos, *out;
1814
1849
  COMMANDS *com;
1815
1850
  bool need_space= 0;
1816
1851
  bool ss_comment= 0;
1817
1852
 
1818
1853
 
1819
 
  if (!line[0] && (buffer->empty()))
 
1854
  if (!line[0] && (buffer->len==0))
1820
1855
    return(0);
1821
1856
  if (status.add_to_history && line[0] && not_in_history(line))
1822
1857
    add_history(line);
1823
1858
  char *end_of_line=line+(uint) strlen(line);
1824
1859
 
1825
 
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
 
1860
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
1826
1861
  {
1827
1862
    if (!preserve_comments)
1828
1863
    {
1829
1864
      // Skip spaces at the beggining of a statement
1830
1865
      if (my_isspace(charset_info,inchar) && (out == line) &&
1831
 
          (buffer->empty()))
 
1866
          (buffer->len==0))
1832
1867
        continue;
1833
1868
    }
1834
1869
 
1850
1885
    }
1851
1886
#endif
1852
1887
        if (!*ml_comment && inchar == '\\' &&
1853
 
            !(*in_string && (drizzle.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)))
 
1888
        !(drizzle.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))
1854
1889
    {
1855
1890
      // Found possbile one character command like \c
1856
1891
 
1857
 
      if (!(inchar = (unsigned char) *++pos))
 
1892
      if (!(inchar = (uchar) *++pos))
1858
1893
        break;        // readline adds one '\'
1859
1894
      if (*in_string || inchar == 'N')  // \N is short for NULL
1860
1895
      {          // Don't allow commands in string
1862
1897
        *out++= (char) inchar;
1863
1898
        continue;
1864
1899
      }
1865
 
      if ((com=find_command(NULL,(char) inchar)))
 
1900
      if ((com=find_command(NullS,(char) inchar)))
1866
1901
      {
1867
1902
        // Flush previously accepted characters
1868
1903
        if (out != line)
1869
1904
        {
1870
 
          buffer->append(line, (out-line));
 
1905
          g_string_append_len(buffer, line, (gssize) (out-line));
1871
1906
          out= line;
1872
1907
        }
1873
1908
 
1901
1936
      }
1902
1937
      else
1903
1938
      {
1904
 
        sprintf(buff,_("Unknown command '\\%c'."),inchar);
 
1939
        sprintf(buff,"Unknown command '\\%c'.",inchar);
1905
1940
        if (put_info(buff,INFO_ERROR,0,0) > 0)
1906
1941
          return(1);
1907
1942
        *out++='\\';
1911
1946
    }
1912
1947
    else if (!*ml_comment && !*in_string &&
1913
1948
             (end_of_line - pos) >= 10 &&
1914
 
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
1915
 
                           (const unsigned char*) "delimiter ", 10))
 
1949
             !my_strnncoll(charset_info, (uchar*) pos, 10,
 
1950
                           (const uchar*) "delimiter ", 10))
1916
1951
    {
1917
1952
      // Flush previously accepted characters
1918
1953
      if (out != line)
1919
1954
      {
1920
 
        buffer->append(line, (out - line));
 
1955
        g_string_append_len(buffer, line, (gssize) (out - line));
1921
1956
        out= line;
1922
1957
      }
1923
1958
 
1924
1959
      // Flush possible comments in the buffer
1925
 
      if (!buffer->empty())
 
1960
      if (buffer->len != 0)
1926
1961
      {
1927
1962
        if (com_go(buffer, 0) > 0) // < 0 is not fatal
1928
1963
          return(1);
1929
1964
        assert(buffer!=NULL);
1930
 
        buffer->clear();
 
1965
        g_string_truncate(buffer,0);
1931
1966
      }
1932
1967
 
1933
1968
      /*
1934
1969
        Delimiter wants the get rest of the given line as argument to
1935
1970
        allow one to change ';' to ';;' and back
1936
1971
      */
1937
 
      buffer->append(pos);
 
1972
      g_string_append(buffer,pos);
1938
1973
      if (com_delimiter(buffer, pos) > 0)
1939
1974
        return(1);
1940
1975
 
1941
 
      buffer->clear();
 
1976
      g_string_truncate(buffer,0);
1942
1977
      break;
1943
1978
    }
1944
1979
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
1954
1989
      // Flush previously accepted characters
1955
1990
      if (out != line)
1956
1991
      {
1957
 
        buffer->append(line, (out-line));
 
1992
        g_string_append_len(buffer, line, (gssize) (out-line));
1958
1993
        out= line;
1959
1994
      }
1960
1995
 
1964
1999
                                 my_isspace(charset_info, pos[2]))))
1965
2000
      {
1966
2001
        // Add trailing single line comments to this statement
1967
 
        buffer->append(pos);
 
2002
        g_string_append(buffer, pos);
1968
2003
        pos+= strlen(pos);
1969
2004
      }
1970
2005
 
1971
2006
      pos--;
1972
2007
 
1973
 
      if ((com= find_command(buffer->c_str(), 0)))
 
2008
      if ((com= find_command(buffer->str, 0)))
1974
2009
      {
1975
2010
 
1976
 
        if ((*com->func)(buffer, buffer->c_str()) > 0)
 
2011
        if ((*com->func)(buffer, buffer->str) > 0)
1977
2012
          return(1);                       // Quit
1978
2013
      }
1979
2014
      else
1981
2016
        if (com_go(buffer, 0) > 0)             // < 0 is not fatal
1982
2017
          return(1);
1983
2018
      }
1984
 
      buffer->clear();
 
2019
      g_string_truncate(buffer,0);
1985
2020
    }
1986
2021
    else if (!*ml_comment
1987
2022
             && (!*in_string
1993
2028
      // Flush previously accepted characters
1994
2029
      if (out != line)
1995
2030
      {
1996
 
        buffer->append(line, (out - line));
 
2031
        g_string_append_len(buffer, line, (gssize) (out - line));
1997
2032
        out= line;
1998
2033
      }
1999
2034
 
2000
2035
      // comment to end of line
2001
2036
      if (preserve_comments)
2002
 
        buffer->append(pos);
 
2037
        g_string_append(buffer,pos);
2003
2038
 
2004
2039
      break;
2005
2040
    }
2016
2051
      *ml_comment= 1;
2017
2052
      if (out != line)
2018
2053
      {
2019
 
        buffer->append(line, (out-line));
 
2054
        g_string_append_len(buffer, line, (gssize) (out-line));
2020
2055
        out=line;
2021
2056
      }
2022
2057
    }
2032
2067
      *ml_comment= 0;
2033
2068
      if (out != line)
2034
2069
      {
2035
 
        buffer->append(line, (out - line));
 
2070
        g_string_append_len(buffer, line, (gssize) (out - line));
2036
2071
        out= line;
2037
2072
      }
2038
2073
      // Consumed a 2 chars or more, and will add 1 at most,
2061
2096
      }
2062
2097
    }
2063
2098
  }
2064
 
  if (out != line || (buffer->length() > 0))
 
2099
  if (out != line || (buffer->len > 0))
2065
2100
  {
2066
2101
    *out++='\n';
2067
2102
    uint length=(uint) (out-line);
2068
 
    if ((!*ml_comment || preserve_comments))
2069
 
      buffer->append(line, length);
 
2103
    if ((!*ml_comment || preserve_comments)
 
2104
        && (g_string_append_len(buffer, line, length) == NULL))
 
2105
      return(1);
2070
2106
  }
2071
2107
  return(0);
2072
2108
}
2076
2112
******************************************************************/
2077
2113
 
2078
2114
 
2079
 
static char **mysql_completion (const char *text, int start, int end);
2080
2115
static char *new_command_generator(const char *text, int);
 
2116
extern char **new_drizzle_completion (const char *text, int start, int end);
2081
2117
 
2082
2118
/*
2083
2119
  Tell the GNU Readline library how to complete.  We want to try to complete
2084
2120
  on command names if this is the first word in the line, or on filenames
2085
2121
  if not.
2086
2122
*/
2087
 
static char *no_completion(const char * a __attribute__((unused)),
2088
 
                           int b __attribute__((unused)))
 
2123
 
 
2124
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE)
 
2125
extern char *no_completion(const char*,int);
 
2126
#else
 
2127
char *no_completion(void);
 
2128
char *no_completion(void)
2089
2129
{
2090
2130
  /* No filename completion */
2091
2131
  return 0;
2092
2132
}
2093
 
 
 
2133
#endif
2094
2134
 
2095
2135
/* glues pieces of history back together if in pieces   */
2096
 
static void fix_history(string *final_command)
 
2136
static void fix_history(GString *final_command)
2097
2137
{
2098
2138
  int total_lines = 1;
2099
 
  const char *ptr = final_command->c_str();
 
2139
  const char *ptr = final_command->str;
 
2140
  /* Converted buffer */
 
2141
  GString * fixed_buffer;
 
2142
  fixed_buffer = g_string_sized_new(16);
2100
2143
  char str_char = '\0';  /* Character if we are in a string or not */
2101
2144
 
2102
 
  /* Converted buffer */
2103
 
  string fixed_buffer;
2104
 
  fixed_buffer.reserve(512);
2105
 
 
2106
2145
  /* find out how many lines we have and remove newlines */
2107
2146
  while (*ptr != '\0')
2108
2147
  {
2116
2155
        str_char = *ptr;
2117
2156
      else if (str_char == *ptr)   /* close string */
2118
2157
        str_char = '\0';
2119
 
      fixed_buffer.append(ptr, 1);
 
2158
      g_string_append_len(fixed_buffer, ptr, 1);
2120
2159
      break;
2121
2160
    case '\n':
2122
2161
      /*
2123
2162
        not in string, change to space
2124
2163
        if in string, leave it alone
2125
2164
      */
2126
 
      fixed_buffer.append((str_char == '\0') ? " " : "\n");
 
2165
      g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2127
2166
      total_lines++;
2128
2167
      break;
2129
2168
    case '\\':
2130
 
      fixed_buffer.append("\\");
 
2169
      g_string_append_c(fixed_buffer, '\\');
2131
2170
      /* need to see if the backslash is escaping anything */
2132
2171
      if (str_char)
2133
2172
      {
2134
2173
        ptr++;
2135
2174
        /* special characters that need escaping */
2136
2175
        if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2137
 
          fixed_buffer.append(ptr, 1);
 
2176
          g_string_append_len(fixed_buffer, ptr, 1);
2138
2177
        else
2139
2178
          ptr--;
2140
2179
      }
2141
2180
      break;
2142
2181
    default:
2143
 
      fixed_buffer.append(ptr, 1);
 
2182
      g_string_append_len(fixed_buffer, ptr, 1);
2144
2183
    }
2145
2184
    ptr++;
2146
2185
  }
2147
2186
  if (total_lines > 1)
2148
 
    add_history(fixed_buffer.c_str());
 
2187
    add_history(fixed_buffer->str);
2149
2188
}
2150
2189
 
2151
2190
/*
2163
2202
  return 1;
2164
2203
}
2165
2204
 
2166
 
static void initialize_readline (char *name)
 
2205
static void initialize_readline (const char *name)
2167
2206
{
2168
2207
  /* Allow conditional parsing of the ~/.inputrc file. */
2169
2208
  rl_readline_name= name;
2170
2209
 
2171
2210
  /* Tell the completer that we want a crack first. */
2172
 
  rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
 
2211
  rl_attempted_completion_function= (rl_completion_func_t*)&new_drizzle_completion;
2173
2212
  rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
2174
2213
}
2175
2214
 
2176
 
 
2177
2215
/*
2178
2216
  Attempt to complete on the contents of TEXT.  START and END show the
2179
2217
  region of TEXT that contains the word to complete.  We can use the
2180
2218
  entire line in case we want to do some simple parsing.  Return the
2181
2219
  array of matches, or NULL if there aren't any.
2182
2220
*/
2183
 
char **mysql_completion (const char *text,
2184
 
                        int start __attribute__((unused)),
2185
 
                        int end __attribute__((unused)))
 
2221
 
 
2222
char **new_drizzle_completion (const char *text,
 
2223
                             int start __attribute__((unused)),
 
2224
                             int end __attribute__((unused)))
2186
2225
{
2187
2226
  if (!status.batch && !quick)
2188
2227
    return rl_completion_matches(text, new_command_generator);
2190
2229
    return (char**) 0;
2191
2230
}
2192
2231
 
2193
 
 
2194
2232
static char *new_command_generator(const char *text,int state)
2195
2233
{
2196
2234
  static int textlen;
2210
2248
 
2211
2249
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2212
2250
      if (!b)
2213
 
        return NULL;
 
2251
        return NullS;
2214
2252
      e = b->pData;
2215
2253
    }
2216
2254
 
2217
2255
    if (e)
2218
2256
    {
2219
 
      ptr= strdup(e->str);
 
2257
      ptr= g_strdup(e->str);
2220
2258
      e = e->pNext;
2221
2259
      return ptr;
2222
2260
    }
2237
2275
        }
2238
2276
      }
2239
2277
    }
2240
 
    ptr= NULL;
 
2278
    ptr= NullS;
2241
2279
    while (e && !ptr)
2242
2280
    {          /* find valid entry in bucket */
2243
2281
      if ((uint) strlen(e->str) == b->nKeyLength)
2244
 
        ptr = strdup(e->str);
 
2282
        ptr = g_strdup(e->str);
2245
2283
      /* find the next used entry */
2246
2284
      e = e->pNext;
2247
2285
      if (!e)
2266
2304
    if (ptr)
2267
2305
      return ptr;
2268
2306
  }
2269
 
  return NULL;
 
2307
  return NullS;
2270
2308
}
2271
2309
 
2272
2310
 
2328
2366
    {
2329
2367
      if (drizzle_num_rows(tables) > 0 && !opt_silent && write_info)
2330
2368
      {
2331
 
        tee_fprintf(stdout, _("\
 
2369
        tee_fprintf(stdout, "\
2332
2370
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"));
 
2371
You can turn off this feature to get a quicker startup with -A\n\n");
2334
2372
      }
2335
2373
      while ((table_row=drizzle_fetch_row(tables)))
2336
2374
      {
2357
2395
  i=0;
2358
2396
  while ((table_row=drizzle_fetch_row(tables)))
2359
2397
  {
2360
 
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NULL)))
 
2398
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NullS)))
2361
2399
    {
2362
2400
      num_fields=drizzle_num_fields(fields);
2363
2401
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2404
2442
    for (;;)
2405
2443
    {
2406
2444
      if (*s == (char) c) return (char*) s;
2407
 
      if (!*s++) return NULL;
 
2445
      if (!*s++) return NullS;
2408
2446
    }
2409
2447
  }
2410
2448
 
2412
2450
  {
2413
2451
    register char *t;
2414
2452
 
2415
 
    t = NULL;
 
2453
    t = NullS;
2416
2454
    do if (*s == (char) c) t = (char*) s; while (*s++);
2417
2455
    return (char*) t;
2418
2456
  }
2425
2463
  /* purecov: begin tested */
2426
2464
  if (opt_reconnect)
2427
2465
  {
2428
 
    put_info(_("No connection. Trying to reconnect..."),INFO_INFO,0,0);
2429
 
    (void) com_connect((string *)0, 0);
 
2466
    put_info("No connection. Trying to reconnect...",INFO_INFO,0,0);
 
2467
    (void) com_connect((GString *) 0, 0);
2430
2468
    if (opt_rehash)
2431
2469
      com_rehash(NULL, NULL);
2432
2470
  }
2433
2471
  if (!connected)
2434
 
    return put_info(_("Can't connect to the server\n"),INFO_ERROR,0,0);
 
2472
    return put_info("Can't connect to the server\n",INFO_ERROR,0,0);
2435
2473
  /* purecov: end */
2436
2474
  return 0;
2437
2475
}
2440
2478
{
2441
2479
  DRIZZLE_RES *res;
2442
2480
 
2443
 
  free(current_db);
 
2481
  my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
2444
2482
  current_db= NULL;
2445
2483
  /* In case of error below current_db will be NULL */
2446
2484
  if (!drizzle_query(&drizzle, "SELECT DATABASE()") &&
2448
2486
  {
2449
2487
    DRIZZLE_ROW row= drizzle_fetch_row(res);
2450
2488
    if (row[0])
2451
 
      current_db= strdup(row[0]);
 
2489
      current_db= g_strdup(row[0]);
2452
2490
    drizzle_free_result(res);
2453
2491
  }
2454
2492
}
2488
2526
  char ccat= (*cur)[num_cat][0];
2489
2527
  if (*last_char != ccat)
2490
2528
  {
2491
 
    put_info(ccat == 'Y' ? _("categories:") : _("topics:"), INFO_INFO,0,0);
 
2529
    put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO,0,0);
2492
2530
    *last_char= ccat;
2493
2531
  }
2494
2532
  tee_fprintf(PAGER, "   %s\n", (*cur)[num_name]);
2495
2533
}
2496
2534
 
2497
2535
 
2498
 
static int com_server_help(string *buffer,
2499
 
                           const char *line __attribute__((unused)),
 
2536
static int com_server_help(GString *buffer,
 
2537
                           char *line __attribute__((unused)),
2500
2538
                           char *help_arg)
2501
2539
{
2502
2540
  DRIZZLE_ROW cur;
2503
 
  const char *server_cmd= buffer->c_str();
 
2541
  const char *server_cmd= buffer->str;
2504
2542
  char cmd_buf[100];
2505
2543
  DRIZZLE_RES *result;
2506
2544
  int error;
2507
2545
 
2508
2546
  if (help_arg[0] != '\'')
2509
2547
  {
2510
 
    char *end_arg= strchr(help_arg, '\0');
 
2548
    char *end_arg= strend(help_arg);
2511
2549
    if(--end_arg)
2512
2550
    {
2513
2551
      while (my_isspace(charset_info,*end_arg))
2514
2552
        end_arg--;
2515
2553
      *++end_arg= '\0';
2516
2554
    }
2517
 
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NULL);
 
2555
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2518
2556
    server_cmd= cmd_buf;
2519
2557
  }
2520
2558
 
2539
2577
      }
2540
2578
 
2541
2579
      init_pager();
2542
 
      tee_fprintf(PAGER,   _("Name: \'%s\'\n"), cur[0]);
2543
 
      tee_fprintf(PAGER,   _("Description:\n%s"), cur[1]);
 
2580
      tee_fprintf(PAGER,   "Name: \'%s\'\n", cur[0]);
 
2581
      tee_fprintf(PAGER,   "Description:\n%s", cur[1]);
2544
2582
      if (cur[2] && *((char*)cur[2]))
2545
 
        tee_fprintf(PAGER, _("Examples:\n%s"), cur[2]);
 
2583
        tee_fprintf(PAGER, "Examples:\n%s", cur[2]);
2546
2584
      tee_fprintf(PAGER,   "\n");
2547
2585
      end_pager();
2548
2586
    }
2555
2593
 
2556
2594
      if (num_fields == 2)
2557
2595
      {
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);
 
2596
        put_info("Many help items for your request exist.", INFO_INFO,0,0);
 
2597
        put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO,0,0);
2560
2598
        num_name= 0;
2561
2599
        num_cat= 1;
2562
2600
      }
2563
2601
      else if ((cur= drizzle_fetch_row(result)))
2564
2602
      {
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);
 
2603
        tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
 
2604
        put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO,0,0);
2567
2605
        num_name= 1;
2568
2606
        num_cat= 2;
2569
2607
        print_help_item(&cur,1,2,&last_char);
2576
2614
    }
2577
2615
    else
2578
2616
    {
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);
 
2617
      put_info("\nNothing found", INFO_INFO,0,0);
 
2618
      put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO,0,0);
2581
2619
    }
2582
2620
  }
2583
2621
 
2587
2625
}
2588
2626
 
2589
2627
static int
2590
 
com_help(string *buffer __attribute__((unused)),
2591
 
         const char *line __attribute__((unused)))
 
2628
com_help(GString *buffer __attribute__((unused)),
 
2629
         char *line __attribute__((unused)))
2592
2630
{
2593
2631
  register int i, j;
2594
2632
  char * help_arg= strchr(line,' '), buff[32], *end;
2596
2634
  {
2597
2635
    while (my_isspace(charset_info,*help_arg))
2598
2636
      help_arg++;
2599
 
    if (*help_arg) return com_server_help(buffer,line,help_arg);
 
2637
    if (*help_arg)
 
2638
      return com_server_help(buffer,line,help_arg);
2600
2639
  }
2601
2640
 
2602
 
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
 
2641
  put_info("List of all Drizzle commands:", INFO_INFO,0,0);
2603
2642
  if (!named_cmds)
2604
 
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
 
2643
    put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO,0,0);
2605
2644
  for (i = 0; commands[i].name; i++)
2606
2645
  {
2607
 
    end= my_stpcpy(buff, commands[i].name);
 
2646
    end= strmov(buff, commands[i].name);
2608
2647
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2609
 
      end= my_stpcpy(end, " ");
 
2648
      end= strmov(end, " ");
2610
2649
    if (commands[i].func)
2611
2650
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2612
 
                  commands[i].cmd_char, _(commands[i].doc));
 
2651
                  commands[i].cmd_char, commands[i].doc);
2613
2652
  }
2614
2653
  if (connected && drizzle_get_server_version(&drizzle) >= 40100)
2615
 
    put_info(_("\nFor server side help, type 'help contents'\n"), INFO_INFO,0,0);
 
2654
    put_info("\nFor server side help, type 'help contents'\n", INFO_INFO,0,0);
2616
2655
  return 0;
2617
2656
}
2618
2657
 
2619
2658
 
2620
2659
static int
2621
 
com_clear(string *buffer,
2622
 
          const char *line __attribute__((unused)))
 
2660
com_clear(GString *buffer,char *line __attribute__((unused)))
2623
2661
{
2624
2662
  if (status.add_to_history)
2625
2663
    fix_history(buffer);
2626
 
  buffer->clear();
 
2664
  g_string_truncate(buffer, 0);
2627
2665
  return 0;
2628
2666
}
2629
2667
 
 
2668
static int
 
2669
com_charset(GString *buffer __attribute__((unused)), char *line)
 
2670
{
 
2671
  char buff[256], *param;
 
2672
  CHARSET_INFO * new_cs;
 
2673
  strmake(buff, line, sizeof(buff) - 1);
 
2674
  param= get_arg(buff, 0);
 
2675
  if (!param || !*param)
 
2676
  {
 
2677
    return put_info("Usage: \\C char_setname | charset charset_name",
 
2678
                    INFO_ERROR, 0, 0);
 
2679
  }
 
2680
  new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
 
2681
  if (new_cs)
 
2682
  {
 
2683
    charset_info= new_cs;
 
2684
    drizzle_set_character_set(&drizzle, charset_info->csname);
 
2685
    default_charset= (char *)charset_info->csname;
 
2686
    default_charset_used= 1;
 
2687
    put_info("Charset changed", INFO_INFO,0,0);
 
2688
  }
 
2689
  else put_info("Charset is not found", INFO_INFO,0,0);
 
2690
  return 0;
 
2691
}
2630
2692
 
2631
2693
/*
2632
2694
  Execute command
2635
2697
  1  if fatal error
2636
2698
*/
2637
2699
static int
2638
 
com_go(string *buffer,
2639
 
       const char *line __attribute__((unused)))
 
2700
com_go(GString *buffer,
 
2701
       char *line __attribute__((unused)))
2640
2702
{
2641
2703
  char          buff[200]; /* about 110 chars used so far */
2642
2704
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2643
2705
  DRIZZLE_RES     *result;
2644
 
  uint32_t         timer, warnings= 0;
 
2706
  ulong         timer, warnings= 0;
2645
2707
  uint          error= 0;
2646
2708
  int           err= 0;
2647
2709
 
2650
2712
  /* Remove garbage for nicer messages */
2651
2713
  remove_cntrl(buffer);
2652
2714
 
2653
 
  if (buffer->empty())
 
2715
  if (buffer->len == 0)
2654
2716
  {
2655
2717
    // Ignore empty quries
2656
2718
    if (status.batch)
2657
2719
      return 0;
2658
 
    return put_info(_("No query specified\n"),INFO_ERROR,0,0);
 
2720
    return put_info("No query specified\n",INFO_ERROR,0,0);
2659
2721
 
2660
2722
  }
2661
2723
  if (!connected && reconnect())
2662
2724
  {
2663
2725
    // Remove query on error
2664
 
    buffer->clear();
 
2726
    g_string_truncate(buffer, 0);
2665
2727
    return opt_reconnect ? -1 : 1;          // Fatal error
2666
2728
  }
2667
2729
  if (verbose)
2668
2730
    (void) com_print(buffer, 0);
2669
2731
 
2670
2732
  if (skip_updates &&
2671
 
      ((buffer->length() < 4) || (buffer->find( "SET ") != 0)))
 
2733
      ((buffer->len < 4)
 
2734
      || g_string_equal(g_string_new_len(buffer->str,4),
 
2735
                        g_string_new("SET "))))
2672
2736
  {
2673
 
    (void) put_info(_("Ignoring query to other database"),INFO_INFO,0,0);
 
2737
    (void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2674
2738
    return 0;
2675
2739
  }
2676
2740
 
2677
2741
  timer=start_timer();
2678
2742
  executing_query= 1;
2679
 
  error= drizzle_real_query_for_lazy(buffer->c_str(),buffer->length());
 
2743
  error= drizzle_real_query_for_lazy(buffer->str,buffer->len);
2680
2744
 
2681
2745
  if (status.add_to_history)
2682
2746
  {
2683
 
    buffer->append(vertical ? "\\G" : delimiter);
 
2747
    g_string_append(buffer, vertical ? "\\G" : delimiter);
2684
2748
    /* Append final command onto history */
2685
2749
    fix_history(buffer);
2686
2750
  }
2687
2751
 
2688
 
  buffer->clear();
 
2752
  g_string_truncate(buffer, 0);
2689
2753
 
2690
2754
  if (error)
2691
2755
    goto end;
2719
2783
    {
2720
2784
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
2721
2785
      {
2722
 
        my_stpcpy(buff, _("Empty set"));
 
2786
        strmov(buff, "Empty set");
 
2787
        if (opt_xml)
 
2788
        {
 
2789
          /*
 
2790
            We must print XML header and footer
 
2791
            to produce a well-formed XML even if
 
2792
            the result set is empty (Bug#27608).
 
2793
          */
 
2794
          init_pager();
 
2795
          print_table_data_xml(result);
 
2796
          end_pager();
 
2797
        }
2723
2798
      }
2724
2799
      else
2725
2800
      {
2726
2801
        init_pager();
2727
 
        if (vertical || (auto_vertical_output &&
2728
 
                         (terminal_width < get_result_width(result))))
 
2802
        if (opt_html)
 
2803
          print_table_data_html(result);
 
2804
        else if (opt_xml)
 
2805
          print_table_data_xml(result);
 
2806
        else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
2729
2807
          print_table_data_vertically(result);
2730
2808
        else if (opt_silent && verbose <= 2 && !output_tables)
2731
2809
          print_tab_data(result);
2732
2810
        else
2733
2811
          print_table_data(result);
2734
 
        sprintf(buff,
2735
 
                ngettext("%ld row in set","%ld rows in set",
2736
 
                         (long) drizzle_num_rows(result)),
2737
 
                (long) drizzle_num_rows(result));
 
2812
        sprintf(buff,"%ld %s in set",
 
2813
                (long) drizzle_num_rows(result),
 
2814
                (long) drizzle_num_rows(result) == 1 ? "row" : "rows");
2738
2815
        end_pager();
2739
2816
        if (drizzle_errno(&drizzle))
2740
2817
          error= put_error(&drizzle);
2741
2818
      }
2742
2819
    }
2743
2820
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2744
 
      my_stpcpy(buff,_("Query OK"));
 
2821
      strmov(buff,"Query OK");
2745
2822
    else
2746
 
      sprintf(buff, ngettext("Query OK, %ld row affected",
2747
 
                             "Query OK, %ld rows affected",
2748
 
                             (long) drizzle_affected_rows(&drizzle)),
2749
 
              (long) drizzle_affected_rows(&drizzle));
 
2823
      sprintf(buff,"Query OK, %ld %s affected",
 
2824
              (long) drizzle_affected_rows(&drizzle),
 
2825
              (long) drizzle_affected_rows(&drizzle) == 1 ? "row" : "rows");
2750
2826
 
2751
 
    pos= strchr(buff, '\0');
 
2827
    pos=strend(buff);
2752
2828
    if ((warnings= drizzle_warning_count(&drizzle)))
2753
2829
    {
2754
2830
      *pos++= ',';
2755
2831
      *pos++= ' ';
2756
2832
      pos=int10_to_str(warnings, pos, 10);
2757
 
      pos=my_stpcpy(pos, " warning");
 
2833
      pos=strmov(pos, " warning");
2758
2834
      if (warnings != 1)
2759
2835
        *pos++= 's';
2760
2836
    }
2761
 
    my_stpcpy(pos, time_buff);
 
2837
    strmov(pos, time_buff);
2762
2838
    put_info(buff,INFO_RESULT,0,0);
2763
2839
    if (drizzle_info(&drizzle))
2764
2840
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
2837
2913
 
2838
2914
 
2839
2915
static int
2840
 
com_ego(string *buffer,const char *line)
 
2916
com_ego(GString *buffer,char *line)
2841
2917
{
2842
2918
  int result;
2843
2919
  bool oldvertical=vertical;
2851
2927
static const char *fieldtype2str(enum enum_field_types type)
2852
2928
{
2853
2929
  switch (type) {
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";
2866
 
    case DRIZZLE_TYPE_VIRTUAL:     return "VIRTUAL";
 
2930
    case MYSQL_TYPE_BLOB:        return "BLOB";
 
2931
    case MYSQL_TYPE_NEWDATE:        return "DATE";
 
2932
    case MYSQL_TYPE_DATETIME:    return "DATETIME";
 
2933
    case MYSQL_TYPE_NEWDECIMAL:  return "DECIMAL";
 
2934
    case MYSQL_TYPE_DOUBLE:      return "DOUBLE";
 
2935
    case MYSQL_TYPE_ENUM:        return "ENUM";
 
2936
    case MYSQL_TYPE_LONG:        return "LONG";
 
2937
    case MYSQL_TYPE_LONGLONG:    return "LONGLONG";
 
2938
    case MYSQL_TYPE_NULL:        return "NULL";
 
2939
    case MYSQL_TYPE_SET:         return "SET";
 
2940
    case MYSQL_TYPE_SHORT:       return "SHORT";
 
2941
    case MYSQL_TYPE_STRING:      return "STRING";
 
2942
    case MYSQL_TYPE_TIME:        return "TIME";
 
2943
    case MYSQL_TYPE_TIMESTAMP:   return "TIMESTAMP";
 
2944
    case MYSQL_TYPE_TINY:        return "TINY";
 
2945
    case MYSQL_TYPE_VAR_STRING:  return "VAR_STRING";
 
2946
    case MYSQL_TYPE_YEAR:        return "YEAR";
2867
2947
    default:                     return "?-unknown-?";
2868
2948
  }
2869
2949
}
2873
2953
  char *s=buf;
2874
2954
  *s=0;
2875
2955
#define ff2s_check_flag(X)                                              \
2876
 
  if (f & X ## _FLAG) { s=my_stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2956
  if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
2877
2957
  ff2s_check_flag(NOT_NULL);
2878
2958
  ff2s_check_flag(PRI_KEY);
2879
2959
  ff2s_check_flag(UNIQUE_KEY);
2880
2960
  ff2s_check_flag(MULTIPLE_KEY);
2881
2961
  ff2s_check_flag(BLOB);
2882
2962
  ff2s_check_flag(UNSIGNED);
 
2963
  ff2s_check_flag(ZEROFILL);
2883
2964
  ff2s_check_flag(BINARY);
2884
2965
  ff2s_check_flag(ENUM);
2885
2966
  ff2s_check_flag(AUTO_INCREMENT);
2931
3012
static void
2932
3013
print_table_data(DRIZZLE_RES *result)
2933
3014
{
 
3015
  GString       *separator = g_string_sized_new(256);
2934
3016
  DRIZZLE_ROW     cur;
2935
3017
  DRIZZLE_FIELD   *field;
2936
3018
  bool          *num_flag;
2937
 
  string separator;
2938
 
  
2939
 
  separator.reserve(256);
2940
3019
 
2941
3020
  num_flag=(bool*) my_malloc(sizeof(bool)*drizzle_num_fields(result),
2942
3021
                             MYF(MY_WME));
2947
3026
      return;
2948
3027
    drizzle_field_seek(result,0);
2949
3028
  }
2950
 
  separator.append("+");
 
3029
  separator = g_string_append_c(separator, '+');
2951
3030
  while ((field = drizzle_fetch_field(result)))
2952
3031
  {
2953
 
    uint32_t length= column_names ? field->name_length : 0;
 
3032
    uint length= column_names ? field->name_length : 0;
2954
3033
    if (quick)
2955
3034
      length=max(length,field->length);
2956
3035
    else
2957
3036
      length=max(length,field->max_length);
2958
 
    if (length < 4 && !(field->flags & NOT_NULL_FLAG))
 
3037
    if (length < 4 && !IS_NOT_NULL(field->flags))
2959
3038
      // Room for "NULL"
2960
3039
      length=4;
2961
3040
    field->max_length=length;
2962
3041
    uint x;
2963
3042
    for (x=0; x< (length+2); x++)
2964
 
      separator.append("-");
2965
 
    separator.append("+");
 
3043
      g_string_append_c(separator, '-');
 
3044
    g_string_append_c(separator, '+');
2966
3045
  }
 
3046
  // End marker for \0
 
3047
  // TODO: Huh? Do we need this with GString?
 
3048
  g_string_append_c(separator, '\0');
2967
3049
 
2968
 
  tee_puts((char*) separator.c_str(), PAGER);
 
3050
  tee_puts((char*) separator->str, PAGER);
2969
3051
  if (column_names)
2970
3052
  {
2971
3053
    drizzle_field_seek(result,0);
2976
3058
      uint numcells= charset_info->cset->numcells(charset_info,
2977
3059
                                                  field->name,
2978
3060
                                                  field->name + name_length);
2979
 
      uint32_t display_length= field->max_length + name_length - numcells;
 
3061
      uint display_length= field->max_length + name_length - numcells;
2980
3062
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
2981
3063
                                             MAX_COLUMN_LENGTH),
2982
3064
                  field->name);
2983
 
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) || 
2984
 
                      (field->type == DRIZZLE_TYPE_NEWDECIMAL));
 
3065
      num_flag[off]= IS_NUM(field->type);
2985
3066
    }
2986
3067
    (void) tee_fputs("\n", PAGER);
2987
 
    tee_puts((char*) separator.c_str(), PAGER);
 
3068
    tee_puts((char*) separator->str, PAGER);
2988
3069
  }
2989
3070
 
2990
3071
  while ((cur= drizzle_fetch_row(result)))
3041
3122
    }
3042
3123
    (void) tee_fputs("\n", PAGER);
3043
3124
  }
3044
 
  tee_puts(separator.c_str(), PAGER);
3045
 
  free(num_flag);
 
3125
  tee_puts(separator->str, PAGER);
 
3126
  my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
3046
3127
}
3047
3128
 
3048
3129
/**
3070
3151
  else
3071
3152
    length= max(length, field->max_length);
3072
3153
 
3073
 
  if (length < 4 && !(field->flags & NOT_NULL_FLAG))
 
3154
  if (length < 4 && !IS_NOT_NULL(field->flags))
3074
3155
    length= 4;        /* Room for "NULL" */
3075
3156
 
3076
3157
  return length;
3132
3213
 
3133
3214
 
3134
3215
static void
 
3216
print_table_data_html(DRIZZLE_RES *result)
 
3217
{
 
3218
  DRIZZLE_ROW  cur;
 
3219
  DRIZZLE_FIELD  *field;
 
3220
 
 
3221
  drizzle_field_seek(result,0);
 
3222
  (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
 
3223
  if (column_names)
 
3224
  {
 
3225
    while((field = drizzle_fetch_field(result)))
 
3226
    {
 
3227
      tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
 
3228
                                         (field->name[0] ? field->name :
 
3229
                                          " &nbsp; ") : "NULL"));
 
3230
    }
 
3231
    (void) tee_fputs("</TR>", PAGER);
 
3232
  }
 
3233
  while ((cur = drizzle_fetch_row(result)))
 
3234
  {
 
3235
    if (interrupted_query)
 
3236
      break;
 
3237
    uint32_t *lengths=drizzle_fetch_lengths(result);
 
3238
    (void) tee_fputs("<TR>", PAGER);
 
3239
    for (uint32_t i= 0; i < drizzle_num_fields(result); i++)
 
3240
    {
 
3241
      (void) tee_fputs("<TD>", PAGER);
 
3242
      safe_put_field(cur[i],lengths[i]);
 
3243
      (void) tee_fputs("</TD>", PAGER);
 
3244
    }
 
3245
    (void) tee_fputs("</TR>", PAGER);
 
3246
  }
 
3247
  (void) tee_fputs("</TABLE>", PAGER);
 
3248
}
 
3249
 
 
3250
 
 
3251
static void
 
3252
print_table_data_xml(DRIZZLE_RES *result)
 
3253
{
 
3254
  DRIZZLE_ROW   cur;
 
3255
  DRIZZLE_FIELD *fields;
 
3256
 
 
3257
  drizzle_field_seek(result,0);
 
3258
 
 
3259
  tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
 
3260
  xmlencode_print(glob_buffer->str, glob_buffer->len);
 
3261
  tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
 
3262
            PAGER);
 
3263
 
 
3264
  fields = drizzle_fetch_fields(result);
 
3265
  while ((cur = drizzle_fetch_row(result)))
 
3266
  {
 
3267
    if (interrupted_query)
 
3268
      break;
 
3269
    uint32_t *lengths=drizzle_fetch_lengths(result);
 
3270
    (void) tee_fputs("\n  <row>\n", PAGER);
 
3271
    for (uint i=0; i < drizzle_num_fields(result); i++)
 
3272
    {
 
3273
      tee_fprintf(PAGER, "\t<field name=\"");
 
3274
      xmlencode_print(fields[i].name, (uint) strlen(fields[i].name));
 
3275
      if (cur[i])
 
3276
      {
 
3277
        tee_fprintf(PAGER, "\">");
 
3278
        xmlencode_print(cur[i], lengths[i]);
 
3279
        tee_fprintf(PAGER, "</field>\n");
 
3280
      }
 
3281
      else
 
3282
        tee_fprintf(PAGER, "\" xsi:nil=\"true\" />\n");
 
3283
    }
 
3284
    (void) tee_fputs("  </row>\n", PAGER);
 
3285
  }
 
3286
  (void) tee_fputs("</resultset>\n", PAGER);
 
3287
}
 
3288
 
 
3289
 
 
3290
static void
3135
3291
print_table_data_vertically(DRIZZLE_RES *result)
3136
3292
{
3137
3293
  DRIZZLE_ROW  cur;
3209
3365
}
3210
3366
 
3211
3367
 
3212
 
static void
3213
 
safe_put_field(const char *pos,uint32_t length)
 
3368
static const char *array_value(const char **array, char key)
 
3369
{
 
3370
  for (; *array; array+= 2)
 
3371
    if (**array == key)
 
3372
      return array[1];
 
3373
  return 0;
 
3374
}
 
3375
 
 
3376
 
 
3377
static void
 
3378
xmlencode_print(const char *src, uint length)
 
3379
{
 
3380
  if (!src)
 
3381
    tee_fputs("NULL", PAGER);
 
3382
  else
 
3383
  {
 
3384
    for (const char *p = src; *p && length; length--)
 
3385
    {
 
3386
      const char *t;
 
3387
      if ((t = array_value(xmlmeta, *p++)))
 
3388
        tee_fputs(t, PAGER);
 
3389
      else
 
3390
        tee_putc(*p, PAGER);
 
3391
    }
 
3392
  }
 
3393
}
 
3394
 
 
3395
 
 
3396
static void
 
3397
safe_put_field(const char *pos,ulong length)
3214
3398
{
3215
3399
  if (!pos)
3216
3400
    tee_fputs("NULL", PAGER);
3278
3462
}
3279
3463
 
3280
3464
static int
3281
 
com_tee(string *buffer __attribute__((unused)), const char *line )
 
3465
com_tee(GString *buffer __attribute__((__unused__)), char *line )
3282
3466
{
3283
3467
  char file_name[FN_REFLEN], *end, *param;
3284
3468
 
3322
3506
 
3323
3507
 
3324
3508
static int
3325
 
com_notee(string *buffer __attribute__((unused)),
3326
 
          const char *line __attribute__((unused)))
 
3509
com_notee(GString *buffer __attribute__((unused)),
 
3510
          char *line __attribute__((unused)))
3327
3511
{
3328
3512
  if (opt_outfile)
3329
3513
    end_tee();
3336
3520
*/
3337
3521
 
3338
3522
static int
3339
 
com_pager(string *buffer __attribute__((unused)),
3340
 
          const char *line __attribute__((unused)))
 
3523
com_pager(GString *buffer __attribute__((__unused__)),
 
3524
          char *line __attribute__((unused)))
3341
3525
{
3342
3526
  char pager_name[FN_REFLEN], *end, *param;
3343
3527
 
3357
3541
    {
3358
3542
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3359
3543
      opt_nopager=1;
3360
 
      my_stpcpy(pager, "stdout");
 
3544
      strmov(pager, "stdout");
3361
3545
      PAGER= stdout;
3362
3546
      return 0;
3363
3547
    }
3364
 
    my_stpcpy(pager, default_pager);
 
3548
    strmov(pager, default_pager);
3365
3549
  }
3366
3550
  else
3367
3551
  {
3370
3554
                                my_iscntrl(charset_info,end[-1])))
3371
3555
      end--;
3372
3556
    end[0]=0;
3373
 
    my_stpcpy(pager, pager_name);
3374
 
    my_stpcpy(default_pager, pager_name);
 
3557
    strmov(pager, pager_name);
 
3558
    strmov(default_pager, pager_name);
3375
3559
  }
3376
3560
  opt_nopager=0;
3377
3561
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3380
3564
 
3381
3565
 
3382
3566
static int
3383
 
com_nopager(string *buffer __attribute__((unused)),
3384
 
            const char *line __attribute__((unused)))
 
3567
com_nopager(GString *buffer __attribute__((unused)),
 
3568
            char *line __attribute__((unused)))
3385
3569
{
3386
 
  my_stpcpy(pager, "stdout");
 
3570
  strmov(pager, "stdout");
3387
3571
  opt_nopager=1;
3388
3572
  PAGER= stdout;
3389
3573
  tee_fprintf(stdout, "PAGER set to stdout\n");
3393
3577
/* If arg is given, exit without errors. This happens on command 'quit' */
3394
3578
 
3395
3579
static int
3396
 
com_quit(string *buffer __attribute__((unused)),
3397
 
         const char *line __attribute__((unused)))
 
3580
com_quit(GString *buffer __attribute__((unused)),
 
3581
         char *line __attribute__((unused)))
3398
3582
{
3399
3583
  /* let the screen auto close on a normal shutdown */
3400
3584
  status.exit_status=0;
3402
3586
}
3403
3587
 
3404
3588
static int
3405
 
com_rehash(string *buffer __attribute__((unused)),
3406
 
           const char *line __attribute__((unused)))
 
3589
com_rehash(GString *buffer __attribute__((unused)),
 
3590
           char *line __attribute__((unused)))
3407
3591
{
3408
3592
  build_completion_hash(1, 0);
3409
3593
  return 0;
3412
3596
 
3413
3597
 
3414
3598
static int
3415
 
com_print(string *buffer,const char *line __attribute__((unused)))
 
3599
com_print(GString *buffer,char *line __attribute__((unused)))
3416
3600
{
3417
3601
  tee_puts("--------------", stdout);
3418
 
  (void) tee_fputs(buffer->c_str(), stdout);
3419
 
  if ( (buffer->length() == 0)
3420
 
       || (buffer->c_str())[(buffer->length())-1] != '\n')
 
3602
  (void) tee_fputs(buffer->str, stdout);
 
3603
  if ( (buffer->len == 0)
 
3604
       || (buffer->str)[(buffer->len)-1] != '\n')
3421
3605
    tee_putc('\n', stdout);
3422
3606
  tee_puts("--------------\n", stdout);
3423
3607
  /* If empty buffer */
3426
3610
 
3427
3611
/* ARGSUSED */
3428
3612
static int
3429
 
com_connect(string *buffer, const char *line)
 
3613
com_connect(GString *buffer, char *line)
3430
3614
{
3431
3615
  char *tmp, buff[256];
3432
3616
  bool save_rehash= opt_rehash;
3433
3617
  int error;
3434
3618
 
3435
 
  memset(buff, 0, sizeof(buff));
 
3619
  bzero(buff, sizeof(buff));
3436
3620
  if (buffer)
3437
3621
  {
3438
3622
    /*
3446
3630
    tmp= get_arg(buff, 0);
3447
3631
    if (tmp && *tmp)
3448
3632
    {
3449
 
      free(current_db);
3450
 
      current_db= strdup(tmp);
 
3633
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
 
3634
      current_db= g_strdup(tmp);
3451
3635
      tmp= get_arg(buff, 1);
3452
3636
      if (tmp)
3453
3637
      {
3454
 
        free(current_host);
3455
 
        current_host=strdup(tmp);
 
3638
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
3639
        current_host=g_strdup(tmp);
3456
3640
      }
3457
3641
    }
3458
3642
    else
3462
3646
    }
3463
3647
    // command used
3464
3648
    assert(buffer!=NULL);
3465
 
    buffer->clear();
 
3649
    g_string_truncate(buffer, 0);
3466
3650
  }
3467
3651
  else
3468
3652
    opt_rehash= 0;
3481
3665
}
3482
3666
 
3483
3667
 
3484
 
static int com_source(string *buffer __attribute__((unused)), const char *line)
 
3668
static int com_source(GString *buffer __attribute__((__unused__)), char *line)
3485
3669
{
3486
3670
  char source_name[FN_REFLEN], *end, *param;
3487
3671
  LINE_BUFFER *line_buff;
3504
3688
  end[0]=0;
3505
3689
  unpack_filename(source_name,source_name);
3506
3690
  /* open file name */
3507
 
  if (!(sql_file = my_fopen(source_name, O_RDONLY,MYF(0))))
 
3691
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
3508
3692
  {
3509
3693
    char buff[FN_REFLEN+60];
3510
3694
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3519
3703
 
3520
3704
  /* Save old status */
3521
3705
  old_status=status;
3522
 
  memset(&status, 0, sizeof(status));
 
3706
  bfill((char*) &status,sizeof(status),(char) 0);
3523
3707
 
3524
3708
  // Run in batch mode
3525
3709
  status.batch=old_status.batch;
3527
3711
  status.file_name=source_name;
3528
3712
  // Empty command buffer
3529
3713
  assert(glob_buffer!=NULL);
3530
 
  glob_buffer->clear();
 
3714
  g_string_truncate(glob_buffer, 0);
3531
3715
  error= read_and_execute(false);
3532
3716
  // Continue as before
3533
3717
  status=old_status;
3539
3723
 
3540
3724
/* ARGSUSED */
3541
3725
static int
3542
 
com_delimiter(string *buffer __attribute__((unused)), const char *line)
 
3726
com_delimiter(GString *buffer __attribute__((unused)), char *line)
3543
3727
{
3544
3728
  char buff[256], *tmp;
3545
3729
 
3569
3753
 
3570
3754
/* ARGSUSED */
3571
3755
static int
3572
 
com_use(string *buffer __attribute__((unused)), const char *line)
 
3756
com_use(GString *buffer __attribute__((unused)), char *line)
3573
3757
{
3574
3758
  char *tmp, buff[FN_REFLEN + 1];
3575
3759
  int select_db;
3576
3760
 
3577
 
  memset(buff, 0, sizeof(buff));
 
3761
  bzero(buff, sizeof(buff));
3578
3762
  strmake(buff, line, sizeof(buff) - 1);
3579
3763
  tmp= get_arg(buff, 0);
3580
3764
  if (!tmp || !*tmp)
3630
3814
      if (drizzle_select_db(&drizzle,tmp))
3631
3815
        return put_error(&drizzle);
3632
3816
    }
3633
 
    free(current_db);
3634
 
    current_db= strdup(tmp);
 
3817
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
3818
    current_db=g_strdup(tmp);
3635
3819
    if (select_db > 1)
3636
3820
      build_completion_hash(opt_rehash, 1);
3637
3821
  }
3641
3825
}
3642
3826
 
3643
3827
static int
3644
 
com_warnings(string *buffer __attribute__((unused)),
3645
 
             const char *line __attribute__((unused)))
 
3828
com_warnings(GString *buffer __attribute__((unused)),
 
3829
             char *line __attribute__((unused)))
3646
3830
{
3647
3831
  show_warnings = 1;
3648
3832
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3650
3834
}
3651
3835
 
3652
3836
static int
3653
 
com_nowarnings(string *buffer __attribute__((unused)),
3654
 
               const char *line __attribute__((unused)))
 
3837
com_nowarnings(GString *buffer __attribute__((unused)),
 
3838
               char *line __attribute__((unused)))
3655
3839
{
3656
3840
  show_warnings = 0;
3657
3841
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3693
3877
        ptr++;
3694
3878
  }
3695
3879
  if (!*ptr)
3696
 
    return NULL;
 
3880
    return NullS;
3697
3881
  while (my_isspace(charset_info, *ptr))
3698
3882
    ptr++;
3699
3883
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
3707
3891
    if (*ptr == '\\' && ptr[1]) // escaped character
3708
3892
    {
3709
3893
      // Remove the backslash
3710
 
      my_stpcpy(ptr, ptr+1);
 
3894
      strmov(ptr, ptr+1);
3711
3895
    }
3712
3896
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3713
3897
    {
3716
3900
    }
3717
3901
  }
3718
3902
  valid_arg= ptr != start;
3719
 
  return valid_arg ? start : NULL;
 
3903
  return valid_arg ? start : NullS;
3720
3904
}
3721
3905
 
3722
3906
 
3729
3913
    connected= 0;
3730
3914
    drizzle_close(&drizzle);
3731
3915
  }
3732
 
  drizzle_create(&drizzle);
 
3916
  drizzle_init(&drizzle);
3733
3917
  if (opt_connect_timeout)
3734
3918
  {
3735
3919
    uint timeout=opt_connect_timeout;
3737
3921
                  (char*) &timeout);
3738
3922
  }
3739
3923
  if (opt_compress)
3740
 
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
3924
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NullS);
3741
3925
  if (opt_secure_auth)
3742
3926
    drizzle_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3743
3927
  if (using_opt_local_infile)
3744
3928
    drizzle_options(&drizzle,DRIZZLE_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
 
3929
  if (opt_protocol)
 
3930
    drizzle_options(&drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
3745
3931
  if (safe_updates)
3746
3932
  {
3747
3933
    char init_command[100];
3751
3937
            select_limit, max_join_size);
3752
3938
    drizzle_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
3753
3939
  }
 
3940
  if (default_charset_used)
 
3941
    drizzle_options(&drizzle, DRIZZLE_SET_CHARSET_NAME, default_charset);
3754
3942
  if (!drizzle_connect(&drizzle, host, user, password,
3755
3943
                          database, opt_drizzle_port, opt_drizzle_unix_port,
3756
3944
                          connect_flag | CLIENT_MULTI_STATEMENTS))
3773
3961
 
3774
3962
 
3775
3963
static int
3776
 
com_status(string *buffer __attribute__((unused)),
3777
 
           const char *line __attribute__((unused)))
 
3964
com_status(GString *buffer __attribute__((unused)),
 
3965
           char *line __attribute__((unused)))
3778
3966
{
 
3967
  const char *status_str;
3779
3968
  char buff[40];
3780
3969
  uint64_t id;
3781
3970
  DRIZZLE_RES *result;
3838
4027
    }
3839
4028
    drizzle_free_result(result);
3840
4029
  }
 
4030
  else
 
4031
  {
 
4032
    /* Probably pre-4.1 server */
 
4033
    tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname);
 
4034
    tee_fprintf(stdout, "Server characterset:\t%s\n", drizzle.charset->csname);
 
4035
  }
3841
4036
 
 
4037
#ifndef EMBEDDED_LIBRARY
3842
4038
  if (strstr(drizzle_get_host_info(&drizzle),"TCP/IP") || ! drizzle.unix_socket)
3843
4039
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle.port);
3844
4040
  else
3845
4041
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle.unix_socket);
3846
4042
  if (drizzle.net.compress)
3847
4043
    tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
 
4044
#endif
3848
4045
 
 
4046
  if ((status_str= drizzle_stat(&drizzle)) && !drizzle_error(&drizzle)[0])
 
4047
  {
 
4048
    ulong sec;
 
4049
    const char *pos= strchr(status_str,' ');
 
4050
    /* print label */
 
4051
    tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str);
 
4052
    if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec)))
 
4053
    {
 
4054
      nice_time((double) sec,buff,0);
 
4055
      tee_puts(buff, stdout);      /* print nice time */
 
4056
      while (*status_str == ' ')
 
4057
        status_str++;  /* to next info */
 
4058
      tee_putc('\n', stdout);
 
4059
      tee_puts(status_str, stdout);
 
4060
    }
 
4061
  }
3849
4062
  if (safe_updates)
3850
4063
  {
3851
4064
    vidattr(A_BOLD);
3873
4086
    char *bufp = buf;
3874
4087
    DRIZZLE_RES *result;
3875
4088
 
3876
 
    bufp= my_stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
 
4089
    bufp= strnmov(buf, drizzle_get_server_info(con), sizeof buf);
3877
4090
 
3878
4091
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3879
4092
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3882
4095
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
3883
4096
      if (cur && cur[0])
3884
4097
      {
3885
 
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NULL);
 
4098
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
3886
4099
      }
3887
4100
      drizzle_free_result(result);
3888
4101
    }
3975
4188
}
3976
4189
 
3977
4190
 
3978
 
static void remove_cntrl(string *buffer)
 
4191
static void remove_cntrl(GString *buffer)
3979
4192
{
3980
 
  const char *start=  buffer->c_str();
3981
 
  const char *end= start + (buffer->length());
 
4193
  char *start=  buffer->str;
 
4194
  char *end= start + (buffer->len);
3982
4195
  while (start < end && !my_isgraph(charset_info,end[-1]))
3983
4196
    end--;
3984
 
  uint pos_to_truncate= (end-start);
3985
 
  if (buffer->length() > pos_to_truncate)
3986
 
    buffer->erase(pos_to_truncate);
 
4197
  uint chars_to_truncate = end-start;
 
4198
  if (buffer->len > chars_to_truncate)
 
4199
    g_string_truncate(buffer, chars_to_truncate);
3987
4200
}
3988
4201
 
3989
4202
 
4036
4249
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
4037
4250
#endif
4038
4251
 
4039
 
static uint32_t start_timer(void)
 
4252
static ulong start_timer(void)
4040
4253
{
4041
4254
  struct tms tms_tmp;
4042
4255
  return times(&tms_tmp);
4044
4257
 
4045
4258
 
4046
4259
/**
4047
 
   Write as many as 52+1 bytes to buff, in the form of a legible
4048
 
   duration of time.
 
4260
   Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
4049
4261
 
4050
4262
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
4051
4263
*/
4052
4264
static void nice_time(double sec,char *buff,bool part_second)
4053
4265
{
4054
 
  uint32_t tmp;
 
4266
  ulong tmp;
4055
4267
  if (sec >= 3600.0*24)
4056
4268
  {
4057
 
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4269
    tmp=(ulong) floor(sec/(3600.0*24));
4058
4270
    sec-=3600.0*24*tmp;
4059
4271
    buff=int10_to_str((long) tmp, buff, 10);
4060
 
    buff=my_stpcpy(buff,tmp > 1 ? " days " : " day ");
 
4272
    buff=strmov(buff,tmp > 1 ? " days " : " day ");
4061
4273
  }
4062
4274
  if (sec >= 3600.0)
4063
4275
  {
4064
 
    tmp=(uint32_t) floor(sec/3600.0);
 
4276
    tmp=(ulong) floor(sec/3600.0);
4065
4277
    sec-=3600.0*tmp;
4066
4278
    buff=int10_to_str((long) tmp, buff, 10);
4067
 
    buff=my_stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
4279
    buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
4068
4280
  }
4069
4281
  if (sec >= 60.0)
4070
4282
  {
4071
 
    tmp=(uint32_t) floor(sec/60.0);
 
4283
    tmp=(ulong) floor(sec/60.0);
4072
4284
    sec-=60.0*tmp;
4073
4285
    buff=int10_to_str((long) tmp, buff, 10);
4074
 
    buff=my_stpcpy(buff," min ");
 
4286
    buff=strmov(buff," min ");
4075
4287
  }
4076
4288
  if (part_second)
4077
4289
    sprintf(buff,"%.2f sec",sec);
4080
4292
}
4081
4293
 
4082
4294
 
4083
 
static void end_timer(uint32_t start_time,char *buff)
 
4295
static void end_timer(ulong start_time,char *buff)
4084
4296
{
4085
4297
  nice_time((double) (start_timer() - start_time) /
4086
4298
            CLOCKS_PER_SEC,buff,1);
4087
4299
}
4088
4300
 
4089
4301
 
4090
 
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4302
static void drizzle_end_timer(ulong start_time,char *buff)
4091
4303
{
4092
4304
  buff[0]=' ';
4093
4305
  buff[1]='(';
4094
4306
  end_timer(start_time,buff+2);
4095
 
  my_stpcpy(strchr(buff, '\0'),")");
 
4307
  strmov(strend(buff),")");
4096
4308
}
4097
4309
 
4098
4310
static const char * construct_prompt()
4099
4311
{
4100
4312
  // Erase the old prompt
4101
4313
  assert(processed_prompt!=NULL);
4102
 
  processed_prompt->clear();
 
4314
  g_string_truncate(processed_prompt, 0);
4103
4315
 
4104
4316
  // Get the date struct
4105
4317
  time_t  lclock = time(NULL);
4110
4322
  {
4111
4323
    if (*c != PROMPT_CHAR)
4112
4324
    {
4113
 
      processed_prompt->append(c, 1);
 
4325
      g_string_append_c(processed_prompt, c[0]);
4114
4326
    }
4115
4327
    else
4116
4328
    {
4127
4339
        break;
4128
4340
      case 'v':
4129
4341
        if (connected)
4130
 
          processed_prompt->append(drizzle_get_server_info(&drizzle));
 
4342
          g_string_append(processed_prompt, drizzle_get_server_info(&drizzle));
4131
4343
        else
4132
 
          processed_prompt->append("not_connected");
 
4344
          g_string_append(processed_prompt, "not_connected");
4133
4345
        break;
4134
4346
      case 'd':
4135
 
        processed_prompt->append(current_db ? current_db : "(none)");
 
4347
        g_string_append(processed_prompt, current_db ? current_db : "(none)");
4136
4348
        break;
4137
4349
      case 'h':
4138
4350
      {
4139
4351
        const char *prompt;
4140
4352
        prompt= connected ? drizzle_get_host_info(&drizzle) : "not_connected";
4141
4353
        if (strstr(prompt, "Localhost"))
4142
 
          processed_prompt->append("localhost");
 
4354
          g_string_append(processed_prompt, "localhost");
4143
4355
        else
4144
4356
        {
4145
 
          const char *end=strrchr(prompt,' ');
4146
 
          if (end != NULL)
4147
 
            processed_prompt->append(prompt, (end-prompt));
 
4357
          const char *end=strcend(prompt,' ');
 
4358
          g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
4148
4359
        }
4149
4360
        break;
4150
4361
      }
4152
4363
      {
4153
4364
        if (!connected)
4154
4365
        {
4155
 
          processed_prompt->append("not_connected");
 
4366
          g_string_append(processed_prompt, "not_connected");
4156
4367
          break;
4157
4368
        }
4158
4369
 
4159
4370
        const char *host_info = drizzle_get_host_info(&drizzle);
4160
4371
        if (strstr(host_info, "memory"))
4161
4372
        {
4162
 
          processed_prompt->append(drizzle.host);
 
4373
          g_string_append(processed_prompt, drizzle.host );
4163
4374
        }
4164
4375
        else if (strstr(host_info,"TCP/IP") ||
4165
4376
                 !drizzle.unix_socket)
4167
4378
        else
4168
4379
        {
4169
4380
          char *pos=strrchr(drizzle.unix_socket,'/');
4170
 
          processed_prompt->append(pos ? pos+1 : drizzle.unix_socket);
 
4381
          g_string_append(processed_prompt, pos ? pos+1 : drizzle.unix_socket);
4171
4382
        }
4172
4383
      }
4173
4384
      break;
4174
4385
      case 'U':
4175
4386
        if (!full_username)
4176
4387
          init_username();
4177
 
        processed_prompt->append(full_username ? full_username :
4178
 
                                 (current_user ?  current_user : "(unknown)"));
 
4388
        g_string_append(processed_prompt, full_username ? full_username :
 
4389
                        (current_user ?  current_user : "(unknown)"));
4179
4390
        break;
4180
4391
      case 'u':
4181
4392
        if (!full_username)
4182
4393
          init_username();
4183
 
        processed_prompt->append(part_username ? part_username :
4184
 
                                 (current_user ?  current_user : "(unknown)"));
 
4394
        g_string_append(processed_prompt, part_username ? part_username :
 
4395
                        (current_user ?  current_user : "(unknown)"));
4185
4396
        break;
4186
4397
      case PROMPT_CHAR:
4187
 
        {
4188
 
          char c= PROMPT_CHAR;
4189
 
          processed_prompt->append(&c, 1);
4190
 
        }
 
4398
        g_string_append_c(processed_prompt, PROMPT_CHAR);
4191
4399
        break;
4192
4400
      case 'n':
4193
 
        {
4194
 
          char c= '\n';
4195
 
          processed_prompt->append(&c, 1);
4196
 
        }
 
4401
        g_string_append_c(processed_prompt, '\n');
4197
4402
        break;
4198
4403
      case ' ':
4199
4404
      case '_':
4200
 
        {
4201
 
          char c= ' ';
4202
 
          processed_prompt->append(&c, 1);
4203
 
        }
 
4405
        g_string_append_c(processed_prompt, ' ');
4204
4406
        break;
4205
4407
      case 'R':
4206
4408
        if (t->tm_hour < 10)
4207
 
          add_int_to_prompt(0);
 
4409
          g_string_append_c(processed_prompt, '0');
4208
4410
        add_int_to_prompt(t->tm_hour);
4209
4411
        break;
4210
4412
      case 'r':
4212
4414
        if (getHour == 0)
4213
4415
          getHour=12;
4214
4416
        if (getHour < 10)
4215
 
          add_int_to_prompt(0);
 
4417
          g_string_append_c(processed_prompt, '0');
4216
4418
        add_int_to_prompt(getHour);
4217
4419
        break;
4218
4420
      case 'm':
4219
4421
        if (t->tm_min < 10)
4220
 
          add_int_to_prompt(0);
 
4422
          g_string_append_c(processed_prompt, '0');
4221
4423
        add_int_to_prompt(t->tm_min);
4222
4424
        break;
4223
4425
      case 'y':
4224
4426
        getYear = t->tm_year % 100;
4225
4427
        if (getYear < 10)
4226
 
          add_int_to_prompt(0);
 
4428
          g_string_append_c(processed_prompt, '0');
4227
4429
        add_int_to_prompt(getYear);
4228
4430
        break;
4229
4431
      case 'Y':
4231
4433
        break;
4232
4434
      case 'D':
4233
4435
        dateTime = ctime(&lclock);
4234
 
        processed_prompt->append(strtok(dateTime,"\n"));
 
4436
        g_string_append(processed_prompt, strtok(dateTime,"\n"));
4235
4437
        break;
4236
4438
      case 's':
4237
4439
        if (t->tm_sec < 10)
4238
 
          add_int_to_prompt(0);
 
4440
          g_string_append_c(processed_prompt, '0');
4239
4441
        add_int_to_prompt(t->tm_sec);
4240
4442
        break;
4241
4443
      case 'w':
4242
 
        processed_prompt->append(day_names[t->tm_wday]);
 
4444
        g_string_append(processed_prompt, (day_names[t->tm_wday]));
4243
4445
        break;
4244
4446
      case 'P':
4245
 
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
 
4447
        g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4246
4448
        break;
4247
4449
      case 'o':
4248
4450
        add_int_to_prompt(t->tm_mon+1);
4249
4451
        break;
4250
4452
      case 'O':
4251
 
        processed_prompt->append(month_names[t->tm_mon]);
 
4453
        g_string_append(processed_prompt, month_names[t->tm_mon]);
4252
4454
        break;
4253
4455
      case '\'':
4254
 
        processed_prompt->append("'");
 
4456
        g_string_append(processed_prompt, "'");
4255
4457
        break;
4256
4458
      case '"':
4257
 
        processed_prompt->append("\"");
 
4459
        g_string_append_c(processed_prompt, '"');
4258
4460
        break;
4259
4461
      case 'S':
4260
 
        processed_prompt->append(";");
 
4462
        g_string_append_c(processed_prompt, ';');
4261
4463
        break;
4262
4464
      case 't':
4263
 
        processed_prompt->append("\t");
 
4465
        g_string_append_c(processed_prompt, '\t');
4264
4466
        break;
4265
4467
      case 'l':
4266
 
        processed_prompt->append(delimiter_str);
 
4468
        g_string_append(processed_prompt, delimiter_str);
4267
4469
        break;
4268
4470
      default:
4269
 
        processed_prompt->append(c, 1);
 
4471
        g_string_append(processed_prompt, c);
4270
4472
      }
4271
4473
    }
4272
4474
  }
4273
 
  return processed_prompt->c_str();
 
4475
  // TODO: Is this needed with GString?
 
4476
  g_string_append_c(processed_prompt, '\0');
 
4477
  return processed_prompt->str;
4274
4478
}
4275
4479
 
4276
4480
 
4277
4481
static void add_int_to_prompt(int toadd)
4278
4482
{
4279
4483
  char buffer[16];
4280
 
  int10_to_str(toadd, buffer, 10);
4281
 
  processed_prompt->append(buffer);
 
4484
  int10_to_str(toadd,buffer,10);
 
4485
  g_string_append(processed_prompt, buffer);
4282
4486
}
4283
4487
 
4284
4488
static void init_username()
4285
4489
{
4286
 
  free(full_username);
4287
 
  free(part_username);
 
4490
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
4491
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
4288
4492
 
4289
4493
  DRIZZLE_RES *result;
4290
4494
  if (!drizzle_query(&drizzle,"select USER()") &&
4291
4495
      (result=drizzle_use_result(&drizzle)))
4292
4496
  {
4293
4497
    DRIZZLE_ROW cur=drizzle_fetch_row(result);
4294
 
    full_username= strdup(cur[0]);
4295
 
    part_username= strdup(strtok(cur[0],"@"));
4296
 
    (void) drizzle_fetch_row(result);        // Read eof
 
4498
    full_username=g_strdup(cur[0]);
 
4499
    part_username=g_strdup(strtok(cur[0],"@"));
 
4500
    (void) drizzle_fetch_row(result);    // Read eof
4297
4501
  }
4298
4502
}
4299
4503
 
4300
 
static int com_prompt(string *buffer __attribute__((unused)),
4301
 
                      const char *line)
 
4504
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
4302
4505
{
4303
4506
  char *ptr=strchr(line, ' ');
4304
4507
  prompt_counter = 0;
4305
 
  free(current_prompt);
4306
 
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
 
4508
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
4509
  current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
4307
4510
  if (!ptr)
4308
4511
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4309
 
                default_prompt);
 
4512
                default_prompt->str);
4310
4513
  else
4311
4514
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4312
4515
  return 0;
4313
4516
}
4314
 
 
4315
 
/*
4316
 
    strcont(str, set) if str contanies any character in the string set.
4317
 
    The result is the position of the first found character in str, or NULL
4318
 
    if there isn't anything found.
4319
 
*/
4320
 
 
4321
 
static const char * strcont(register const char *str, register const char *set)
4322
 
{
4323
 
  register const char * start = (const char *) set;
4324
 
 
4325
 
  while (*str)
4326
 
  {
4327
 
    while (*set)
4328
 
    {
4329
 
      if (*set++ == *str)
4330
 
        return ((const char*) str);
4331
 
    }
4332
 
    set=start; str++;
4333
 
  }
4334
 
  return NULL;
4335
 
} /* strcont */