summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-06-11 20:20:35 +0200
committerSergei Golubchik <serg@mariadb.org>2015-06-11 20:20:35 +0200
commit810cf362eae28d4a096e0acea7efa67dd32aa05b (patch)
tree4f7b2f858e8a57022e790bcac6d88b5e3451ee0f /sql
parenta99efc00a68fe2406343e63b67fc4ea58bed345a (diff)
parentd199a0ffb0aac86881ea2db7dd78bc07b438dc67 (diff)
downloadmariadb-git-810cf362eae28d4a096e0acea7efa67dd32aa05b.tar.gz
Merge branch '5.5' into 10.0
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc10
-rw-r--r--sql/field.h1
-rw-r--r--sql/filesort.cc4
-rw-r--r--sql/ha_ndbcluster_binlog.cc6
-rw-r--r--sql/item.cc41
-rw-r--r--sql/item.h9
-rw-r--r--sql/item_strfunc.cc10
-rw-r--r--sql/item_sum.cc18
-rw-r--r--sql/log.h8
-rw-r--r--sql/log_event.cc6
-rw-r--r--sql/message.rc4
-rw-r--r--sql/rpl_utility.cc2
-rw-r--r--sql/sql_base.cc3
-rw-r--r--sql/sql_connect.cc13
-rw-r--r--sql/sql_lex.cc15
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_partition_admin.cc11
-rw-r--r--sql/sql_plugin.cc25
-rw-r--r--sql/sql_select.cc18
-rw-r--r--sql/sql_servers.cc3
-rw-r--r--sql/sql_show.cc17
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy62
-rw-r--r--sql/table.h2
-rw-r--r--sql/tztime.cc3
-rw-r--r--sql/winservice.h80
27 files changed, 239 insertions, 139 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 31d8b46e587..ba677975de1 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2633,7 +2633,7 @@ void Field_decimal::sql_type(String &res) const
if (dec)
tmp--;
res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
- "decimal(%d,%d)",tmp,dec));
+ "decimal(%d,%d)/*old*/",tmp,dec));
add_zerofill_and_unsigned(res);
}
@@ -7923,6 +7923,14 @@ err_exit:
return -1;
}
+Field::geometry_type Field_geom::geometry_type_merge(geometry_type a,
+ geometry_type b)
+{
+ if (a == b)
+ return a;
+ return Field::GEOM_GEOMETRY;
+}
+
#endif /*HAVE_SPATIAL*/
/****************************************************************************
diff --git a/sql/field.h b/sql/field.h
index a52bd01395a..97a820e9470 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -2591,6 +2591,7 @@ public:
int reset(void) { return Field_blob::reset() || !maybe_null(); }
geometry_type get_geometry_type() { return geom_type; };
+ static geometry_type geometry_type_merge(geometry_type, geometry_type);
};
#endif /*HAVE_SPATIAL*/
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 027437fca67..a545bb623c0 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, Monty Program Ab.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 73513ac9f40..64ae31ce231 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1,5 +1,4 @@
-/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
- Copyright (c) 2012, 2013, Monty Proram Ab.
+/* Copyright (c) 2006, 2015, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2529,7 +2528,8 @@ ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname)
char path[FN_REFLEN + 1];
build_table_filename(path, sizeof(path) - 1, dbname, "", "", 0);
- if (find_files(thd, &files, dbname, path, NullS, 0) != FIND_FILES_OK)
+ if (find_files(thd, &files, dbname, path, NullS, 0, NULL) !=
+ FIND_FILES_OK)
{
DBUG_PRINT("info", ("Failed to find files"));
DBUG_RETURN(true);
diff --git a/sql/item.cc b/sql/item.cc
index a465c2d4e36..bffa7e2990d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1179,6 +1179,42 @@ Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
/**
+ Some pieces of the code do not support changing of
+ Item_cache to other Item types.
+
+ Example:
+ Item_singlerow_subselect has "Item_cache **row".
+ Creating of Item_func_conv_charset followed by THD::change_item_tree()
+ should not change row[i] from Item_cache directly to Item_func_conv_charset, because Item_singlerow_subselect
+ because Item_singlerow_subselect later calls Item_cache-specific methods,
+ e.g. row[i]->store() and row[i]->cache_value().
+
+ Let's wrap Item_func_conv_charset in a new Item_cache,
+ so the Item_cache-specific methods can still be used for
+ Item_singlerow_subselect::row[i] safely.
+
+ As a bonus we cache the converted value, instead of converting every time
+
+ TODO: we should eventually check all other use cases of change_item_tree().
+ Perhaps some more potentially dangerous substitution examples exist.
+*/
+Item *Item_cache::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ if (!example)
+ return Item::safe_charset_converter(tocs);
+ Item *conv= example->safe_charset_converter(tocs);
+ if (conv == example)
+ return this;
+ Item_cache *cache;
+ if (!conv || !(cache= new Item_cache_str(conv)))
+ return NULL; // Safe conversion is not possible, or OEM
+ cache->setup(conv);
+ cache->fixed= false; // Make Item::fix_fields() happy
+ return cache;
+}
+
+
+/**
@details
Created mostly for mysql_prepare_table(). Important
when a string ENUM/SET column is described with a numeric default value:
@@ -9471,6 +9507,11 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
item_decimals= 0;
decimals= MY_MAX(decimals, item_decimals);
}
+
+ if (fld_type == FIELD_TYPE_GEOMETRY)
+ geometry_type=
+ Field_geom::geometry_type_merge(geometry_type, item->get_geometry_type());
+
if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
{
decimals= MY_MIN(MY_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
diff --git a/sql/item.h b/sql/item.h
index ce757749217..171bdb05310 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4477,7 +4477,6 @@ class Item_cache: public Item_basic_constant
{
protected:
Item *example;
- table_map used_table_map;
/**
Field that this object will get value from. This is used by
index-based subquery engines to detect and remove the equality injected
@@ -4495,7 +4494,7 @@ protected:
bool value_cached;
public:
Item_cache():
- example(0), used_table_map(0), cached_field(0),
+ example(0), cached_field(0),
cached_field_type(MYSQL_TYPE_STRING),
value_cached(0)
{
@@ -4504,7 +4503,7 @@ public:
null_value= 1;
}
Item_cache(enum_field_types field_type_arg):
- example(0), used_table_map(0), cached_field(0),
+ example(0), cached_field(0),
cached_field_type(field_type_arg),
value_cached(0)
{
@@ -4513,8 +4512,6 @@ public:
null_value= 1;
}
- void set_used_tables(table_map map) { used_table_map= map; }
-
virtual bool allocate(uint i) { return 0; }
virtual bool setup(Item *item)
{
@@ -4531,7 +4528,6 @@ public:
enum_field_types field_type() const { return cached_field_type; }
static Item_cache* get_cache(const Item *item);
static Item_cache* get_cache(const Item* item, const Item_result type);
- table_map used_tables() const { return used_table_map; }
virtual void keep_array() {}
virtual void print(String *str, enum_query_type query_type);
bool eq_def(Field *field)
@@ -4582,6 +4578,7 @@ public:
return TRUE;
return (this->*processor)(arg);
}
+ virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 32a19341895..972ae5afb16 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -5122,6 +5122,16 @@ null:
void Item_dyncol_get::print(String *str, enum_query_type query_type)
{
+ /*
+ Parent cast doesn't exist yet, only print dynamic column name. This happens
+ when called from create_func_cast() / wrong_precision_error().
+ */
+ if (!str->length())
+ {
+ args[1]->print(str, query_type);
+ return;
+ }
+
/* see create_func_dyncol_get */
DBUG_ASSERT(str->length() >= 5);
DBUG_ASSERT(strncmp(str->ptr() + str->length() - 5, "cast(", 5) == 0);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 21f14ae8435..1c5682417a5 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3311,7 +3311,19 @@ void Item_func_group_concat::cleanup()
}
DBUG_ASSERT(tree == 0);
}
-
+ /*
+ As the ORDER structures pointed to by the elements of the
+ 'order' array may be modified in find_order_in_list() called
+ from Item_func_group_concat::setup() to point to runtime
+ created objects, we need to reset them back to the original
+ arguments of the function.
+ */
+ ORDER **order_ptr= order;
+ for (uint i= 0; i < arg_count_order; i++)
+ {
+ (*order_ptr)->item= &args[arg_count_field + i];
+ order_ptr++;
+ }
DBUG_VOID_RETURN;
}
diff --git a/sql/log.h b/sql/log.h
index d3540aa4499..48970f7452a 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -990,11 +990,9 @@ uint purge_log_get_error_code(int res);
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
void sql_print_error(const char *format, ...);
-void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
-void sql_print_information(const char *format, ...)
- ATTRIBUTE_FORMAT(printf, 1, 2);
-typedef void (*sql_print_message_func)(const char *format, ...)
- ATTRIBUTE_FORMAT_FPTR(printf, 1, 2);
+void sql_print_warning(const char *format, ...);
+void sql_print_information(const char *format, ...);
+typedef void (*sql_print_message_func)(const char *format, ...);
extern sql_print_message_func sql_print_message_handlers[];
int error_log_print(enum loglevel level, const char *format,
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 29cb10c0abf..69b981f3f47 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2406,6 +2406,12 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
my_snprintf(typestr, typestr_length, "STRING(%d)", length);
return my_b_write_quoted_with_length(file, ptr, length);
+ case MYSQL_TYPE_DECIMAL:
+ my_b_printf(file,
+ "!! Old DECIMAL (mysql-4.1 or earlier). "
+ "Not enough metadata to display the value. ");
+ break;
+
default:
{
char tmp[5];
diff --git a/sql/message.rc b/sql/message.rc
index 116522b7d48..0885a897e6f 100644
--- a/sql/message.rc
+++ b/sql/message.rc
@@ -1,2 +1,2 @@
-LANGUAGE 0x9,0x1
-1 11 MSG00001.bin
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 9067f1e4253..146bf3b0c0e 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -452,7 +452,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_
CHARSET_INFO *cs= str->charset();
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
- "decimal(%d,?)", metadata);
+ "decimal(%d,?)/*old*/", metadata);
str->length(length);
}
break;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 619bd4bd98f..13b8625ebe6 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8015,9 +8015,10 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
if (select_lex->first_cond_optimization)
{
leaves.empty();
- if (!select_lex->is_prep_leaf_list_saved)
+ if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED)
{
make_leaves_list(leaves, tables, full_table_list, first_select_table);
+ select_lex->prep_leaf_list_state= SELECT_LEX::READY;
select_lex->leaf_tables_exec.empty();
}
else
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 807b028a4b1..0202b4493ac 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1122,7 +1122,7 @@ bool setup_connection_thread_globals(THD *thd)
bool login_connection(THD *thd)
{
NET *net= &thd->net;
- int error;
+ int error= 0;
DBUG_ENTER("login_connection");
DBUG_PRINT("info", ("login_connection called by thread %lu",
thd->thread_id));
@@ -1141,7 +1141,8 @@ bool login_connection(THD *thd)
my_sleep(1000); /* must wait after eof() */
#endif
statistic_increment(aborted_connects,&LOCK_status);
- DBUG_RETURN(1);
+ error=1;
+ goto exit;
}
/* Connect completed, set read/write timeouts back to default */
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
@@ -1151,10 +1152,13 @@ bool login_connection(THD *thd)
if (increment_connection_count(thd, TRUE))
{
my_error(ER_OUTOFMEMORY, MYF(0), 2*sizeof(USER_STATS));
- DBUG_RETURN(1);
+ error= 1;
+ goto exit;
}
- DBUG_RETURN(0);
+exit:
+ mysql_audit_notify_connection_connect(thd);
+ DBUG_RETURN(error);
}
@@ -1295,7 +1299,6 @@ bool thd_prepare_connection(THD *thd)
bool rc;
lex_start(thd);
rc= login_connection(thd);
- mysql_audit_notify_connection_connect(thd);
if (rc)
return rc;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d8f40897a59..2026d5f5059 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -556,6 +556,7 @@ void lex_start(THD *thd)
lex->is_lex_started= TRUE;
lex->used_tables= 0;
+ lex->only_view= FALSE;
lex->reset_slave_info.all= false;
lex->limit_rows_examined= 0;
lex->limit_rows_examined_cnt= ULONGLONG_MAX;
@@ -1873,7 +1874,7 @@ void st_select_lex::init_query()
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0;
link_next= 0;
- is_prep_leaf_list_saved= FALSE;
+ prep_leaf_list_state= UNINIT;
have_merged_subqueries= FALSE;
bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
m_non_agg_field_used= false;
@@ -4152,12 +4153,22 @@ bool st_select_lex::save_prep_leaf_tables(THD *thd)
{
List_iterator_fast<TABLE_LIST> li(leaf_tables);
TABLE_LIST *table;
+
+ /*
+ Check that the SELECT_LEX was really prepared and so tables are setup.
+
+ It can be subquery in SET clause of UPDATE which was not prepared yet, so
+ its tables are not yet setup and ready for storing.
+ */
+ if (prep_leaf_list_state != READY)
+ return FALSE;
+
while ((table= li++))
{
if (leaf_tables_prep.push_back(table))
return TRUE;
}
- is_prep_leaf_list_saved= TRUE;
+ prep_leaf_list_state= SAVED;
for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
{
for (SELECT_LEX *sl= u->first_select(); sl; sl= sl->next_select())
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index b17f0f4ec63..dcd8ddfce91 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -733,7 +733,8 @@ public:
List<TABLE_LIST> leaf_tables;
List<TABLE_LIST> leaf_tables_exec;
List<TABLE_LIST> leaf_tables_prep;
- bool is_prep_leaf_list_saved;
+ enum leaf_list_state {UNINIT, READY, SAVED};
+ enum leaf_list_state prep_leaf_list_state;
uint insert_tables;
st_select_lex *merged_into; /* select which this select is merged into */
/* (not 0 only for views/derived tables) */
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 8c59febeb77..87803c220ea 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -824,9 +824,16 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
log. The exception is a unimplemented truncate method or failure
before any call to handler::truncate() is done.
Also, it is logged in statement format, regardless of the binlog format.
+
+ Since we've changed data within the table, we also have to invalidate
+ the query cache for it.
*/
- if (error != HA_ERR_WRONG_COMMAND && binlog_stmt)
- error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
+ if (error != HA_ERR_WRONG_COMMAND)
+ {
+ query_cache_invalidate3(thd, first_table, FALSE);
+ if (binlog_stmt)
+ error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
+ }
/*
A locked table ticket was upgraded to a exclusive lock. After the
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 7fbd6b63490..dc408703da4 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -264,13 +264,14 @@ public:
{ TRASH(ptr_arg, size); }
sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
- struct st_mysql_sys_var *plugin_var_arg)
+ struct st_mysql_sys_var *plugin_var_arg,
+ struct st_plugin_int *plugin_arg)
:sys_var(chain, name_arg, plugin_var_arg->comment,
(plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) |
(plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0),
0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0,
VARIABLE_NOT_IN_BINLOG, NULL, NULL, NULL),
- plugin_var(plugin_var_arg)
+ plugin(plugin_arg), plugin_var(plugin_var_arg)
{ plugin_var->name= name_arg; }
sys_var_pluginvar *cast_pluginvar() { return this; }
bool check_update_type(Item_result type);
@@ -1413,22 +1414,6 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
goto err;
}
- /*
- set the plugin attribute of plugin's sys vars so they are pointing
- to the active plugin
- */
- if (plugin->system_vars)
- {
- sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
- for (;;)
- {
- var->plugin= plugin;
- if (!var->next)
- break;
- var= var->next->cast_pluginvar();
- }
- }
-
ret= 0;
err:
@@ -3961,7 +3946,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
continue;
tmp_backup[tmp->nbackups++].save(&o->name);
if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
- v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o);
+ v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o, tmp);
else
{
len= plugin_name.length + strlen(o->name) + 2;
@@ -3969,7 +3954,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
strxmov(varname, plugin_name.str, "-", o->name, NullS);
my_casedn_str(&my_charset_latin1, varname);
convert_dash_to_underscore(varname, len-1);
- v= new (mem_root) sys_var_pluginvar(&chain, varname, o);
+ v= new (mem_root) sys_var_pluginvar(&chain, varname, o, tmp);
}
DBUG_ASSERT(v); /* check that an object was actually constructed */
} /* end for */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2aeddf2415d..e0f560f0b3a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9736,10 +9736,24 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!sel->quick_keys.is_subset(tab->checked_keys) ||
!sel->needed_reg.is_subset(tab->checked_keys))
{
+ /*
+ "Range checked for each record" is a "last resort" access method
+ that should only be used when the other option is a cross-product
+ join.
+
+ We use the following condition (it's approximate):
+ 1. There are potential keys for (sel->needed_reg)
+ 2. There were no possible ways to construct a quick select, or
+ the quick select would be more expensive than the full table
+ scan.
+ */
tab->use_quick= (!sel->needed_reg.is_clear_all() &&
(sel->quick_keys.is_clear_all() ||
- (sel->quick &&
- (sel->quick->records >= 100L)))) ?
+ (sel->quick &&
+ sel->quick->read_time >
+ tab->table->file->scan_time() +
+ tab->table->file->stats.records/TIME_FOR_COMPARE
+ ))) ?
2 : 1;
sel->read_tables= used_tables & ~current_map;
sel->quick_keys.clear_all();
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 2b0576ffba9..8d5bb2b596d 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -326,7 +326,8 @@ get_server_from_table_to_cache(TABLE *table)
table->use_all_columns();
/* get each field into the server struct ptr */
- server->server_name= get_field(&mem, table->field[0]);
+ ptr= get_field(&mem, table->field[0]);
+ server->server_name= ptr ? ptr : blank;
server->server_name_length= (uint) strlen(server->server_name);
ptr= get_field(&mem, table->field[1]);
server->host= ptr ? ptr : blank;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b566029740a..2413cb5ba53 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2301,7 +2301,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
if ((tmp->vio_ok() || tmp->system_thread) &&
- (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
+ (!user || (!tmp->system_thread &&
+ tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
{
thread_info *thd_info= new thread_info;
@@ -2679,7 +2680,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
ulonglong max_counter;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
- (user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
+ (user && (tmp->system_thread || !tmp_sctx->user ||
+ strcmp(tmp_sctx->user, user))))
continue;
restore_record(table, s->default_values);
@@ -8099,15 +8101,20 @@ bool get_schema_tables_result(JOIN *join,
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_information_schema_tables())
{
+#if MYSQL_VERSION_ID > 100105
+#error I_S tables only need to be re-populated if make_cond_for_info_schema() will preserve outer fields
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
lex->current_select->master_unit()->item);
+#else
+#define is_subselect false
+#endif
/* A value of 0 indicates a dummy implementation */
if (table_list->schema_table->fill_table == 0)
continue;
/* skip I_S optimizations specific to get_all_tables */
- if (thd->lex->describe &&
+ if (lex->describe &&
(table_list->schema_table->fill_table != get_all_tables))
continue;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 817ab6e8967..da2a220d3f1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5478,7 +5478,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (!table->view)
{
int result __attribute__((unused))=
- show_create_table(thd, table, &query, create_info, WITHOUT_DB_NAME);
+ show_create_table(thd, table, &query, create_info, WITH_DB_NAME);
DBUG_ASSERT(result == 0); // show_create_table() always return 0
do_logging= FALSE;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 41647a7262f..a63d8a51a86 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -225,7 +225,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
view->definer.user= decoy.definer.user;
lex->definer= &view->definer;
}
- if (lex->create_view_algorithm == DTYPE_ALGORITHM_UNDEFINED)
+ if (lex->create_view_algorithm == VIEW_ALGORITHM_INHERIT)
lex->create_view_algorithm= (uint8) decoy.algorithm;
if (lex->create_view_suid == VIEW_SUID_DEFAULT)
lex->create_view_suid= decoy.view_suid ?
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 9c7898b1b02..d980de7e1a5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -7142,7 +7142,7 @@ alter:
my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
MYSQL_YYABORT;
}
- lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
+ lex->create_view_algorithm= VIEW_ALGORITHM_INHERIT;
lex->create_view_mode= VIEW_ALTER;
}
view_tail
@@ -7912,8 +7912,13 @@ opt_checksum_type:
| EXTENDED_SYM { Lex->check_opt.flags= T_EXTEND; }
;
+repair_table_or_view:
+ table_or_tables table_list opt_mi_repair_type
+ | VIEW_SYM { Lex->only_view= TRUE; } table_list opt_view_repair_type
+ ;
+
repair:
- REPAIR opt_no_write_to_binlog table_or_view
+ REPAIR opt_no_write_to_binlog
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_REPAIR;
@@ -7923,18 +7928,9 @@ repair:
/* Will be overriden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
- table_list opt_mi_repair_type
+ repair_table_or_view
{
LEX* lex= thd->lex;
- if ((lex->only_view &&
- ((lex->check_opt.flags & (T_QUICK | T_EXTEND)) ||
- (lex->check_opt.sql_flags & TT_USEFRM))) ||
- (!lex->only_view &&
- (lex->check_opt.sql_flags & TT_FROM_MYSQL)))
- {
- my_parse_error(ER(ER_SYNTAX_ERROR));
- MYSQL_YYABORT;
- }
DBUG_ASSERT(!lex->m_sql_cmd);
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
if (lex->m_sql_cmd == NULL)
@@ -7956,6 +7952,10 @@ mi_repair_type:
QUICK { Lex->check_opt.flags|= T_QUICK; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
| USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; }
+ ;
+
+opt_view_repair_type:
+ /* empty */ { }
| FROM MYSQL_SYM { Lex->check_opt.sql_flags|= TT_FROM_MYSQL; }
;
@@ -8075,30 +8075,27 @@ binlog_base64_event:
}
;
-check:
- CHECK_SYM table_or_view
+check_view_or_table:
+ table_or_tables table_list opt_mi_check_type
+ | VIEW_SYM { Lex->only_view= TRUE; } table_list opt_view_check_type
+ ;
+
+check: CHECK_SYM
{
LEX *lex=Lex;
- if (lex->sphead)
- {
- my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK");
- MYSQL_YYABORT;
- }
lex->sql_command = SQLCOM_CHECK;
lex->check_opt.init();
lex->alter_info.reset();
/* Will be overriden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
- table_list opt_mi_check_type
+ check_view_or_table
{
LEX* lex= thd->lex;
- if (lex->only_view &&
- (lex->check_opt.flags & (T_QUICK | T_FAST | T_EXTEND |
- T_CHECK_ONLY_CHANGED)))
+ if (lex->sphead)
{
- my_parse_error(ER(ER_SYNTAX_ERROR));
+ my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK");
MYSQL_YYABORT;
}
DBUG_ASSERT(!lex->m_sql_cmd);
@@ -8127,6 +8124,11 @@ mi_check_type:
| FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
;
+opt_view_check_type:
+ /* empty */ { }
+ | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
+ ;
+
optimize:
OPTIMIZE opt_no_write_to_binlog table_or_tables
{
@@ -8208,7 +8210,6 @@ keycache:
LEX *lex=Lex;
lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
lex->ident= $6;
- lex->only_view= FALSE;
}
;
@@ -8253,7 +8254,6 @@ preload:
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
lex->alter_info.reset();
- lex->only_view= FALSE;
}
preload_list_or_parts
{}
@@ -12540,7 +12540,6 @@ show_param:
lex->sql_command = SQLCOM_SHOW_CREATE;
if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
MYSQL_YYABORT;
- lex->only_view= 0;
lex->create_info.storage_media= HA_SM_DEFAULT;
}
| CREATE VIEW_SYM table_ident
@@ -14858,13 +14857,8 @@ lock:
;
table_or_tables:
- TABLE_SYM { Lex->only_view= FALSE; }
- | TABLES { Lex->only_view= FALSE; }
- ;
-
-table_or_view:
- table_or_tables
- | VIEW_SYM { Lex->only_view= TRUE; }
+ TABLE_SYM { }
+ | TABLES { }
;
table_lock_list:
diff --git a/sql/table.h b/sql/table.h
index df7fd852a76..39faa8b9765 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1541,6 +1541,8 @@ typedef struct st_schema_table
#define DT_PHASES_MATERIALIZE (DT_COMMON | DT_MATERIALIZE)
#define VIEW_ALGORITHM_UNDEFINED 0
+/* Special value for ALTER VIEW: inherit original algorithm. */
+#define VIEW_ALGORITHM_INHERIT DTYPE_VIEW
#define VIEW_ALGORITHM_MERGE (DTYPE_VIEW | DTYPE_MERGE)
#define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW | DTYPE_MATERIALIZE)
diff --git a/sql/tztime.cc b/sql/tztime.cc
index d3b4fec6335..6486e9b2018 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2523,7 +2523,8 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose)
for (i= 0; i < cur_dir->number_of_files; i++)
{
- if (cur_dir->dir_entry[i].name[0] != '.')
+ if (cur_dir->dir_entry[i].name[0] != '.' &&
+ strcmp(cur_dir->dir_entry[i].name, "Factory"))
{
name_end_tmp= strmake(name_end, cur_dir->dir_entry[i].name,
FN_REFLEN - (name_end - fullname));
diff --git a/sql/winservice.h b/sql/winservice.h
index fca7b129de5..c3e2bfe1b20 100644
--- a/sql/winservice.h
+++ b/sql/winservice.h
@@ -1,40 +1,40 @@
-/*
- Copyright (c) 2011, 2012, Monty Program Ab
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Extract properties of a windows service binary path
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <windows.h>
-typedef struct mysqld_service_properties_st
-{
- char mysqld_exe[MAX_PATH];
- char inifile[MAX_PATH];
- char datadir[MAX_PATH];
- int version_major;
- int version_minor;
- int version_patch;
-} mysqld_service_properties;
-
-extern int get_mysql_service_properties(const wchar_t *bin_path,
- mysqld_service_properties *props);
-
-#ifdef __cplusplus
-}
-#endif
+/*
+ Copyright (c) 2011, 2012, Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Extract properties of a windows service binary path
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+typedef struct mysqld_service_properties_st
+{
+ char mysqld_exe[MAX_PATH];
+ char inifile[MAX_PATH];
+ char datadir[MAX_PATH];
+ int version_major;
+ int version_minor;
+ int version_patch;
+} mysqld_service_properties;
+
+extern int get_mysql_service_properties(const wchar_t *bin_path,
+ mysqld_service_properties *props);
+
+#ifdef __cplusplus
+}
+#endif