Commit 8c5c4dd4 authored by unknown's avatar unknown

Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1

into teton.kitebird.com:/home/paul/mysql-4.1

parents 0b38cf97 24794dbc
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
**********************************************************************/ **********************************************************************/
#define MTEST_VERSION "2.0" #define MTEST_VERSION "2.1"
#include <my_global.h> #include <my_global.h>
#include <mysql_embed.h> #include <mysql_embed.h>
...@@ -54,13 +54,9 @@ ...@@ -54,13 +54,9 @@
#include <m_ctype.h> #include <m_ctype.h>
#include <my_dir.h> #include <my_dir.h>
#include <hash.h> #include <hash.h>
#include <stdio.h>
#include <stdlib.h>
#include <my_getopt.h> #include <my_getopt.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <violite.h> #include <violite.h>
#define MAX_QUERY 65536 #define MAX_QUERY 65536
...@@ -90,7 +86,8 @@ ...@@ -90,7 +86,8 @@
#define MAX_CON_TRIES 5 #define MAX_CON_TRIES 5
#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
#define DEFAULT_DELIMITER ";"
#define MAX_DELIMITER 16
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,
...@@ -118,6 +115,8 @@ static FILE** cur_file; ...@@ -118,6 +115,8 @@ static FILE** cur_file;
static FILE** file_stack_end; static FILE** file_stack_end;
static uint lineno_stack[MAX_INCLUDE_DEPTH]; static uint lineno_stack[MAX_INCLUDE_DEPTH];
static char TMPDIR[FN_REFLEN]; static char TMPDIR[FN_REFLEN];
static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER;
static uint delimiter_length= 1;
static int *cur_block, *block_stack_end; static int *cur_block, *block_stack_end;
static int block_stack[BLOCK_STACK_DEPTH]; static int block_stack[BLOCK_STACK_DEPTH];
...@@ -213,7 +212,8 @@ Q_WAIT_FOR_SLAVE_TO_STOP, ...@@ -213,7 +212,8 @@ 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_EXEC, Q_EXEC, 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
...@@ -285,6 +285,7 @@ const char *command_names[]= ...@@ -285,6 +285,7 @@ const char *command_names[]=
"enable_info", "enable_info",
"disable_info", "disable_info",
"exec", "exec",
"delimiter",
0 0
}; };
...@@ -1476,7 +1477,8 @@ int safe_connect(MYSQL* con, const char* host, const char* user, ...@@ -1476,7 +1477,8 @@ int safe_connect(MYSQL* con, const char* host, const char* user,
int i; int i;
for (i = 0; i < MAX_CON_TRIES; ++i) for (i = 0; i < MAX_CON_TRIES; ++i)
{ {
if (mysql_real_connect(con, host,user, pass, db, port, sock, 0)) if (mysql_real_connect(con, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS))
{ {
con_error = 0; con_error = 0;
break; break;
...@@ -1626,24 +1628,46 @@ int do_while(struct st_query* q) ...@@ -1626,24 +1628,46 @@ int do_while(struct st_query* q)
} }
my_bool end_of_query(int c, char* p)
{
uint i, j;
int tmp[MAX_DELIMITER]= {0};
for (i= 0; c == *(delimiter + i) && i < delimiter_length;
i++, c= fgetc(*cur_file))
tmp[i]= c;
tmp[i]= c;
for (j= i; j > 0 && i != delimiter_length; j--)
ungetc(tmp[j], *cur_file);
if (i == delimiter_length)
{
ungetc(tmp[i], *cur_file);
*p= 0;
return 1;
}
return 0;
}
int read_line(char* buf, int size) int read_line(char* buf, int size)
{ {
int c; int c;
char* p = buf, *buf_end = buf + size-1; char* p= buf, *buf_end= buf + size - 1;
int no_save = 0; int no_save= 0;
enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2, enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2,
R_ESC_SLASH_Q1, R_ESC_SLASH_Q2, R_ESC_SLASH_Q1, R_ESC_SLASH_Q2,
R_Q2, R_COMMENT, R_LINE_START} state = R_LINE_START; R_Q2, R_COMMENT, R_LINE_START} state= R_LINE_START;
start_lineno= *lineno; start_lineno= *lineno;
for (; p < buf_end ;) for (; p < buf_end ;)
{ {
no_save = 0; no_save= 0;
c = fgetc(*cur_file); c= fgetc(*cur_file);
if (feof(*cur_file)) if (feof(*cur_file))
{ {
if ((*cur_file) != stdin) if ((*cur_file) != stdin)
my_fclose(*cur_file,MYF(0)); my_fclose(*cur_file, MYF(0));
cur_file--; cur_file--;
lineno--; lineno--;
if (cur_file == file_stack) if (cur_file == file_stack)
...@@ -1654,11 +1678,8 @@ int read_line(char* buf, int size) ...@@ -1654,11 +1678,8 @@ 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 (end_of_query(c, p))
{
*p = 0;
return 0; return 0;
}
else if (c == '\'') else if (c == '\'')
state = R_Q1; state = R_Q1;
else if (c == '"') else if (c == '"')
...@@ -1672,7 +1693,7 @@ int read_line(char* buf, int size) ...@@ -1672,7 +1693,7 @@ int read_line(char* buf, int size)
case R_COMMENT: case R_COMMENT:
if (c == '\n') if (c == '\n')
{ {
*p=0; *p= 0;
(*lineno)++; (*lineno)++;
return 0; return 0;
} }
...@@ -1682,78 +1703,72 @@ int read_line(char* buf, int size) ...@@ -1682,78 +1703,72 @@ int read_line(char* buf, int size)
{ {
state = R_COMMENT; state = R_COMMENT;
} }
else if (my_isspace(charset_info,c)) else if (my_isspace(charset_info, c))
{ {
if (c == '\n') if (c == '\n')
start_lineno= ++*lineno; /* Query hasn't started yet */ start_lineno= ++*lineno; /* Query hasn't started yet */
no_save = 1; no_save= 1;
} }
else if (c == '}') else if (c == '}')
{ {
*buf++ = '}'; *buf++= '}';
*buf = 0; *buf= 0;
return 0; return 0;
} }
else if (c == ';' || c == '{') else if (end_of_query(c, p) || c == '{')
{ {
*p = 0; *p= 0;
return 0; return 0;
} }
else if (c == '\'') else if (c == '\'')
state = R_Q1; state= R_Q1;
else if (c == '"') else if (c == '"')
state = R_Q2; state= R_Q2;
else else
state = R_NORMAL; state= R_NORMAL;
break; break;
case R_Q1: case R_Q1:
if (c == '\'') if (c == '\'')
state = R_ESC_Q_Q1; state= R_ESC_Q_Q1;
else if (c == '\\') else if (c == '\\')
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 (end_of_query(c, p))
{
*p = 0;
return 0; return 0;
}
if (c != '\'') if (c != '\'')
state = R_NORMAL; state= R_NORMAL;
else else
state = R_Q1; state= R_Q1;
break; break;
case R_ESC_SLASH_Q1: case R_ESC_SLASH_Q1:
state = R_Q1; state= R_Q1;
break; break;
case R_Q2: case R_Q2:
if (c == '"') if (c == '"')
state = R_ESC_Q_Q2; state= R_ESC_Q_Q2;
else if (c == '\\') else if (c == '\\')
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 (end_of_query(c, p))
{
*p = 0;
return 0; return 0;
}
if (c != '"') if (c != '"')
state = R_NORMAL; state= R_NORMAL;
else else
state = R_Q2; state= R_Q2;
break; break;
case R_ESC_SLASH_Q2: case R_ESC_SLASH_Q2:
state = R_Q2; state= R_Q2;
break; break;
} }
if (!no_save) if (!no_save)
*p++ = c; *p++= c;
} }
*p=0; /* Always end with \0 */ *p= 0; /* Always end with \0 */
return feof(*cur_file); return feof(*cur_file);
} }
...@@ -1770,22 +1785,22 @@ int read_query(struct st_query** q_ptr) ...@@ -1770,22 +1785,22 @@ int read_query(struct st_query** q_ptr)
get_dynamic(&q_lines, (gptr) q_ptr, parser.current_line) ; get_dynamic(&q_lines, (gptr) q_ptr, parser.current_line) ;
return 0; return 0;
} }
if (!(*q_ptr=q=(struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) || if (!(*q_ptr= q= (struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) ||
insert_dynamic(&q_lines, (gptr) &q)) insert_dynamic(&q_lines, (gptr) &q))
die(NullS); die(NullS);
q->record_file[0] = 0; q->record_file[0]= 0;
q->require_file=0; q->require_file= 0;
q->first_word_len = 0; q->first_word_len= 0;
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno, memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
sizeof(global_expected_errno)); sizeof(global_expected_errno));
q->expected_errors=global_expected_errors; q->expected_errors= global_expected_errors;
q->abort_on_error = global_expected_errno[0] == 0; q->abort_on_error= global_expected_errno[0] == 0;
bzero((gptr) global_expected_errno,sizeof(global_expected_errno)); bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
global_expected_errors=0; global_expected_errors=0;
q->type = Q_UNKNOWN; q->type = Q_UNKNOWN;
q->query_buf=q->query=0; q->query_buf= q->query= 0;
if (read_line(read_query_buf, sizeof(read_query_buf))) if (read_line(read_query_buf, sizeof(read_query_buf)))
return 1; return 1;
...@@ -1795,20 +1810,20 @@ int read_query(struct st_query** q_ptr) ...@@ -1795,20 +1810,20 @@ int read_query(struct st_query** q_ptr)
} }
else if (p[0] == '-' && p[1] == '-') else if (p[0] == '-' && p[1] == '-')
{ {
q->type = Q_COMMENT_WITH_COMMAND; q->type= Q_COMMENT_WITH_COMMAND;
p+=2; /* To calculate first word */ p+= 2; /* To calculate first word */
} }
else else
{ {
if (*p == '!') if (*p == '!')
{ {
q->abort_on_error = 0; q->abort_on_error= 0;
p++; p++;
if (*p == '$') if (*p == '$')
{ {
expected_errno = 0; expected_errno= 0;
p++; p++;
for (;my_isdigit(charset_info,*p);p++) for (; my_isdigit(charset_info, *p); p++)
expected_errno = expected_errno * 10 + *p - '0'; expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0] = expected_errno; q->expected_errno[0] = expected_errno;
q->expected_errno[1] = 0; q->expected_errno[1] = 0;
...@@ -1816,30 +1831,30 @@ int read_query(struct st_query** q_ptr) ...@@ -1816,30 +1831,30 @@ int read_query(struct st_query** q_ptr)
} }
} }
while (*p && my_isspace(charset_info,*p)) while (*p && my_isspace(charset_info, *p))
p++ ; p++ ;
if (*p == '@') if (*p == '@')
{ {
p++; p++;
p1 = q->record_file; p1 = q->record_file;
while (!my_isspace(charset_info,*p) && while (!my_isspace(charset_info, *p) &&
p1 < q->record_file + sizeof(q->record_file) - 1) p1 < q->record_file + sizeof(q->record_file) - 1)
*p1++ = *p++; *p1++ = *p++;
*p1 = 0; *p1 = 0;
} }
} }
while (*p && my_isspace(charset_info,*p)) while (*p && my_isspace(charset_info, *p))
p++; p++;
if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME)))) if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME))))
die(NullS); die(NullS);
/* Calculate first word and first argument */ /* Calculate first word and first argument */
for (p=q->query; *p && !my_isspace(charset_info,*p) ; p++) ; for (p= q->query; *p && !my_isspace(charset_info, *p) ; p++) ;
q->first_word_len = (uint) (p - q->query); q->first_word_len= (uint) (p - q->query);
while (*p && my_isspace(charset_info,*p)) while (*p && my_isspace(charset_info, *p))
p++; p++;
q->first_argument=p; q->first_argument= p;
q->end = strend(q->query); q->end= strend(q->query);
parser.read_lines++; parser.read_lines++;
return 0; return 0;
} }
...@@ -2133,12 +2148,12 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) ...@@ -2133,12 +2148,12 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
int run_query(MYSQL* mysql, struct st_query* q, int flags) int run_query(MYSQL* mysql, struct st_query* q, int flags)
{ {
MYSQL_RES* res = 0; MYSQL_RES* res= 0;
int i, error = 0; int i, error= 0, err= 0, counter= 0;
DYNAMIC_STRING *ds; DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query; DYNAMIC_STRING eval_query;
char* query; char* query, buff[MAX_DELIMITER + 1]= {0};
int query_len; int query_len;
DBUG_ENTER("run_query"); DBUG_ENTER("run_query");
...@@ -2166,150 +2181,159 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) ...@@ -2166,150 +2181,159 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len)) if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len))
die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)", die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)",
start_lineno, query, start_lineno, query, mysql_errno(mysql), errno);
mysql_errno(mysql), errno);
if ((flags & QUERY_SEND) && !disable_query_log)
{
replace_dynstr_append_mem(ds,query, query_len);
dynstr_append_mem(ds,";\n",2);
}
if (!(flags & QUERY_REAP))
DBUG_RETURN(0);
if ((*mysql->methods->read_query_result)(mysql) || do
(!(last_result = res = mysql_store_result(mysql)) &&
mysql_field_count(mysql)))
{ {
if (q->require_file) if ((flags & QUERY_SEND) && !disable_query_log && !counter)
{ {
abort_not_supported_test(); replace_dynstr_append_mem(ds,query, query_len);
sprintf(buff, "%s\n", delimiter);
dynstr_append_mem(ds, buff, delimiter_length + 1);
} }
if (q->abort_on_error) if (!(flags & QUERY_REAP))
die("At line %u: query '%s' failed: %d: %s", start_lineno, query, DBUG_RETURN(0);
mysql_errno(mysql), mysql_error(mysql));
else if ((!counter && (*mysql->methods->read_query_result)(mysql)) ||
(!(last_result= res= mysql_store_result(mysql)) &&
mysql_field_count(mysql)))
{ {
for (i=0 ; (uint) i < q->expected_errors ; i++) if (q->require_file)
{
abort_not_supported_test();
}
if (q->abort_on_error)
die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
mysql_errno(mysql), mysql_error(mysql));
else
{ {
if ((q->expected_errno[i] == mysql_errno(mysql))) for (i=0 ; (uint) i < q->expected_errors ; i++)
{ {
if (i == 0 && q->expected_errors == 1) if ((q->expected_errno[i] == mysql_errno(mysql)))
{ {
/* Only log error if there is one possible error */ if (i == 0 && q->expected_errors == 1)
dynstr_append_mem(ds,"ERROR ",6); {
replace_dynstr_append_mem(ds, mysql_sqlstate(mysql), /* Only log error if there is one possible error */
strlen(mysql_sqlstate(mysql))); dynstr_append_mem(ds,"ERROR ",6);
dynstr_append_mem(ds,": ",2); replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
replace_dynstr_append_mem(ds,mysql_error(mysql), strlen(mysql_sqlstate(mysql)));
strlen(mysql_error(mysql))); dynstr_append_mem(ds, ": ", 2);
dynstr_append_mem(ds,"\n",1); replace_dynstr_append_mem(ds,mysql_error(mysql),
strlen(mysql_error(mysql)));
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (q->expected_errno[0] != 0)
dynstr_append(ds,"Got one of the listed errors\n");
goto end; /* Ok */
} }
/* Don't log error if we may not get an error */
else if (q->expected_errno[0] != 0)
dynstr_append(ds,"Got one of the listed errors\n");
goto end; /* Ok */
} }
} DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors));
DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors)); dynstr_append_mem(ds, "ERROR ",6);
dynstr_append_mem(ds,"ERROR ",6); replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
replace_dynstr_append_mem(ds, mysql_sqlstate(mysql), strlen(mysql_sqlstate(mysql)));
strlen(mysql_sqlstate(mysql))); dynstr_append_mem(ds,": ",2);
dynstr_append_mem(ds,": ",2); replace_dynstr_append_mem(ds, mysql_error(mysql),
replace_dynstr_append_mem(ds, mysql_error(mysql), strlen(mysql_error(mysql)));
strlen(mysql_error(mysql))); dynstr_append_mem(ds,"\n",1);
dynstr_append_mem(ds,"\n",1); if (i)
if (i) {
{ verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
verbose_msg("query '%s' failed with wrong errno %d instead of %d...", q->query, mysql_errno(mysql), q->expected_errno[0]);
q->query, mysql_errno(mysql), q->expected_errno[0]); error= 1;
error= 1; goto end;
}
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
mysql_error(mysql));
/*
if we do not abort on error, failure to run the query does
not fail the whole test case
*/
goto end; goto end;
} }
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), /*{
mysql_error(mysql)); verbose_msg("failed in mysql_store_result for query '%s' (%d)", query,
/* mysql_errno(mysql));
if we do not abort on error, failure to run the query does error = 1;
not fail the whole test case goto end;
*/ }*/
goto end;
} }
/*{
verbose_msg("failed in mysql_store_result for query '%s' (%d)", query, if (q->expected_errno[0])
mysql_errno(mysql)); {
error = 1; error = 1;
verbose_msg("query '%s' succeeded - should have failed with errno %d...",
q->query, q->expected_errno[0]);
goto end; goto end;
}*/ }
}
if (q->expected_errno[0])
{
error = 1;
verbose_msg("query '%s' succeeded - should have failed with errno %d...",
q->query, q->expected_errno[0]);
goto end;
}
if (!disable_result_log) if (!disable_result_log)
{
if (res)
{ {
int num_fields= mysql_num_fields(res); if (res)
MYSQL_FIELD *fields= mysql_fetch_fields(res);
for (i = 0; i < num_fields; i++)
{ {
if (i) int num_fields= mysql_num_fields(res);
dynstr_append_mem(ds, "\t", 1); MYSQL_FIELD *fields= mysql_fetch_fields(res);
dynstr_append(ds, fields[i].name);
for (i = 0; i < num_fields; i++)
{
if (i)
dynstr_append_mem(ds, "\t", 1);
dynstr_append(ds, fields[i].name);
}
dynstr_append_mem(ds, "\n", 1);
append_result(ds, res);
} }
dynstr_append_mem(ds, "\n", 1);
append_result(ds, res);
}
/* Add all warnings to the result */ /* Add all warnings to the result */
if (!disable_warnings && mysql_warning_count(mysql)) if (!disable_warnings && mysql_warning_count(mysql))
{
MYSQL_RES *warn_res=0;
uint count= mysql_warning_count(mysql);
if (!mysql_real_query(mysql, "SHOW WARNINGS", 13))
{ {
warn_res=mysql_store_result(mysql); MYSQL_RES *warn_res=0;
uint count= mysql_warning_count(mysql);
if (!mysql_real_query(mysql, "SHOW WARNINGS", 13))
{
warn_res= mysql_store_result(mysql);
}
if (!warn_res)
verbose_msg("Warning count is %u but didn't get any warnings\n",
count);
else
{
dynstr_append_mem(ds, "Warnings:\n", 10);
append_result(ds, warn_res);
mysql_free_result(warn_res);
}
} }
if (!warn_res) if (!disable_info && mysql_info(mysql))
verbose_msg("Warning count is %u but didn't get any warnings\n",
count);
else
{ {
dynstr_append_mem(ds, "Warnings:\n", 10); dynstr_append(ds, "info: ");
append_result(ds, warn_res); dynstr_append(ds, mysql_info(mysql));
mysql_free_result(warn_res); dynstr_append_mem(ds, "\n", 1);
} }
} }
if (!disable_info && mysql_info(mysql))
{
dynstr_append(ds, "info: ");
dynstr_append(ds, mysql_info(mysql));
dynstr_append_mem(ds, "\n", 1);
}
}
if (glob_replace) if (glob_replace)
free_replace(); free_replace();
if (record) if (record)
{ {
if (!q->record_file[0] && !result_file) if (!q->record_file[0] && !result_file)
die("At line %u: Missing result file", start_lineno); die("At line %u: Missing result file", start_lineno);
if (!result_file) if (!result_file)
str_to_file(q->record_file, ds->str, ds->length); str_to_file(q->record_file, ds->str, ds->length);
} }
else if (q->record_file[0]) else if (q->record_file[0])
{ {
error = check_result(ds, q->record_file, q->require_file); error = check_result(ds, q->record_file, q->require_file);
} }
if (res)
mysql_free_result(res);
last_result= 0;
counter++;
} while (!(err= mysql_next_result(mysql)));
if (err >= 1)
mysql_error(mysql);
end: end:
if (res)
mysql_free_result(res);
last_result=0; last_result=0;
if (ds == &ds_tmp) if (ds == &ds_tmp)
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
...@@ -2524,6 +2548,10 @@ int main(int argc, char **argv) ...@@ -2524,6 +2548,10 @@ int main(int argc, char **argv)
case Q_DEC: do_dec(q); break; case Q_DEC: do_dec(q); break;
case Q_ECHO: do_echo(q); break; case Q_ECHO: do_echo(q); break;
case Q_SYSTEM: do_system(q); break; case Q_SYSTEM: do_system(q); break;
case Q_DELIMITER:
strmake(delimiter, q->first_argument, sizeof(delimiter) - 1);
delimiter_length= strlen(delimiter);
break;
case Q_LET: do_let(q); break; case Q_LET: do_let(q); break;
case Q_EVAL_RESULT: eval_result = 1; break; case Q_EVAL_RESULT: eval_result = 1; break;
case Q_EVAL: case Q_EVAL:
...@@ -2653,6 +2681,7 @@ int main(int argc, char **argv) ...@@ -2653,6 +2681,7 @@ int main(int argc, char **argv)
} }
} }
/* /*
Read arguments for embedded server and put them into Read arguments for embedded server and put them into
embedded_server_args_count and embedded_server_args[] embedded_server_args_count and embedded_server_args[]
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "heapdef.h" #include "heapdef.h"
#include <m_ctype.h> #include <m_ctype.h>
#include <assert.h>
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key,
uint start_key_len, uint start_key_len,
...@@ -566,50 +567,87 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record) ...@@ -566,50 +567,87 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
return 0; return 0;
} }
/*
Update auto_increment info
SYNOPSIS
update_auto_increment()
info MyISAM handler
record Row to update
IMPLEMENTATION
Only replace the auto_increment value if it is higher than the previous
one. For signed columns we don't update the auto increment value if it's
less than zero.
*/
void heap_update_auto_increment(HP_INFO *info, const byte *record) void heap_update_auto_increment(HP_INFO *info, const byte *record)
{ {
ulonglong value; ulonglong value= 0; /* Store unsigned values here */
longlong s_value= 0; /* Store signed values here */
HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg; HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
const uchar *key= (uchar*) record + keyseg->start; const uchar *key= (uchar*) record + keyseg->start;
switch (info->s->auto_key_type) { switch (info->s->auto_key_type) {
case HA_KEYTYPE_INT8: case HA_KEYTYPE_INT8:
s_value= (longlong) *(char*)key;
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
value= (ulonglong) *(uchar*) key; value=(ulonglong) *(uchar*) key;
break; break;
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
s_value= (longlong) sint2korr(key);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
value= (ulonglong) uint2korr(key); value=(ulonglong) uint2korr(key);
break; break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
s_value= (longlong) sint4korr(key);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
value= (ulonglong) uint4korr(key); value=(ulonglong) uint4korr(key);
break; break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
s_value= (longlong) sint3korr(key);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
value= (ulonglong) uint3korr(key); value=(ulonglong) uint3korr(key);
break; break;
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
{ {
float f_1; float f_1;
float4get(f_1, key); float4get(f_1,key);
value= (ulonglong) f_1; /* Ignore negative values */
value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
break; break;
} }
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
{ {
double f_1; double f_1;
float8get(f_1, key); float8get(f_1,key);
value= (ulonglong) f_1; /* Ignore negative values */
value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
break; break;
} }
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
s_value= sint8korr(key);
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
value= uint8korr(key); value= uint8korr(key);
break; break;
default: default:
value= 0; /* Error */ DBUG_ASSERT(0);
value=0; /* Error */
break; break;
} }
set_if_bigger(info->s->auto_increment, value);
/*
The following code works becasue if s_value < 0 then value is 0
and if s_value == 0 then value will contain either s_value or the
correct value.
*/
set_if_bigger(info->s->auto_increment,
(s_value > 0) ? (ulonglong) s_value : value);
} }
...@@ -407,6 +407,28 @@ a b c d e f g h dd ...@@ -407,6 +407,28 @@ a b c d e f g h dd
1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00 1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00
2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00 2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00
drop table t1, t2; drop table t1, t2;
create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10));
create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`ifnull(a,a)` tinyint(4) default NULL,
`ifnull(b,b)` smallint(6) default NULL,
`ifnull(c,c)` mediumint(9) default NULL,
`ifnull(d,d)` int(11) default NULL,
`ifnull(e,e)` bigint(20) default NULL,
`ifnull(f,f)` float(3,2) default NULL,
`ifnull(g,g)` double(4,3) default NULL,
`ifnull(h,h)` decimal(5,4) default NULL,
`ifnull(i,i)` year(4) default NULL,
`ifnull(j,j)` date default NULL,
`ifnull(k,k)` datetime NOT NULL default '0000-00-00 00:00:00',
`ifnull(l,l)` datetime default NULL,
`ifnull(m,m)` char(1) default NULL,
`ifnull(n,n)` char(3) default NULL,
`ifnull(o,o)` char(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14'); create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14');
insert into t1 values ('','',0,0.0); insert into t1 values ('','',0,0.0);
describe t1; describe t1;
......
...@@ -6,6 +6,12 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -6,6 +6,12 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select high_priority interval((55,10,20,30,40,50,60,70,80,90,100)) AS `INTERVAL(55,10,20,30,40,50,60,70,80,90,100)`,interval((3,1,(1 + 1),(((1 + 1) + 1) + 1))) AS `interval(3,1,1+1,1+1+1+1)`,field(_latin1'IBM',_latin1'NCA',_latin1'ICL',_latin1'SUN',_latin1'IBM',_latin1'DIGITAL') AS `field("IBM","NCA","ICL","SUN","IBM","DIGITAL")`,field(_latin1'A',_latin1'B',_latin1'C') AS `field("A","B","C")`,elt(2,_latin1'ONE',_latin1'TWO',_latin1'THREE') AS `elt(2,"ONE","TWO","THREE")`,interval((0,1,2,3,4)) AS `interval(0,1,2,3,4)`,(elt(1,1,2,3) | 0) AS `elt(1,1,2,3)|0`,(elt(1,1.1,1.2,1.3) + 0) AS `elt(1,1.1,1.2,1.3)+0` Note 1003 select high_priority interval((55,10,20,30,40,50,60,70,80,90,100)) AS `INTERVAL(55,10,20,30,40,50,60,70,80,90,100)`,interval((3,1,(1 + 1),(((1 + 1) + 1) + 1))) AS `interval(3,1,1+1,1+1+1+1)`,field(_latin1'IBM',_latin1'NCA',_latin1'ICL',_latin1'SUN',_latin1'IBM',_latin1'DIGITAL') AS `field("IBM","NCA","ICL","SUN","IBM","DIGITAL")`,field(_latin1'A',_latin1'B',_latin1'C') AS `field("A","B","C")`,elt(2,_latin1'ONE',_latin1'TWO',_latin1'THREE') AS `elt(2,"ONE","TWO","THREE")`,interval((0,1,2,3,4)) AS `interval(0,1,2,3,4)`,(elt(1,1,2,3) | 0) AS `elt(1,1,2,3)|0`,(elt(1,1.1,1.2,1.3) + 0) AS `elt(1,1.1,1.2,1.3)+0`
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56)
1
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77)
1
select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd"); select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
find_in_set("b","a,b,c") find_in_set("c","a,b,c") find_in_set("dd","a,bbb,dd") find_in_set("bbb","a,bbb,dd") find_in_set("b","a,b,c") find_in_set("c","a,b,c") find_in_set("dd","a,bbb,dd") find_in_set("bbb","a,bbb,dd")
2 3 3 2 2 3 3 2
...@@ -50,9 +56,3 @@ id elt(two.val,'one','two') ...@@ -50,9 +56,3 @@ id elt(two.val,'one','two')
2 one 2 one
4 two 4 two
drop table t1,t2; drop table t1,t2;
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56)
1
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77)
1
select 1;
1
1
select 2;
select 3;
select 4||||
2
2
3
3
4
4
select 5;
select 6;
select 50, 'abc';'abcd'
5
5
6
6
50 abc
50 abc
select "abcd'";'abcd'
abcd'
abcd'
select "'abcd";'abcd'
'abcd
'abcd
select 5'abcd'
5
5
select 'finish';
finish
finish
...@@ -64,7 +64,7 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); ...@@ -64,7 +64,7 @@ INSERT INTO t1 VALUES ("1\""), ("\"2");
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r;
INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5');
-- MySQL dump 10.2 -- MySQL dump 10.3
-- --
-- Host: localhost Database: test -- Host: localhost Database: test
-- ------------------------------------------------------ -- ------------------------------------------------------
......
...@@ -1636,6 +1636,7 @@ t1 CREATE TABLE `t1` ( ...@@ -1636,6 +1636,7 @@ t1 CREATE TABLE `t1` (
`a` enum('','a','b') NOT NULL default 'b' `a` enum('','a','b') NOT NULL default 'b'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
set names latin1;
create table t1 (a enum(0xE4, '1', '2') not null default 0xE4); create table t1 (a enum(0xE4, '1', '2') not null default 0xE4);
show columns from t1; show columns from t1;
Field Type Null Key Default Extra Field Type Null Key Default Extra
...@@ -1643,6 +1644,6 @@ a enum(' ...@@ -1643,6 +1644,6 @@ a enum('
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` enum('','1','2') NOT NULL default '?' `a` enum('','1','2') NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
...@@ -318,11 +318,17 @@ select ...@@ -318,11 +318,17 @@ select
addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
from t1; from t1;
explain t2; explain t2;
select * from t2; select * from t2;
drop table t1, t2; drop table t1, t2;
create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10));
create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
show create table t2;
drop table t1,t2;
#
# Test of default()
#
create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14'); create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14');
insert into t1 values ('','',0,0.0); insert into t1 values ('','',0,0.0);
describe t1; describe t1;
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
select interval(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0; select interval(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
explain extended select INTERVAL(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0; explain extended select INTERVAL(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
# Test 8 and 9 values (Bug #1561)
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd"); select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
select find_in_set("d","a,b,c"),find_in_set("dd","a,bbb,d"),find_in_set("bb","a,bbb,dd"); select find_in_set("d","a,b,c"),find_in_set("dd","a,bbb,d"),find_in_set("bb","a,bbb,dd");
select make_set(0,'a','b','c'),make_set(-1,'a','b','c'),make_set(1,'a','b','c'),make_set(2,'a','b','c'),make_set(1+2,concat('a','b'),'c'); select make_set(0,'a','b','c'),make_set(-1,'a','b','c'),make_set(1,'a','b','c'),make_set(2,'a','b','c'),make_set(1+2,concat('a','b'),'c');
...@@ -35,8 +39,3 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2); ...@@ -35,8 +39,3 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2);
select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id;
select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
drop table t1,t2; drop table t1,t2;
# some more INTERVAL tests
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
select 1;
delimiter ||||;
select 2;
select 3;
select 4||||
delimiter 'abcd'||||
select 5;
select 6;
select 50, 'abc';'abcd'
select "abcd'";'abcd'select "'abcd";'abcd'
select 5'abcd'
delimiter ;'abcd'
select 'finish';
...@@ -24,7 +24,6 @@ sleep 5; ...@@ -24,7 +24,6 @@ sleep 5;
show slave status; show slave status;
stop slave; stop slave;
change master to master_log_pos=173; change master to master_log_pos=173;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
start slave; start slave;
sleep 2; sleep 2;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
......
...@@ -29,8 +29,8 @@ drop table t1; ...@@ -29,8 +29,8 @@ drop table t1;
# Bug #2077 # Bug #2077
# #
set names latin1;
create table t1 (a enum(0xE4, '1', '2') not null default 0xE4); create table t1 (a enum(0xE4, '1', '2') not null default 0xE4);
show columns from t1; show columns from t1;
# should be fixed ASAP
show create table t1; show create table t1;
drop table t1; drop table t1;
...@@ -5192,16 +5192,21 @@ void Field_enum::sort_string(char *to,uint length __attribute__((unused))) ...@@ -5192,16 +5192,21 @@ void Field_enum::sort_string(char *to,uint length __attribute__((unused)))
void Field_enum::sql_type(String &res) const void Field_enum::sql_type(String &res) const
{ {
char buffer[255];
String enum_item(buffer, sizeof(buffer), res.charset());
res.length(0); res.length(0);
res.append("enum("); res.append("enum(");
bool flag=0; bool flag=0;
for (const char **pos=typelib->type_names; *pos ; pos++) for (const char **pos= typelib->type_names; *pos; pos++)
{ {
if (flag) if (flag)
res.append(','); res.append(',');
append_unescaped(&res, *pos, strlen(*pos)); /* convert to res.charset() == utf8, then quote */
flag=1; enum_item.copy(*pos, strlen(*pos), charset(), res.charset());
append_unescaped(&res, enum_item.ptr(), enum_item.length());
flag= 1;
} }
res.append(')'); res.append(')');
} }
...@@ -5300,16 +5305,21 @@ String *Field_set::val_str(String *val_buffer, ...@@ -5300,16 +5305,21 @@ String *Field_set::val_str(String *val_buffer,
void Field_set::sql_type(String &res) const void Field_set::sql_type(String &res) const
{ {
char buffer[255];
String set_item(buffer, sizeof(buffer), res.charset());
res.length(0); res.length(0);
res.append("set("); res.append("set(");
bool flag=0; bool flag=0;
for (const char **pos=typelib->type_names; *pos ; pos++) for (const char **pos= typelib->type_names; *pos; pos++)
{ {
if (flag) if (flag)
res.append(','); res.append(',');
append_unescaped(&res, *pos, strlen(*pos)); /* convert to res.charset() == utf8, then quote */
flag=1; set_item.copy(*pos, strlen(*pos), charset(), res.charset());
append_unescaped(&res, set_item.ptr(), set_item.length());
flag= 1;
} }
res.append(')'); res.append(')');
} }
......
...@@ -327,11 +327,6 @@ public: ...@@ -327,11 +327,6 @@ public:
unireg_check_arg, field_name_arg, table_arg, unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg) dec_arg, zero_arg,unsigned_arg)
{} {}
Field_decimal(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg,bool unsigned_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg,0,0,unsigned_arg)
{}
enum_field_types type() const { return FIELD_TYPE_DECIMAL;} enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
...@@ -362,11 +357,6 @@ public: ...@@ -362,11 +357,6 @@ public:
unireg_check_arg, field_name_arg, table_arg, unireg_check_arg, field_name_arg, table_arg,
0, zero_arg,unsigned_arg) 0, zero_arg,unsigned_arg)
{} {}
Field_tiny(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg,bool unsigned_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg,0,0,unsigned_arg)
{}
enum Item_result result_type () const { return INT_RESULT; } enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return FIELD_TYPE_TINY;} enum_field_types type() const { return FIELD_TYPE_TINY;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
...@@ -608,13 +598,9 @@ public: ...@@ -608,13 +598,9 @@ public:
:Field_str(ptr_arg, len_arg, null, 1, :Field_str(ptr_arg, len_arg, null, 1,
unireg_check_arg, field_name_arg, table_arg, cs) unireg_check_arg, field_name_arg, table_arg, cs)
{} {}
Field_null(uint32 len_arg, const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0, len_arg, null, 1,
NONE, field_name_arg, table_arg, cs)
{}
enum_field_types type() const { return FIELD_TYPE_NULL;} enum_field_types type() const { return FIELD_TYPE_NULL;}
int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } int store(const char *to, uint length, CHARSET_INFO *cs)
{ null[0]=1; return 0; }
int store(double nr) { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; }
int store(longlong nr) { null[0]=1; return 0; } int store(longlong nr) { null[0]=1; return 0; }
void reset(void) {} void reset(void) {}
...@@ -684,10 +670,6 @@ public: ...@@ -684,10 +670,6 @@ public:
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, 1, 1) unireg_check_arg, field_name_arg, table_arg, 1, 1)
{} {}
Field_year(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_tiny(len_arg,maybe_null_arg,field_name_arg,table_arg,1)
{}
enum_field_types type() const { return FIELD_TYPE_YEAR;} enum_field_types type() const { return FIELD_TYPE_YEAR;}
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
......
...@@ -995,35 +995,42 @@ enum_field_types Item::field_type() const ...@@ -995,35 +995,42 @@ enum_field_types Item::field_type() const
Field *Item::tmp_table_field_from_field_type(TABLE *table) Field *Item::tmp_table_field_from_field_type(TABLE *table)
{ {
switch (field_type()) /*
{ The field functions defines a field to be not null if null_ptr is not 0
*/
uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
switch (field_type()) {
case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_DECIMAL:
return new Field_decimal(max_length, maybe_null, name, table, return new Field_decimal((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, decimals, 0, unsigned_flag);
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
return new Field_tiny(max_length, maybe_null, name, table, return new Field_tiny((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, 0, unsigned_flag);
case MYSQL_TYPE_SHORT: case MYSQL_TYPE_SHORT:
return new Field_short(max_length, maybe_null, name, table, return new Field_short((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, 0, unsigned_flag);
case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONG:
return new Field_long(max_length, maybe_null, name, table, return new Field_long((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, 0, unsigned_flag);
case MYSQL_TYPE_FLOAT:
return new Field_float(max_length, maybe_null, name, table, decimals);
case MYSQL_TYPE_DOUBLE:
return new Field_double(max_length, maybe_null, name, table, decimals);
case MYSQL_TYPE_NULL:
return new Field_null(max_length, name, table, &my_charset_bin);
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_LONGLONG:
return new Field_longlong(max_length, maybe_null, name, table, return new Field_longlong((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, 0, unsigned_flag);
#endif #endif
case MYSQL_TYPE_FLOAT:
return new Field_float((char*) 0, max_length, null_ptr, 0, Field::NONE,
name, table, decimals, 0, unsigned_flag);
case MYSQL_TYPE_DOUBLE:
return new Field_double((char*) 0, max_length, null_ptr, 0, Field::NONE,
name, table, decimals, 0, unsigned_flag);
case MYSQL_TYPE_NULL:
return new Field_null((char*) 0, max_length, Field::NONE,
name, table, &my_charset_bin);
case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_INT24: case MYSQL_TYPE_INT24:
return new Field_long(max_length, maybe_null, name, table, return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE,
unsigned_flag); name, table, 0, unsigned_flag);
case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, &my_charset_bin); return new Field_date(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME:
...@@ -1032,34 +1039,38 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) ...@@ -1032,34 +1039,38 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME:
return new Field_datetime(maybe_null, name, table, &my_charset_bin); return new Field_datetime(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_YEAR: case MYSQL_TYPE_YEAR:
return new Field_year(max_length, maybe_null, name, table); return new Field_year((char*) 0, max_length, null_ptr, 0, Field::NONE,
name, table);
default:
/* This case should never be choosen */
DBUG_ASSERT(0);
/* If something goes awfully wrong, it's better to get a string than die */
case MYSQL_TYPE_ENUM: case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET: case MYSQL_TYPE_SET:
return new Field_long(max_length, maybe_null, name, table, case MYSQL_TYPE_VAR_STRING:
unsigned_flag); if (max_length > 255)
break; // If blob
return new Field_varstring(max_length, maybe_null, name, table,
collation.collation);
case MYSQL_TYPE_STRING:
if (max_length > 255) // If blob
break;
return new Field_string(max_length, maybe_null, name, table,
collation.collation);
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_GEOMETRY:
return new Field_blob(max_length, maybe_null, name, table, collation.collation); break; // Blob handled outside of case
case MYSQL_TYPE_VAR_STRING:
if (max_length > 255)
return new Field_blob(max_length, maybe_null, name, table, collation.collation);
else
return new Field_varstring(max_length, maybe_null, name, table, collation.collation);
case MYSQL_TYPE_STRING:
if (max_length > 255)
return new Field_blob(max_length, maybe_null, name, table, collation.collation);
else
return new Field_string(max_length, maybe_null, name, table, collation.collation);
default:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
/* blob is special as it's generated for both blobs and long strings */
return new Field_blob(max_length, maybe_null, name, table,
collation.collation);
} }
/* ARGSUSED */ /* ARGSUSED */
void Item_field::make_field(Send_field *tmp_field) void Item_field::make_field(Send_field *tmp_field)
{ {
......
...@@ -2787,6 +2787,9 @@ int main(int argc, char **argv) ...@@ -2787,6 +2787,9 @@ int main(int argc, char **argv)
int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name, int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10); "MySQLShutdown"), 10);
/* Must be initialized early for comparison of service name */
system_charset_info= &my_charset_utf8_general_ci;
if (Service.GetOS()) /* true NT family */ if (Service.GetOS()) /* true NT family */
{ {
char file_path[FN_REFLEN]; char file_path[FN_REFLEN];
......
...@@ -688,14 +688,14 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, ...@@ -688,14 +688,14 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
{ {
byte *pos; byte *pos;
uint flags=field->flags; uint flags=field->flags;
String type(tmp,sizeof(tmp), field->charset()); String type(tmp,sizeof(tmp), system_charset_info);
uint col_access; uint col_access;
bool null_default_value=0; bool null_default_value=0;
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(field->field_name, system_charset_info); protocol->store(field->field_name, system_charset_info);
field->sql_type(type); field->sql_type(type);
protocol->store(type.ptr(), type.length(), type.charset()); protocol->store(type.ptr(), type.length(), system_charset_info);
if (verbose) if (verbose)
protocol->store(field->has_charset() ? field->charset()->name : "NULL", protocol->store(field->has_charset() ? field->charset()->name : "NULL",
system_charset_info); system_charset_info);
...@@ -1117,7 +1117,13 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1117,7 +1117,13 @@ store_create_info(THD *thd, TABLE *table, String *packet)
type.set(tmp, sizeof(tmp), field->charset()); type.set(tmp, sizeof(tmp), field->charset());
field->val_str(&type,&type); field->val_str(&type,&type);
if (type.length()) if (type.length())
append_unescaped(packet, type.ptr(), type.length()); {
String def_val;
/* convert to system_charset_info == utf8 */
def_val.copy(type.ptr(), type.length(), field->charset(),
system_charset_info);
append_unescaped(packet, def_val.ptr(), def_val.length());
}
else else
packet->append("''",2); packet->append("''",2);
} }
......
...@@ -1058,9 +1058,21 @@ ulong next_io_size(register ulong pos) ...@@ -1058,9 +1058,21 @@ ulong next_io_size(register ulong pos)
} /* next_io_size */ } /* next_io_size */
/* Store in String an SQL quoted string */ /*
Store an SQL quoted string.
SYNOPSIS
append_unescaped()
res result String
pos string to be quoted
length it's length
NOTE
This function works correctly with utf8 or single-byte charset strings.
May fail with some multibyte charsets though.
*/
void append_unescaped(String *res,const char *pos, uint length) void append_unescaped(String *res, const char *pos, uint length)
{ {
const char *end= pos+length; const char *end= pos+length;
res->append('\''); res->append('\'');
......
...@@ -55,6 +55,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, ...@@ -55,6 +55,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr; vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking; vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking; vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ignore_timeout;
} }
else /* default is VIO_TYPE_TCPIP */ else /* default is VIO_TYPE_TCPIP */
#endif #endif
...@@ -73,6 +74,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, ...@@ -73,6 +74,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr; vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking; vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking; vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ignore_timeout;
} }
else else
#endif #endif
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <m_string.h> #include <m_string.h>
#include <violite.h> #include <violite.h>
void vio_ignore_timeout(Vio *vio, uint timeout);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
#include "my_net.h" /* needed because of struct in_addr */ #include "my_net.h" /* needed because of struct in_addr */
......
...@@ -355,6 +355,13 @@ int vio_close_pipe(Vio * vio) ...@@ -355,6 +355,13 @@ int vio_close_pipe(Vio * vio)
DBUG_RETURN(r); DBUG_RETURN(r);
} }
void vio_ignore_timeout(Vio *vio __attribute__((unused)),
uint timeout __attribute__((unused)))
{
}
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
int vio_read_shared_memory(Vio * vio, gptr buf, int size) int vio_read_shared_memory(Vio * vio, gptr buf, int size)
......
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