diff options
-rw-r--r-- | BitKeeper/etc/logging_ok | 2 | ||||
-rw-r--r-- | Docs/manual.texi | 9 | ||||
-rw-r--r-- | acconfig.h | 3 | ||||
-rw-r--r-- | client/client_priv.h | 2 | ||||
-rw-r--r-- | client/mysql.cc | 13 | ||||
-rw-r--r-- | configure.in | 10 | ||||
-rw-r--r-- | include/mysql.h | 3 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 50 | ||||
-rw-r--r-- | innobase/include/dict0dict.h | 17 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 48 | ||||
-rw-r--r-- | libmysql/libmysql.c | 53 | ||||
-rw-r--r-- | mysql-test/t/comments.test | 3 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 9 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 12 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_load.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 13 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 | ||||
-rw-r--r-- | sql/unireg.cc | 4 | ||||
-rw-r--r-- | sql/unireg.h | 5 |
22 files changed, 213 insertions, 61 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 75f06d03cb1..fc2cbd97a56 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -8,6 +8,7 @@ arjen@co3064164-a.bitbike.com bell@sanja.is.com.ua davida@isil.mysql.com heikki@donna.mysql.fi +heikki@hundin.mysql.fi jani@hynda.mysql.fi jani@janikt.pp.saunalahti.fi jani@rhols221.adsl.netsonic.fi @@ -15,6 +16,7 @@ jcole@abel.spaceapes.com jcole@main.burghcom.com jcole@sarvik.tfr.cafe.ee jcole@tetra.spaceapes.com +jorge@linux.jorge.mysql.com kaj@work.mysql.com miguel@light.local monty@bitch.mysql.fi diff --git a/Docs/manual.texi b/Docs/manual.texi index 3b8c8da822c..105453c87b5 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -48779,8 +48779,17 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.49 @itemize @bullet @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 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 @node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x diff --git a/acconfig.h b/acconfig.h index 128e567a927..02be1ace0c6 100644 --- a/acconfig.h +++ b/acconfig.h @@ -21,6 +21,9 @@ /* Version of .frm files */ #undef DOT_FRM_VERSION +/* If LOAD DATA LOCAL INFILE should be enabled by default */ +#undef ENABLED_LOCAL_INFILE + /* READLINE: */ #undef FIONREAD_IN_SYS_IOCTL diff --git a/client/client_priv.h b/client/client_priv.h index 9a090b774bd..e8355e801a2 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -31,4 +31,4 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, 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}; diff --git a/client/mysql.cc b/client/mysql.cc index bd81a40ef29..769b4490096 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -38,7 +38,7 @@ #include <signal.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 */ #define MAX_COLUMN_LENGTH 1024 @@ -116,10 +116,10 @@ static MYSQL mysql; /* The connection */ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, connected=0,opt_raw_data=0,unbuffered=0,output_tables=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, 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 int connect_flag=CLIENT_INTERACTIVE; static char *current_host,*current_db,*current_user=0,*opt_password=0, @@ -436,6 +436,7 @@ static struct option long_options[] = {"xml", no_argument, 0, 'X'}, {"host", required_argument, 0, 'h'}, {"ignore-spaces", no_argument, 0, 'i'}, + {"local-infile", optional_argument, 0, OPT_LOCAL_INFILE}, {"no-auto-rehash",no_argument, 0, 'A'}, {"no-named-commands", no_argument, 0, 'g'}, {"no-tee", no_argument, 0, OPT_NOTEE}, @@ -738,6 +739,10 @@ static int get_options(int argc, char **argv) case 'C': opt_compress=1; break; + case OPT_LOCAL_INFILE: + using_opt_local_infile=1; + opt_local_infile= test(!optarg || atoi(optarg)>0); + break; case 'L': skip_line_numbers=1; break; @@ -2235,6 +2240,8 @@ sql_real_connect(char *host,char *database,char *user,char *password, } if (opt_compress) 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 if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, diff --git a/configure.in b/configure.in index ddc24e484c4..f8f5d88369b 100644 --- a/configure.in +++ b/configure.in @@ -518,7 +518,7 @@ AC_ARG_ENABLE(thread-safe-client, [ THREAD_SAFE_CLIENT=no ] ) -# Make thread safe client +# compile with strings functions in assembler AC_ARG_ENABLE(assembler, [ --enable-assembler Use assembler versions of some string functions if available.], @@ -583,6 +583,14 @@ AC_ARG_WITH(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. MYSQL_SYS_LARGEFILE diff --git a/include/mysql.h b/include/mysql.h index 4e57bd5888e..074ea0a1876 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -157,7 +157,8 @@ struct st_mysql_options { enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND, 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, MYSQL_STATUS_USE_RESULT}; diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 8311c508ccc..efdac031423 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -196,21 +196,6 @@ dict_mutex_exit_for_mysql(void) } /************************************************************************ -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. */ void @@ -496,6 +481,41 @@ dict_table_get( } /************************************************************************** +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. */ void diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 79d67ecae15..0f6f516c2cb 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -27,13 +27,6 @@ Created 1/8/1996 Heikki Tuuri #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. */ void @@ -195,6 +188,16 @@ dict_table_get( char* table_name, /* in: table name */ 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. */ dict_table_t* diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 292f8c0c6c8..f5ed0ef65af 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -273,8 +273,6 @@ row_create_prebuilt( ulint ref_len; ulint i; - dict_table_increment_handle_count(table); - heap = mem_heap_create(128); prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t)); @@ -1468,6 +1466,13 @@ loop: table = dict_table_get_low(drop->table_name); 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) { return(n_tables + n_tables_dropped); @@ -1477,10 +1482,16 @@ loop: row_drop_table_for_mysql_in_background(drop->table_name); +already_dropped: mutex_enter(&kernel_mutex); 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); @@ -1746,6 +1757,13 @@ row_drop_table_for_mysql( 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); err = DB_SUCCESS; @@ -1807,6 +1825,7 @@ row_drop_database_for_mysql( char* name, /* in: database name which ends to '/' */ trx_t* trx) /* in: transaction handle */ { + dict_table_t* table; char* table_name; int err = DB_SUCCESS; @@ -1817,12 +1836,35 @@ row_drop_database_for_mysql( trx->op_info = (char *) "dropping database"; trx_start_if_not_started(trx); - +loop: mutex_enter(&(dict_sys->mutex)); while ((table_name = dict_get_first_table_name_in_db(name))) { 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); mem_free(table_name); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0e9a163a5b5..32aa8e59888 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -60,7 +60,7 @@ static my_bool mysql_client_init=0; uint mysql_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__ #define CONNECT_TIMEOUT 20 @@ -694,12 +694,14 @@ mysql_free_result(MYSQL_RES *result) ****************************************************************************/ static const char *default_options[]= -{"port","socket","compress","password","pipe", "timeout", "user", - "init-command", "host", "database", "debug", "return-found-rows", - "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", "ssl-cipher" - "character-set-dir", "default-character-set", "interactive-timeout", - "connect_timeout", "replication-probe", "enable-reads-from-master", - "repl-parse-query", +{ + "port","socket","compress","password","pipe", "timeout", "user", + "init-command", "host", "database", "debug", "return-found-rows", + "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", + "character-set-dir", "default-character-set", "interactive-timeout", + "connect-timeout", "local-infile", "disable-local-infile", + "replication-probe", "enable-reads-from-master", "repl-parse-query", + "ssl-chiper", NullS }; @@ -734,6 +736,9 @@ static void mysql_read_default_options(struct st_mysql_options *options, opt_arg=end+1; *end=0; /* Remove '=' */ } + /* Change all '_' in variable name to '-' */ + for (end= *option ; (end= strcend(end,'_')) ; ) + *end= '-'; switch (find_type(*option+2,&option_types,2)) { case 1: /* port */ if (opt_arg) @@ -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)); break; 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; - case 21: /* replication probe */ + case 22: + options->client_flag&= CLIENT_LOCAL_FILES; + break; + case 23: /* replication probe */ options->rpl_probe = 1; break; - case 22: /* enable-reads-from-master */ + case 24: /* enable-reads-from-master */ options->rpl_parse = 1; break; - case 23: /* repl-parse-query */ + case 25: /* repl-parse-query */ options->no_master_reads = 0; break; default: @@ -1321,6 +1335,14 @@ mysql_init(MYSQL *mysql) if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) (void) signal(SIGPIPE,pipe_sig_handler); #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; } @@ -1770,7 +1792,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (mysql->options.use_ssl) client_flag|=CLIENT_SSL; #endif /* HAVE_OPENSSL */ - if (db) client_flag|=CLIENT_CONNECT_WITH_DB; #ifdef HAVE_COMPRESS @@ -2714,11 +2735,17 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) mysql->options.connect_timeout= *(uint*) arg; break; case MYSQL_OPT_COMPRESS: - mysql->options.compress=1; /* Remember for connect */ + mysql->options.compress= 1; /* Remember for connect */ break; case MYSQL_OPT_NAMED_PIPE: mysql->options.named_pipe=1; /* Force named pipe */ 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: my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); mysql->options.init_command=my_strdup(arg,MYF(MY_WME)); diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test index a85419c0295..2fc6237907c 100644 --- a/mysql-test/t/comments.test +++ b/mysql-test/t/comments.test @@ -5,7 +5,7 @@ select 1+2/*hello*/+3; select 1 /* long multi line comment */; -!$1065 /* empty query */; +!$1065 ; select 1 /*!32301 +1 */; select 1 /*!52301 +1 */; select 1--1; @@ -15,3 +15,4 @@ select 1 --2 +1; select 1 # The rest of the row will be ignored ; +/* line with only comment */; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e2657e5cad7..4cf06dfb731 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -987,7 +987,10 @@ ha_innobase::open( /* 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\ Cannot find table %s from the internal data dictionary\n\ @@ -2831,7 +2834,9 @@ innobase_drop_database( memcpy(namebuf, ptr, len); namebuf[len] = '/'; namebuf[len + 1] = '\0'; - +#ifdef __WIN__ + casedn_str(namebuf); +#endif trx = trx_allocate_for_mysql(); error = row_drop_database_for_mysql(namebuf, trx); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 03ec5ad9381..924f85b0a89 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -583,6 +583,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count; extern pthread_attr_t connection_attrib; extern bool opt_endinfo, using_udf_functions, locked_in_memory, opt_using_transactions, use_temp_pool, mysql_embedded; +extern bool opt_local_infile; extern char f_fyllchar; 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, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b5789dd0ff8..187a4732aa0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -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_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 ready_to_exit,shutdown_in_progress; 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))) static sig_handler print_signal_warning(int sig) { - sql_print_error("Warning: Got signal %d from thread %d", - sig,my_thread_id()); + if (opt_warnings) + sql_print_error("Warning: Got signal %d from thread %d", + sig,my_thread_id()); #ifdef DONT_REMEMBER_SIGNAL sigset(sig,print_signal_warning); /* int. thread system calls */ #endif @@ -2686,7 +2688,7 @@ enum options { OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE, 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[] = { @@ -2748,6 +2750,7 @@ static struct option long_options[] = { {"init-file", required_argument, 0, (int) OPT_INIT_FILE}, {"log", optional_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-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX}, {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG}, @@ -3615,6 +3618,9 @@ static void get_options(int argc,char **argv) case 'P': mysql_port= (unsigned int) atoi(optarg); break; + case OPT_LOCAL_INFILE: + opt_local_infile= test(!optarg || atoi(optarg) != 0); + break; case OPT_SLAVE_SKIP_ERRORS: init_slave_skip_errors(optarg); break; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d61e47d0883..a3497d23ee5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -768,6 +768,7 @@ int yylex(void *arg) return(TEXT_STRING); case STATE_COMMENT: // Comment + lex->options|= OPTION_FOUND_COMMENT; while ((c = yyGet()) != '\n' && c) ; yyUnget(); // Safety against eof state = STATE_START; // Try again @@ -779,6 +780,7 @@ int yylex(void *arg) break; } yySkip(); // Skip '*' + lex->options|= OPTION_FOUND_COMMENT; if (yyPeek() == '!') // MySQL command in comment { ulong version=MYSQL_VERSION_ID; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6a966336ad7..c0ede015eb8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -57,6 +57,7 @@ enum enum_sql_command { SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE, SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO, + SQLCOM_EMPTY_QUERY, SQLCOM_END }; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 899f2e20469..419e3fccabd 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -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) 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); file = -1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 01327363c59..7f9c8da05c1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1312,6 +1312,10 @@ mysql_execute_command(void) res=mysql_do(thd, *lex->insert_list); break; + case SQLCOM_EMPTY_QUERY: + send_ok(&thd->net); + break; + case SQLCOM_PURGE: { if (check_process_priv(thd)) @@ -2094,13 +2098,20 @@ mysql_execute_command(void) { uint privilege= (lex->duplicates == DUP_REPLACE ? 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)) goto error; } 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) || grant_option && check_grant(thd,privilege,tables)) goto error; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 91cf0ae5fc9..c3db58ce20b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -596,9 +596,17 @@ END_OF_INPUT query: END_OF_INPUT { - if (!current_thd->bootstrap) + THD *thd=current_thd; + if (!thd->bootstrap && + (!(thd->lex.options & OPTION_FOUND_COMMENT))) + { send_error(¤t_thd->net,ER_EMPTY_QUERY); - YYABORT; + YYABORT; + } + else + { + thd->lex.sql_command = SQLCOM_EMPTY_QUERY; + } } | verb_clause END_OF_INPUT {} diff --git a/sql/unireg.cc b/sql/unireg.cc index 8c72dfc2855..16ba8c7d58b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -486,11 +486,11 @@ static bool pack_fields(File file,List<create_field> &create_fields) if (field->interval_id > int_count) { int_count=field->interval_id; - tmp.append('\377'); + tmp.append(NAMES_SEP_CHAR); for (const char **pos=field->interval->type_names ; *pos ; pos++) { tmp.append(*pos); - tmp.append('\377'); + tmp.append(NAMES_SEP_CHAR); } tmp.append('\0'); // End of intervall } diff --git a/sql/unireg.h b/sql/unireg.h index 9b220f87918..c4d2052d1da 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -70,11 +70,6 @@ #define FERR -1 /* Error from my_functions */ #define CREATE_MODE 0 /* Default mode on new files */ #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 DISK_BUFFER_SIZE (uint) (IO_SIZE*16) /* Size of diskbuffer */ |