summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2010-06-17 17:31:51 +0400
committerKonstantin Osipov <kostja@sun.com>2010-06-17 17:31:51 +0400
commitcc6dabba377bd05bb9a6a9ffaa985bbe5e38bcc1 (patch)
tree9413ba739bc0dbf1e647293756a3503f17dcde07 /sql
parent91a7b147056a228804f81726127035aa305702ff (diff)
parent45c7bf3c54fa852b312773688fdce15bffe49abf (diff)
downloadmariadb-git-cc6dabba377bd05bb9a6a9ffaa985bbe5e38bcc1.tar.gz
Merge trunk-bugfixing -> trunk-runtime
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc5
-rw-r--r--sql/field.cc15
-rw-r--r--sql/ha_ndbcluster_binlog.cc5
-rw-r--r--sql/ha_partition.cc13
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/item_subselect.cc17
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/log_event.cc40
-rw-r--r--sql/log_event_old.cc31
-rw-r--r--sql/mysqld.cc247
-rw-r--r--sql/net_serv.cc14
-rw-r--r--sql/opt_sum.cc41
-rw-r--r--sql/share/errmsg-utf8.txt3
-rw-r--r--sql/sp.cc25
-rw-r--r--sql/sp.h6
-rw-r--r--sql/sp_head.cc34
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_class.h5
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_delete.cc10
-rw-r--r--sql/sql_delete.h4
-rw-r--r--sql/sql_derived.cc6
-rw-r--r--sql/sql_handler.cc23
-rw-r--r--sql/sql_lex.cc49
-rw-r--r--sql/sql_lex.h55
-rw-r--r--sql/sql_list.h56
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_olap.cc4
-rw-r--r--sql/sql_parse.cc105
-rw-r--r--sql/sql_parse.h2
-rw-r--r--sql/sql_partition.cc4
-rw-r--r--sql/sql_plugin.cc60
-rw-r--r--sql/sql_prepare.cc36
-rw-r--r--sql/sql_select.cc63
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_trigger.cc13
-rw-r--r--sql/sql_union.cc38
-rw-r--r--sql/sql_update.cc10
-rw-r--r--sql/sql_view.cc14
-rw-r--r--sql/sql_yacc.yy27
-rw-r--r--sql/sys_vars.cc25
-rw-r--r--sql/table.cc94
-rw-r--r--sql/table.h3
-rw-r--r--sql/thr_malloc.cc8
-rw-r--r--sql/unireg.cc14
49 files changed, 806 insertions, 448 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 28fd1e240a2..c778d72a016 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1447,7 +1447,10 @@ Event_job_data::execute(THD *thd, bool drop)
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
{
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state;
+ if (parser_state.init(thd, thd->query(), thd->query_length()))
+ goto end;
+
lex_start(thd);
if (parse_sql(thd, & parser_state, creation_ctx))
diff --git a/sql/field.cc b/sql/field.cc
index 88a7f43819d..bfaaf10b141 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5271,7 +5271,6 @@ String *Field_time::val_str(String *val_buffer,
bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
- long tmp;
THD *thd= table ? table->in_use : current_thd;
if (!(fuzzydate & TIME_FUZZY_DATE))
{
@@ -5281,19 +5280,7 @@ bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
thd->warning_info->current_row_for_warning());
return 1;
}
- tmp=(long) sint3korr(ptr);
- ltime->neg=0;
- if (tmp < 0)
- {
- ltime->neg= 1;
- tmp=-tmp;
- }
- ltime->hour=tmp/10000;
- tmp-=ltime->hour*10000;
- ltime->minute= tmp/100;
- ltime->second= tmp % 100;
- ltime->year= ltime->month= ltime->day= ltime->second_part= 0;
- return 0;
+ return Field_time::get_time(ltime);
}
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 0db7956fe28..ab046164485 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -277,8 +277,9 @@ static void run_query(THD *thd, char *buf, char *end,
DBUG_ASSERT(!thd->locked_tables_mode);
{
- Parser_state parser_state(thd, thd->query(), thd->query_length());
- mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
+ Parser_state parser_state;
+ if (!parser_state.init(thd, thd->query(), thd->query_length()))
+ mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
}
if (no_print_error && thd->is_slave_error)
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 9e06c0371d4..3fb5a30b560 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -91,7 +91,9 @@ static int partition_initialize(void *p)
partition_hton->create= partition_create_handler;
partition_hton->partition_flags= partition_flags;
partition_hton->alter_table_flags= alter_table_flags;
- partition_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
+ partition_hton->flags= HTON_NOT_USER_SELECTABLE |
+ HTON_HIDDEN |
+ HTON_TEMPORARY_NOT_SUPPORTED;
return 0;
}
@@ -360,7 +362,7 @@ bool ha_partition::initialize_partition(MEM_ROOT *mem_root)
}
else if (get_from_handler_file(table_share->normalized_path.str, mem_root))
{
- mem_alloc_error(2);
+ my_error(ER_FAILED_READ_FROM_PAR_FILE, MYF(0));
DBUG_RETURN(1);
}
/*
@@ -1897,6 +1899,13 @@ uint ha_partition::del_ren_cre_table(const char *from,
handler **file, **abort_file;
DBUG_ENTER("del_ren_cre_table()");
+ /* Not allowed to create temporary partitioned tables */
+ if (create_info && create_info->options & HA_LEX_CREATE_TMP_TABLE)
+ {
+ my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
if (get_from_handler_file(from, ha_thd()->mem_root))
DBUG_RETURN(TRUE);
DBUG_ASSERT(m_file_buffer);
diff --git a/sql/handler.h b/sql/handler.h
index ad26534d91d..fc49d9e647d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -988,7 +988,7 @@ typedef struct st_ha_create_information
ulong avg_row_length;
ulong used_fields;
ulong key_block_size;
- SQL_LIST merge_list;
+ SQL_I_List<TABLE_LIST> merge_list;
handlerton *db_type;
/**
Row type of the table definition.
diff --git a/sql/item.cc b/sql/item.cc
index c59a17a0ea3..05363f41d07 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4111,7 +4111,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
{
Item **group_by_ref= NULL;
Item **select_ref= NULL;
- ORDER *group_list= (ORDER*) select->group_list.first;
+ ORDER *group_list= select->group_list.first;
bool ambiguous_fields= FALSE;
uint counter;
enum_resolution_type resolution;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index a0b3f2c29a1..8813324262c 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1324,8 +1324,8 @@ public:
else
{
args[0]->update_used_tables();
- if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
- !with_subselect)
+ if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
+ !with_subselect))
{
/* Remember if the value is always NULL or never NULL */
cached_value= (longlong) args[0]->is_null();
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 10ef992594e..809926338af 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -252,12 +252,12 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
if (item->walk(processor, walk_subquery, argument))
return 1;
}
- for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
+ for (order= lex->order_list.first ; order; order= order->next)
{
if ((*order->item)->walk(processor, walk_subquery, argument))
return 1;
}
- for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
+ for (order= lex->group_list.first ; order; order= order->next)
{
if ((*order->item)->walk(processor, walk_subquery, argument))
return 1;
@@ -1784,15 +1784,15 @@ int subselect_single_select_engine::prepare()
SELECT_LEX *save_select= thd->lex->current_select;
thd->lex->current_select= select_lex;
if (join->prepare(&select_lex->ref_pointer_array,
- (TABLE_LIST*) select_lex->table_list.first,
+ select_lex->table_list.first,
select_lex->with_wild,
select_lex->where,
select_lex->order_list.elements +
select_lex->group_list.elements,
- (ORDER*) select_lex->order_list.first,
- (ORDER*) select_lex->group_list.first,
+ select_lex->order_list.first,
+ select_lex->group_list.first,
select_lex->having,
- (ORDER*) 0, select_lex,
+ NULL, select_lex,
select_lex->master_unit()))
return 1;
thd->lex->current_select= save_select;
@@ -2455,14 +2455,13 @@ table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
table_map subselect_single_select_engine::upper_select_const_tables()
{
- return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
- leaf_tables);
+ return calc_const_tables(select_lex->outer_select()->leaf_tables);
}
table_map subselect_union_engine::upper_select_const_tables()
{
- return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
+ return calc_const_tables(unit->outer_select()->leaf_tables);
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 15927c4b11e..77c45ea85f7 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2995,7 +2995,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
Item_func_group_concat::
Item_func_group_concat(Name_resolution_context *context_arg,
bool distinct_arg, List<Item> *select_list,
- SQL_LIST *order_list, String *separator_arg)
+ SQL_I_List<ORDER> *order_list, String *separator_arg)
:tmp_table_param(0), separator(separator_arg), tree(0),
unique_filter(NULL), table(0),
order(0), context(context_arg),
@@ -3039,7 +3039,7 @@ Item_func_group_concat(Name_resolution_context *context_arg,
if (arg_count_order)
{
ORDER **order_ptr= order;
- for (ORDER *order_item= (ORDER*) order_list->first;
+ for (ORDER *order_item= order_list->first;
order_item != NULL;
order_item= order_item->next)
{
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 99fcb14d160..b4539995632 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1375,7 +1375,7 @@ class Item_func_group_concat : public Item_sum
public:
Item_func_group_concat(Name_resolution_context *context_arg,
bool is_distinct, List<Item> *is_select,
- SQL_LIST *is_order, String *is_separator);
+ SQL_I_List<ORDER> *is_order, String *is_separator);
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
~Item_func_group_concat();
diff --git a/sql/log_event.cc b/sql/log_event.cc
index f7c6d09f98f..7778ee18f5c 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3254,9 +3254,12 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
thd->table_map_for_update= (table_map)table_map_for_update;
/* Execute the query (note that we bypass dispatch_command()) */
- Parser_state parser_state(thd, thd->query(), thd->query_length());
- mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
- log_slow_statement(thd);
+ Parser_state parser_state;
+ if (!parser_state.init(thd, thd->query(), thd->query_length()))
+ {
+ mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
+ log_slow_statement(thd);
+ }
/*
Resetting the enable_slow_log thd variable.
@@ -9144,8 +9147,35 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
*/
if (table->key_info->flags & HA_NOSAME)
{
- table->file->ha_index_end();
- goto ok;
+ /* Unique does not have non nullable part */
+ if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
+ {
+ table->file->ha_index_end();
+ goto ok;
+ }
+ else
+ {
+ KEY *keyinfo= table->key_info;
+ /*
+ Unique has nullable part. We need to check if there is any field in the
+ BI image that is null and part of UNNI.
+ */
+ bool null_found= FALSE;
+ for (uint i=0; i < keyinfo->key_parts && !null_found; i++)
+ {
+ uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
+ Field **f= table->field+fieldnr;
+ null_found= (*f)->is_null();
+ }
+
+ if (!null_found)
+ {
+ table->file->ha_index_end();
+ goto ok;
+ }
+
+ /* else fall through to index scan */
+ }
}
/*
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 76eda43aa48..d9b48cd134e 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -2339,8 +2339,35 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
*/
if (table->key_info->flags & HA_NOSAME)
{
- table->file->ha_index_end();
- DBUG_RETURN(0);
+ /* Unique does not have non nullable part */
+ if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
+ {
+ table->file->ha_index_end();
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ KEY *keyinfo= table->key_info;
+ /*
+ Unique has nullable part. We need to check if there is any field in the
+ BI image that is null and part of UNNI.
+ */
+ bool null_found= FALSE;
+ for (uint i=0; i < keyinfo->key_parts && !null_found; i++)
+ {
+ uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
+ Field **f= table->field+fieldnr;
+ null_found= (*f)->is_null();
+ }
+
+ if (!null_found)
+ {
+ table->file->ha_index_end();
+ DBUG_RETURN(0);
+ }
+
+ /* else fall through to index scan */
+ }
}
/*
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index db0080451f2..7968d637223 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -224,9 +224,9 @@ typedef fp_except fp_except_t;
# define fpu_control_t unsigned int
# define _FPU_EXTENDED 0x300
# define _FPU_DOUBLE 0x200
-# ifdef __GNUC__
-# define _FPU_GETCW(cw) __asm__ __volatile__("fnstcw %0" : "=m" (*&cw))
-# define _FPU_SETCW(cw) __asm__ __volatile__("fldcw %0" : : "m" (*&cw))
+# if defined(__GNUC__) || defined(__SUNPRO_CC)
+# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
# else
# define _FPU_GETCW(cw) (cw= 0)
# define _FPU_SETCW(cw)
@@ -3113,6 +3113,10 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
MYSQL_ERROR::WARN_LEVEL_ERROR,
str);
}
+
+ /* When simulating OOM, skip writing to error log to avoid mtr errors */
+ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
+
if (!thd || MyFlags & ME_NOREFRESH)
sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
DBUG_VOID_RETURN;
@@ -3131,7 +3135,7 @@ void *my_str_malloc_mysqld(size_t size)
void my_str_free_mysqld(void *ptr)
{
- my_free((uchar*)ptr, MYF(MY_FAE));
+ my_free(ptr, MYF(MY_FAE));
}
#endif /* EMBEDDED_LIBRARY */
@@ -3366,6 +3370,13 @@ static int init_common_variables()
max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= flush_status_time= my_time(0);
+ /* TODO: remove this when my_time_t is 64 bit compatible */
+ if (server_start_time >= (time_t) MY_TIME_T_MAX)
+ {
+ sql_print_error("This MySQL server doesn't support dates later then 2038");
+ return 1;
+ }
+
rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter;
if (!rpl_filter || !binlog_filter)
@@ -5949,12 +5960,12 @@ DYNAMIC_ARRAY all_options;
struct my_option my_long_options[]=
{
{"help", '?', "Display this help and exit.",
- (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
#ifdef HAVE_REPLICATION
{"abort-slave-event-count", 0,
"Option used by mysql-test for debugging and testing of replication.",
- (uchar**) &abort_slave_event_count, (uchar**) &abort_slave_event_count,
+ &abort_slave_event_count, &abort_slave_event_count,
0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
{"allow-suspicious-udfs", 0,
@@ -5962,15 +5973,17 @@ struct my_option my_long_options[]=
"without corresponding xxx_init() or xxx_deinit(). That also means "
"that one can load any function from any library, for example exit() "
"from libc.so",
- (uchar**) &opt_allow_suspicious_udfs, (uchar**) &opt_allow_suspicious_udfs,
+ &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
+ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
+ "will also set transaction isolation level 'serializable'.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
- (uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
+ &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-do-db", OPT_BINLOG_DO_DB,
- "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
+ "Tells the master it should log updates for the specified database, "
+ "and exclude all others not explicitly mentioned.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
"Tells the master that updates to the given database should not be logged to the binary log.",
@@ -5979,9 +5992,8 @@ struct my_option my_long_options[]=
"The maximum size of a row-based binary log event in bytes. Rows will be "
"grouped into events smaller than this size if possible. "
"The value has to be a multiple of 256.",
- (uchar**) &opt_binlog_rows_event_max_size,
- (uchar**) &opt_binlog_rows_event_max_size, 0,
- GET_ULONG, REQUIRED_ARG,
+ &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
+ 0, GET_ULONG, REQUIRED_ARG,
/* def_value */ 1024, /* min_value */ 256, /* max_value */ ULONG_MAX,
/* sub_size */ 0, /* block_size */ 256,
/* app_type */ 0
@@ -5992,25 +6004,25 @@ struct my_option my_long_options[]=
#endif
{"character-set-client-handshake", 0,
"Don't ignore client side character set value sent during handshake.",
- (uchar**) &opt_character_set_client_handshake,
- (uchar**) &opt_character_set_client_handshake,
+ &opt_character_set_client_handshake,
+ &opt_character_set_client_handshake,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"character-set-filesystem", 0,
"Set the filesystem character set.",
- (uchar**) &character_set_filesystem_name,
- (uchar**) &character_set_filesystem_name,
+ &character_set_filesystem_name,
+ &character_set_filesystem_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"character-set-server", 'C', "Set the default character set.",
- (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
+ &default_character_set_name, &default_character_set_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"chroot", 'r', "Chroot mysqld daemon during startup.",
- (uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
+ &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"collation-server", 0, "Set the default collation.",
- (uchar**) &default_collation_name, (uchar**) &default_collation_name,
+ &default_collation_name, &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
- (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
{"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -6018,128 +6030,126 @@ struct my_option my_long_options[]=
of initializing it here it is done in init_common_variables() due
to a compiler bug in Sun Studio compiler. */
{"default-storage-engine", 0, "The default storage engine for new tables",
- (uchar**) &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
+ &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0 },
{"default-time-zone", 0, "Set the default time zone.",
- (uchar**) &default_tz_name, (uchar**) &default_tz_name,
+ &default_tz_name, &default_tz_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
#ifdef HAVE_OPENSSL
{"des-key-file", 0,
"Load keys for des_encrypt() and des_encrypt from given file.",
- (uchar**) &des_key_file, (uchar**) &des_key_file, 0, GET_STR, REQUIRED_ARG,
+ &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
#ifdef HAVE_REPLICATION
{"disconnect-slave-event-count", 0,
"Option used by mysql-test for debugging and testing of replication.",
- (uchar**) &disconnect_slave_event_count,
- (uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
- 0, 0, 0},
+ &disconnect_slave_event_count, &disconnect_slave_event_count,
+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
#ifdef HAVE_STACK_TRACE_ON_SEGV
{"enable-pstack", 0, "Print a symbolic stack trace on failure.",
- (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
+ &opt_do_pstack, &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
#endif /* HAVE_STACK_TRACE_ON_SEGV */
- /* See how it's handled in get_one_option() */
{"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0,
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"external-locking", 0, "Use system (external) locking (disabled by default). With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.",
- (uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
+
+ {"external-locking", 0, "Use system (external) locking (disabled by "
+ "default). With this option enabled you can run myisamchk to test "
+ "(not repair) tables while the MySQL server is running. Disable with "
+ "--skip-external-locking.", &opt_external_locking, &opt_external_locking,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
/* We must always support the next option to make scripts like mysqltest
easier to do */
{"gdb", 0,
"Set up signals usable for debugging.",
- (uchar**) &opt_debugging, (uchar**) &opt_debugging,
+ &opt_debugging, &opt_debugging,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_LARGE_PAGE_OPTION
{"super-large-pages", 0, "Enable support for super large pages.",
- (uchar**) &opt_super_large_pages, (uchar**) &opt_super_large_pages, 0,
+ &opt_super_large_pages, &opt_super_large_pages, 0,
GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
#endif
{"language", 'L',
"Client error messages in given language. May be given as a full path. "
"Deprecated. Use --lc-messages-dir instead.",
- (uchar**) &lc_messages_dir_ptr, (uchar**) &lc_messages_dir_ptr, 0,
+ &lc_messages_dir_ptr, &lc_messages_dir_ptr, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"lc-messages", 0,
"Set the language used for the error messages.",
- (uchar**) &lc_messages, (uchar**) &lc_messages, 0, GET_STR, REQUIRED_ARG,
+ &lc_messages, &lc_messages, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0 },
{"lc-time-names", 0,
"Set the language used for the month names and the days of the week.",
- (uchar**) &lc_time_names_name,
- (uchar**) &lc_time_names_name,
+ &lc_time_names_name, &lc_time_names_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"log", 'l', "Log connections and queries to file (deprecated option, use "
- "--general-log/--general-log-file instead).", (uchar**) &opt_logname,
- (uchar**) &opt_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ "--general-log/--general-log-file instead).", &opt_logname, &opt_logname,
+ 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-bin", OPT_BIN_LOG,
"Log update queries in binary format. Optional (but strongly recommended "
"to avoid replication problems if server's hostname changes) argument "
"should be the chosen location for the binary log files.",
- (uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
+ &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC,
OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-bin-index", 0,
"File that holds the names for last binary log files.",
- (uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
+ &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
- (uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
+ &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-short-format", 0,
"Don't log extra information to update and slow-query logs.",
- (uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
+ &opt_short_log_format, &opt_short_log_format,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-admin-statements", 0,
- "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
- (uchar**) &opt_log_slow_admin_statements,
- (uchar**) &opt_log_slow_admin_statements,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to "
+ "the slow log if it is open.", &opt_log_slow_admin_statements,
+ &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-slave-statements", 0,
"Log slow statements executed by slave thread to the slow log if it is open.",
- (uchar**) &opt_log_slow_slave_statements,
- (uchar**) &opt_log_slow_slave_statements,
+ &opt_log_slow_slave_statements, &opt_log_slow_slave_statements,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-queries", OPT_SLOW_QUERY_LOG,
"Log slow queries to a table or log file. Defaults logging to table "
"mysql.slow_log or hostname-slow.log if --log-output=file is used. "
"Must be enabled to activate other slow log options. "
"Deprecated option, use --slow-query-log/--slow-query-log-file instead.",
- (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR_ALLOC, OPT_ARG,
+ &opt_slow_logname, &opt_slow_logname, 0, GET_STR_ALLOC, OPT_ARG,
0, 0, 0, 0, 0, 0},
{"log-tc", 0,
"Path to transaction coordinator log (used for transactions that affect "
"more than one storage engine, when binary log is disabled).",
- (uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
+ &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_MMAP
{"log-tc-size", 0, "Size of transaction coordinator log.",
- (uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
+ &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
TC_LOG_PAGE_SIZE, 0},
#endif
{"master-info-file", 0,
- "The location and name of the file that remembers the master and where the I/O replication \
-thread is in the master's binlogs.",
- (uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
+ "The location and name of the file that remembers the master and where "
+ "the I/O replication thread is in the master's binlogs.",
+ &master_info_file, &master_info_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"master-retry-count", 0,
"The number of tries the slave will make to connect to the master before giving up.",
- (uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
+ &master_retry_count, &master_retry_count, 0, GET_ULONG,
REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
{"init-rpl-role", 0, "Set the replication role.",
- (uchar**)&rpl_status, (uchar**)&rpl_status, &rpl_role_typelib,
+ &rpl_status, &rpl_status, &rpl_role_typelib,
GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"max-binlog-dump-events", 0,
"Option used by mysql-test for debugging and testing of replication.",
- (uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
+ &max_binlog_dump_events, &max_binlog_dump_events, 0,
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
- {"memlock", 0, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
- (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
+ &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"one-thread", OPT_ONE_THREAD,
"(Deprecated): Only use one thread (for debugging under Linux). Use "
"thread-handling=no-threads instead.",
@@ -6147,67 +6157,88 @@ thread is in the master's binlogs.",
{"old-style-user-limits", 0,
"Enable old-style user limits (before 5.0.3, user resources were counted "
"per each user+host vs. per account).",
- (uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
+ &opt_old_style_user_limits, &opt_old_style_user_limits,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"port-open-timeout", 0,
"Maximum time in seconds to wait for the port to become free. "
- "(Default: No wait).", (uchar**) &mysqld_port_timeout,
- (uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "(Default: No wait).", &mysqld_port_timeout, &mysqld_port_timeout, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-do-db", OPT_REPLICATE_DO_DB,
- "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
+ "Tells the slave thread to restrict replication to the specified database. "
+ "To specify more than one database, use the directive multiple times, "
+ "once for each database. Note that this will only work if you do not use "
+ "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
+ "while having selected a different or no database. If you need cross "
+ "database updates to work, make sure you have 3.23.28 or later, and use "
+ "replicate-wild-do-table=db_name.%.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-do-table", OPT_REPLICATE_DO_TABLE,
- "Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "Tells the slave thread to restrict replication to the specified table. "
+ "To specify more than one table, use the directive multiple times, once "
+ "for each table. This will work for cross-database updates, in contrast "
+ "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
- "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "Tells the slave thread to not replicate to the specified database. To "
+ "specify more than one database to ignore, use the directive multiple "
+ "times, once for each database. This option will not work if you use "
+ "cross database updates. If you need cross database updates to work, "
+ "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
+ "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
"Tells the slave thread to not replicate to the specified table. To specify "
"more than one table to ignore, use the directive multiple times, once for "
"each table. This will work for cross-database updates, in contrast to "
- "replicate-ignore-db.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
- "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
+ "Updates to a database with a different name than the original. Example: "
+ "replicate-rewrite-db=master_db_name->slave_db_name.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
{"replicate-same-server-id", 0,
- "In replication, if set to 1, do not skip events having our server id. \
-Default value is 0 (to break infinite loops in circular replication). \
-Can't be set to 1 if --log-slave-updates is used.",
- (uchar**) &replicate_same_server_id,
- (uchar**) &replicate_same_server_id,
+ "In replication, if set to 1, do not skip events having our server id. "
+ "Default value is 0 (to break infinite loops in circular replication). "
+ "Can't be set to 1 if --log-slave-updates is used.",
+ &replicate_same_server_id, &replicate_same_server_id,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
- "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar.",
+ "Tells the slave thread to restrict replication to the tables that match "
+ "the specified wildcard pattern. To specify more than one table, use the "
+ "directive multiple times, once for each table. This will work for cross-"
+ "database updates. Example: replicate-wild-do-table=foo%.bar% will "
+ "replicate only updates to tables in all databases that start with foo "
+ "and whose table names start with bar.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
- "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
+ "Tells the slave thread to not replicate to the tables that match the "
+ "given wildcard pattern. To specify more than one table to ignore, use "
+ "the directive multiple times, once for each table. This will work for "
+ "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
+ "will not do updates to tables in databases that start with foo and whose "
+ "table names start with bar.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"safe-user-create", 0,
"Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
- (uchar**) &opt_safe_user_create, (uchar**) &opt_safe_user_create, 0, GET_BOOL,
+ &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
{"safemalloc", 0, "Enable the memory allocation checking.",
- (uchar**) &sf_malloc_quick, (uchar**) &sf_malloc_quick, 0,
+ &sf_malloc_quick, &sf_malloc_quick, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"safemalloc-mem-limit", 0, "Simulate memory shortage.",
- (uchar**)&sf_malloc_mem_limit, (uchar**)&sf_malloc_mem_limit, 0, GET_UINT,
+ &sf_malloc_mem_limit, &sf_malloc_mem_limit, 0, GET_UINT,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"show-slave-auth-info", 0,
"Show user and password in SHOW SLAVE HOSTS on this master.",
- (uchar**) &opt_show_slave_auth_info, (uchar**) &opt_show_slave_auth_info, 0,
+ &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DISABLE_GRANT_OPTIONS
{"skip-grant-tables", 0,
"Start without grant tables. This gives all users FULL ACCESS to all tables.",
- (uchar**) &opt_noacl, (uchar**) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
#endif
{"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
@@ -6215,8 +6246,8 @@ Can't be set to 1 if --log-slave-updates is used.",
{"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-slave-start", 0,
- "If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
- (uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ "If set, slave is not autostarted.", &opt_skip_slave_start,
+ &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-stack-trace", OPT_SKIP_STACK_TRACE,
"Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
0, 0, 0, 0},
@@ -6227,14 +6258,14 @@ Can't be set to 1 if --log-slave-updates is used.",
#ifdef HAVE_REPLICATION
{"sporadic-binlog-dump-fail", 0,
"Option used by mysql-test for debugging and testing of replication.",
- (uchar**) &opt_sporadic_binlog_dump_fail,
- (uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ &opt_sporadic_binlog_dump_fail,
+ &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
#endif /* HAVE_REPLICATION */
#ifdef HAVE_OPENSSL
{"ssl", 0,
"Enable SSL for connection (automatically enabled with other flags).",
- (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
+ &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
0, 0, 0},
#endif
#ifdef __WIN__
@@ -6243,7 +6274,7 @@ Can't be set to 1 if --log-slave-updates is used.",
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"symbolic-links", 's', "Enable symbolic link support.",
- (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
+ &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
/*
The system call realpath() produces warnings under valgrind and
purify. These are not suppressed: instead we disable symlinks
@@ -6251,49 +6282,51 @@ Can't be set to 1 if --log-slave-updates is used.",
*/
IF_PURIFY(0,1), 0, 0, 0, 0, 0},
{"sysdate-is-now", 0,
- "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. Since 5.0, SYSDATE() returns a `dynamic' value different for different invocations, even within the same statement.",
- (uchar**) &global_system_variables.sysdate_is_now,
+ "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
+ "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
+ "invocations, even within the same statement.",
+ &global_system_variables.sysdate_is_now,
0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
{"tc-heuristic-recover", 0,
- "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
- (uchar**) &tc_heuristic_recover, (uchar**) &tc_heuristic_recover,
+ "Decision to use in heuristic recover process. Possible values are COMMIT "
+ "or ROLLBACK.", &tc_heuristic_recover, &tc_heuristic_recover,
&tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#if defined(ENABLED_DEBUG_SYNC)
{"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
"Enable the debug sync facility "
"and optionally specify a default wait timeout in seconds. "
"A zero value keeps the facility disabled.",
- (uchar**) &opt_debug_sync_timeout, 0,
+ &opt_debug_sync_timeout, 0,
0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
#endif /* defined(ENABLED_DEBUG_SYNC) */
{"temp-pool", 0,
#if (ENABLE_TEMP_POOL)
- "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
+ "Using this option will cause most temporary files created to use a small "
+ "set of names, rather than a unique name for each new file.",
#else
"This option is ignored on this OS.",
#endif
- (uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
+ &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
{"transaction-isolation", 0,
"Default transaction isolation level.",
- (uchar**)&global_system_variables.tx_isolation,
- (uchar**)&global_system_variables.tx_isolation, &tx_isolation_typelib,
+ &global_system_variables.tx_isolation,
+ &global_system_variables.tx_isolation, &tx_isolation_typelib,
GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
{"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Used with --help option for detailed help.",
- (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
- 0, 0},
+ &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"plugin-load", 0,
"Optional semicolon-separated list of plugins to load, where each plugin is "
"identified as name=library, where name is the plugin name and library "
"is the plugin library in plugin_dir.",
- (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
+ &opt_plugin_load, &opt_plugin_load, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"table_cache", 0, "Deprecated; use --table-open-cache instead.",
- (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
+ &table_cache_size, &table_cache_size, 0, GET_ULONG,
REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -7425,7 +7458,7 @@ mysqld_get_one_option(int optid,
C_MODE_START
-static uchar* *
+static void*
mysql_getopt_value(const char *keyname, uint key_length,
const struct my_option *option, int *error)
{
@@ -7446,13 +7479,13 @@ mysql_getopt_value(const char *keyname, uint key_length,
}
switch (option->id) {
case OPT_KEY_BUFFER_SIZE:
- return (uchar**) &key_cache->param_buff_size;
+ return &key_cache->param_buff_size;
case OPT_KEY_CACHE_BLOCK_SIZE:
- return (uchar**) &key_cache->param_block_size;
+ return &key_cache->param_block_size;
case OPT_KEY_CACHE_DIVISION_LIMIT:
- return (uchar**) &key_cache->param_division_limit;
+ return &key_cache->param_division_limit;
case OPT_KEY_CACHE_AGE_THRESHOLD:
- return (uchar**) &key_cache->param_age_threshold;
+ return &key_cache->param_age_threshold;
}
}
}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 28ed4cbdbaf..918798529de 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -16,11 +16,7 @@
/**
@file
- This file is the net layer API for the MySQL client/server protocol,
- which is a tightly coupled, proprietary protocol owned by MySQL AB.
- @note
- Any re-implementations of this protocol must also be under GPL
- unless one has got an license from MySQL AB stating otherwise.
+ This file is the net layer API for the MySQL client/server protocol.
Write and read of logical packets to/from socket.
@@ -924,7 +920,13 @@ my_real_read(NET *net, size_t *complen)
("Packets out of order (Found: %d, expected %u)",
(int) net->buff[net->where_b + 3],
net->pkt_nr));
-#ifdef EXTRA_DEBUG
+ /*
+ We don't make noise server side, since the client is expected
+ to break the protocol for e.g. --send LOAD DATA .. LOCAL where
+ the server expects the client to send a file, but the client
+ may reply with a new command instead.
+ */
+#if defined (EXTRA_DEBUG) && !defined (MYSQL_SERVER)
fflush(stdout);
fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
(int) net->buff[net->where_b + 3],
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 0c79c8dc797..e020c94a3bd 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -143,7 +143,10 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref,
1) We have only MIN() and the argument column is nullable, or
2) there is a > predicate on it, nullability is irrelevant.
We need to scan the next bigger record first.
+ Open interval is not used if the search key involves the last keypart,
+ and it would not work.
*/
+ DBUG_ASSERT(prefix_len < ref->key_length);
error= table->file->index_read_map(table->record[0],
ref->key_buff,
make_prev_keypart_map(ref->key_parts),
@@ -596,18 +599,19 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
key_part_map *key_part_used, uint *range_fl,
uint *prefix_len)
{
+ DBUG_ENTER("matching_cond");
if (!cond)
- return 1;
+ DBUG_RETURN(TRUE);
Field *field= field_part->field;
if (!(cond->used_tables() & field->table->map))
{
/* Condition doesn't restrict the used table */
- return 1;
+ DBUG_RETURN(TRUE);
}
if (cond->type() == Item::COND_ITEM)
{
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
- return 0;
+ DBUG_RETURN(FALSE);
/* AND */
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
@@ -616,13 +620,13 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
{
if (!matching_cond(max_fl, ref, keyinfo, field_part, item,
key_part_used, range_fl, prefix_len))
- return 0;
+ DBUG_RETURN(FALSE);
}
- return 1;
+ DBUG_RETURN(TRUE);
}
if (cond->type() != Item::FUNC_ITEM)
- return 0; // Not operator, can't optimize
+ DBUG_RETURN(FALSE); // Not operator, can't optimize
bool eq_type= 0; // =, <=> or IS NULL
bool is_null_safe_eq= FALSE; // The operator is NULL safe, e.g. <=>
@@ -656,7 +660,7 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
eq_type= 1;
break;
default:
- return 0; // Can't optimize function
+ DBUG_RETURN(FALSE); // Can't optimize function
}
Item *args[3];
@@ -664,11 +668,11 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
/* Test if this is a comparison of a field and constant */
if (!simple_pred((Item_func*) cond, args, &inv))
- return 0;
+ DBUG_RETURN(FALSE);
if (!is_null_safe_eq && !is_null &&
(args[1]->is_null() || (between && args[2]->is_null())))
- return FALSE;
+ DBUG_RETURN(FALSE);
if (inv && !eq_type)
less_fl= 1-less_fl; // Convert '<' -> '>' (etc)
@@ -680,14 +684,14 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
{
if (part > field_part)
- return 0; // Field is beyond the tested parts
+ DBUG_RETURN(FALSE); // Field is beyond the tested parts
if (part->field->eq(((Item_field*) args[0])->field))
break; // Found a part of the key for the field
}
bool is_field_part= part == field_part;
if (!(is_field_part || eq_type))
- return 0;
+ DBUG_RETURN(FALSE);
key_part_map org_key_part_used= *key_part_used;
if (eq_type || between || max_fl == less_fl)
@@ -707,6 +711,17 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
*key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
}
+ if (org_key_part_used == *key_part_used &&
+ /*
+ The current search key is not being extended with a new key part. This
+ means that the a condition is added a key part for which there was a
+ previous condition. We can only overwrite such key parts in some special
+ cases, e.g. a > 2 AND a > 1 (here range_fl must be set to something). In
+ all other cases the WHERE condition is always false anyway.
+ */
+ (eq_type || *range_fl == 0))
+ DBUG_RETURN(FALSE);
+
if (org_key_part_used != *key_part_used ||
(is_field_part &&
(between || eq_type || max_fl == less_fl) && !cond->val_int()))
@@ -752,11 +767,11 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
{
if ((!is_null && !cond->val_int()) ||
(is_null && !test(part->field->is_null())))
- return 0; // Impossible test
+ DBUG_RETURN(FALSE); // Impossible test
}
else if (is_field_part)
*range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
- return 1;
+ DBUG_RETURN(TRUE);
}
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 9c2cb40badc..9e7fdbfeae5 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6343,3 +6343,6 @@ ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN
ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
eng "Cannot change the sql_log_bin inside a stored function or trigger"
+ER_FAILED_READ_FROM_PAR_FILE
+ eng "Failed to read from the .par file"
+ swe "Misslyckades läsa från .par filen"
diff --git a/sql/sp.cc b/sql/sp.cc
index e7bf15c56d5..5328471f4c0 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -720,11 +720,18 @@ static sp_head *sp_compile(THD *thd, String *defstr, ulong sql_mode,
ha_rows old_select_limit= thd->variables.select_limit;
sp_rcontext *old_spcont= thd->spcont;
Silence_deprecated_warning warning_handler;
+ Parser_state parser_state;
thd->variables.sql_mode= sql_mode;
thd->variables.select_limit= HA_POS_ERROR;
- Parser_state parser_state(thd, defstr->c_ptr(), defstr->length());
+ if (parser_state.init(thd, defstr->c_ptr(), defstr->length()))
+ {
+ thd->variables.sql_mode= old_sql_mode;
+ thd->variables.select_limit= old_select_limit;
+ return NULL;
+ }
+
lex_start(thd);
thd->push_internal_handler(&warning_handler);
thd->spcont= 0;
@@ -1716,7 +1723,7 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
rn->mdl_request.init(key, MDL_SHARED);
if (my_hash_insert(&prelocking_ctx->sroutines, (uchar *)rn))
return FALSE;
- prelocking_ctx->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
+ prelocking_ctx->sroutines_list.link_in_list(rn, &rn->next);
rn->belong_to_view= belong_to_view;
rn->m_sp_cache_version= 0;
return TRUE;
@@ -1766,8 +1773,7 @@ void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx)
{
Sroutine_hash_entry *not_own_rt, *next_rt;
- for (not_own_rt=
- *(Sroutine_hash_entry **)prelocking_ctx->sroutines_list_own_last;
+ for (not_own_rt= *prelocking_ctx->sroutines_list_own_last;
not_own_rt; not_own_rt= next_rt)
{
/*
@@ -1778,7 +1784,7 @@ void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx)
my_hash_delete(&prelocking_ctx->sroutines, (uchar *)not_own_rt);
}
- *(Sroutine_hash_entry **)prelocking_ctx->sroutines_list_own_last= NULL;
+ *prelocking_ctx->sroutines_list_own_last= NULL;
prelocking_ctx->sroutines_list.next= prelocking_ctx->sroutines_list_own_last;
prelocking_ctx->sroutines_list.elements=
prelocking_ctx->sroutines_list_own_elements;
@@ -1863,10 +1869,10 @@ sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
*/
void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
- SQL_LIST *src, TABLE_LIST *belong_to_view)
+ SQL_I_List<Sroutine_hash_entry> *src,
+ TABLE_LIST *belong_to_view)
{
- for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first;
- rt; rt= rt->next)
+ for (Sroutine_hash_entry *rt= src->first; rt; rt= rt->next)
(void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
&rt->mdl_request.key, belong_to_view);
}
@@ -1892,8 +1898,7 @@ int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
in sroutines_list has an MDL lock unless it's a top-level call, or a
trigger, but triggers can't occur here (see the preceding assert).
*/
- DBUG_ASSERT(rt->mdl_request.ticket ||
- rt == (Sroutine_hash_entry*) thd->lex->sroutines_list.first);
+ DBUG_ASSERT(rt->mdl_request.ticket || rt == thd->lex->sroutines_list.first);
return sp_cache_routine(thd, type, &name, lookup_only, sp);
}
diff --git a/sql/sp.h b/sql/sp.h
index e16c0718f3f..10e70261b86 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -34,7 +34,8 @@ struct LEX;
struct TABLE;
struct TABLE_LIST;
typedef struct st_hash HASH;
-typedef struct st_sql_list SQL_LIST;
+template <typename T> class SQL_I_List;
+
/* Tells what SP_DEFAULT_ACCESS should be mapped to */
#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL
@@ -164,7 +165,8 @@ bool sp_update_sp_used_routines(HASH *dst, HASH *src);
void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
HASH *src, TABLE_LIST *belong_to_view);
void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
- SQL_LIST *src, TABLE_LIST *belong_to_view);
+ SQL_I_List<Sroutine_hash_entry> *src,
+ TABLE_LIST *belong_to_view);
extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
my_bool first);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 61f00fdf59a..f75acf11984 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -50,6 +50,32 @@
extern "C" uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first);
+/**
+ Helper function which operates on a THD object to set the query start_time to
+ the current time.
+
+ @param[in, out] thd The session object
+
+*/
+
+static void reset_start_time_for_sp(THD *thd)
+{
+ if (!thd->in_sub_stmt)
+ {
+ /*
+ First investigate if there is a cached time stamp
+ */
+ if (thd->user_time)
+ {
+ thd->start_time= thd->user_time;
+ }
+ else
+ {
+ my_micro_time_and_time(&thd->start_time);
+ }
+ }
+}
+
Item_result
sp_map_result_type(enum enum_field_types type)
{
@@ -1240,11 +1266,11 @@ sp_head::execute(THD *thd)
DBUG_PRINT("execute", ("Instruction %u", ip));
/*
- Make current_time() et al work. But don't change NOW() in FUNCTION
- or TRIGGER.
+ We need to reset start_time to allow for time to flow inside a stored
+ procedure. This is only done for SP since time is suppose to be constant
+ during execution of triggers and functions.
*/
- if (!thd->in_sub_stmt)
- thd->set_time();
+ reset_start_time_for_sp(thd);
/*
We have to set thd->stmt_arena before executing the instruction
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 03d365115cf..d29796149a7 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -878,6 +878,9 @@ THD::raise_condition_no_handler(uint sql_errno,
if (no_warnings_for_error && (level == MYSQL_ERROR::WARN_LEVEL_ERROR))
DBUG_RETURN(NULL);
+ /* When simulating OOM, skip writing to error log to avoid mtr errors */
+ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL););
+
cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg);
DBUG_RETURN(cond);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 44af0b7d66e..c11c15571f2 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2212,6 +2212,11 @@ public:
start_time= user_time= t;
start_utime= utime_after_lock= my_micro_time();
}
+ /*TODO: this will be obsolete when we have support for 64 bit my_time_t */
+ inline bool is_valid_time()
+ {
+ return (start_time < (time_t) MY_TIME_T_MAX);
+ }
void set_time_after_lock() { utime_after_lock= my_micro_time(); }
ulonglong current_utime() { return my_micro_time(); }
inline ulonglong found_rows(void)
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 481715098b7..35ba39afd81 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -496,6 +496,7 @@ check_user(THD *thd, enum enum_server_command command,
}
my_ok(thd);
thd->password= test(passwd_len); // remember for error messages
+#ifndef EMBEDDED_LIBRARY
/*
Allow the network layer to skip big packets. Although a malicious
authenticated session might use this to trick the server to read
@@ -503,6 +504,7 @@ check_user(THD *thd, enum enum_server_command command,
that needs to be preserved as to not break backwards compatibility.
*/
thd->net.skip_big_packet= TRUE;
+#endif
/* Ready to handle queries */
DBUG_RETURN(0);
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index ece72e97d0d..c4a773fee9c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -47,7 +47,7 @@
*/
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- SQL_LIST *order, ha_rows limit, ulonglong options)
+ SQL_I_List<ORDER> *order, ha_rows limit, ulonglong options)
{
bool will_batch;
int error, loc_error;
@@ -91,7 +91,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (select_lex->setup_ref_array(thd, order->elements) ||
setup_order(thd, select_lex->ref_pointer_array, &tables,
- fields, all_fields, (ORDER*) order->first))
+ fields, all_fields, order->first))
{
delete select;
free_underlaid_joins(thd, &thd->lex->select_lex);
@@ -224,14 +224,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ha_rows examined_rows;
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
- usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
+ usable_index= get_index_for_order(table, order->first, limit);
if (usable_index == MAX_KEY)
{
table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
- if (!(sortorder= make_unireg_sortorder((ORDER*) order->first,
+ if (!(sortorder= make_unireg_sortorder(order->first,
&length, NULL)) ||
(table->sort.found_records = filesort(thd, table, sortorder, length,
select, HA_POS_ERROR, 1,
@@ -486,7 +486,7 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
int mysql_multi_delete_prepare(THD *thd)
{
LEX *lex= thd->lex;
- TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
+ TABLE_LIST *aux_tables= lex->auxiliary_table_list.first;
TABLE_LIST *target_tbl;
DBUG_ENTER("mysql_multi_delete_prepare");
diff --git a/sql/sql_delete.h b/sql/sql_delete.h
index c718323ce1e..264991c220b 100644
--- a/sql/sql_delete.h
+++ b/sql/sql_delete.h
@@ -23,10 +23,10 @@ struct TABLE_LIST;
class Item;
typedef class Item COND;
-typedef struct st_sql_list SQL_LIST;
+template <typename T> class SQL_I_List;
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- SQL_LIST *order, ha_rows rows, ulonglong options);
+ SQL_I_List<ORDER> *order, ha_rows rows, ulonglong options);
#endif /* SQL_DELETE_INCLUDED */
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index e86ae52e501..47bc13beb53 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -285,13 +285,13 @@ bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
lex->current_select= first_select;
res= mysql_select(thd, &first_select->ref_pointer_array,
- (TABLE_LIST*) first_select->table_list.first,
+ first_select->table_list.first,
first_select->with_wild,
first_select->item_list, first_select->where,
(first_select->order_list.elements+
first_select->group_list.elements),
- (ORDER *) first_select->order_list.first,
- (ORDER *) first_select->group_list.first,
+ first_select->order_list.first,
+ first_select->group_list.first,
first_select->having, (ORDER*) NULL,
(first_select->options | thd->variables.option_bits |
SELECT_NO_UNLOCK),
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index b2e793b5938..d6f2a472e05 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -605,6 +605,14 @@ retry:
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
goto err;
}
+ /* Check if the same index involved. */
+ if ((uint) keyno != table->file->get_index())
+ {
+ if (mode == RNEXT)
+ mode= RFIRST;
+ else if (mode == RPREV)
+ mode= RLAST;
+ }
}
if (insert_fields(thd, &thd->lex->select_lex.context,
@@ -627,9 +635,16 @@ retry:
case RNEXT:
if (table->file->inited != handler::NONE)
{
- error=keyname ?
- table->file->index_next(table->record[0]) :
- table->file->rnd_next(table->record[0]);
+ if (keyname)
+ {
+ /* Check if we read from the same index. */
+ DBUG_ASSERT((uint) keyno == table->file->get_index());
+ error= table->file->index_next(table->record[0]);
+ }
+ else
+ {
+ error= table->file->rnd_next(table->record[0]);
+ }
break;
}
/* else fall through */
@@ -650,6 +665,8 @@ retry:
break;
case RPREV:
DBUG_ASSERT(keyname != 0);
+ /* Check if we read from the same index. */
+ DBUG_ASSERT((uint) keyno == table->file->get_index());
if (table->file->inited != handler::NONE)
{
error=table->file->index_prev(table->record[0]);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3f3c650d1e8..5f8b1148dcb 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -147,20 +147,30 @@ st_parsing_options::reset()
Perform initialization of Lex_input_stream instance.
Basically, a buffer for pre-processed query. This buffer should be large
- enough to keep multi-statement query. The allocation is done once in the
- Lex_input_stream constructor in order to prevent memory pollution when
+ enough to keep multi-statement query. The allocation is done once in
+ Lex_input_stream::init() in order to prevent memory pollution when
the server is processing large multi-statement queries.
-
- @todo Check return value of THD::alloc().
*/
-Lex_input_stream::Lex_input_stream(THD *thd,
- const char* buffer,
- unsigned int length)
- :m_thd(thd)
+bool Lex_input_stream::init(THD *thd,
+ const char* buff,
+ unsigned int length)
{
+ DBUG_EXECUTE_IF("bug42064_simulate_oom",
+ DBUG_SET("+d,simulate_out_of_memory"););
+
m_cpp_buf= (char*) thd->alloc(length + 1);
- reset(buffer, length);
+
+ DBUG_EXECUTE_IF("bug42064_simulate_oom",
+ DBUG_SET("-d,bug42064_simulate_oom"););
+
+ if (m_cpp_buf == NULL)
+ return TRUE;
+
+ m_thd= thd;
+ reset(buff, length);
+
+ return FALSE;
}
@@ -203,8 +213,6 @@ Lex_input_stream::reset(const char *buffer, unsigned int length)
m_cpp_ptr= m_cpp_buf;
}
-Lex_input_stream::~Lex_input_stream()
-{}
/**
The operation is called from the parser in order to
@@ -1756,7 +1764,7 @@ void st_select_lex::init_select()
linkage= UNSPECIFIED_TYPE;
order_list.elements= 0;
order_list.first= 0;
- order_list.next= (uchar**) &order_list.first;
+ order_list.next= &order_list.first;
/* Set limit and offset to default values */
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
offset_limit= 0; /* denotes the default offset = 0 */
@@ -2079,7 +2087,7 @@ uint st_select_lex::get_in_sum_expr()
TABLE_LIST* st_select_lex::get_table_list()
{
- return (TABLE_LIST*) table_list.first;
+ return table_list.first;
}
List<Item>* st_select_lex::get_item_list()
@@ -2136,9 +2144,8 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type)
if (fake_select_lex->order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
- fake_select_lex->print_order(
- str,
- (ORDER *) fake_select_lex->order_list.first,
+ fake_select_lex->print_order(str,
+ fake_select_lex->order_list.first,
query_type);
}
fake_select_lex->print_limit(thd, str, query_type);
@@ -2783,7 +2790,7 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
{
select_lex.context.table_list=
select_lex.context.first_name_resolution_table= first->next_local;
- select_lex.table_list.first= (uchar*) (first->next_local);
+ select_lex.table_list.first= first->next_local;
select_lex.table_list.elements--; //safety
first->next_local= 0;
/*
@@ -2815,7 +2822,7 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
void LEX::first_lists_tables_same()
{
- TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
+ TABLE_LIST *first_table= select_lex.table_list.first;
if (query_tables != first_table && first_table != 0)
{
TABLE_LIST *next;
@@ -2862,9 +2869,9 @@ void LEX::link_first_table_back(TABLE_LIST *first,
if (link_to_local)
{
- first->next_local= (TABLE_LIST*) select_lex.table_list.first;
+ first->next_local= select_lex.table_list.first;
select_lex.context.table_list= first;
- select_lex.table_list.first= (uchar*) first;
+ select_lex.table_list.first= first;
select_lex.table_list.elements++; //safety
}
}
@@ -3030,7 +3037,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
prep_having= *having_conds;
*having_conds= having= prep_having->copy_andor_structure(thd);
}
- fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
+ fix_prepare_info_in_table_list(thd, table_list.first);
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 0bca1c9c50b..05af1237be8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -641,8 +641,8 @@ public:
LEX *parent_lex;
enum olap_type olap;
/* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */
- SQL_LIST table_list;
- SQL_LIST group_list; /* GROUP BY clause. */
+ SQL_I_List<TABLE_LIST> table_list;
+ SQL_I_List<ORDER> group_list; /* GROUP BY clause. */
List<Item> item_list; /* list of fields & expressions */
List<String> interval_list;
bool is_item_list_lookup;
@@ -664,8 +664,8 @@ public:
TABLE_LIST *leaf_tables;
const char *type; /* type of select for EXPLAIN */
- SQL_LIST order_list; /* ORDER clause */
- SQL_LIST *gorder_list;
+ SQL_I_List<ORDER> order_list; /* ORDER clause */
+ SQL_I_List<ORDER> *gorder_list;
Item *select_limit, *offset_limit; /* LIMIT clause parameters */
// Arrays of pointers to top elements of all_fields list
Item **ref_pointer_array;
@@ -816,7 +816,7 @@ public:
{
order_list.elements= 0;
order_list.first= 0;
- order_list.next= (uchar**) &order_list.first;
+ order_list.next= &order_list.first;
}
/*
This method created for reiniting LEX in mysql_admin_table() and can be
@@ -998,6 +998,8 @@ extern const LEX_STRING null_lex_str;
extern const LEX_STRING empty_lex_str;
+struct Sroutine_hash_entry;
+
/*
Class representing list of all tables used by statement and other
information which is necessary for opening and locking its tables,
@@ -1048,9 +1050,9 @@ public:
We use these two members for restoring of 'sroutines_list' to the state
in which it was right after query parsing.
*/
- SQL_LIST sroutines_list;
- uchar **sroutines_list_own_last;
- uint sroutines_list_own_elements;
+ SQL_I_List<Sroutine_hash_entry> sroutines_list;
+ Sroutine_hash_entry **sroutines_list_own_last;
+ uint sroutines_list_own_elements;
/*
These constructor and destructor serve for creation/destruction
@@ -1378,8 +1380,21 @@ enum enum_comment_state
class Lex_input_stream
{
public:
- Lex_input_stream(THD *thd, const char* buff, unsigned int length);
- ~Lex_input_stream();
+ Lex_input_stream()
+ {
+ }
+
+ ~Lex_input_stream()
+ {
+ }
+
+ /**
+ Object initializer. Must be called before usage.
+
+ @retval FALSE OK
+ @retval TRUE Error
+ */
+ bool init(THD *thd, const char *buff, unsigned int length);
void reset(const char *buff, unsigned int length);
@@ -1903,7 +1918,8 @@ struct LEX: public Query_tables_list
*/
List<Name_resolution_context> context_stack;
- SQL_LIST proc_list, auxiliary_table_list, save_list;
+ SQL_I_List<ORDER> proc_list;
+ SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list;
Create_field *last_field;
Item_sum *in_sum_func;
udf_func udf;
@@ -2034,7 +2050,7 @@ struct LEX: public Query_tables_list
fields to TABLE object at table open (altough for latter pointer to table
being opened is probably enough).
*/
- SQL_LIST trg_table_fields;
+ SQL_I_List<Item_trigger_field> trg_table_fields;
/*
stmt_definition_begin is intended to point to the next word after
@@ -2324,10 +2340,21 @@ public:
class Parser_state
{
public:
- Parser_state(THD *thd, const char* buff, unsigned int length)
- : m_lip(thd, buff, length), m_yacc()
+ Parser_state()
+ : m_yacc()
{}
+ /**
+ Object initializer. Must be called before usage.
+
+ @retval FALSE OK
+ @retval TRUE Error
+ */
+ bool init(THD *thd, const char *buff, unsigned int length)
+ {
+ return m_lip.init(thd, buff, length);
+ }
+
~Parser_state()
{}
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 60d9697a606..d57534b0999 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -67,45 +67,61 @@ public:
/**
- Struct to handle simple linked lists.
-
- @todo What is the relation between this class and list_node, below?
- /Matz
-
- @see list_node, base_list, List
+ Simple intrusive linked list.
+ @remark Similar in nature to base_list, but intrusive. It keeps a
+ a pointer to the first element in the list and a indirect
+ reference to the last element.
*/
-typedef struct st_sql_list {
+template <typename T>
+class SQL_I_List :public Sql_alloc
+{
+public:
uint elements;
- uchar *first;
- uchar **next;
+ /** The first element in the list. */
+ T *first;
+ /** A reference to the next element in the list. */
+ T **next;
+
+ SQL_I_List() { empty(); }
+
+ SQL_I_List(const SQL_I_List &tmp)
+ {
+ elements= tmp.elements;
+ first= tmp.first;
+ next= elements ? tmp.next : &first;
+ }
- st_sql_list() {} /* Remove gcc warning */
inline void empty()
{
- elements=0;
- first=0;
+ elements= 0;
+ first= NULL;
next= &first;
}
- inline void link_in_list(uchar *element,uchar **next_ptr)
+
+ inline void link_in_list(T *element, T **next_ptr)
{
elements++;
- (*next)=element;
+ (*next)= element;
next= next_ptr;
- *next=0;
+ *next= NULL;
}
- inline void save_and_clear(struct st_sql_list *save)
+
+ inline void save_and_clear(SQL_I_List<T> *save)
{
*save= *this;
empty();
}
- inline void push_front(struct st_sql_list *save)
+
+ inline void push_front(SQL_I_List<T> *save)
{
- *save->next= first; /* link current list last */
+ /* link current list last */
+ *save->next= first;
first= save->first;
elements+= save->elements;
}
- inline void push_back(struct st_sql_list *save)
+
+ inline void push_back(SQL_I_List<T> *save)
{
if (save->first)
{
@@ -114,7 +130,7 @@ typedef struct st_sql_list {
elements+= save->elements;
}
}
-} SQL_LIST;
+};
/*
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 2c42f29ae71..7e540ffbe4b 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -995,6 +995,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
}
+
+ if (thd->is_error())
+ read_info.error= 1;
+
if (read_info.error)
break;
if (skip_lines)
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
index cdfa5e3f496..b957d1e9be4 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -147,14 +147,14 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
lex->last_selects=select_lex;
- for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
+ for (ORDER *order= select_lex->group_list.first ; order ; order=order->next)
item_list_copy.push_back(*(order->item));
List<Item> all_fields(select_lex->item_list);
if (setup_tables(lex->thd, &select_lex->context, &select_lex->top_join_list,
- (TABLE_LIST *)select_lex->table_list.first
+ select_lex->table_list.first
&select_lex->leaf_tables, FALSE) ||
setup_fields(lex->thd, 0, select_lex->item_list, MARK_COLUMNS_READ,
&all_fields,1) ||
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6ff631ad7c7..273eadf4205 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -559,7 +559,14 @@ static void handle_bootstrap_impl(THD *thd)
mode we have only one thread.
*/
thd->set_time();
- Parser_state parser_state(thd, thd->query(), length);
+ Parser_state parser_state;
+ if (parser_state.init(thd, thd->query(), length))
+ {
+ thd->protocol->end_statement();
+ bootstrap_error= 1;
+ break;
+ }
+
mysql_parse(thd, thd->query(), length, &parser_state);
close_thread_tables(thd); // Free tables
@@ -916,6 +923,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->enable_slow_log= TRUE;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
+ if (!thd->is_valid_time())
+ {
+ /*
+ If the time has got past 2038 we need to shut this server down
+ We do this by making sure every command is a shutdown and we
+ have enough privileges to shut the server down
+
+ TODO: remove this when we have full 64 bit my_time_t support
+ */
+ thd->security_ctx->master_access|= SHUTDOWN_ACL;
+ command= COM_SHUTDOWN;
+ }
thd->set_query_id(get_query_id());
if (!(server_command_flags[command] & CF_SKIP_QUERY_ID))
next_query_id();
@@ -1109,7 +1128,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#if defined(ENABLED_PROFILING)
thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state;
+ if (parser_state.init(thd, thd->query(), thd->query_length()))
+ break;
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
@@ -1238,8 +1259,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_reset_thd_for_next_command(thd);
thd->lex->
- select_lex.table_list.link_in_list((uchar*) &table_list,
- (uchar**) &table_list.next_local);
+ select_lex.table_list.link_in_list(&table_list,
+ &table_list.next_local);
thd->lex->add_to_query_tables(&table_list);
init_mdl_requests(&table_list);
@@ -1341,8 +1362,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
packet[0].
*/
- enum mysql_enum_shutdown_level level=
- (enum mysql_enum_shutdown_level) (uchar) packet[0];
+ enum mysql_enum_shutdown_level level;
+ if (!thd->is_valid_time())
+ level= SHUTDOWN_DEFAULT;
+ else
+ level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
if (level == SHUTDOWN_DEFAULT)
level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
@@ -1689,7 +1713,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
{
DBUG_RETURN(1);
}
- TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
+ TABLE_LIST *table_list= select_lex->table_list.first;
table_list->schema_select_lex= schema_select_lex;
table_list->schema_table_reformed= 1;
DBUG_RETURN(0);
@@ -2012,7 +2036,7 @@ mysql_execute_command(THD *thd)
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
SELECT_LEX *select_lex= &lex->select_lex;
/* first table of first SELECT_LEX */
- TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
+ TABLE_LIST *first_table= select_lex->table_list.first;
/* list of all tables in query */
TABLE_LIST *all_tables;
/* most outer SELECT_LEX_UNIT of query */
@@ -2047,7 +2071,7 @@ mysql_execute_command(THD *thd)
all_tables= lex->query_tables;
/* set context for commands which do not use setup_tables */
select_lex->
- context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
+ context.resolve_in_table_list_only(select_lex->
table_list.first);
/*
@@ -2679,7 +2703,7 @@ case SQLCOM_PREPARE:
if (create_info.used_fields & HA_CREATE_USED_UNION)
{
TABLE_LIST *tab;
- for (tab= (TABLE_LIST*) create_info.merge_list.first;
+ for (tab= create_info.merge_list.first;
tab;
tab= tab->next_local)
{
@@ -2862,7 +2886,6 @@ end_with_restore_list:
NULL, /* Do not use first_table->grant with select_lex->db */
0, 0) ||
check_merge_table_access(thd, first_table->db,
- (TABLE_LIST *)
create_info.merge_list.first))
goto error; /* purecov: inspected */
if (check_grant(thd, priv_needed, all_tables, FALSE, UINT_MAX, FALSE))
@@ -2896,7 +2919,7 @@ end_with_restore_list:
first_table,
&alter_info,
select_lex->order_list.elements,
- (ORDER *) select_lex->order_list.first,
+ select_lex->order_list.first,
lex->ignore);
break;
}
@@ -3035,7 +3058,7 @@ end_with_restore_list:
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- select_lex->table_list.first= (uchar*) first_table;
+ select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
break;
}
@@ -3047,7 +3070,7 @@ end_with_restore_list:
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_check_table(thd, first_table, &lex->check_opt);
- select_lex->table_list.first= (uchar*) first_table;
+ select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
break;
}
@@ -3067,7 +3090,7 @@ end_with_restore_list:
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- select_lex->table_list.first= (uchar*) first_table;
+ select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
break;
}
@@ -3090,7 +3113,7 @@ end_with_restore_list:
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- select_lex->table_list.first= (uchar*) first_table;
+ select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
break;
}
@@ -3108,7 +3131,7 @@ end_with_restore_list:
lex->value_list,
select_lex->where,
select_lex->order_list.elements,
- (ORDER *) select_lex->order_list.first,
+ select_lex->order_list.first,
unit->select_limit_cnt,
lex->duplicates, lex->ignore,
&found, &updated));
@@ -3268,7 +3291,7 @@ end_with_restore_list:
MYSQL_INSERT_SELECT_START(thd->query());
/* Skip first table, which is the table we are inserting in */
TABLE_LIST *second_table= first_table->next_local;
- select_lex->table_list.first= (uchar*) second_table;
+ select_lex->table_list.first= second_table;
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= mysql_insert_select_prepare(thd);
@@ -3300,7 +3323,7 @@ end_with_restore_list:
}
/* revert changes for SP */
MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func());
- select_lex->table_list.first= (uchar*) first_table;
+ select_lex->table_list.first= first_table;
}
/*
If we have inserted into a VIEW, and the base table has
@@ -3349,8 +3372,7 @@ end_with_restore_list:
case SQLCOM_DELETE_MULTI:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- TABLE_LIST *aux_tables=
- (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
+ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
multi_delete *del_result;
if ((res= multi_delete_precheck(thd, all_tables)))
@@ -5216,7 +5238,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
case SCH_STATISTICS:
{
TABLE_LIST *dst_table;
- dst_table= (TABLE_LIST *) table->schema_select_lex->table_list.first;
+ dst_table= table->schema_select_lex->table_list.first;
DBUG_ASSERT(dst_table);
@@ -5932,14 +5954,17 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
bool error= 0;
DBUG_ENTER("mysql_test_parse_for_slave");
- Parser_state parser_state(thd, inBuf, length);
- lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ Parser_state parser_state;
+ if (!(error= parser_state.init(thd, inBuf, length)))
+ {
+ lex_start(thd);
+ mysql_reset_thd_for_next_command(thd);
- if (!parse_sql(thd, & parser_state, NULL) &&
- all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
- error= 1; /* Ignore question */
- thd->end_statement();
+ if (!parse_sql(thd, & parser_state, NULL) &&
+ all_tables_not_ok(thd, lex->select_lex.table_list.first))
+ error= 1; /* Ignore question */
+ thd->end_statement();
+ }
thd->cleanup_after_query();
DBUG_RETURN(error);
}
@@ -6064,7 +6089,7 @@ add_proc_to_list(THD* thd, Item *item)
*item_ptr= item;
order->item=item_ptr;
order->free_me=0;
- thd->lex->proc_list.link_in_list((uchar*) order,(uchar**) &order->next);
+ thd->lex->proc_list.link_in_list(order, &order->next);
return 0;
}
@@ -6073,7 +6098,7 @@ add_proc_to_list(THD* thd, Item *item)
save order by and tables in own lists.
*/
-bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
+bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
{
ORDER *order;
DBUG_ENTER("add_to_list");
@@ -6085,7 +6110,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
order->free_me=0;
order->used=0;
order->counter_used= 0;
- list.link_in_list((uchar*) order,(uchar**) &order->next);
+ list.link_in_list(order, &order->next);
DBUG_RETURN(0);
}
@@ -6217,7 +6242,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
/* check that used name is unique */
if (lock_type != TL_IGNORE)
{
- TABLE_LIST *first_table= (TABLE_LIST*) table_list.first;
+ TABLE_LIST *first_table= table_list.first;
if (lex->sql_command == SQLCOM_CREATE_VIEW)
first_table= first_table ? first_table->next_local : NULL;
for (TABLE_LIST *tables= first_table ;
@@ -6259,7 +6284,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
previous table reference to 'ptr'. Here we also add one element to the
list 'table_list'.
*/
- table_list.link_in_list((uchar*) ptr, (uchar**) &ptr->next_local);
+ table_list.link_in_list(ptr, &ptr->next_local);
ptr->next_name_resolution_table= NULL;
/* Link table in global list (all used tables) */
lex->add_to_query_tables(ptr);
@@ -6493,7 +6518,7 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
DBUG_ENTER("set_lock_for_tables");
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
for_update));
- for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
+ for (TABLE_LIST *tables= table_list.first;
tables;
tables= tables->next_local)
{
@@ -7231,8 +7256,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
{
SELECT_LEX *select_lex= &thd->lex->select_lex;
- TABLE_LIST *aux_tables=
- (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
+ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
DBUG_ENTER("multi_delete_precheck");
@@ -7335,13 +7359,13 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
{
- TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
+ TABLE_LIST *tables= lex->select_lex.table_list.first;
TABLE_LIST *target_tbl;
DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
lex->table_count= 0;
- for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
+ for (target_tbl= lex->auxiliary_table_list.first;
target_tbl; target_tbl= target_tbl->next_local)
{
lex->table_count++;
@@ -7513,8 +7537,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
&create_table->grant.m_internal,
0, 0) ||
check_merge_table_access(thd, create_table->db,
- (TABLE_LIST *)
- lex->create_info.merge_list.first))
+ lex->create_info.merge_list.first))
goto err;
if (want_priv != CREATE_TMP_ACL &&
check_grant(thd, want_priv, create_table, FALSE, 1, FALSE))
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index c9264b999b3..df76df72e09 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -116,7 +116,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum enum_field_types t
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type);
-bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
+bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group, bool asc);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
SELECT_LEX *lex);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index fa9c698622b..bc9a7d8ee65 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4199,7 +4199,9 @@ bool mysql_unpack_partition(THD *thd,
thd->variables.character_set_client= system_charset_info;
- Parser_state parser_state(thd, part_buf, part_info_len);
+ Parser_state parser_state;
+ if (parser_state.init(thd, part_buf, part_info_len))
+ goto end;
if (init_lex_with_single_table(thd, table, &lex))
goto end;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index bd6ff3a951d..97c480ea0bd 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1994,10 +1994,6 @@ typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
-#define SET_PLUGIN_VAR_RESOLVE(opt)\
- *(mysql_sys_var_ptr_p*)&((opt)->resolve)= mysql_sys_var_ptr
-typedef uchar *(*mysql_sys_var_ptr_p)(void* a_thd, int offset);
-
/****************************************************************************
default variable data check and update functions
@@ -2532,11 +2528,49 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
return (uchar*)thd->variables.dynamic_variables_ptr + offset;
}
-static uchar *mysql_sys_var_ptr(void* a_thd, int offset)
+
+/**
+ For correctness and simplicity's sake, a pointer to a function
+ must be compatible with pointed-to type, that is, the return and
+ parameters types must be the same. Thus, a callback function is
+ defined for each scalar type. The functions are assigned in
+ construct_options to their respective types.
+*/
+
+static char *mysql_sys_var_char(THD* thd, int offset)
+{
+ return (char *) intern_sys_var_ptr(thd, offset, true);
+}
+
+static int *mysql_sys_var_int(THD* thd, int offset)
+{
+ return (int *) intern_sys_var_ptr(thd, offset, true);
+}
+
+static long *mysql_sys_var_long(THD* thd, int offset)
{
- return intern_sys_var_ptr((THD *)a_thd, offset, true);
+ return (long *) intern_sys_var_ptr(thd, offset, true);
}
+static unsigned long *mysql_sys_var_ulong(THD* thd, int offset)
+{
+ return (unsigned long *) intern_sys_var_ptr(thd, offset, true);
+}
+
+static long long *mysql_sys_var_longlong(THD* thd, int offset)
+{
+ return (long long *) intern_sys_var_ptr(thd, offset, true);
+}
+
+static unsigned long long *mysql_sys_var_ulonglong(THD* thd, int offset)
+{
+ return (unsigned long long *) intern_sys_var_ptr(thd, offset, true);
+}
+
+static char **mysql_sys_var_str(THD* thd, int offset)
+{
+ return (char **) intern_sys_var_ptr(thd, offset, true);
+}
void plugin_thdvar_init(THD *thd)
{
@@ -3081,25 +3115,25 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
continue;
switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
case PLUGIN_VAR_BOOL:
- SET_PLUGIN_VAR_RESOLVE((thdvar_bool_t *) opt);
+ ((thdvar_bool_t *) opt)->resolve= mysql_sys_var_char;
break;
case PLUGIN_VAR_INT:
- SET_PLUGIN_VAR_RESOLVE((thdvar_int_t *) opt);
+ ((thdvar_int_t *) opt)->resolve= mysql_sys_var_int;
break;
case PLUGIN_VAR_LONG:
- SET_PLUGIN_VAR_RESOLVE((thdvar_long_t *) opt);
+ ((thdvar_long_t *) opt)->resolve= mysql_sys_var_long;
break;
case PLUGIN_VAR_LONGLONG:
- SET_PLUGIN_VAR_RESOLVE((thdvar_longlong_t *) opt);
+ ((thdvar_longlong_t *) opt)->resolve= mysql_sys_var_longlong;
break;
case PLUGIN_VAR_STR:
- SET_PLUGIN_VAR_RESOLVE((thdvar_str_t *) opt);
+ ((thdvar_str_t *) opt)->resolve= mysql_sys_var_str;
break;
case PLUGIN_VAR_ENUM:
- SET_PLUGIN_VAR_RESOLVE((thdvar_enum_t *) opt);
+ ((thdvar_enum_t *) opt)->resolve= mysql_sys_var_ulong;
break;
case PLUGIN_VAR_SET:
- SET_PLUGIN_VAR_RESOLVE((thdvar_set_t *) opt);
+ ((thdvar_set_t *) opt)->resolve= mysql_sys_var_ulonglong;
break;
default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index e5d7514d9f5..09ae0acc6ad 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1330,7 +1330,7 @@ static int mysql_test_update(Prepared_statement *stmt,
if (mysql_prepare_update(thd, table_list, &select->where,
select->order_list.elements,
- (ORDER *) select->order_list.first))
+ select->order_list.first))
goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1845,11 +1845,10 @@ error:
static int mysql_insert_select_prepare_tester(THD *thd)
{
SELECT_LEX *first_select= &thd->lex->select_lex;
- TABLE_LIST *second_table= ((TABLE_LIST*)first_select->table_list.first)->
- next_local;
+ TABLE_LIST *second_table= first_select->table_list.first->next_local;
/* Skip first table, which is the table we are inserting in */
- first_select->table_list.first= (uchar *) second_table;
+ first_select->table_list.first= second_table;
thd->lex->select_lex.context.table_list=
thd->lex->select_lex.context.first_name_resolution_table= second_table;
@@ -1886,7 +1885,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
return 1;
/* store it, because mysql_insert_select_prepare_tester change it */
- first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
+ first_local_table= lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
res=
@@ -1894,7 +1893,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
&mysql_insert_select_prepare_tester,
OPTION_SETUP_TABLES_DONE);
/* revert changes made by mysql_insert_select_prepare_tester */
- lex->select_lex.table_list.first= (uchar*) first_local_table;
+ lex->select_lex.table_list.first= first_local_table;
return res;
}
@@ -2404,10 +2403,10 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
DBUG_ASSERT(sl->join == 0);
ORDER *order;
/* Fix GROUP list */
- for (order= (ORDER *)sl->group_list.first; order; order= order->next)
+ for (order= sl->group_list.first; order; order= order->next)
order->item= &order->item_ptr;
/* Fix ORDER list */
- for (order= (ORDER *)sl->order_list.first; order; order= order->next)
+ for (order= sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
/* clear the no_error flag for INSERT/UPDATE IGNORE */
@@ -2451,7 +2450,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
(multi-delete). We do a full clean up, although at the moment all we
need to clean in the tables of MULTI-DELETE list is 'table' member.
*/
- for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxiliary_table_list.first;
+ for (TABLE_LIST *tables= lex->auxiliary_table_list.first;
tables;
tables= tables->next_global)
{
@@ -2945,7 +2944,9 @@ Execute_sql_statement::execute_server_code(THD *thd)
if (alloc_query(thd, m_sql_text.str, m_sql_text.length))
return TRUE;
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state;
+ if (parser_state.init(thd, thd->query(), thd->query_length()))
+ return TRUE;
parser_state.m_lip.multi_statements= FALSE;
lex_start(thd);
@@ -3185,14 +3186,23 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state;
+ if (parser_state.init(thd, thd->query(), thd->query_length()))
+ {
+ thd->restore_backup_statement(this, &stmt_backup);
+ thd->restore_active_arena(this, &stmt_backup);
+ thd->stmt_arena= old_stmt_arena;
+ DBUG_RETURN(TRUE);
+ }
+
parser_state.m_lip.stmt_prepare_mode= TRUE;
parser_state.m_lip.multi_statements= FALSE;
+
lex_start(thd);
error= parse_sql(thd, & parser_state, NULL) ||
- thd->is_error() ||
- init_param_array(this);
+ thd->is_error() ||
+ init_param_array(this);
lex->set_trg_event_type_for_tables();
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 10884a95b74..992fa8f6212 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -276,15 +276,15 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
setup_tables_done_option changed for next rexecution
*/
res= mysql_select(thd, &select_lex->ref_pointer_array,
- (TABLE_LIST*) select_lex->table_list.first,
+ select_lex->table_list.first,
select_lex->with_wild, select_lex->item_list,
select_lex->where,
select_lex->order_list.elements +
select_lex->group_list.elements,
- (ORDER*) select_lex->order_list.first,
- (ORDER*) select_lex->group_list.first,
+ select_lex->order_list.first,
+ select_lex->group_list.first,
select_lex->having,
- (ORDER*) lex->proc_list.first,
+ lex->proc_list.first,
select_lex->options | thd->variables.option_bits |
setup_tables_done_option,
result, unit, select_lex);
@@ -2747,31 +2747,53 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
/*
Build transitive closure for relation 'to be dependent on'.
This will speed up the plan search for many cases with outer joins,
- as well as allow us to catch illegal cross references/
+ as well as allow us to catch illegal cross references.
Warshall's algorithm is used to build the transitive closure.
- As we use bitmaps to represent the relation the complexity
- of the algorithm is O((number of tables)^2).
+ As we may restart the outer loop upto 'table_count' times, the
+ complexity of the algorithm is O((number of tables)^3).
+ However, most of the iterations will be shortcircuited when
+ there are no pedendencies to propogate.
*/
- for (i= 0, s= stat ; i < table_count ; i++, s++)
+ for (i= 0 ; i < table_count ; i++)
{
- for (uint j= 0 ; j < table_count ; j++)
+ uint j;
+ table= stat[i].table;
+
+ if (!table->reginfo.join_tab->dependent)
+ continue;
+
+ /* Add my dependencies to other tables depending on me */
+ for (j= 0, s= stat ; j < table_count ; j++, s++)
{
- table= stat[j].table;
if (s->dependent & table->map)
+ {
+ table_map was_dependent= s->dependent;
s->dependent |= table->reginfo.join_tab->dependent;
+ /*
+ If we change dependencies for a table we already have
+ processed: Redo dependency propagation from this table.
+ */
+ if (i > j && s->dependent != was_dependent)
+ {
+ i = j-1;
+ break;
+ }
+ }
}
- if (outer_join & s->table->map)
- s->table->maybe_null= 1;
}
- /* Catch illegal cross references for outer joins */
+
for (i= 0, s= stat ; i < table_count ; i++, s++)
{
+ /* Catch illegal cross references for outer joins */
if (s->dependent & s->table->map)
{
join->tables=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
goto error;
}
+
+ if (outer_join & s->table->map)
+ s->table->maybe_null= 1;
s->key_dependent= s->dependent;
}
}
@@ -8824,6 +8846,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
NESTED_JOIN *nested_join;
TABLE_LIST *prev_table= 0;
List_iterator<TABLE_LIST> li(*join_list);
+ bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
DBUG_ENTER("simplify_joins");
/*
@@ -8934,7 +8957,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
if (prev_table)
{
/* The order of tables is reverse: prev_table follows table */
- if (prev_table->straight)
+ if (prev_table->straight || straight_join)
prev_table->dep_tables|= used_tables;
if (prev_table->on_expr)
{
@@ -17005,15 +17028,15 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
thd->lex->current_select= first;
unit->set_limit(unit->global_parameters);
res= mysql_select(thd, &first->ref_pointer_array,
- (TABLE_LIST*) first->table_list.first,
+ first->table_list.first,
first->with_wild, first->item_list,
first->where,
first->order_list.elements +
first->group_list.elements,
- (ORDER*) first->order_list.first,
- (ORDER*) first->group_list.first,
+ first->order_list.first,
+ first->group_list.first,
first->having,
- (ORDER*) thd->lex->proc_list.first,
+ thd->lex->proc_list.first,
first->options | thd->variables.option_bits | SELECT_DESCRIBE,
result, unit, first);
}
@@ -17316,7 +17339,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
if (group_list.elements)
{
str->append(STRING_WITH_LEN(" group by "));
- print_order(str, (ORDER *) group_list.first, query_type);
+ print_order(str, group_list.first, query_type);
switch (olap)
{
case CUBE_TYPE:
@@ -17347,7 +17370,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
if (order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
- print_order(str, (ORDER *) order_list.first, query_type);
+ print_order(str, order_list.first, query_type);
}
// limit
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2a0c6425122..f1d7e48ffcc 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2939,8 +2939,7 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
bool res;
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
enum_sql_command save_sql_command= lex->sql_command;
- TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
- table_list.first;
+ TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first;
TABLE *table= tables->table;
int error= 1;
DBUG_ENTER("fill_schema_show");
@@ -3561,7 +3560,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
goto err;
if (make_table_list(thd, &sel, db_name, table_name))
goto err;
- TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
+ TABLE_LIST *show_table_list= sel.table_list.first;
lex->all_selects_list= &sel;
lex->derived_tables= 0;
lex->sql_command= SQLCOM_SHOW_FIELDS;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3e9d26bd253..902e7fa7b5f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4693,7 +4693,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
table->next_global= 0;
save_next_local= table->next_local;
table->next_local= 0;
- select->table_list.first= (uchar*)table;
+ select->table_list.first= table;
/*
Time zone tables and SP tables can be add to lex->query_tables list,
so it have to be prepared.
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index e9330574b34..2f084c369b6 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -681,7 +681,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*/
old_field= new_field= table->field;
- for (trg_field= (Item_trigger_field *)(lex->trg_table_fields.first);
+ for (trg_field= lex->trg_table_fields.first;
trg_field; trg_field= trg_field->next_trg_field)
{
/*
@@ -1326,9 +1326,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
thd->variables.sql_mode= (ulong)*trg_sql_mode;
- Parser_state parser_state(thd,
- trg_create_str->str,
- trg_create_str->length);
+ Parser_state parser_state;
+ if (parser_state.init(thd, trg_create_str->str, trg_create_str->length))
+ goto err_with_lex_cleanup;
Trigger_creation_ctx *creation_ctx=
Trigger_creation_ctx::create(thd,
@@ -1442,7 +1442,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
*/
triggers->trigger_fields[lex.trg_chistics.event]
[lex.trg_chistics.action_time]=
- (Item_trigger_field *)(lex.trg_table_fields.first);
+ lex.trg_table_fields.first;
/*
Also let us bind these objects to Field objects in table being
opened.
@@ -1452,8 +1452,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
SELECT)...
Anyway some things can be checked only during trigger execution.
*/
- for (Item_trigger_field *trg_field=
- (Item_trigger_field *)(lex.trg_table_fields.first);
+ for (Item_trigger_field *trg_field= lex.trg_table_fields.first;
trg_field;
trg_field= trg_field->next_trg_field)
{
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index a4d3f61f0e3..9ca4556524f 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -148,20 +148,19 @@ void
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
{
thd_arg->lex->current_select= fake_select_lex;
- fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
- (uchar **)
- &result_table_list.next_local);
+ fake_select_lex->table_list.link_in_list(&result_table_list,
+ &result_table_list.next_local);
fake_select_lex->context.table_list=
fake_select_lex->context.first_name_resolution_table=
fake_select_lex->get_table_list();
if (!fake_select_lex->first_execution)
{
- for (ORDER *order= (ORDER *) global_parameters->order_list.first;
+ for (ORDER *order= global_parameters->order_list.first;
order;
order= order->next)
order->item= &order->item_ptr;
}
- for (ORDER *order= (ORDER *)global_parameters->order_list.first;
+ for (ORDER *order= global_parameters->order_list.first;
order;
order=order->next)
{
@@ -253,18 +252,18 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
saved_error= join->prepare(&sl->ref_pointer_array,
- (TABLE_LIST*) sl->table_list.first,
+ sl->table_list.first,
sl->with_wild,
sl->where,
(can_skip_order_by ? 0 :
sl->order_list.elements) +
sl->group_list.elements,
can_skip_order_by ?
- (ORDER*) 0 : (ORDER *)sl->order_list.first,
- (ORDER*) sl->group_list.first,
+ NULL : sl->order_list.first,
+ sl->group_list.first,
sl->having,
- (is_union_select ? (ORDER*) 0 :
- (ORDER*) thd_arg->lex->proc_list.first),
+ (is_union_select ? NULL :
+ thd_arg->lex->proc_list.first),
sl, this);
/* There are no * in the statement anymore (for PS) */
sl->with_wild= 0;
@@ -358,7 +357,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{
ORDER *ord;
Item_func::Functype ft= Item_func::FT_FUNC;
- for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
+ for (ord= global_parameters->order_list.first; ord; ord= ord->next)
if ((*ord->item)->walk (&Item::find_function_processor, FALSE,
(uchar *) &ft))
{
@@ -420,12 +419,11 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= fake_select_lex;
saved_error= fake_select_lex->join->
prepare(&fake_select_lex->ref_pointer_array,
- (TABLE_LIST*) fake_select_lex->table_list.first,
+ fake_select_lex->table_list.first,
0, 0,
fake_select_lex->order_list.elements,
- (ORDER*) fake_select_lex->order_list.first,
- (ORDER*) NULL, NULL,
- (ORDER*) NULL,
+ fake_select_lex->order_list.first,
+ NULL, NULL, NULL,
fake_select_lex, this);
fake_select_lex->table_list.empty();
}
@@ -601,8 +599,8 @@ bool st_select_lex_unit::exec()
&result_table_list,
0, item_list, NULL,
global_parameters->order_list.elements,
- (ORDER*)global_parameters->order_list.first,
- (ORDER*) NULL, NULL, (ORDER*) NULL,
+ global_parameters->order_list.first,
+ NULL, NULL, NULL,
fake_select_lex->options | SELECT_NO_UNLOCK,
result, this, fake_select_lex);
}
@@ -624,8 +622,8 @@ bool st_select_lex_unit::exec()
&result_table_list,
0, item_list, NULL,
global_parameters->order_list.elements,
- (ORDER*)global_parameters->order_list.first,
- (ORDER*) NULL, NULL, (ORDER*) NULL,
+ global_parameters->order_list.first,
+ NULL, NULL, NULL,
fake_select_lex->options | SELECT_NO_UNLOCK,
result, this, fake_select_lex);
}
@@ -701,7 +699,7 @@ bool st_select_lex_unit::cleanup()
if (global_parameters->order_list.elements)
{
ORDER *ord;
- for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
+ for (ord= global_parameters->order_list.first; ord; ord= ord->next)
(*ord->item)->walk (&Item::cleanup_processor, 0, 0);
}
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 9adfe896c73..127368cef5c 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -408,7 +408,7 @@ int mysql_update(THD *thd,
matching rows before updating the table!
*/
if (used_index < MAX_KEY && old_covering_keys.is_set(used_index))
- table->mark_columns_used_by_index(used_index);
+ table->add_read_columns_used_by_index(used_index);
else
{
table->use_all_columns();
@@ -1288,7 +1288,7 @@ int multi_update::prepare(List<Item> &not_used_values,
SELECT_LEX_UNIT *lex_unit)
{
TABLE_LIST *table_ref;
- SQL_LIST update;
+ SQL_I_List<TABLE_LIST> update;
table_map tables_to_update;
Item_field *item;
List_iterator_fast<Item> field_it(*fields);
@@ -1369,11 +1369,11 @@ int multi_update::prepare(List<Item> &not_used_values,
leaf_table_count++;
if (tables_to_update & table->map)
{
- TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
+ TABLE_LIST *tl= (TABLE_LIST*) thd->memdup(table_ref,
sizeof(*tl));
if (!tl)
DBUG_RETURN(1);
- update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
+ update.link_in_list(tl, &tl->next_local);
tl->shared= table_count++;
table->no_keyread=1;
table->covering_keys.clear_all();
@@ -1394,7 +1394,7 @@ int multi_update::prepare(List<Item> &not_used_values,
table_count= update.elements;
- update_tables= (TABLE_LIST*) update.first;
+ update_tables= update.first;
tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3c8de0a253c..69abe70e863 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -897,7 +897,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
{
/* TODO: change here when we will support UNIONs */
- for (TABLE_LIST *tbl= (TABLE_LIST *)lex->select_lex.table_list.first;
+ for (TABLE_LIST *tbl= lex->select_lex.table_list.first;
tbl;
tbl= tbl->next_local)
{
@@ -1016,7 +1016,7 @@ loop_out:
*/
if (view->updatable_view &&
!lex->select_lex.master_unit()->is_union() &&
- !((TABLE_LIST*)lex->select_lex.table_list.first)->next_local &&
+ !(lex->select_lex.table_list.first)->next_local &&
find_table_in_global_list(lex->query_tables->next_global,
lex->query_tables->db,
lex->query_tables->table_name))
@@ -1217,9 +1217,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
char old_db_buf[NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
- Parser_state parser_state(thd,
- table->select_stmt.str,
- table->select_stmt.length);
+ Parser_state parser_state;
+ if (parser_state.init(thd, table->select_stmt.str,
+ table->select_stmt.length))
+ goto err;
/*
Use view db name as thread default database, in order to ensure
@@ -1377,8 +1378,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
This may change in future, for example if we enable merging of
views with subqueries in select list.
*/
- view_main_select_tables=
- (TABLE_LIST*)lex->select_lex.table_list.first;
+ view_main_select_tables= lex->select_lex.table_list.first;
/*
Let us set proper lock type for tables of the view's main
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 10186806f05..1c673f4ca42 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -526,8 +526,7 @@ set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val)
Let us add this item to list of all Item_trigger_field
objects in trigger.
*/
- lex->trg_table_fields.link_in_list((uchar *) trg_fld,
- (uchar **) &trg_fld->next_trg_field);
+ lex->trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field);
return lex->sphead->add_instr(sp_fld);
}
@@ -5124,7 +5123,7 @@ create_table_option:
*/
TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
DBUG_ASSERT(last_non_sel_table->next_global ==
- (TABLE_LIST *)lex->create_info.merge_list.first);
+ lex->create_info.merge_list.first);
last_non_sel_table->next_global= 0;
Lex->query_tables_last= &last_non_sel_table->next_global;
@@ -6166,8 +6165,7 @@ alter:
MYSQL_YYABORT;
lex->col_list.empty();
lex->select_lex.init_order();
- lex->select_lex.db=
- ((TABLE_LIST*) lex->select_lex.table_list.first)->db;
+ lex->select_lex.db= (lex->select_lex.table_list.first)->db;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.db_type= 0;
lex->create_info.default_table_charset= NULL;
@@ -7231,8 +7229,8 @@ select_from:
opt_order_clause opt_limit_clause procedure_clause
{
Select->context.table_list=
- Select->context.first_name_resolution_table=
- (TABLE_LIST *) Select->table_list.first;
+ Select->context.first_name_resolution_table=
+ Select->table_list.first;
}
| FROM DUAL_SYM where_clause opt_limit_clause
/* oracle compatibility: oracle always requires FROM clause,
@@ -8924,9 +8922,8 @@ opt_gorder_clause:
| order_clause
{
SELECT_LEX *select= Select;
- select->gorder_list=
- (SQL_LIST*) sql_memdup((char*) &select->order_list,
- sizeof(st_sql_list));
+ select->gorder_list= new (YYTHD->mem_root)
+ SQL_I_List<ORDER>(select->order_list);
if (select->gorder_list == NULL)
MYSQL_YYABORT;
select->order_list.empty();
@@ -9984,7 +9981,7 @@ procedure_clause:
}
lex->proc_list.elements=0;
lex->proc_list.first=0;
- lex->proc_list.next= (uchar**) &lex->proc_list.first;
+ lex->proc_list.next= &lex->proc_list.first;
Item_field *item= new (YYTHD->mem_root)
Item_field(&lex->current_select->context,
NULL, NULL, $2.str);
@@ -11949,8 +11946,8 @@ simple_ident_q:
Let us add this item to list of all Item_trigger_field objects
in trigger.
*/
- lex->trg_table_fields.link_in_list((uchar*) trg_fld,
- (uchar**) &trg_fld->next_trg_field);
+ lex->trg_table_fields.link_in_list(trg_fld,
+ &trg_fld->next_trg_field);
$$= trg_fld;
}
@@ -12036,7 +12033,7 @@ field_ident:
ident { $$=$1;}
| ident '.' ident '.' ident
{
- TABLE_LIST *table= (TABLE_LIST*) Select->table_list.first;
+ TABLE_LIST *table= Select->table_list.first;
if (my_strcasecmp(table_alias_charset, $1.str, table->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
@@ -12052,7 +12049,7 @@ field_ident:
}
| ident '.' ident
{
- TABLE_LIST *table= (TABLE_LIST*) Select->table_list.first;
+ TABLE_LIST *table= Select->table_list.first;
if (my_strcasecmp(table_alias_charset, $1.str, table->alias))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), $1.str);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e829d0784e9..7eb9a72273b 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2393,12 +2393,33 @@ static ulonglong read_timestamp(THD *thd)
{
return (ulonglong) thd->start_time;
}
+
+
+static bool check_timestamp(sys_var *self, THD *thd, set_var *var)
+{
+ time_t val;
+
+ if (!var->value)
+ return FALSE;
+
+ val= (time_t) var->save_result.ulonglong_value;
+ if (val < (time_t) MY_TIME_T_MIN || val > (time_t) MY_TIME_T_MAX)
+ {
+ my_message(ER_UNKNOWN_ERROR,
+ "This version of MySQL doesn't support dates later than 2038",
+ MYF(0));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
static Sys_var_session_special Sys_timestamp(
"timestamp", "Set the time for this client",
sys_var::ONLY_SESSION, NO_CMD_LINE,
VALID_RANGE(0, ~(time_t)0), BLOCK_SIZE(1),
- NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0), ON_UPDATE(update_timestamp),
- ON_READ(read_timestamp));
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_timestamp),
+ ON_UPDATE(update_timestamp), ON_READ(read_timestamp));
static bool update_last_insert_id(THD *thd, set_var *var)
{
diff --git a/sql/table.cc b/sql/table.cc
index 84153f6d9c5..dbd657bee67 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -61,6 +61,8 @@ static uint find_field(Field **fields, uchar *record, uint start, uint length);
inline bool is_system_table_name(const char *name, uint length);
+static ulong get_form_pos(File file, uchar *head);
+
/**************************************************************************
Object_creation_ctx implementation.
**************************************************************************/
@@ -702,7 +704,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
disk_buff= 0;
error= 3;
- if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
+ /* Position of the form in the form file. */
+ if (!(pos= get_form_pos(file, head)))
goto err; /* purecov: inspected */
mysql_file_seek(file,pos,MY_SEEK_SET,MYF(0));
@@ -2092,52 +2095,46 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size)
}
}
- /* Find where a form starts */
- /* if formname is NullS then only formnames is read */
+/**
+ Find where a form starts.
+
+ @param head The start of the form file.
-ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
+ @remark If formname is NULL then only formnames is read.
+
+ @retval The form position.
+*/
+
+static ulong get_form_pos(File file, uchar *head)
{
- uint a_length,names,length;
- uchar *pos,*buf;
+ uchar *pos, *buf;
+ uint names, length;
ulong ret_value=0;
DBUG_ENTER("get_form_pos");
- names=uint2korr(head+8);
- a_length=(names+2)*sizeof(char *); /* Room for two extra */
+ names= uint2korr(head+8);
- if (!save_names)
- a_length=0;
- else
- save_names->type_names=0; /* Clear if error */
+ if (!(names= uint2korr(head+8)))
+ DBUG_RETURN(0);
- if (names)
- {
- length=uint2korr(head+4);
- mysql_file_seek(file, 64L, MY_SEEK_SET, MYF(0));
- if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
- MYF(MY_WME))) ||
- mysql_file_read(file, buf+a_length, (size_t) (length+names*4),
- MYF(MY_NABP)))
- { /* purecov: inspected */
- x_free((uchar*) buf); /* purecov: inspected */
- DBUG_RETURN(0L); /* purecov: inspected */
- }
- pos= buf+a_length+length;
- ret_value=uint4korr(pos);
- }
- if (! save_names)
- {
- if (names)
- my_free((uchar*) buf,MYF(0));
- }
- else if (!names)
- bzero((char*) save_names,sizeof(save_names));
- else
+ length= uint2korr(head+4);
+
+ mysql_file_seek(file, 64L, MY_SEEK_SET, MYF(0));
+
+ if (!(buf= (uchar*) my_malloc(length+names*4, MYF(MY_WME))))
+ DBUG_RETURN(0);
+
+ if (mysql_file_read(file, buf, length+names*4, MYF(MY_NABP)))
{
- char *str;
- str=(char *) (buf+a_length);
- fix_type_pointers((const char ***) &buf,save_names,1,&str);
+ x_free(buf);
+ DBUG_RETURN(0);
}
+
+ pos= buf+length;
+ ret_value= uint4korr(pos);
+
+ my_free(buf, MYF(0));
+
DBUG_RETURN(ret_value);
}
@@ -4442,6 +4439,27 @@ void TABLE::mark_columns_used_by_index(uint index)
/*
+ Add fields used by a specified index to the table's read_set.
+
+ NOTE:
+ The original state can be restored with
+ restore_column_maps_after_mark_index().
+*/
+
+void TABLE::add_read_columns_used_by_index(uint index)
+{
+ MY_BITMAP *bitmap= &tmp_set;
+ DBUG_ENTER("TABLE::add_read_columns_used_by_index");
+
+ set_keyread(TRUE);
+ bitmap_copy(bitmap, read_set);
+ mark_columns_used_by_index_no_reset(index, bitmap);
+ column_bitmaps_set(bitmap, write_set);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Restore to use normal column maps after key read
NOTES
diff --git a/sql/table.h b/sql/table.h
index 1307770d8e1..fb312dac132 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1060,6 +1060,7 @@ public:
void prepare_for_position(void);
void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
void mark_columns_used_by_index(uint index);
+ void add_read_columns_used_by_index(uint index);
void restore_column_maps_after_mark_index();
void mark_auto_increment_column(void);
void mark_columns_needed_for_update(void);
@@ -1354,7 +1355,7 @@ struct TABLE_LIST
}
/*
- List of tables local to a subquery (used by SQL_LIST). Considers
+ List of tables local to a subquery (used by SQL_I_List). Considers
views as leaves (unlike 'next_leaf' below). Created at parse time
in st_select_lex::add_table_to_list() -> table_list.link_in_list().
*/
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index 7696f28081d..79a6fd79d4c 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -24,8 +24,6 @@
extern "C" {
void sql_alloc_error_handler(void)
{
- sql_print_error("%s", ER(ER_OUT_OF_RESOURCES));
-
THD *thd= current_thd;
if (thd)
{
@@ -53,6 +51,12 @@ extern "C" {
NULL);
}
}
+
+ /* Skip writing to the error log to avoid mtr complaints */
+ DBUG_EXECUTE_IF("simulate_out_of_memory", return;);
+
+ sql_print_error("%s", ER(ER_OUT_OF_RESOURCES));
+
}
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index dbe4e8712ea..802e5b7429c 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -117,7 +117,6 @@ bool mysql_create_frm(THD *thd, const char *file_name,
File file;
ulong filepos, data_offset;
uchar fileinfo[64],forminfo[288],*keybuff;
- TYPELIB formnames;
uchar *screen_buff;
char buff[128];
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -128,7 +127,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
DBUG_ENTER("mysql_create_frm");
DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
- formnames.type_names=0;
+
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0)))
DBUG_RETURN(1);
DBUG_ASSERT(db_file != NULL);
@@ -267,8 +266,15 @@ bool mysql_create_frm(THD *thd, const char *file_name,
key_buff_length= uint4korr(fileinfo+47);
keybuff=(uchar*) my_malloc(key_buff_length, MYF(0));
key_info_length= pack_keys(keybuff, keys, key_info, data_offset);
- (void) get_form_pos(file,fileinfo,&formnames);
- if (!(filepos=make_new_entry(file,fileinfo,&formnames,"")))
+
+ /*
+ Ensure that there are no forms in this newly created form file.
+ Even if the form file exists, create_frm must truncate it to
+ ensure one form per form file.
+ */
+ DBUG_ASSERT(uint2korr(fileinfo+8) == 0);
+
+ if (!(filepos= make_new_entry(file, fileinfo, NULL, "")))
goto err;
maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
int2store(forminfo+2,maxlength);