Skip to content

Commit a0d870e

Browse files
committed
MDEV-36269: improve error handling for source command
- refactor and move batch_readline_init to mysql.cc for proper error handling - add a unit test to the end of main/mysql_client_test.test to resolve embedded test failures
1 parent c4264c9 commit a0d870e

File tree

5 files changed

+103
-45
lines changed

5 files changed

+103
-45
lines changed

client/my_readline.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ typedef struct st_line_buffer
3434
bool truncated;
3535
} LINE_BUFFER;
3636

37-
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
37+
extern LINE_BUFFER *batch_readline_init(ulong max_size, const char *path);
3838
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
3939
extern char *batch_readline(LINE_BUFFER *buffer, bool binary_mode);
4040
extern void batch_readline_end(LINE_BUFFER *buffer);
41+
extern bool init_line_buffer(LINE_BUFFER *buffer, File file, ulong size, ulong max_size);
4142

4243
#endif /* CLIENT_MY_READLINE_INCLUDED */

client/mysql.cc

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,78 @@ inline int get_command_index(char cmd_char)
12071207
return -1;
12081208
}
12091209

1210+
LINE_BUFFER *batch_readline_init(ulong max_size, const char *path)
1211+
{
1212+
LINE_BUFFER *line_buff;
1213+
File file;
1214+
MY_STAT input_file_stat;
1215+
char buff[FN_REFLEN + 512];
1216+
1217+
if (path)
1218+
{
1219+
if ((file= my_open(path, O_RDONLY | O_BINARY, MYF(0))) < 0)
1220+
{
1221+
my_snprintf(buff, sizeof(buff), "Failed to open file '%.*s', error: %d",
1222+
FN_REFLEN, path, my_errno);
1223+
put_info(buff, INFO_ERROR, 0);
1224+
return 0;
1225+
}
1226+
}
1227+
else
1228+
{
1229+
file= my_fileno(stdin);
1230+
}
1231+
1232+
if (my_fstat(file, &input_file_stat, MYF(0)))
1233+
{
1234+
my_snprintf(buff, sizeof(buff), "Failed to stat file '%.*s', error: %d",
1235+
FN_REFLEN, path ? path : "stdin", my_errno);
1236+
if (path)
1237+
my_close(file, MYF(0));
1238+
put_info(buff, INFO_ERROR, 0);
1239+
return 0;
1240+
}
1241+
1242+
if (MY_S_ISDIR(input_file_stat.st_mode))
1243+
{
1244+
my_snprintf(buff, sizeof(buff), "Can't read from a directory '%.*s'",
1245+
FN_REFLEN, path ? path : "stdin");
1246+
if (path)
1247+
my_close(file, MYF(0));
1248+
put_info(buff, INFO_ERROR, 0);
1249+
return 0;
1250+
}
1251+
1252+
if (MY_S_ISBLK(input_file_stat.st_mode))
1253+
{
1254+
my_snprintf(buff, sizeof(buff), "Can't read from a block device '%.*s'",
1255+
FN_REFLEN, path ? path : "stdin");
1256+
if (path)
1257+
my_close(file, MYF(0));
1258+
put_info(buff, INFO_ERROR, 0);
1259+
return 0;
1260+
}
1261+
1262+
if (!(line_buff= (LINE_BUFFER*) my_malloc(PSI_NOT_INSTRUMENTED,
1263+
sizeof(*line_buff),
1264+
MYF(MY_WME | MY_ZEROFILL))))
1265+
{
1266+
if (path)
1267+
my_close(file, MYF(0));
1268+
return 0;
1269+
}
1270+
1271+
if (init_line_buffer(line_buff, file, IO_SIZE, max_size))
1272+
{
1273+
my_free(line_buff);
1274+
if (path)
1275+
my_close(file, MYF(0));
1276+
return 0;
1277+
}
1278+
1279+
return line_buff;
1280+
}
1281+
12101282
static int delimiter_index= -1;
12111283
static int charset_index= -1;
12121284
static int sandbox_index= -1;
@@ -1281,10 +1353,8 @@ int main(int argc,char *argv[])
12811353
}
12821354

12831355
if (status.batch && !status.line_buff &&
1284-
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
1356+
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, NULL)))
12851357
{
1286-
put_info("Can't initialize batch_readline - may be the input source is "
1287-
"a directory or a block device.", INFO_ERROR, 0);
12881358
free_defaults(defaults_argv);
12891359
my_end(0);
12901360
exit(1);
@@ -4682,7 +4752,6 @@ static int com_source(String *, char *line)
46824752
LINE_BUFFER *line_buff;
46834753
int error;
46844754
STATUS old_status;
4685-
FILE *sql_file;
46864755
my_bool save_ignore_errors;
46874756

46884757
if (status.sandbox)
@@ -4702,18 +4771,10 @@ static int com_source(String *, char *line)
47024771
end--;
47034772
end[0]=0;
47044773
unpack_filename(source_name,source_name);
4705-
/* open file name */
4706-
if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0))))
4707-
{
4708-
char buff[FN_REFLEN+60];
4709-
sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
4710-
return put_info(buff, INFO_ERROR, 0);
4711-
}
47124774

4713-
if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, sql_file)))
4775+
if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, source_name)))
47144776
{
4715-
my_fclose(sql_file,MYF(0));
4716-
return put_info("Can't initialize batch_readline", INFO_ERROR, 0);
4777+
return 1;
47174778
}
47184779

47194780
/* Save old status */
@@ -4732,7 +4793,7 @@ static int com_source(String *, char *line)
47324793
ignore_errors= save_ignore_errors;
47334794
status=old_status; // Continue as before
47344795
in_com_source= aborted= 0;
4735-
my_fclose(sql_file,MYF(0));
4796+
my_close(line_buff->file, MYF(0));
47364797
batch_readline_end(line_buff);
47374798
/*
47384799
If we got an error during source operation, don't abort the client

client/readline.cc

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,12 @@
2323
#include <my_dir.h>
2424
#include "my_readline.h"
2525

26-
static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
27-
ulong max_size);
26+
bool init_line_buffer(LINE_BUFFER *buffer, File file, ulong size, ulong max_size);
2827
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
2928
static size_t fill_buffer(LINE_BUFFER *buffer);
3029
static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
3130

3231

33-
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
34-
{
35-
LINE_BUFFER *line_buff;
36-
37-
#ifndef _WIN32
38-
MY_STAT input_file_stat;
39-
if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) ||
40-
MY_S_ISDIR(input_file_stat.st_mode) ||
41-
MY_S_ISBLK(input_file_stat.st_mode))
42-
return 0;
43-
#endif
44-
45-
if (!(line_buff=(LINE_BUFFER*)
46-
my_malloc(PSI_NOT_INSTRUMENTED, sizeof(*line_buff),
47-
MYF(MY_WME | MY_ZEROFILL))))
48-
return 0;
49-
if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size))
50-
{
51-
my_free(line_buff);
52-
return 0;
53-
}
54-
return line_buff;
55-
}
56-
57-
5832
char *batch_readline(LINE_BUFFER *line_buff, bool binary_mode)
5933
{
6034
char *pos;
@@ -105,8 +79,7 @@ LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str)
10579
Functions to handle buffered readings of lines from a stream
10680
******************************************************************************/
10781

108-
static bool
109-
init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,ulong max_buffer)
82+
bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,ulong max_buffer)
11083
{
11184
buffer->file=file;
11285
buffer->bufread=size;

mysql-test/main/mysql_client_test.result

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,11 @@ SET @@global.collation_server= @save_collation_server;
262262
SET @@global.character_set_client= @save_character_set_client;
263263
SET @@global.collation_connection= @save_collation_connection;
264264
FOUND 1 /Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)'/ in mysqld.1.err
265+
#
266+
# MDEV-36269: Improve error handling for SOURCE command
267+
# Test that SOURCE on an existent directory returns a clear error
268+
#
269+
#
270+
# Try to SOURCE the current directory (should fail)
271+
#
272+
End of 10.11 tests

mysql-test/main/mysql_client_test.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,18 @@ SET @@global.collation_connection= @save_collation_connection;
6363
let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err;
6464
let SEARCH_PATTERN= Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)';
6565
source include/search_pattern_in_file.inc;
66+
67+
--echo #
68+
--echo # MDEV-36269: Improve error handling for SOURCE command
69+
--echo # Test that SOURCE on an existent directory returns a clear error
70+
--echo #
71+
72+
--echo #
73+
--echo # Try to SOURCE the current directory (should fail)
74+
--echo #
75+
76+
--replace_regex /(ERROR at line 1: Failed to).*/\1 REPLACED/
77+
--error 1
78+
--exec $MYSQL -e "source ."
79+
80+
--echo End of 10.11 tests

0 commit comments

Comments
 (0)