Commit e070e9a0 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

merge with 3.23.49

parents 15e9ca78 e45cff23
...@@ -8,6 +8,7 @@ arjen@co3064164-a.bitbike.com ...@@ -8,6 +8,7 @@ arjen@co3064164-a.bitbike.com
bell@sanja.is.com.ua bell@sanja.is.com.ua
davida@isil.mysql.com davida@isil.mysql.com
heikki@donna.mysql.fi heikki@donna.mysql.fi
heikki@hundin.mysql.fi
jani@hynda.mysql.fi jani@hynda.mysql.fi
jani@janikt.pp.saunalahti.fi jani@janikt.pp.saunalahti.fi
jani@rhols221.adsl.netsonic.fi jani@rhols221.adsl.netsonic.fi
...@@ -15,6 +16,7 @@ jcole@abel.spaceapes.com ...@@ -15,6 +16,7 @@ jcole@abel.spaceapes.com
jcole@main.burghcom.com jcole@main.burghcom.com
jcole@sarvik.tfr.cafe.ee jcole@sarvik.tfr.cafe.ee
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
jorge@linux.jorge.mysql.com
kaj@work.mysql.com kaj@work.mysql.com
miguel@light.local miguel@light.local
monty@bitch.mysql.fi monty@bitch.mysql.fi
......
...@@ -48779,8 +48779,17 @@ not yet 100% confident in this code. ...@@ -48779,8 +48779,17 @@ not yet 100% confident in this code.
@appendixsubsec Changes in release 3.23.49 @appendixsubsec Changes in release 3.23.49
@itemize @bullet @itemize @bullet
@item @item
Don't give warning for statement that is only a comment; This is needed for
@code{mysqldump --disable-keys} to work.
@item
Fixed unlikely caching bug when doing a join without keys. In this case Fixed unlikely caching bug when doing a join without keys. In this case
the last used field for a table always returned @code{NULL}. the last used field for a table always returned @code{NULL}.
@item
Added options to make @code{LOAD DATA LOCAL INFILE} more secure.
@item
MySQL binary release 3.23.48 for Linux contained a new glibc library, which
has serious problems under high load and RedHat 7.2. The 3.23.49 binary
release doesn't have this problem.
@end itemize @end itemize
@node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x @node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
/* Version of .frm files */ /* Version of .frm files */
#undef DOT_FRM_VERSION #undef DOT_FRM_VERSION
/* If LOAD DATA LOCAL INFILE should be enabled by default */
#undef ENABLED_LOCAL_INFILE
/* READLINE: */ /* READLINE: */
#undef FIONREAD_IN_SYS_IOCTL #undef FIONREAD_IN_SYS_IOCTL
......
...@@ -31,4 +31,4 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, ...@@ -31,4 +31,4 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS,
OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE,
OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES,
OPT_MASTER_DATA, OPT_AUTOCOMMIT}; OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_LOCAL_INFILE};
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <signal.h> #include <signal.h>
#include <violite.h> #include <violite.h>
const char *VER="11.19"; const char *VER="11.20";
/* Don't try to make a nice table if the data is too big */ /* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024 #define MAX_COLUMN_LENGTH 1024
...@@ -116,10 +116,10 @@ static MYSQL mysql; /* The connection */ ...@@ -116,10 +116,10 @@ static MYSQL mysql; /* The connection */
static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, no_rehash=0,skip_updates=0,safe_updates=0,one_database=0,
opt_compress=0, opt_compress=0, using_opt_local_infile=0,
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
opt_xml=0,opt_nopager=1, opt_outfile=0, no_named_cmds=1; opt_xml=0,opt_nopager=1, opt_outfile=0, no_named_cmds=1;
static uint verbose=0,opt_silent=0,opt_mysql_port=0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0; static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE; static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0, static char *current_host,*current_db,*current_user=0,*opt_password=0,
...@@ -436,6 +436,7 @@ static struct option long_options[] = ...@@ -436,6 +436,7 @@ static struct option long_options[] =
{"xml", no_argument, 0, 'X'}, {"xml", no_argument, 0, 'X'},
{"host", required_argument, 0, 'h'}, {"host", required_argument, 0, 'h'},
{"ignore-spaces", no_argument, 0, 'i'}, {"ignore-spaces", no_argument, 0, 'i'},
{"local-infile", optional_argument, 0, OPT_LOCAL_INFILE},
{"no-auto-rehash",no_argument, 0, 'A'}, {"no-auto-rehash",no_argument, 0, 'A'},
{"no-named-commands", no_argument, 0, 'g'}, {"no-named-commands", no_argument, 0, 'g'},
{"no-tee", no_argument, 0, OPT_NOTEE}, {"no-tee", no_argument, 0, OPT_NOTEE},
...@@ -738,6 +739,10 @@ static int get_options(int argc, char **argv) ...@@ -738,6 +739,10 @@ static int get_options(int argc, char **argv)
case 'C': case 'C':
opt_compress=1; opt_compress=1;
break; break;
case OPT_LOCAL_INFILE:
using_opt_local_infile=1;
opt_local_infile= test(!optarg || atoi(optarg)>0);
break;
case 'L': case 'L':
skip_line_numbers=1; skip_line_numbers=1;
break; break;
...@@ -2235,6 +2240,8 @@ sql_real_connect(char *host,char *database,char *user,char *password, ...@@ -2235,6 +2240,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
} }
if (opt_compress) if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
if (using_opt_local_infile)
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
......
...@@ -518,7 +518,7 @@ AC_ARG_ENABLE(thread-safe-client, ...@@ -518,7 +518,7 @@ AC_ARG_ENABLE(thread-safe-client,
[ THREAD_SAFE_CLIENT=no ] [ THREAD_SAFE_CLIENT=no ]
) )
# Make thread safe client # compile with strings functions in assembler
AC_ARG_ENABLE(assembler, AC_ARG_ENABLE(assembler,
[ --enable-assembler Use assembler versions of some string [ --enable-assembler Use assembler versions of some string
functions if available.], functions if available.],
...@@ -583,6 +583,14 @@ AC_ARG_WITH(mysqld-user, ...@@ -583,6 +583,14 @@ AC_ARG_WITH(mysqld-user,
) )
AC_SUBST(MYSQLD_USER) AC_SUBST(MYSQLD_USER)
# compile with strings functions in assembler
AC_ARG_ENABLE(local-infile,
[ --enable-local-infile
If LOAD DATA LOCAL INFILE is enabled by default.],
[ ENABLED_LOCAL_INFILE=$enablewal ],
[ ENABLED_LOCAL_INFILE=no ]
)
# Use Paul Eggerts macros from GNU tar to check for large file support. # Use Paul Eggerts macros from GNU tar to check for large file support.
MYSQL_SYS_LARGEFILE MYSQL_SYS_LARGEFILE
......
...@@ -157,7 +157,8 @@ struct st_mysql_options { ...@@ -157,7 +157,8 @@ struct st_mysql_options {
enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND, MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME}; MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_LOCAL_INFILE};
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT}; MYSQL_STATUS_USE_RESULT};
......
...@@ -195,21 +195,6 @@ dict_mutex_exit_for_mysql(void) ...@@ -195,21 +195,6 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
} }
/************************************************************************
Increments the count of open MySQL handles to a table. */
void
dict_table_increment_handle_count(
/*==============================*/
dict_table_t* table) /* in: table */
{
mutex_enter(&(dict_sys->mutex));
table->n_mysql_handles_opened++;
mutex_exit(&(dict_sys->mutex));
}
/************************************************************************ /************************************************************************
Decrements the count of open MySQL handles to a table. */ Decrements the count of open MySQL handles to a table. */
...@@ -495,6 +480,41 @@ dict_table_get( ...@@ -495,6 +480,41 @@ dict_table_get(
return(table); return(table);
} }
/**************************************************************************
Returns a table object and increments MySQL open handle count on the table.
*/
dict_table_t*
dict_table_get_and_increment_handle_count(
/*======================================*/
/* out: table, NULL if does not exist */
char* table_name, /* in: table name */
trx_t* trx) /* in: transaction handle or NULL */
{
dict_table_t* table;
UT_NOT_USED(trx);
mutex_enter(&(dict_sys->mutex));
table = dict_table_get_low(table_name);
if (table != NULL) {
table->n_mysql_handles_opened++;
}
mutex_exit(&(dict_sys->mutex));
if (table != NULL) {
if (!table->stat_initialized) {
dict_update_statistics(table);
}
}
return(table);
}
/************************************************************************** /**************************************************************************
Adds a table object to the dictionary cache. */ Adds a table object to the dictionary cache. */
......
...@@ -26,13 +26,6 @@ Created 1/8/1996 Heikki Tuuri ...@@ -26,13 +26,6 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include "trx0types.h" #include "trx0types.h"
/************************************************************************
Increments the count of open MySQL handles to a table. */
void
dict_table_increment_handle_count(
/*==============================*/
dict_table_t* table); /* in: table */
/************************************************************************ /************************************************************************
Decrements the count of open MySQL handles to a table. */ Decrements the count of open MySQL handles to a table. */
...@@ -195,6 +188,16 @@ dict_table_get( ...@@ -195,6 +188,16 @@ dict_table_get(
char* table_name, /* in: table name */ char* table_name, /* in: table name */
trx_t* trx); /* in: transaction handle */ trx_t* trx); /* in: transaction handle */
/************************************************************************** /**************************************************************************
Returns a table object and increments MySQL open handle count on the table.
*/
dict_table_t*
dict_table_get_and_increment_handle_count(
/*======================================*/
/* out: table, NULL if does not exist */
char* table_name, /* in: table name */
trx_t* trx); /* in: transaction handle or NULL */
/**************************************************************************
Returns a table object, based on table id, and memoryfixes it. */ Returns a table object, based on table id, and memoryfixes it. */
dict_table_t* dict_table_t*
......
...@@ -273,8 +273,6 @@ row_create_prebuilt( ...@@ -273,8 +273,6 @@ row_create_prebuilt(
ulint ref_len; ulint ref_len;
ulint i; ulint i;
dict_table_increment_handle_count(table);
heap = mem_heap_create(128); heap = mem_heap_create(128);
prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t)); prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t));
...@@ -1468,6 +1466,13 @@ loop: ...@@ -1468,6 +1466,13 @@ loop:
table = dict_table_get_low(drop->table_name); table = dict_table_get_low(drop->table_name);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
if (table == NULL) {
/* If for some reason the table has already been dropped
through some other mechanism, do not try to drop it */
goto already_dropped;
}
if (table->n_mysql_handles_opened > 0) { if (table->n_mysql_handles_opened > 0) {
return(n_tables + n_tables_dropped); return(n_tables + n_tables_dropped);
...@@ -1477,10 +1482,16 @@ loop: ...@@ -1477,10 +1482,16 @@ loop:
row_drop_table_for_mysql_in_background(drop->table_name); row_drop_table_for_mysql_in_background(drop->table_name);
already_dropped:
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop); UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Dropped table %s in background drop queue.\n",
drop->table_name);
mem_free(drop->table_name); mem_free(drop->table_name);
mem_free(drop); mem_free(drop);
...@@ -1746,6 +1757,13 @@ row_drop_table_for_mysql( ...@@ -1746,6 +1757,13 @@ row_drop_table_for_mysql(
if (table->n_mysql_handles_opened > 0) { if (table->n_mysql_handles_opened > 0) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: MySQL is trying to drop table %s\n"
"InnoDB: though there are still open handles to it.\n"
"InnoDB: Adding the table to the background drop queue.\n",
table->name);
row_add_table_to_background_drop_list(table); row_add_table_to_background_drop_list(table);
err = DB_SUCCESS; err = DB_SUCCESS;
...@@ -1807,6 +1825,7 @@ row_drop_database_for_mysql( ...@@ -1807,6 +1825,7 @@ row_drop_database_for_mysql(
char* name, /* in: database name which ends to '/' */ char* name, /* in: database name which ends to '/' */
trx_t* trx) /* in: transaction handle */ trx_t* trx) /* in: transaction handle */
{ {
dict_table_t* table;
char* table_name; char* table_name;
int err = DB_SUCCESS; int err = DB_SUCCESS;
...@@ -1817,12 +1836,35 @@ row_drop_database_for_mysql( ...@@ -1817,12 +1836,35 @@ row_drop_database_for_mysql(
trx->op_info = (char *) "dropping database"; trx->op_info = (char *) "dropping database";
trx_start_if_not_started(trx); trx_start_if_not_started(trx);
loop:
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
while ((table_name = dict_get_first_table_name_in_db(name))) { while ((table_name = dict_get_first_table_name_in_db(name))) {
ut_a(memcmp(table_name, name, strlen(name)) == 0); ut_a(memcmp(table_name, name, strlen(name)) == 0);
table = dict_table_get_low(table_name);
ut_a(table);
/* Wait until MySQL does not have any queries running on
the table */
if (table->n_mysql_handles_opened > 0) {
mutex_exit(&(dict_sys->mutex));
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: MySQL is trying to drop database %s\n"
"InnoDB: though there are still open handles to table %s.\n",
name, table_name);
os_thread_sleep(1000000);
mem_free(table_name);
goto loop;
}
err = row_drop_table_for_mysql(table_name, trx, TRUE); err = row_drop_table_for_mysql(table_name, trx, TRUE);
mem_free(table_name); mem_free(table_name);
......
...@@ -60,7 +60,7 @@ static my_bool mysql_client_init=0; ...@@ -60,7 +60,7 @@ static my_bool mysql_client_init=0;
uint mysql_port=0; uint mysql_port=0;
my_string mysql_unix_port=0; my_string mysql_unix_port=0;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS) #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
#ifdef __WIN__ #ifdef __WIN__
#define CONNECT_TIMEOUT 20 #define CONNECT_TIMEOUT 20
...@@ -694,12 +694,14 @@ mysql_free_result(MYSQL_RES *result) ...@@ -694,12 +694,14 @@ mysql_free_result(MYSQL_RES *result)
****************************************************************************/ ****************************************************************************/
static const char *default_options[]= static const char *default_options[]=
{"port","socket","compress","password","pipe", "timeout", "user", {
"init-command", "host", "database", "debug", "return-found-rows", "port","socket","compress","password","pipe", "timeout", "user",
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", "ssl-cipher" "init-command", "host", "database", "debug", "return-found-rows",
"character-set-dir", "default-character-set", "interactive-timeout", "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
"connect_timeout", "replication-probe", "enable-reads-from-master", "character-set-dir", "default-character-set", "interactive-timeout",
"repl-parse-query", "connect-timeout", "local-infile", "disable-local-infile",
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-chiper",
NullS NullS
}; };
...@@ -734,6 +736,9 @@ static void mysql_read_default_options(struct st_mysql_options *options, ...@@ -734,6 +736,9 @@ static void mysql_read_default_options(struct st_mysql_options *options,
opt_arg=end+1; opt_arg=end+1;
*end=0; /* Remove '=' */ *end=0; /* Remove '=' */
} }
/* Change all '_' in variable name to '-' */
for (end= *option ; (end= strcend(end,'_')) ; )
*end= '-';
switch (find_type(*option+2,&option_types,2)) { switch (find_type(*option+2,&option_types,2)) {
case 1: /* port */ case 1: /* port */
if (opt_arg) if (opt_arg)
...@@ -831,15 +836,24 @@ static void mysql_read_default_options(struct st_mysql_options *options, ...@@ -831,15 +836,24 @@ static void mysql_read_default_options(struct st_mysql_options *options,
options->charset_name = my_strdup(opt_arg, MYF(MY_WME)); options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
break; break;
case 19: /* Interactive-timeout */ case 19: /* Interactive-timeout */
options->client_flag|=CLIENT_INTERACTIVE; options->client_flag|= CLIENT_INTERACTIVE;
break;
case 21:
if (!opt_arg || atoi(opt_arg) != 0)
options->client_flag|= CLIENT_LOCAL_FILES;
else
options->client_flag&= ~CLIENT_LOCAL_FILES;
break; break;
case 21: /* replication probe */ case 22:
options->client_flag&= CLIENT_LOCAL_FILES;
break;
case 23: /* replication probe */
options->rpl_probe = 1; options->rpl_probe = 1;
break; break;
case 22: /* enable-reads-from-master */ case 24: /* enable-reads-from-master */
options->rpl_parse = 1; options->rpl_parse = 1;
break; break;
case 23: /* repl-parse-query */ case 25: /* repl-parse-query */
options->no_master_reads = 0; options->no_master_reads = 0;
break; break;
default: default:
...@@ -1321,6 +1335,14 @@ mysql_init(MYSQL *mysql) ...@@ -1321,6 +1335,14 @@ mysql_init(MYSQL *mysql)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler); (void) signal(SIGPIPE,pipe_sig_handler);
#endif #endif
/*
Only enable LOAD DATA INFILE by default if configured with
--with-enabled-local-inflile
*/
#ifdef ENABLED_LOCAL_INFILE
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
#endif
return mysql; return mysql;
} }
...@@ -1770,7 +1792,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1770,7 +1792,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (mysql->options.use_ssl) if (mysql->options.use_ssl)
client_flag|=CLIENT_SSL; client_flag|=CLIENT_SSL;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
if (db) if (db)
client_flag|=CLIENT_CONNECT_WITH_DB; client_flag|=CLIENT_CONNECT_WITH_DB;
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
...@@ -2714,11 +2735,17 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) ...@@ -2714,11 +2735,17 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
mysql->options.connect_timeout= *(uint*) arg; mysql->options.connect_timeout= *(uint*) arg;
break; break;
case MYSQL_OPT_COMPRESS: case MYSQL_OPT_COMPRESS:
mysql->options.compress=1; /* Remember for connect */ mysql->options.compress= 1; /* Remember for connect */
break; break;
case MYSQL_OPT_NAMED_PIPE: case MYSQL_OPT_NAMED_PIPE:
mysql->options.named_pipe=1; /* Force named pipe */ mysql->options.named_pipe=1; /* Force named pipe */
break; break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
if (!arg || test(*(uint*) arg))
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
else
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
break;
case MYSQL_INIT_COMMAND: case MYSQL_INIT_COMMAND:
my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.init_command=my_strdup(arg,MYF(MY_WME)); mysql->options.init_command=my_strdup(arg,MYF(MY_WME));
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
select 1+2/*hello*/+3; select 1+2/*hello*/+3;
select 1 /* long select 1 /* long
multi line comment */; multi line comment */;
!$1065 /* empty query */; !$1065 ;
select 1 /*!32301 +1 */; select 1 /*!32301 +1 */;
select 1 /*!52301 +1 */; select 1 /*!52301 +1 */;
select 1--1; select 1--1;
...@@ -15,3 +15,4 @@ select 1 --2 ...@@ -15,3 +15,4 @@ select 1 --2
+1; +1;
select 1 # The rest of the row will be ignored select 1 # The rest of the row will be ignored
; ;
/* line with only comment */;
...@@ -987,7 +987,10 @@ ha_innobase::open( ...@@ -987,7 +987,10 @@ ha_innobase::open(
/* Get pointer to a table object in InnoDB dictionary cache */ /* Get pointer to a table object in InnoDB dictionary cache */
if (NULL == (ib_table = dict_table_get(norm_name, NULL))) { ib_table = dict_table_get_and_increment_handle_count(
norm_name, NULL);
if (NULL == ib_table) {
sql_print_error("InnoDB error:\n\ sql_print_error("InnoDB error:\n\
Cannot find table %s from the internal data dictionary\n\ Cannot find table %s from the internal data dictionary\n\
...@@ -2831,7 +2834,9 @@ innobase_drop_database( ...@@ -2831,7 +2834,9 @@ innobase_drop_database(
memcpy(namebuf, ptr, len); memcpy(namebuf, ptr, len);
namebuf[len] = '/'; namebuf[len] = '/';
namebuf[len + 1] = '\0'; namebuf[len + 1] = '\0';
#ifdef __WIN__
casedn_str(namebuf);
#endif
trx = trx_allocate_for_mysql(); trx = trx_allocate_for_mysql();
error = row_drop_database_for_mysql(namebuf, trx); error = row_drop_database_for_mysql(namebuf, trx);
......
...@@ -583,6 +583,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count; ...@@ -583,6 +583,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count;
extern pthread_attr_t connection_attrib; extern pthread_attr_t connection_attrib;
extern bool opt_endinfo, using_udf_functions, locked_in_memory, extern bool opt_endinfo, using_udf_functions, locked_in_memory,
opt_using_transactions, use_temp_pool, mysql_embedded; opt_using_transactions, use_temp_pool, mysql_embedded;
extern bool opt_local_infile;
extern char f_fyllchar; extern char f_fyllchar;
extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_key_count, ha_read_next_count, ha_read_prev_count,
......
...@@ -297,6 +297,7 @@ ulong bytes_sent = 0L, bytes_received = 0L; ...@@ -297,6 +297,7 @@ ulong bytes_sent = 0L, bytes_received = 0L;
bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
bool opt_using_transactions, using_update_log, opt_warnings=0; bool opt_using_transactions, using_update_log, opt_warnings=0;
bool opt_local_infile=1;
bool volatile abort_loop,select_thread_in_use,grant_option; bool volatile abort_loop,select_thread_in_use,grant_option;
bool volatile ready_to_exit,shutdown_in_progress; bool volatile ready_to_exit,shutdown_in_progress;
ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
...@@ -708,8 +709,9 @@ static pthread_handler_decl(kill_server_thread,arg __attribute__((unused))) ...@@ -708,8 +709,9 @@ static pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
static sig_handler print_signal_warning(int sig) static sig_handler print_signal_warning(int sig)
{ {
sql_print_error("Warning: Got signal %d from thread %d", if (opt_warnings)
sig,my_thread_id()); sql_print_error("Warning: Got signal %d from thread %d",
sig,my_thread_id());
#ifdef DONT_REMEMBER_SIGNAL #ifdef DONT_REMEMBER_SIGNAL
sigset(sig,print_signal_warning); /* int. thread system calls */ sigset(sig,print_signal_warning); /* int. thread system calls */
#endif #endif
...@@ -2686,7 +2688,7 @@ enum options { ...@@ -2686,7 +2688,7 @@ enum options {
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE, OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE, OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE
}; };
static struct option long_options[] = { static struct option long_options[] = {
...@@ -2748,6 +2750,7 @@ static struct option long_options[] = { ...@@ -2748,6 +2750,7 @@ static struct option long_options[] = {
{"init-file", required_argument, 0, (int) OPT_INIT_FILE}, {"init-file", required_argument, 0, (int) OPT_INIT_FILE},
{"log", optional_argument, 0, 'l'}, {"log", optional_argument, 0, 'l'},
{"language", required_argument, 0, 'L'}, {"language", required_argument, 0, 'L'},
{"local-infile", optional_argument, 0, (int) OPT_LOCAL_INFILE},
{"log-bin", optional_argument, 0, (int) OPT_BIN_LOG}, {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG},
{"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX}, {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX},
{"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG}, {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG},
...@@ -3615,6 +3618,9 @@ static void get_options(int argc,char **argv) ...@@ -3615,6 +3618,9 @@ static void get_options(int argc,char **argv)
case 'P': case 'P':
mysql_port= (unsigned int) atoi(optarg); mysql_port= (unsigned int) atoi(optarg);
break; break;
case OPT_LOCAL_INFILE:
opt_local_infile= test(!optarg || atoi(optarg) != 0);
break;
case OPT_SLAVE_SKIP_ERRORS: case OPT_SLAVE_SKIP_ERRORS:
init_slave_skip_errors(optarg); init_slave_skip_errors(optarg);
break; break;
......
...@@ -768,6 +768,7 @@ int yylex(void *arg) ...@@ -768,6 +768,7 @@ int yylex(void *arg)
return(TEXT_STRING); return(TEXT_STRING);
case STATE_COMMENT: // Comment case STATE_COMMENT: // Comment
lex->options|= OPTION_FOUND_COMMENT;
while ((c = yyGet()) != '\n' && c) ; while ((c = yyGet()) != '\n' && c) ;
yyUnget(); // Safety against eof yyUnget(); // Safety against eof
state = STATE_START; // Try again state = STATE_START; // Try again
...@@ -779,6 +780,7 @@ int yylex(void *arg) ...@@ -779,6 +780,7 @@ int yylex(void *arg)
break; break;
} }
yySkip(); // Skip '*' yySkip(); // Skip '*'
lex->options|= OPTION_FOUND_COMMENT;
if (yyPeek() == '!') // MySQL command in comment if (yyPeek() == '!') // MySQL command in comment
{ {
ulong version=MYSQL_VERSION_ID; ulong version=MYSQL_VERSION_ID;
......
...@@ -57,6 +57,7 @@ enum enum_sql_command { ...@@ -57,6 +57,7 @@ enum enum_sql_command {
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE,
SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO, SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO,
SQLCOM_EMPTY_QUERY,
SQLCOM_END SQLCOM_END
}; };
......
...@@ -145,7 +145,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -145,7 +145,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (read_file_from_client && handle_duplicates == DUP_ERROR) if (read_file_from_client && handle_duplicates == DUP_ERROR)
handle_duplicates=DUP_IGNORE; handle_duplicates=DUP_IGNORE;
if (read_file_from_client && (thd->client_capabilities & CLIENT_LOCAL_FILES)) if (read_file_from_client)
{ {
(void)net_request_file(&thd->net,ex->file_name); (void)net_request_file(&thd->net,ex->file_name);
file = -1; file = -1;
......
...@@ -1312,6 +1312,10 @@ mysql_execute_command(void) ...@@ -1312,6 +1312,10 @@ mysql_execute_command(void)
res=mysql_do(thd, *lex->insert_list); res=mysql_do(thd, *lex->insert_list);
break; break;
case SQLCOM_EMPTY_QUERY:
send_ok(&thd->net);
break;
case SQLCOM_PURGE: case SQLCOM_PURGE:
{ {
if (check_process_priv(thd)) if (check_process_priv(thd))
...@@ -2094,13 +2098,20 @@ mysql_execute_command(void) ...@@ -2094,13 +2098,20 @@ mysql_execute_command(void)
{ {
uint privilege= (lex->duplicates == DUP_REPLACE ? uint privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | UPDATE_ACL | DELETE_ACL : INSERT_ACL); INSERT_ACL | UPDATE_ACL | DELETE_ACL : INSERT_ACL);
if (!(lex->local_file && (thd->client_capabilities & CLIENT_LOCAL_FILES)))
if (!lex->local_file)
{ {
if (check_access(thd,privilege | FILE_ACL,tables->db)) if (check_access(thd,privilege | FILE_ACL,tables->db))
goto error; goto error;
} }
else else
{ {
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
! opt_local_infile)
{
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND);
goto error;
}
if (check_access(thd,privilege,tables->db,&tables->grant.privilege) || if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
grant_option && check_grant(thd,privilege,tables)) grant_option && check_grant(thd,privilege,tables))
goto error; goto error;
......
...@@ -596,9 +596,17 @@ END_OF_INPUT ...@@ -596,9 +596,17 @@ END_OF_INPUT
query: query:
END_OF_INPUT END_OF_INPUT
{ {
if (!current_thd->bootstrap) THD *thd=current_thd;
if (!thd->bootstrap &&
(!(thd->lex.options & OPTION_FOUND_COMMENT)))
{
send_error(&current_thd->net,ER_EMPTY_QUERY); send_error(&current_thd->net,ER_EMPTY_QUERY);
YYABORT; YYABORT;
}
else
{
thd->lex.sql_command = SQLCOM_EMPTY_QUERY;
}
} }
| verb_clause END_OF_INPUT {} | verb_clause END_OF_INPUT {}
......
...@@ -486,11 +486,11 @@ static bool pack_fields(File file,List<create_field> &create_fields) ...@@ -486,11 +486,11 @@ static bool pack_fields(File file,List<create_field> &create_fields)
if (field->interval_id > int_count) if (field->interval_id > int_count)
{ {
int_count=field->interval_id; int_count=field->interval_id;
tmp.append('\377'); tmp.append(NAMES_SEP_CHAR);
for (const char **pos=field->interval->type_names ; *pos ; pos++) for (const char **pos=field->interval->type_names ; *pos ; pos++)
{ {
tmp.append(*pos); tmp.append(*pos);
tmp.append('\377'); tmp.append(NAMES_SEP_CHAR);
} }
tmp.append('\0'); // End of intervall tmp.append('\0'); // End of intervall
} }
......
...@@ -70,11 +70,6 @@ ...@@ -70,11 +70,6 @@
#define FERR -1 /* Error from my_functions */ #define FERR -1 /* Error from my_functions */
#define CREATE_MODE 0 /* Default mode on new files */ #define CREATE_MODE 0 /* Default mode on new files */
#define NAMES_SEP_CHAR '\377' /* Char to sep. names */ #define NAMES_SEP_CHAR '\377' /* Char to sep. names */
#ifdef MSDOS
#define EXTRA_FIELD_CHAR (char) '\234' /* Interchangebly with '#' */
#else
#define EXTRA_FIELD_CHAR '#' /* Interchangebly with '#' */
#endif
#define READ_RECORD_BUFFER (uint) (IO_SIZE*8) /* Pointer_buffer_size */ #define READ_RECORD_BUFFER (uint) (IO_SIZE*8) /* Pointer_buffer_size */
#define DISK_BUFFER_SIZE (uint) (IO_SIZE*16) /* Size of diskbuffer */ #define DISK_BUFFER_SIZE (uint) (IO_SIZE*16) /* Size of diskbuffer */
......
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