Make the CLI client (client/mysql.cc) work with multi-line SPs.

Make the mysqltest program (client/mysqltest.c) work with multi-line SPs.
parent b88ef166
...@@ -17,6 +17,7 @@ bell@sanja.is.com.ua ...@@ -17,6 +17,7 @@ bell@sanja.is.com.ua
bk@admin.bk bk@admin.bk
davida@isil.mysql.com davida@isil.mysql.com
gluh@gluh.(none) gluh@gluh.(none)
gluh@gluh.mysql.r18.ru
heikki@donna.mysql.fi heikki@donna.mysql.fi
heikki@hundin.mysql.fi heikki@hundin.mysql.fi
heikki@rescue. heikki@rescue.
......
...@@ -100,6 +100,7 @@ extern "C" { ...@@ -100,6 +100,7 @@ extern "C" {
#include "completion_hash.h" #include "completion_hash.h"
#define PROMPT_CHAR '\\' #define PROMPT_CHAR '\\'
#define DEFAULT_DELIMITER ';'
typedef struct st_status typedef struct st_status
{ {
...@@ -151,6 +152,7 @@ static char pager[FN_REFLEN], outfile[FN_REFLEN]; ...@@ -151,6 +152,7 @@ static char pager[FN_REFLEN], outfile[FN_REFLEN];
static FILE *PAGER, *OUTFILE; static FILE *PAGER, *OUTFILE;
static MEM_ROOT hash_mem_root; static MEM_ROOT hash_mem_root;
static uint prompt_counter; static uint prompt_counter;
static char delimiter= DEFAULT_DELIMITER;
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
static char *shared_memory_base_name=0; static char *shared_memory_base_name=0;
...@@ -177,7 +179,7 @@ static int com_quit(String *str,char*), ...@@ -177,7 +179,7 @@ static int com_quit(String *str,char*),
com_use(String *str,char*), com_source(String *str, char*), com_use(String *str,char*), com_source(String *str, char*),
com_rehash(String *str, char*), com_tee(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*),
com_notee(String *str, char*), com_shell(String *str, char *), com_notee(String *str, char*), com_shell(String *str, char *),
com_prompt(String *str, char*); com_prompt(String *str, char*), com_delimiter(String *str, char*);
#ifndef __WIN__ #ifndef __WIN__
static int com_nopager(String *str, char*), com_pager(String *str, char*), static int com_nopager(String *str, char*), com_pager(String *str, char*),
...@@ -245,7 +247,8 @@ static COMMANDS commands[] = { ...@@ -245,7 +247,8 @@ static COMMANDS commands[] = {
"Set outfile [to_outfile]. Append everything into given outfile." }, "Set outfile [to_outfile]. Append everything into given outfile." },
{ "use", 'u', com_use, 1, { "use", 'u', com_use, 1,
"Use another database. Takes database name as argument." }, "Use another database. Takes database name as argument." },
{ "delimiter", 'd', com_delimiter, 1,
"Set query delimiter. " },
/* Get bash-like expansion for some commands */ /* Get bash-like expansion for some commands */
{ "create table", 0, 0, 0, ""}, { "create table", 0, 0, 0, ""},
{ "create database", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""},
...@@ -911,7 +914,7 @@ static COMMANDS *find_command (char *name,char cmd_char) ...@@ -911,7 +914,7 @@ static COMMANDS *find_command (char *name,char cmd_char)
{ {
while (my_isspace(system_charset_info,*name)) while (my_isspace(system_charset_info,*name))
name++; name++;
if (strchr(name,';') || strstr(name,"\\g")) if (strchr(name, delimiter) || strstr(name,"\\g"))
return ((COMMANDS *) 0); return ((COMMANDS *) 0);
if ((end=strcont(name," \t"))) if ((end=strcont(name," \t")))
{ {
...@@ -989,7 +992,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -989,7 +992,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
return 1; // Quit return 1; // Quit
if (com->takes_params) if (com->takes_params)
{ {
for (pos++ ; *pos && *pos != ';' ; pos++) ; // Remove parameters for (pos++ ; *pos && *pos != delimiter; pos++) ; // Remove parameters
if (!*pos) if (!*pos)
pos--; pos--;
} }
...@@ -1005,7 +1008,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -1005,7 +1008,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
continue; continue;
} }
} }
else if (!*ml_comment && inchar == ';' && !*in_string) else if (!*ml_comment && inchar == delimiter && !*in_string)
{ // ';' is end of command { // ';' is end of command
if (out != line) if (out != line)
buffer.append(line,(uint) (out-line)); // Add this line buffer.append(line,(uint) (out-line)); // Add this line
...@@ -1514,7 +1517,7 @@ com_help (String *buffer __attribute__((unused)), ...@@ -1514,7 +1517,7 @@ com_help (String *buffer __attribute__((unused)),
for (i = 0; commands[i].name; i++) for (i = 0; commands[i].name; i++)
{ {
if (commands[i].func) if (commands[i].func)
tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, tee_fprintf(stdout, "%-10s(\\%c)\t%s\n", commands[i].name,
commands[i].cmd_char, commands[i].doc); commands[i].cmd_char, commands[i].doc);
} }
if (connected) if (connected)
...@@ -2324,6 +2327,37 @@ static int com_source(String *buffer, char *line) ...@@ -2324,6 +2327,37 @@ static int com_source(String *buffer, char *line)
return error; return error;
} }
/* ARGSUSED */
static int
com_delimiter(String *buffer __attribute__((unused)), char *line)
{
char *tmp;
char buff[256];
if (strlen(line)> 255)
{
put_info("'DELIMITER' command was too long.", INFO_ERROR);
return 0;
}
bzero(buff, sizeof(buff));
strmov(buff, line);
tmp= get_arg(buff, 0);
if (!tmp || !*tmp)
{
put_info("DELIMITER must be followed by a 'delimiter' char", INFO_ERROR);
return 0;
}
if (strlen(tmp)> 1)
{
put_info("Argument must be one char", INFO_ERROR);
return 0;
}
delimiter= *tmp;
return 0;
}
/* ARGSUSED */ /* ARGSUSED */
static int static int
......
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
#define DEFAULT_DELIMITER ';'
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC}; OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC};
...@@ -123,6 +124,8 @@ static int block_stack[BLOCK_STACK_DEPTH]; ...@@ -123,6 +124,8 @@ static int block_stack[BLOCK_STACK_DEPTH];
static int block_ok_stack[BLOCK_STACK_DEPTH]; static int block_ok_stack[BLOCK_STACK_DEPTH];
static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors; static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors;
static char delimiter= DEFAULT_DELIMITER;
DYNAMIC_ARRAY q_lines; DYNAMIC_ARRAY q_lines;
typedef struct typedef struct
...@@ -197,7 +200,7 @@ Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, ...@@ -197,7 +200,7 @@ Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
Q_WAIT_FOR_SLAVE_TO_STOP, Q_WAIT_FOR_SLAVE_TO_STOP,
Q_REQUIRE_VERSION, Q_REQUIRE_VERSION,
Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
Q_ENABLE_INFO, Q_DISABLE_INFO, Q_ENABLE_INFO, Q_DISABLE_INFO, Q_DELIMITER,
Q_UNKNOWN, /* Unknown command. */ Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */ Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND Q_COMMENT_WITH_COMMAND
...@@ -260,6 +263,7 @@ const char *command_names[]= ...@@ -260,6 +263,7 @@ const char *command_names[]=
"disable_warnings", "disable_warnings",
"enable_info", "enable_info",
"diable_info", "diable_info",
"delimiter",
0 0
}; };
...@@ -1537,6 +1541,16 @@ int do_while(struct st_query* q) ...@@ -1537,6 +1541,16 @@ int do_while(struct st_query* q)
return 0; return 0;
} }
int do_delimiter(char *p)
{
while (*p && my_isspace(system_charset_info,*p))
p++;
if (!*p)
die("Missing delimiter character\n");
delimiter=*p;
return 0;
}
int safe_copy_unescape(char* dest, char* src, int size) int safe_copy_unescape(char* dest, char* src, int size)
{ {
...@@ -1616,7 +1630,7 @@ int read_line(char* buf, int size) ...@@ -1616,7 +1630,7 @@ int read_line(char* buf, int size)
switch(state) { switch(state) {
case R_NORMAL: case R_NORMAL:
/* Only accept '{' in the beginning of a line */ /* Only accept '{' in the beginning of a line */
if (c == ';') if (c == delimiter)
{ {
*p = 0; *p = 0;
return 0; return 0;
...@@ -1656,7 +1670,7 @@ int read_line(char* buf, int size) ...@@ -1656,7 +1670,7 @@ int read_line(char* buf, int size)
*buf = 0; *buf = 0;
return 0; return 0;
} }
else if (c == ';' || c == '{') else if (c == delimiter || c == '{')
{ {
*p = 0; *p = 0;
return 0; return 0;
...@@ -1676,7 +1690,7 @@ int read_line(char* buf, int size) ...@@ -1676,7 +1690,7 @@ int read_line(char* buf, int size)
state = R_ESC_SLASH_Q1; state = R_ESC_SLASH_Q1;
break; break;
case R_ESC_Q_Q1: case R_ESC_Q_Q1:
if (c == ';') if (c == delimiter)
{ {
*p = 0; *p = 0;
return 0; return 0;
...@@ -1697,7 +1711,7 @@ int read_line(char* buf, int size) ...@@ -1697,7 +1711,7 @@ int read_line(char* buf, int size)
state = R_ESC_SLASH_Q2; state = R_ESC_SLASH_Q2;
break; break;
case R_ESC_Q_Q2: case R_ESC_Q_Q2:
if (c == ';') if (c == delimiter)
{ {
*p = 0; *p = 0;
return 0; return 0;
...@@ -2543,6 +2557,9 @@ int main(int argc, char** argv) ...@@ -2543,6 +2557,9 @@ int main(int argc, char** argv)
do_sync_with_master2(""); do_sync_with_master2("");
break; break;
} }
case Q_DELIMITER:
do_delimiter(q->first_argument);
break;
case Q_COMMENT: /* Ignore row */ case Q_COMMENT: /* Ignore row */
case Q_COMMENT_WITH_COMMAND: case Q_COMMENT_WITH_COMMAND:
case Q_PING: case Q_PING:
......
...@@ -66,6 +66,7 @@ c_h="" i_h="" ...@@ -66,6 +66,7 @@ c_h="" i_h=""
c_u="" i_u="" c_u="" i_u=""
c_f="" i_f="" c_f="" i_f=""
c_t="" c_c="" c_t="" c_c=""
c_p=""
# Check for old tables # Check for old tables
if test ! -f $mdata/db.frm if test ! -f $mdata/db.frm
...@@ -207,6 +208,16 @@ then ...@@ -207,6 +208,16 @@ then
c_c="$c_c comment='Column privileges';" c_c="$c_c comment='Column privileges';"
fi fi
if test ! -f $mdata/proc.frm
then
c_p="$c_p CREATE TABLE proc ("
c_p="$c_p name char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p body blob DEFAULT '' NOT NULL,"
c_p="$c_p PRIMARY KEY (name)"
c_p="$c_p )"
c_p="$c_p comment='Stored Procedures';"
fi
mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \ mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG" --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG"
echo "running $mysqld_boot" echo "running $mysqld_boot"
...@@ -227,6 +238,9 @@ $i_f ...@@ -227,6 +238,9 @@ $i_f
$c_t $c_t
$c_c $c_c
$c_p
END_OF_DATA END_OF_DATA
then then
exit 0 exit 0
......
...@@ -4,6 +4,7 @@ columns_priv ...@@ -4,6 +4,7 @@ columns_priv
db db
func func
host host
proc
tables_priv tables_priv
user user
show tables; show tables;
...@@ -16,6 +17,7 @@ columns_priv ...@@ -16,6 +17,7 @@ columns_priv
db db
func func
host host
proc
tables_priv tables_priv
user user
show tables; show tables;
...@@ -28,6 +30,7 @@ columns_priv ...@@ -28,6 +30,7 @@ columns_priv
db db
func func
host host
proc
tables_priv tables_priv
user user
show tables; show tables;
......
drop table if exists t1;
create table t1(a1 char(10));
create procedure a()
begin
insert into t1 values("aa");
insert into t1 values("ab");
end;
create procedure b()
begin
insert into t1 values("ba");
insert into t1 values("bb");
insert into t1 values("cc");
end;
call a();
call b();
select * from t1;
a1
aa
ab
ba
bb
cc
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1(a1 char(10));
delimiter |;
create procedure a()
begin
insert into t1 values("aa");
insert into t1 values("ab");
end|
create procedure b()
begin
insert into t1 values("ba");
insert into t1 values("bb");
insert into t1 values("cc");
end|
delimiter ;|
call a();
call b();
select * from t1;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment