Commit da7dc303 authored by Alexey Kopytov's avatar Alexey Kopytov

Automerge.

parents 0d18d930 73a7d993
...@@ -29,5 +29,5 @@ typedef struct st_line_buffer ...@@ -29,5 +29,5 @@ typedef struct st_line_buffer
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file); extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, my_string str); extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, my_string str);
extern char *batch_readline(LINE_BUFFER *buffer); extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated);
extern void batch_readline_end(LINE_BUFFER *buffer); extern void batch_readline_end(LINE_BUFFER *buffer);
...@@ -112,6 +112,8 @@ extern "C" { ...@@ -112,6 +112,8 @@ extern "C" {
#define PROMPT_CHAR '\\' #define PROMPT_CHAR '\\'
#define DEFAULT_DELIMITER ";" #define DEFAULT_DELIMITER ";"
#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L)
typedef struct st_status typedef struct st_status
{ {
int exit_status; int exit_status;
...@@ -1035,7 +1037,7 @@ static void fix_history(String *final_command); ...@@ -1035,7 +1037,7 @@ static void fix_history(String *final_command);
static COMMANDS *find_command(char *name,char cmd_name); static COMMANDS *find_command(char *name,char cmd_name);
static bool add_line(String &buffer,char *line,char *in_string, static bool add_line(String &buffer,char *line,char *in_string,
bool *ml_comment); bool *ml_comment, bool truncated);
static void remove_cntrl(String &buffer); static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result); static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result); static void print_table_data_html(MYSQL_RES *result);
...@@ -1117,7 +1119,7 @@ int main(int argc,char *argv[]) ...@@ -1117,7 +1119,7 @@ int main(int argc,char *argv[])
exit(1); exit(1);
} }
if (status.batch && !status.line_buff && if (status.batch && !status.line_buff &&
!(status.line_buff=batch_readline_init(opt_max_allowed_packet+512,stdin))) !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{ {
free_defaults(defaults_argv); free_defaults(defaults_argv);
my_end(0); my_end(0);
...@@ -1766,13 +1768,14 @@ static int read_and_execute(bool interactive) ...@@ -1766,13 +1768,14 @@ static int read_and_execute(bool interactive)
ulong line_number=0; ulong line_number=0;
bool ml_comment= 0; bool ml_comment= 0;
COMMANDS *com; COMMANDS *com;
bool truncated= 0;
status.exit_status=1; status.exit_status=1;
for (;;) for (;;)
{ {
if (!interactive) if (!interactive)
{ {
line=batch_readline(status.line_buff); line=batch_readline(status.line_buff, &truncated);
/* /*
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF. Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
Editors like "notepad" put this marker in Editors like "notepad" put this marker in
...@@ -1891,7 +1894,7 @@ static int read_and_execute(bool interactive) ...@@ -1891,7 +1894,7 @@ static int read_and_execute(bool interactive)
#endif #endif
continue; continue;
} }
if (add_line(glob_buffer,line,&in_string,&ml_comment)) if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated))
break; break;
} }
/* if in batch mode, send last query even if it doesn't end with \g or go */ /* if in batch mode, send last query even if it doesn't end with \g or go */
...@@ -1977,7 +1980,7 @@ static COMMANDS *find_command(char *name,char cmd_char) ...@@ -1977,7 +1980,7 @@ static COMMANDS *find_command(char *name,char cmd_char)
static bool add_line(String &buffer,char *line,char *in_string, static bool add_line(String &buffer,char *line,char *in_string,
bool *ml_comment) bool *ml_comment, bool truncated)
{ {
uchar inchar; uchar inchar;
char buff[80], *pos, *out; char buff[80], *pos, *out;
...@@ -2224,9 +2227,10 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -2224,9 +2227,10 @@ static bool add_line(String &buffer,char *line,char *in_string,
{ {
uint length=(uint) (out-line); uint length=(uint) (out-line);
if (length < 9 || if (!truncated &&
(length < 9 ||
my_strnncoll (charset_info, my_strnncoll (charset_info,
(uchar *)line, 9, (const uchar *) "delimiter", 9)) (uchar *)line, 9, (const uchar *) "delimiter", 9)))
{ {
/* /*
Don't add a new line in case there's a DELIMITER command to be Don't add a new line in case there's a DELIMITER command to be
...@@ -3886,7 +3890,7 @@ static int com_source(String *buffer, char *line) ...@@ -3886,7 +3890,7 @@ static int com_source(String *buffer, char *line)
return put_info(buff, INFO_ERROR, 0); return put_info(buff, INFO_ERROR, 0);
} }
if (!(line_buff=batch_readline_init(opt_max_allowed_packet+512,sql_file))) if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, sql_file)))
{ {
my_fclose(sql_file,MYF(0)); my_fclose(sql_file,MYF(0));
return put_info("Can't initialize batch_readline", INFO_ERROR, 0); return put_info("Can't initialize batch_readline", INFO_ERROR, 0);
......
...@@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size, ...@@ -24,7 +24,7 @@ static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
ulong max_size); ulong max_size);
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str); static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str);
static uint fill_buffer(LINE_BUFFER *buffer); static uint fill_buffer(LINE_BUFFER *buffer);
static char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length); static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated);
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
...@@ -42,12 +42,13 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) ...@@ -42,12 +42,13 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
} }
char *batch_readline(LINE_BUFFER *line_buff) char *batch_readline(LINE_BUFFER *line_buff, bool *truncated)
{ {
char *pos; char *pos;
ulong out_length; ulong out_length;
DBUG_ASSERT(truncated != NULL);
if (!(pos=intern_read_line(line_buff,&out_length))) if (!(pos=intern_read_line(line_buff,&out_length, truncated)))
return 0; return 0;
if (out_length && pos[out_length-1] == '\n') if (out_length && pos[out_length-1] == '\n')
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
...@@ -149,6 +150,14 @@ static uint fill_buffer(LINE_BUFFER *buffer) ...@@ -149,6 +150,14 @@ static uint fill_buffer(LINE_BUFFER *buffer)
read_count=(buffer->bufread - bufbytes)/IO_SIZE; read_count=(buffer->bufread - bufbytes)/IO_SIZE;
if ((read_count*=IO_SIZE)) if ((read_count*=IO_SIZE))
break; break;
if (buffer->bufread * 2 > buffer->max_size)
{
/*
So we must grow the buffer but we cannot due to the max_size limit.
Return 0 w/o setting buffer->eof to signal this condition.
*/
return 0;
}
buffer->bufread *= 2; buffer->bufread *= 2;
if (!(buffer->buffer = (char*) my_realloc(buffer->buffer, if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
buffer->bufread+1, buffer->bufread+1,
...@@ -172,12 +181,16 @@ static uint fill_buffer(LINE_BUFFER *buffer) ...@@ -172,12 +181,16 @@ static uint fill_buffer(LINE_BUFFER *buffer)
DBUG_PRINT("fill_buff", ("Got %d bytes", read_count)); DBUG_PRINT("fill_buff", ("Got %d bytes", read_count));
if (!read_count)
{
buffer->eof = 1;
/* Kludge to pretend every nonempty file ends with a newline. */ /* Kludge to pretend every nonempty file ends with a newline. */
if (!read_count && bufbytes && buffer->end[-1] != '\n') if (bufbytes && buffer->end[-1] != '\n')
{ {
buffer->eof = read_count = 1; read_count = 1;
*buffer->end = '\n'; *buffer->end = '\n';
} }
}
buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes; buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes;
buffer->end+=read_count; buffer->end+=read_count;
*buffer->end=0; /* Sentinel */ *buffer->end=0; /* Sentinel */
...@@ -186,7 +199,7 @@ static uint fill_buffer(LINE_BUFFER *buffer) ...@@ -186,7 +199,7 @@ static uint fill_buffer(LINE_BUFFER *buffer)
char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated)
{ {
char *pos; char *pos;
uint length; uint length;
...@@ -200,14 +213,23 @@ char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length) ...@@ -200,14 +213,23 @@ char *intern_read_line(LINE_BUFFER *buffer,ulong *out_length)
pos++; pos++;
if (pos == buffer->end) if (pos == buffer->end)
{ {
if ((uint) (pos - buffer->start_of_line) < buffer->max_size) /*
{ fill_buffer() can return 0 either on EOF in which case we abort
or when the internal buffer has hit the size limit. In the latter case
return what we have read so far and signal string truncation.
*/
if (!(length=fill_buffer(buffer)) || length == (uint) -1) if (!(length=fill_buffer(buffer)) || length == (uint) -1)
{
if (buffer->eof)
DBUG_RETURN(0); DBUG_RETURN(0);
continue;
} }
else
continue;
pos--; /* break line here */ pos--; /* break line here */
*truncated= 1;
} }
else
*truncated= 0;
buffer->end_of_line=pos+1; buffer->end_of_line=pos+1;
*out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line); *out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
DBUG_RETURN(buffer->start_of_line); DBUG_RETURN(buffer->start_of_line);
......
...@@ -192,4 +192,15 @@ delimiter ...@@ -192,4 +192,15 @@ delimiter
1 1
1 1
1 1
set @old_max_allowed_packet = @@global.max_allowed_packet;
set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024;
set @@max_allowed_packet = @@global.max_allowed_packet;
CREATE TABLE t1(data LONGBLOB);
INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024);
SELECT LENGTH(data) FROM t1;
LENGTH(data)
2097152
DROP TABLE t1;
set @@global.max_allowed_packet = @old_max_allowed_packet;
set @@max_allowed_packet = @@global.max_allowed_packet;
End of 5.0 tests End of 5.0 tests
...@@ -341,4 +341,31 @@ EOF ...@@ -341,4 +341,31 @@ EOF
remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql;
#
# Bug #41486: extra character appears in BLOB for every ~40Mb after
# mysqldump/import
#
# Have to change the global variable as the mysql client will use
# a separate session
set @old_max_allowed_packet = @@global.max_allowed_packet;
# 2 MB blob length + some space for the rest of INSERT query
set @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024;
set @@max_allowed_packet = @@global.max_allowed_packet;
CREATE TABLE t1(data LONGBLOB);
INSERT INTO t1 SELECT REPEAT('1', 2*1024*1024);
--exec $MYSQL_DUMP test t1 >$MYSQLTEST_VARDIR/tmp/bug41486.sql
# Check that the mysql client does not insert extra newlines when loading
# strings longer than client's max_allowed_packet
--exec $MYSQL --max_allowed_packet=1M test < $MYSQLTEST_VARDIR/tmp/bug41486.sql 2>&1
SELECT LENGTH(data) FROM t1;
remove_file $MYSQLTEST_VARDIR/tmp/bug41486.sql;
DROP TABLE t1;
set @@global.max_allowed_packet = @old_max_allowed_packet;
set @@max_allowed_packet = @@global.max_allowed_packet;
--echo End of 5.0 tests --echo End of 5.0 tests
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