diff options
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | client/mysqltest.cc | 2 | ||||
-rw-r--r-- | cmake/build_configurations/mysql_release.cmake | 1 | ||||
-rw-r--r-- | config.h.cmake | 6 | ||||
-rw-r--r-- | include/mysql.h | 2 | ||||
-rw-r--r-- | include/mysql.h.pp | 2 | ||||
-rw-r--r-- | mysql-test/disabled.def | 1 | ||||
-rw-r--r-- | mysql-test/r/mysql.result | 26 | ||||
-rw-r--r-- | mysql-test/t/mysql.test | 22 | ||||
-rw-r--r-- | mysys/my_file.c | 7 | ||||
-rw-r--r-- | sql-common/client.c | 30 |
11 files changed, 94 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b270208a2d..92c1f9ef060 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,9 +264,15 @@ IF(HAVE_GGDB3) SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") ENDIF(HAVE_GGDB3) -OPTION(ENABLED_LOCAL_INFILE - "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) +SET(ENABLED_LOCAL_INFILE "AUTO" CACHE STRING "If we should should enable LOAD DATA LOCAL by default (OFF/ON/AUTO)") MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE) +IF (ENABLED_LOCAL_INFILE MATCHES "^(0|FALSE)$") + SET(ENABLED_LOCAL_INFILE OFF) +ELSEIF(ENABLED_LOCAL_INFILE MATCHES "^(1|TRUE)$") + SET(ENABLED_LOCAL_INFILE ON) +ELSEIF (NOT ENABLED_LOCAL_INFILE MATCHES "^(ON|OFF|AUTO)$") + MESSAGE(FATAL_ERROR "ENABLED_LOCAL_INFILE must be one of OFF, ON, AUTO") +ENDIF() OPTION(WITH_FAST_MUTEXES "Compile with fast mutexes" OFF) MARK_AS_ADVANCED(WITH_FAST_MUTEXES) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 77ce8d6dc8a..7ec2a62dcf7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -6105,7 +6105,6 @@ void do_connect(struct st_command *command) #endif if (opt_compress || con_compress) mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) @@ -9211,7 +9210,6 @@ int main(int argc, char **argv) (void *) &opt_connect_timeout); if (opt_compress) mysql_options(con->mysql,MYSQL_OPT_COMPRESS,NullS); - mysql_options(con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(con->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 78314342426..b82b87b6237 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -96,7 +96,6 @@ IF(FEATURE_SET) ENDFOREACH() ENDIF() -OPTION(ENABLED_LOCAL_INFILE "" ON) IF(RPM) SET(WITH_SSL system CACHE STRING "") SET(WITH_ZLIB system CACHE STRING "") diff --git a/config.h.cmake b/config.h.cmake index e039cf12fca..c22638a6cc0 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -536,7 +536,11 @@ /* MySQL features */ -#cmakedefine ENABLED_LOCAL_INFILE 1 +#define LOCAL_INFILE_MODE_OFF 0 +#define LOCAL_INFILE_MODE_ON 1 +#define LOCAL_INFILE_MODE_AUTO 2 +#define ENABLED_LOCAL_INFILE LOCAL_INFILE_MODE_@ENABLED_LOCAL_INFILE@ + #cmakedefine ENABLED_PROFILING 1 #cmakedefine EXTRA_DEBUG 1 #cmakedefine BACKUP_TEST 1 diff --git a/include/mysql.h b/include/mysql.h index f088ad668a1..fc814787c22 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -283,7 +283,7 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; - my_bool unused1; + my_bool auto_local_infile; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ diff --git a/include/mysql.h.pp b/include/mysql.h.pp index a593f526c6e..f891ad6f2c9 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -354,7 +354,7 @@ typedef struct st_mysql my_bool free_me; my_bool reconnect; char scramble[20 +1]; - my_bool unused1; + my_bool auto_local_infile; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; const struct st_mysql_methods *methods; diff --git a/mysql-test/disabled.def b/mysql-test/disabled.def index 17bc921ab66..9292081b45e 100644 --- a/mysql-test/disabled.def +++ b/mysql-test/disabled.def @@ -19,3 +19,4 @@ ssl_crl : broken upstream ssl_crl_clrpath : broken upstream file_contents : MDEV-6526 these files are not installed anymore lowercase_fs_on : lower_case_table_names=0 is not an error until 10.1 +partition_open_files_limit : open_files_limit check broken by MDEV-18360 diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 8a24128daa2..ffa5d020153 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -587,3 +587,29 @@ a 2 drop table "a1\""b1"; set sql_mode=default; +create table t1 (a text); +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +select count(*) from t1; +count(*) +41 +truncate table t1; +select count(*) from t1; +count(*) +0 +truncate table t1; +drop table t1; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 60dc16bfac7..a8e0a0094e4 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -656,3 +656,25 @@ show create table "a1\""b1"; select * from "a1\""b1"; drop table "a1\""b1"; set sql_mode=default; + +# +# mysql --local-infile +# +--let $ldli = load data local infile '$MYSQLTEST_VARDIR/tmp/bug.sql' into table test.t1; +create table t1 (a text); +--exec $MYSQL -e "$ldli" +select count(*) from t1; truncate table t1; +--exec $MYSQL --enable-local-infile -e "$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL --disable-local-infile -e "$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +--exec $MYSQL --enable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +--error 1 +--exec $MYSQL --disable-local-infile -e "/*q*/$ldli" +select count(*) from t1; truncate table t1; +drop table t1; diff --git a/mysys/my_file.c b/mysys/my_file.c index a23ab487d00..23226595b2e 100644 --- a/mysys/my_file.c +++ b/mysys/my_file.c @@ -52,10 +52,9 @@ static uint set_max_open_files(uint max_file_limit) DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u", (uint) rlimit.rlim_cur, (uint) rlimit.rlim_max)); - if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY) - rlimit.rlim_cur = max_file_limit; - if (rlimit.rlim_cur >= max_file_limit) - DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */ + if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY || + rlimit.rlim_cur >= max_file_limit) + DBUG_RETURN(max_file_limit); rlimit.rlim_cur= rlimit.rlim_max= max_file_limit; if (setrlimit(RLIMIT_NOFILE, &rlimit)) max_file_limit= old_cur; /* Use original value */ diff --git a/sql-common/client.c b/sql-common/client.c index d78e6167809..4bebf9ec63e 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -110,6 +110,12 @@ my_bool net_flush(NET *net); #include <my_context.h> #include <mysql_async.h> +typedef enum { + ALWAYS_ACCEPT, /* heuristics is disabled, use CLIENT_LOCAL_FILES */ + WAIT_FOR_QUERY, /* heuristics is enabled, not sending files */ + ACCEPT_FILE_REQUEST /* heuristics is enabled, ready to send a file */ +} auto_local_infile_state; + #define native_password_plugin_name "mysql_native_password" #define old_password_plugin_name "mysql_old_password" @@ -1632,8 +1638,10 @@ mysql_init(MYSQL *mysql) --enable-local-infile */ -#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER) +#if ENABLED_LOCAL_INFILE && !defined(MYSQL_SERVER) mysql->options.client_flag|= CLIENT_LOCAL_FILES; + mysql->auto_local_infile= ENABLED_LOCAL_INFILE == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; #endif #ifdef HAVE_SMEM @@ -3999,8 +4007,14 @@ static my_bool cli_read_query_result(MYSQL *mysql) ulong field_count; MYSQL_DATA *fields; ulong length; +#ifdef MYSQL_CLIENT + my_bool can_local_infile= mysql->auto_local_infile != WAIT_FOR_QUERY; +#endif DBUG_ENTER("cli_read_query_result"); + if (mysql->auto_local_infile == ACCEPT_FILE_REQUEST) + mysql->auto_local_infile= WAIT_FOR_QUERY; + if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ @@ -4037,7 +4051,8 @@ get_info: { int error; - if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES)) + if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES) || + !can_local_infile) { set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); DBUG_RETURN(1); @@ -4075,6 +4090,13 @@ int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) { DBUG_ENTER("mysql_send_query"); + if (mysql->options.client_flag & CLIENT_LOCAL_FILES && + mysql->auto_local_infile == WAIT_FOR_QUERY && + (*query == 'l' || *query == 'L')) + { + if (strncasecmp(query, STRING_WITH_LEN("load")) == 0) + mysql->auto_local_infile= ACCEPT_FILE_REQUEST; + } DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1)); } @@ -4288,10 +4310,12 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ break; case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ - if (!arg || MY_TEST(*(uint*) arg)) + if (!arg || *(uint*) arg) mysql->options.client_flag|= CLIENT_LOCAL_FILES; else mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; + mysql->auto_local_infile= arg && *(uint*)arg == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; break; case MYSQL_INIT_COMMAND: add_init_command(&mysql->options,arg); |