~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Monty Taylor
  • Date: 2008-09-14 22:10:23 UTC
  • mto: This revision was merged to the branch mainline in revision 388.
  • Revision ID: monty@inaugust.com-20080914221023-otz8vuui590zp5yf
Got rid of libsqlcommon and some surious defines.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 *
34
34
 **/
35
35
 
36
 
#include <config.h>
37
 
 
38
36
#include <string>
39
 
#include CMATH_H
40
37
 
41
38
#include "client_priv.h"
42
39
#include <mystrings/m_ctype.h>
43
40
#include <stdarg.h>
 
41
#ifndef __GNU_LIBRARY__
 
42
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
 
43
#endif
44
44
#include <readline/history.h>
45
45
#include "my_readline.h"
46
46
#include <signal.h>
 
47
#include <vio/violite.h>
47
48
#include <sys/ioctl.h>
48
49
 
49
50
 
51
52
#include <locale.h>
52
53
#endif
53
54
 
54
 
#include <drizzled/gettext.h>
55
 
 
56
 
#if defined(CMATH_NAMESPACE)
57
 
  using namespace CMATH_NAMESPACE;
58
 
#endif
 
55
#include <libdrizzle/gettext.h>
59
56
 
60
57
const char *VER= "14.14";
61
58
 
65
62
/* Buffer to hold 'version' and 'version_comment' */
66
63
#define MAX_SERVER_VERSION_LENGTH     128
67
64
 
 
65
/* Array of options to pass to libdrizzled */
 
66
#define MAX_SERVER_ARGS               64
 
67
 
68
68
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
69
69
void sql_element_free(void *ptr);
70
70
 
71
 
 
72
71
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
73
72
#include <curses.h>
74
 
#ifdef __sun
75
 
#undef clear
76
 
#undef erase
77
 
#endif
78
73
#include <term.h>
79
74
#else
80
75
#if defined(HAVE_TERMIOS_H)
85
80
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
86
81
#include <asm/termbits.h>    // Standard linux
87
82
#endif
 
83
#undef VOID
88
84
#if defined(HAVE_TERMCAP_H)
89
85
#include <termcap.h>
90
86
#else
209
205
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
210
206
/* The names of functions that actually do the manipulation. */
211
207
static int get_options(int argc,char **argv);
212
 
extern "C" bool get_one_option(int optid, const struct my_option *opt,
213
 
                               char *argument);
 
208
bool get_one_option(int optid, const struct my_option *opt,
 
209
                    char *argument);
214
210
static int com_quit(string *str,const char*),
215
211
  com_go(string *str,const char*), com_ego(string *str,const char*),
216
212
  com_print(string *str,const char*),
609
605
  { "QUARTER", 0, 0, 0, ""},
610
606
  { "QUERY", 0, 0, 0, ""},
611
607
  { "QUICK", 0, 0, 0, ""},
 
608
  { "RAID0", 0, 0, 0, ""},
 
609
  { "RAID_CHUNKS", 0, 0, 0, ""},
 
610
  { "RAID_CHUNKSIZE", 0, 0, 0, ""},
 
611
  { "RAID_TYPE", 0, 0, 0, ""},
612
612
  { "READ", 0, 0, 0, ""},
613
613
  { "READS", 0, 0, 0, ""},
614
614
  { "REAL", 0, 0, 0, ""},
1010
1010
static void end_timer(uint32_t start_time,char *buff);
1011
1011
static void drizzle_end_timer(uint32_t start_time,char *buff);
1012
1012
static void nice_time(double sec,char *buff,bool part_second);
1013
 
extern "C" RETSIGTYPE drizzle_end(int sig);
1014
 
extern "C" RETSIGTYPE handle_sigint(int sig);
 
1013
extern sig_handler drizzle_end(int sig);
 
1014
extern sig_handler handle_sigint(int sig);
1015
1015
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1016
 
static RETSIGTYPE window_resize(int sig);
 
1016
static sig_handler window_resize(int sig);
1017
1017
#endif
1018
1018
 
1019
1019
int main(int argc,char *argv[])
1040
1040
  prompt_counter=0;
1041
1041
 
1042
1042
  outfile[0]=0;      // no (default) outfile
1043
 
  my_stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1043
  stpcpy(pager, "stdout");  // the default, if --pager wasn't given
1044
1044
  {
1045
1045
    char *tmp=getenv("PAGER");
1046
1046
    if (tmp && strlen(tmp))
1047
1047
    {
1048
1048
      default_pager_set= 1;
1049
 
      my_stpcpy(default_pager, tmp);
 
1049
      stpcpy(default_pager, tmp);
1050
1050
    }
1051
1051
  }
1052
1052
  if (!isatty(0) || !isatty(1))
1072
1072
      close(stdout_fileno_copy);             /* Clean up dup(). */
1073
1073
  }
1074
1074
 
1075
 
  load_defaults("drizzle",load_default_groups,&argc,&argv);
 
1075
  load_defaults("my",load_default_groups,&argc,&argv);
1076
1076
  defaults_argv=argv;
1077
1077
  if (get_options(argc, (char **) argv))
1078
1078
  {
1146
1146
          strncmp(link_name, "/dev/null", 10) == 0)
1147
1147
      {
1148
1148
        /* The .drizzle_history file is a symlink to /dev/null, don't use it */
1149
 
        free(histfile);
 
1149
        my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
1150
1150
        histfile= 0;
1151
1151
      }
1152
1152
    }
1176
1176
  return(0);        // Keep compiler happy
1177
1177
}
1178
1178
 
1179
 
RETSIGTYPE drizzle_end(int sig)
 
1179
sig_handler drizzle_end(int sig)
1180
1180
{
1181
1181
  drizzle_close(&drizzle);
1182
1182
  if (!status.batch && !quick && histfile)
1197
1197
    delete glob_buffer;
1198
1198
  if (processed_prompt)
1199
1199
    delete processed_prompt;
1200
 
  free(opt_password);
1201
 
  free(opt_drizzle_unix_port);
1202
 
  free(histfile);
1203
 
  free(histfile_tmp);
1204
 
  free(current_db);
1205
 
  free(current_host);
1206
 
  free(current_user);
1207
 
  free(full_username);
1208
 
  free(part_username);
1209
 
  free(default_prompt);
1210
 
  free(current_prompt);
 
1200
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
1201
  my_free(opt_drizzle_unix_port,MYF(MY_ALLOW_ZERO_PTR));
 
1202
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
 
1203
  my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
 
1204
  my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
1205
  my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
1206
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
 
1207
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
1208
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
 
1209
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1210
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1211
  drizzle_server_end();
1211
1212
  free_defaults(defaults_argv);
1212
1213
  my_end(my_end_arg);
1213
1214
  exit(status.exit_status);
1219
1220
  If query is in process, kill query
1220
1221
  no query in process, terminate like previous behavior
1221
1222
*/
1222
 
extern "C"
1223
 
RETSIGTYPE handle_sigint(int sig)
 
1223
sig_handler handle_sigint(int sig)
1224
1224
{
1225
1225
  char kill_buffer[40];
1226
1226
  DRIZZLE *kill_drizzle= NULL;
1253
1253
 
1254
1254
 
1255
1255
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1256
 
RETSIGTYPE window_resize(int sig __attribute__((unused)))
 
1256
sig_handler window_resize(int sig __attribute__((unused)))
1257
1257
{
1258
1258
  struct winsize window_size;
1259
1259
 
1359
1359
  {"password", 'p',
1360
1360
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
1361
1361
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1362
 
  {"port", 'P', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
 
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
1363
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
1364
1364
   (char**) &opt_drizzle_port,
1365
1365
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,  0},
1448
1448
 
1449
1449
  if (version)
1450
1450
    return;
1451
 
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
1452
 
           "This software comes with ABSOLUTELY NO WARRANTY. "
1453
 
           "This is free software,\n"
1454
 
           "and you are welcome to modify and redistribute it "
1455
 
           "under the GPL license\n"));
 
1451
  printf(_("\
 
1452
Copyright (C) 2000-2008 MySQL AB\n                                      \
 
1453
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
 
1454
and you are welcome to modify and redistribute it under the GPL license\n"));
1456
1455
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
1457
1456
  my_print_help(my_long_options);
1458
 
  print_defaults("drizzle", load_default_groups);
 
1457
  print_defaults("my", load_default_groups);
1459
1458
  my_print_variables(my_long_options);
1460
1459
}
1461
1460
 
1462
1461
 
1463
 
extern "C" bool
 
1462
bool
1464
1463
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
1465
1464
               char *argument)
1466
1465
{
1475
1474
  case OPT_DELIMITER:
1476
1475
    if (argument == disabled_my_option)
1477
1476
    {
1478
 
      my_stpcpy(delimiter, DEFAULT_DELIMITER);
 
1477
      stpcpy(delimiter, DEFAULT_DELIMITER);
1479
1478
    }
1480
1479
    else
1481
1480
    {
1521
1520
      {
1522
1521
        default_pager_set= 1;
1523
1522
        strmake(pager, argument, sizeof(pager) - 1);
1524
 
        my_stpcpy(default_pager, pager);
 
1523
        stpcpy(default_pager, pager);
1525
1524
      }
1526
1525
      else if (default_pager_set)
1527
 
        my_stpcpy(pager, default_pager);
 
1526
        stpcpy(pager, default_pager);
1528
1527
      else
1529
1528
        opt_nopager= 1;
1530
1529
    }
1562
1561
    if (argument)
1563
1562
    {
1564
1563
      char *start= argument;
1565
 
      free(opt_password);
 
1564
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1566
1565
      opt_password= strdup(argument);
1567
1566
      while (*argument) *argument++= 'x';        // Destroy argument
1568
1567
      if (*start)
1615
1614
  pagpoint= getenv("PAGER");
1616
1615
  if (!((char*) (pagpoint)))
1617
1616
  {
1618
 
    my_stpcpy(pager, "stdout");
 
1617
    stpcpy(pager, "stdout");
1619
1618
    opt_nopager= 1;
1620
1619
  }
1621
1620
  else
1622
 
    my_stpcpy(pager, pagpoint);
1623
 
  my_stpcpy(default_pager, pager);
 
1621
    stpcpy(pager, pagpoint);
 
1622
  stpcpy(default_pager, pager);
1624
1623
 
1625
1624
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1626
1625
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
1633
1632
 
1634
1633
  if (status.batch) /* disable pager and outfile in this case */
1635
1634
  {
1636
 
    my_stpcpy(default_pager, "stdout");
1637
 
    my_stpcpy(pager, "stdout");
 
1635
    stpcpy(default_pager, "stdout");
 
1636
    stpcpy(pager, "stdout");
1638
1637
    opt_nopager= 1;
1639
1638
    default_pager_set= 0;
1640
1639
    opt_outfile= 0;
1650
1649
  if (argc == 1)
1651
1650
  {
1652
1651
    skip_updates= 0;
1653
 
    free(current_db);
 
1652
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
1654
1653
    current_db= strdup(*argv);
1655
1654
  }
1656
1655
  if (tty_password)
1657
 
    opt_password= get_tty_password(NULL);
 
1656
    opt_password= get_tty_password(NullS);
1658
1657
  if (debug_info_flag)
1659
1658
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1660
1659
  if (debug_check_flag)
1683
1682
        you save the file using "Unicode UTF-8" format.
1684
1683
      */
1685
1684
      if (!line_number &&
1686
 
          (unsigned char) line[0] == 0xEF &&
1687
 
          (unsigned char) line[1] == 0xBB &&
1688
 
          (unsigned char) line[2] == 0xBF)
 
1685
          (uchar) line[0] == 0xEF &&
 
1686
          (uchar) line[1] == 0xBB &&
 
1687
          (uchar) line[2] == 0xBF)
1689
1688
        line+= 3;
1690
1689
      line_number++;
1691
1690
      if (!glob_buffer->empty())
1779
1778
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
1780
1779
                                !(strlen(name) >= 9 &&
1781
1780
                                  !my_strnncoll(charset_info,
1782
 
                                                (unsigned char*) name, 9,
1783
 
                                                (const unsigned char*) "delimiter",
 
1781
                                                (uchar*) name, 9,
 
1782
                                                (const uchar*) "delimiter",
1784
1783
                                                9))))
1785
1784
      return((COMMANDS *) 0);
1786
1785
    if ((end=strcont(name," \t")))
1798
1797
  for (uint i= 0; commands[i].name; i++)
1799
1798
  {
1800
1799
    if (commands[i].func &&
1801
 
        ((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)))
 
1800
        ((name && !my_strnncoll(charset_info,(const uchar*)name,len, (const uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
1802
1801
    {
1803
1802
      return(&commands[i]);
1804
1803
    }
1810
1809
static bool add_line(string *buffer, char *line, char *in_string,
1811
1810
                        bool *ml_comment)
1812
1811
{
1813
 
  unsigned char inchar;
 
1812
  uchar inchar;
1814
1813
  char buff[80], *pos, *out;
1815
1814
  COMMANDS *com;
1816
1815
  bool need_space= 0;
1823
1822
    add_history(line);
1824
1823
  char *end_of_line=line+(uint) strlen(line);
1825
1824
 
1826
 
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
 
1825
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
1827
1826
  {
1828
1827
    if (!preserve_comments)
1829
1828
    {
1855
1854
    {
1856
1855
      // Found possbile one character command like \c
1857
1856
 
1858
 
      if (!(inchar = (unsigned char) *++pos))
 
1857
      if (!(inchar = (uchar) *++pos))
1859
1858
        break;        // readline adds one '\'
1860
1859
      if (*in_string || inchar == 'N')  // \N is short for NULL
1861
1860
      {          // Don't allow commands in string
1863
1862
        *out++= (char) inchar;
1864
1863
        continue;
1865
1864
      }
1866
 
      if ((com=find_command(NULL,(char) inchar)))
 
1865
      if ((com=find_command(NullS,(char) inchar)))
1867
1866
      {
1868
1867
        // Flush previously accepted characters
1869
1868
        if (out != line)
1912
1911
    }
1913
1912
    else if (!*ml_comment && !*in_string &&
1914
1913
             (end_of_line - pos) >= 10 &&
1915
 
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
1916
 
                           (const unsigned char*) "delimiter ", 10))
 
1914
             !my_strnncoll(charset_info, (uchar*) pos, 10,
 
1915
                           (const uchar*) "delimiter ", 10))
1917
1916
    {
1918
1917
      // Flush previously accepted characters
1919
1918
      if (out != line)
2078
2077
 
2079
2078
 
2080
2079
static char **mysql_completion (const char *text, int start, int end);
2081
 
extern "C" char *new_command_generator(const char *text, int);
 
2080
static char *new_command_generator(const char *text, int);
2082
2081
 
2083
2082
/*
2084
2083
  Tell the GNU Readline library how to complete.  We want to try to complete
2191
2190
    return (char**) 0;
2192
2191
}
2193
2192
 
2194
 
extern "C"
2195
 
char *new_command_generator(const char *text,int state)
 
2193
 
 
2194
static char *new_command_generator(const char *text,int state)
2196
2195
{
2197
2196
  static int textlen;
2198
2197
  char *ptr;
2211
2210
 
2212
2211
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2213
2212
      if (!b)
2214
 
        return NULL;
 
2213
        return NullS;
2215
2214
      e = b->pData;
2216
2215
    }
2217
2216
 
2238
2237
        }
2239
2238
      }
2240
2239
    }
2241
 
    ptr= NULL;
 
2240
    ptr= NullS;
2242
2241
    while (e && !ptr)
2243
2242
    {          /* find valid entry in bucket */
2244
2243
      if ((uint) strlen(e->str) == b->nKeyLength)
2267
2266
    if (ptr)
2268
2267
      return ptr;
2269
2268
  }
2270
 
  return NULL;
 
2269
  return NullS;
2271
2270
}
2272
2271
 
2273
2272
 
2358
2357
  i=0;
2359
2358
  while ((table_row=drizzle_fetch_row(tables)))
2360
2359
  {
2361
 
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NULL)))
 
2360
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NullS)))
2362
2361
    {
2363
2362
      num_fields=drizzle_num_fields(fields);
2364
2363
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2405
2404
    for (;;)
2406
2405
    {
2407
2406
      if (*s == (char) c) return (char*) s;
2408
 
      if (!*s++) return NULL;
 
2407
      if (!*s++) return NullS;
2409
2408
    }
2410
2409
  }
2411
2410
 
2413
2412
  {
2414
2413
    register char *t;
2415
2414
 
2416
 
    t = NULL;
 
2415
    t = NullS;
2417
2416
    do if (*s == (char) c) t = (char*) s; while (*s++);
2418
2417
    return (char*) t;
2419
2418
  }
2441
2440
{
2442
2441
  DRIZZLE_RES *res;
2443
2442
 
2444
 
  free(current_db);
 
2443
  my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
2445
2444
  current_db= NULL;
2446
2445
  /* In case of error below current_db will be NULL */
2447
2446
  if (!drizzle_query(&drizzle, "SELECT DATABASE()") &&
2498
2497
 
2499
2498
static int com_server_help(string *buffer,
2500
2499
                           const char *line __attribute__((unused)),
2501
 
                           const char *help_arg)
 
2500
                           char *help_arg)
2502
2501
{
2503
2502
  DRIZZLE_ROW cur;
2504
2503
  const char *server_cmd= buffer->c_str();
2505
 
  string cmd_buf;
 
2504
  char cmd_buf[100];
2506
2505
  DRIZZLE_RES *result;
2507
2506
  int error;
2508
2507
 
2509
 
  cmd_buf.reserve(100);
2510
2508
  if (help_arg[0] != '\'')
2511
2509
  {
2512
 
    const char *end_arg= strchr(help_arg, '\0');
 
2510
    char *end_arg= strchr(help_arg, '\0');
2513
2511
    if(--end_arg)
2514
2512
    {
2515
2513
      while (my_isspace(charset_info,*end_arg))
2516
2514
        end_arg--;
 
2515
      *++end_arg= '\0';
2517
2516
    }
2518
 
    cmd_buf.append("help '");
2519
 
    cmd_buf.append(help_arg, end_arg-help_arg);
2520
 
    cmd_buf.append("'");
2521
 
  
2522
 
    server_cmd= cmd_buf.c_str();
 
2517
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
 
2518
    server_cmd= cmd_buf;
2523
2519
  }
2524
2520
 
2525
2521
  if (!connected && reconnect())
2595
2591
         const char *line __attribute__((unused)))
2596
2592
{
2597
2593
  register int i, j;
2598
 
  const char *help_arg= strchr(line,' ');
2599
 
  char buff[32], *end;
 
2594
  char * help_arg= strchr(line,' '), buff[32], *end;
2600
2595
  if (help_arg)
2601
2596
  {
2602
2597
    while (my_isspace(charset_info,*help_arg))
2609
2604
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2610
2605
  for (i = 0; commands[i].name; i++)
2611
2606
  {
2612
 
    end= my_stpcpy(buff, commands[i].name);
 
2607
    end= stpcpy(buff, commands[i].name);
2613
2608
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2614
 
      end= my_stpcpy(end, " ");
 
2609
      end= stpcpy(end, " ");
2615
2610
    if (commands[i].func)
2616
2611
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2617
2612
                  commands[i].cmd_char, _(commands[i].doc));
2724
2719
    {
2725
2720
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
2726
2721
      {
2727
 
        my_stpcpy(buff, _("Empty set"));
 
2722
        stpcpy(buff, _("Empty set"));
2728
2723
      }
2729
2724
      else
2730
2725
      {
2746
2741
      }
2747
2742
    }
2748
2743
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2749
 
      my_stpcpy(buff,_("Query OK"));
 
2744
      stpcpy(buff,_("Query OK"));
2750
2745
    else
2751
2746
      sprintf(buff, ngettext("Query OK, %ld row affected",
2752
2747
                             "Query OK, %ld rows affected",
2759
2754
      *pos++= ',';
2760
2755
      *pos++= ' ';
2761
2756
      pos=int10_to_str(warnings, pos, 10);
2762
 
      pos=my_stpcpy(pos, " warning");
 
2757
      pos=stpcpy(pos, " warning");
2763
2758
      if (warnings != 1)
2764
2759
        *pos++= 's';
2765
2760
    }
2766
 
    my_stpcpy(pos, time_buff);
 
2761
    stpcpy(pos, time_buff);
2767
2762
    put_info(buff,INFO_RESULT,0,0);
2768
2763
    if (drizzle_info(&drizzle))
2769
2764
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
2865
2860
    case DRIZZLE_TYPE_LONG:        return "LONG";
2866
2861
    case DRIZZLE_TYPE_LONGLONG:    return "LONGLONG";
2867
2862
    case DRIZZLE_TYPE_NULL:        return "NULL";
 
2863
    case DRIZZLE_TYPE_SHORT:       return "SHORT";
2868
2864
    case DRIZZLE_TYPE_TIME:        return "TIME";
2869
2865
    case DRIZZLE_TYPE_TIMESTAMP:   return "TIMESTAMP";
2870
2866
    case DRIZZLE_TYPE_TINY:        return "TINY";
2871
 
    case DRIZZLE_TYPE_VIRTUAL:     return "VIRTUAL";
2872
2867
    default:                     return "?-unknown-?";
2873
2868
  }
2874
2869
}
2878
2873
  char *s=buf;
2879
2874
  *s=0;
2880
2875
#define ff2s_check_flag(X)                                              \
2881
 
  if (f & X ## _FLAG) { s=my_stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2876
  if (f & X ## _FLAG) { s=stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
2882
2877
  ff2s_check_flag(NOT_NULL);
2883
2878
  ff2s_check_flag(PRI_KEY);
2884
2879
  ff2s_check_flag(UNIQUE_KEY);
3047
3042
    (void) tee_fputs("\n", PAGER);
3048
3043
  }
3049
3044
  tee_puts(separator.c_str(), PAGER);
3050
 
  free(num_flag);
 
3045
  my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
3051
3046
}
3052
3047
 
3053
3048
/**
3285
3280
static int
3286
3281
com_tee(string *buffer __attribute__((unused)), const char *line )
3287
3282
{
3288
 
  char file_name[FN_REFLEN], *end;
3289
 
  const char *param;
 
3283
  char file_name[FN_REFLEN], *end, *param;
3290
3284
 
3291
3285
  if (status.batch)
3292
3286
    return 0;
3345
3339
com_pager(string *buffer __attribute__((unused)),
3346
3340
          const char *line __attribute__((unused)))
3347
3341
{
3348
 
  char pager_name[FN_REFLEN], *end;
3349
 
  const char *param;
 
3342
  char pager_name[FN_REFLEN], *end, *param;
3350
3343
 
3351
3344
  if (status.batch)
3352
3345
    return 0;
3364
3357
    {
3365
3358
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3366
3359
      opt_nopager=1;
3367
 
      my_stpcpy(pager, "stdout");
 
3360
      stpcpy(pager, "stdout");
3368
3361
      PAGER= stdout;
3369
3362
      return 0;
3370
3363
    }
3371
 
    my_stpcpy(pager, default_pager);
 
3364
    stpcpy(pager, default_pager);
3372
3365
  }
3373
3366
  else
3374
3367
  {
3377
3370
                                my_iscntrl(charset_info,end[-1])))
3378
3371
      end--;
3379
3372
    end[0]=0;
3380
 
    my_stpcpy(pager, pager_name);
3381
 
    my_stpcpy(default_pager, pager_name);
 
3373
    stpcpy(pager, pager_name);
 
3374
    stpcpy(default_pager, pager_name);
3382
3375
  }
3383
3376
  opt_nopager=0;
3384
3377
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3390
3383
com_nopager(string *buffer __attribute__((unused)),
3391
3384
            const char *line __attribute__((unused)))
3392
3385
{
3393
 
  my_stpcpy(pager, "stdout");
 
3386
  stpcpy(pager, "stdout");
3394
3387
  opt_nopager=1;
3395
3388
  PAGER= stdout;
3396
3389
  tee_fprintf(stdout, "PAGER set to stdout\n");
3453
3446
    tmp= get_arg(buff, 0);
3454
3447
    if (tmp && *tmp)
3455
3448
    {
3456
 
      free(current_db);
 
3449
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
3457
3450
      current_db= strdup(tmp);
3458
3451
      tmp= get_arg(buff, 1);
3459
3452
      if (tmp)
3460
3453
      {
3461
 
        free(current_host);
 
3454
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
3462
3455
        current_host=strdup(tmp);
3463
3456
      }
3464
3457
    }
3490
3483
 
3491
3484
static int com_source(string *buffer __attribute__((unused)), const char *line)
3492
3485
{
3493
 
  char source_name[FN_REFLEN], *end;
3494
 
  const char *param;
 
3486
  char source_name[FN_REFLEN], *end, *param;
3495
3487
  LINE_BUFFER *line_buff;
3496
3488
  int error;
3497
3489
  STATUS old_status;
3512
3504
  end[0]=0;
3513
3505
  unpack_filename(source_name,source_name);
3514
3506
  /* open file name */
3515
 
  if (!(sql_file = my_fopen(source_name, O_RDONLY,MYF(0))))
 
3507
  if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
3516
3508
  {
3517
3509
    char buff[FN_REFLEN+60];
3518
3510
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3638
3630
      if (drizzle_select_db(&drizzle,tmp))
3639
3631
        return put_error(&drizzle);
3640
3632
    }
3641
 
    free(current_db);
 
3633
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
3642
3634
    current_db= strdup(tmp);
3643
3635
    if (select_db > 1)
3644
3636
      build_completion_hash(opt_rehash, 1);
3701
3693
        ptr++;
3702
3694
  }
3703
3695
  if (!*ptr)
3704
 
    return NULL;
 
3696
    return NullS;
3705
3697
  while (my_isspace(charset_info, *ptr))
3706
3698
    ptr++;
3707
3699
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
3715
3707
    if (*ptr == '\\' && ptr[1]) // escaped character
3716
3708
    {
3717
3709
      // Remove the backslash
3718
 
      my_stpcpy(ptr, ptr+1);
 
3710
      stpcpy(ptr, ptr+1);
3719
3711
    }
3720
3712
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3721
3713
    {
3724
3716
    }
3725
3717
  }
3726
3718
  valid_arg= ptr != start;
3727
 
  return valid_arg ? start : NULL;
 
3719
  return valid_arg ? start : NullS;
3728
3720
}
3729
3721
 
3730
3722
 
3745
3737
                  (char*) &timeout);
3746
3738
  }
3747
3739
  if (opt_compress)
3748
 
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
3740
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NullS);
3749
3741
  if (opt_secure_auth)
3750
3742
    drizzle_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3751
3743
  if (using_opt_local_infile)
3873
3865
static const char *
3874
3866
server_version_string(DRIZZLE *con)
3875
3867
{
3876
 
  static string buf("");
3877
 
  static bool server_version_string_reserved= false;
 
3868
  static char buf[MAX_SERVER_VERSION_LENGTH] = "";
3878
3869
 
3879
 
  if (!server_version_string_reserved)
3880
 
  {
3881
 
    buf.reserve(MAX_SERVER_VERSION_LENGTH);
3882
 
    server_version_string_reserved= true;
3883
 
  }
3884
3870
  /* Only one thread calls this, so no synchronization is needed */
3885
3871
  if (buf[0] == '\0')
3886
3872
  {
 
3873
    char *bufp = buf;
3887
3874
    DRIZZLE_RES *result;
3888
3875
 
3889
 
    buf.append(drizzle_get_server_info(con));
 
3876
    bufp= stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
3890
3877
 
3891
3878
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3892
3879
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3895
3882
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
3896
3883
      if (cur && cur[0])
3897
3884
      {
3898
 
        buf.append(" ");
3899
 
        buf.append(cur[0]);
 
3885
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
3900
3886
      }
3901
3887
      drizzle_free_result(result);
3902
3888
    }
 
3889
 
 
3890
    /* str*nmov doesn't guarantee NUL-termination */
 
3891
    if (bufp == buf + sizeof buf)
 
3892
      buf[sizeof buf - 1] = '\0';
3903
3893
  }
3904
3894
 
3905
 
  return buf.c_str();
 
3895
  return buf;
3906
3896
}
3907
3897
 
3908
3898
static int
4067
4057
    tmp=(uint32_t) floor(sec/(3600.0*24));
4068
4058
    sec-=3600.0*24*tmp;
4069
4059
    buff=int10_to_str((long) tmp, buff, 10);
4070
 
    buff=my_stpcpy(buff,tmp > 1 ? " days " : " day ");
 
4060
    buff=stpcpy(buff,tmp > 1 ? " days " : " day ");
4071
4061
  }
4072
4062
  if (sec >= 3600.0)
4073
4063
  {
4074
4064
    tmp=(uint32_t) floor(sec/3600.0);
4075
4065
    sec-=3600.0*tmp;
4076
4066
    buff=int10_to_str((long) tmp, buff, 10);
4077
 
    buff=my_stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
4067
    buff=stpcpy(buff,tmp > 1 ? " hours " : " hour ");
4078
4068
  }
4079
4069
  if (sec >= 60.0)
4080
4070
  {
4081
4071
    tmp=(uint32_t) floor(sec/60.0);
4082
4072
    sec-=60.0*tmp;
4083
4073
    buff=int10_to_str((long) tmp, buff, 10);
4084
 
    buff=my_stpcpy(buff," min ");
 
4074
    buff=stpcpy(buff," min ");
4085
4075
  }
4086
4076
  if (part_second)
4087
4077
    sprintf(buff,"%.2f sec",sec);
4102
4092
  buff[0]=' ';
4103
4093
  buff[1]='(';
4104
4094
  end_timer(start_time,buff+2);
4105
 
  my_stpcpy(strchr(buff, '\0'),")");
 
4095
  stpcpy(strchr(buff, '\0'),")");
4106
4096
}
4107
4097
 
4108
4098
static const char * construct_prompt()
4293
4283
 
4294
4284
static void init_username()
4295
4285
{
4296
 
  free(full_username);
4297
 
  free(part_username);
 
4286
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
4287
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
4298
4288
 
4299
4289
  DRIZZLE_RES *result;
4300
4290
  if (!drizzle_query(&drizzle,"select USER()") &&
4310
4300
static int com_prompt(string *buffer __attribute__((unused)),
4311
4301
                      const char *line)
4312
4302
{
4313
 
  const char *ptr=strchr(line, ' ');
 
4303
  char *ptr=strchr(line, ' ');
4314
4304
  prompt_counter = 0;
4315
 
  free(current_prompt);
 
4305
  my_free(current_prompt, MYF(MY_ALLOW_ZERO_PTR));
4316
4306
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4317
4307
  if (!ptr)
4318
4308
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4324
4314
 
4325
4315
/*
4326
4316
    strcont(str, set) if str contanies any character in the string set.
4327
 
    The result is the position of the first found character in str, or NULL
 
4317
    The result is the position of the first found character in str, or NullS
4328
4318
    if there isn't anything found.
4329
4319
*/
4330
4320