summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorTatiana A. Nurnberg <azundris@mysql.com>2009-03-06 16:11:34 +0100
committerTatiana A. Nurnberg <azundris@mysql.com>2009-03-06 16:11:34 +0100
commitcee070e1bb20552136b2ed5f2351d3b685fbddeb (patch)
tree7fc5bfde8b352f380a7308cd118a1023c1ddd138 /sql
parent13328b0f45c449020b3b70ed9de1668e16d51bb4 (diff)
parent53802ae6ca0ea2d95c9d24b8c07a27213406131e (diff)
downloadmariadb-git-cee070e1bb20552136b2ed5f2351d3b685fbddeb.tar.gz
manual merge
Diffstat (limited to 'sql')
-rw-r--r--sql/item_func.cc10
-rw-r--r--sql/log.cc7
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/opt_range.cc57
-rw-r--r--sql/protocol.cc3
-rw-r--r--sql/rpl_record.cc34
-rw-r--r--sql/set_var.cc13
-rw-r--r--sql/share/errmsg.txt23
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sql_cache.cc47
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h9
-rw-r--r--sql/sql_parse.cc21
-rw-r--r--sql/sql_show.cc13
-rw-r--r--sql/sql_table.cc9
-rw-r--r--sql/sql_yacc.yy17
-rw-r--r--sql/unireg.cc17
19 files changed, 234 insertions, 61 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index ec95254baaa..4322fa058a7 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4837,7 +4837,9 @@ bool Item_func_get_system_var::is_written_to_binlog()
void Item_func_get_system_var::fix_length_and_dec()
{
+ char *cptr;
maybe_null=0;
+ max_length= 0;
if (var->check_type(var_type))
{
@@ -4867,8 +4869,14 @@ void Item_func_get_system_var::fix_length_and_dec()
break;
case SHOW_CHAR:
case SHOW_CHAR_PTR:
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ cptr= var->show_type() == SHOW_CHAR_PTR ?
+ *(char**) var->value_ptr(current_thd, var_type, &component) :
+ (char*) var->value_ptr(current_thd, var_type, &component);
+ if (cptr)
+ max_length= strlen(cptr) * system_charset_info->mbmaxlen;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
collation.set(system_charset_info, DERIVATION_SYSCONST);
- max_length= MAX_BLOB_WIDTH;
decimals=NOT_FIXED_DEC;
break;
case SHOW_BOOL:
diff --git a/sql/log.cc b/sql/log.cc
index 74dc75702ae..44296daa939 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -4650,10 +4650,14 @@ bool flush_error_log()
uchar buf[IO_SIZE];
freopen(err_temp,"a+",stderr);
+ setbuf(stderr, NULL);
(void) my_delete(err_renamed, MYF(0));
my_rename(log_error_file,err_renamed,MYF(0));
if (freopen(log_error_file,"a+",stdout))
+ {
freopen(log_error_file,"a+",stderr);
+ setbuf(stderr, NULL);
+ }
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
{
@@ -4669,7 +4673,10 @@ bool flush_error_log()
#else
my_rename(log_error_file,err_renamed,MYF(0));
if (freopen(log_error_file,"a+",stdout))
+ {
freopen(log_error_file,"a+",stderr);
+ setbuf(stderr, NULL);
+ }
else
result= 1;
#endif
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bd1afc7f0ca..1391b87e8e3 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3703,7 +3703,10 @@ static int init_server_components()
#ifndef EMBEDDED_LIBRARY
if (freopen(log_error_file, "a+", stdout))
#endif
+ {
freopen(log_error_file, "a+", stderr);
+ setbuf(stderr, NULL);
+ }
}
}
@@ -4331,6 +4334,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
{
freopen(log_error_file,"a+",stdout);
freopen(log_error_file,"a+",stderr);
+ setbuf(stderr, NULL);
FreeConsole(); // Remove window
}
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 9f8f17eb4ba..31cb829fd93 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -9239,32 +9239,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
KEY *cur_index_info= table->key_info;
KEY *cur_index_info_end= cur_index_info + table->s->keys;
- KEY_PART_INFO *cur_part= NULL;
- KEY_PART_INFO *end_part; /* Last part for loops. */
- /* Last index part. */
- KEY_PART_INFO *last_part= NULL;
- KEY_PART_INFO *first_non_group_part= NULL;
- KEY_PART_INFO *first_non_infix_part= NULL;
- uint key_infix_parts= 0;
- uint cur_group_key_parts= 0;
- uint cur_group_prefix_len= 0;
/* Cost-related variables for the best index so far. */
double best_read_cost= DBL_MAX;
ha_rows best_records= 0;
SEL_ARG *best_index_tree= NULL;
ha_rows best_quick_prefix_records= 0;
uint best_param_idx= 0;
- double cur_read_cost= DBL_MAX;
- ha_rows cur_records;
+
+ const uint pk= param->table->s->primary_key;
SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0;
uint cur_param_idx=MAX_KEY;
- key_map cur_used_key_parts;
- uint pk= param->table->s->primary_key;
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
cur_index_info++, cur_index++)
{
+ KEY_PART_INFO *cur_part;
+ KEY_PART_INFO *end_part; /* Last part for loops. */
+ /* Last index part. */
+ KEY_PART_INFO *last_part;
+ KEY_PART_INFO *first_non_group_part;
+ KEY_PART_INFO *first_non_infix_part;
+ uint key_infix_parts;
+ uint cur_group_key_parts= 0;
+ uint cur_group_prefix_len= 0;
+ double cur_read_cost;
+ ha_rows cur_records;
+ key_map used_key_parts_map;
+ uint cur_key_infix_len= 0;
+ uchar cur_key_infix[MAX_KEY_LENGTH];
+ uint cur_used_key_parts;
+
/* Check (B1) - if current index is covering. */
if (!table->covering_keys.is_set(cur_index))
goto next_index;
@@ -9334,7 +9339,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else if (join->select_distinct)
{
select_items_it.rewind();
- cur_used_key_parts.clear_all();
+ used_key_parts_map.clear_all();
uint max_key_part= 0;
while ((item= select_items_it++))
{
@@ -9345,13 +9350,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
Check if this attribute was already present in the select list.
If it was present, then its corresponding key part was alredy used.
*/
- if (cur_used_key_parts.is_set(key_part_nr))
+ if (used_key_parts_map.is_set(key_part_nr))
continue;
if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
goto next_index;
cur_part= cur_index_info->key_part + key_part_nr - 1;
cur_group_prefix_len+= cur_part->store_length;
- cur_used_key_parts.set_bit(key_part_nr);
+ used_key_parts_map.set_bit(key_part_nr);
++cur_group_key_parts;
max_key_part= max(max_key_part,key_part_nr);
}
@@ -9363,7 +9368,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
ulonglong all_parts, cur_parts;
all_parts= (1<<max_key_part) - 1;
- cur_parts= cur_used_key_parts.to_ulonglong() >> 1;
+ cur_parts= used_key_parts_map.to_ulonglong() >> 1;
if (all_parts != cur_parts)
goto next_index;
}
@@ -9413,7 +9418,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
&dummy);
if (!get_constant_key_infix(cur_index_info, index_range_tree,
first_non_group_part, min_max_arg_part,
- last_part, thd, key_infix, &key_infix_len,
+ last_part, thd, cur_key_infix,
+ &cur_key_infix_len,
&first_non_infix_part))
goto next_index;
}
@@ -9467,9 +9473,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
}
/* If we got to this point, cur_index_info passes the test. */
- key_infix_parts= key_infix_len ?
+ key_infix_parts= cur_key_infix_len ?
(first_non_infix_part - first_non_group_part) : 0;
- used_key_parts= cur_group_key_parts + key_infix_parts;
+ cur_used_key_parts= cur_group_key_parts + key_infix_parts;
/* Compute the cost of using this index. */
if (tree)
@@ -9481,7 +9487,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
cur_index_tree, TRUE);
}
- cost_group_min_max(table, cur_index_info, used_key_parts,
+ cost_group_min_max(table, cur_index_info, cur_used_key_parts,
cur_group_key_parts, tree, cur_index_tree,
cur_quick_prefix_records, have_min, have_max,
&cur_read_cost, &cur_records);
@@ -9492,7 +9498,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
{
- DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
index_info= cur_index_info;
index= cur_index;
best_read_cost= cur_read_cost;
@@ -9502,11 +9507,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
best_param_idx= cur_param_idx;
group_key_parts= cur_group_key_parts;
group_prefix_len= cur_group_prefix_len;
+ key_infix_len= cur_key_infix_len;
+ if (key_infix_len)
+ memcpy (key_infix, cur_key_infix, sizeof (key_infix));
+ used_key_parts= cur_used_key_parts;
}
- next_index:
- cur_group_key_parts= 0;
- cur_group_prefix_len= 0;
+ next_index:;
}
if (!index_info) /* No usable index found. */
DBUG_RETURN(NULL);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 6699196fbc7..16975c68a54 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -598,7 +598,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
field.length / item->collation.collation->mbminlen :
field.length / item->collation.collation->mbmaxlen;
max_length*= thd_charset->mbmaxlen;
- field_length= (max_length > UINT_MAX32) ? UINT_MAX32 : max_length;
+ field_length= (max_length > UINT_MAX32) ?
+ UINT_MAX32 : (uint32) max_length;
int4store(pos + 2, field_length);
}
pos[6]= field.type;
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index 7c74dcba5a0..14a80cbb4b6 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -297,21 +297,16 @@ unpack_row(Relay_log_info const *rli,
/**
Fills @c table->record[0] with default values.
- First @c empty_record() is called and then, additionally, fields are
- initialized explicitly with a call to @c set_default().
-
- For optimization reasons, the explicit initialization can be skipped for
- first @c skip fields. This is useful if later we are going to fill these
- fields from other source (e.g. from a Rows replication event).
-
- If @c check is true, fields are explicitly initialized only if they have
- default value or can be NULL. Otherwise error is reported.
+ First @c restore_record() is called to restore the default values for
+ record concerning the given table. Then, if @c check is true,
+ a check is performed to see if fields are have default value or can
+ be NULL. Otherwise error is reported.
@param table Table whose record[0] buffer is prepared.
- @param skip Number of columns for which default value initialization
+ @param skip Number of columns for which default/nullable check
should be skipped.
- @param check Indicates if errors should be checked when setting default
- values.
+ @param check Indicates if errors should be raised when checking
+ default/nullable field properties.
@returns 0 on success or a handler level error code
*/
@@ -321,25 +316,28 @@ int prepare_record(TABLE *const table,
DBUG_ENTER("prepare_record");
int error= 0;
- empty_record(table);
+ restore_record(table, s->default_values);
- if (skip >= table->s->fields) // nothing to do
+ /*
+ This skip should be revisited in 6.0, because in 6.0 RBR one
+ can have holes in the row (as the grain of the writeset is
+ the column and not the entire row).
+ */
+ if (skip >= table->s->fields || !check)
DBUG_RETURN(0);
- /* Explicit initialization of fields */
+ /* Checking if exists default/nullable fields in the default values. */
for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
{
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
- if (check && ((f->flags & mask) == mask))
+ if (((f->flags & mask) == mask))
{
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
error = HA_ERR_ROWS_EVENT_APPLY;
}
- else
- f->set_default();
}
DBUG_RETURN(error);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 6c2ac2e32a9..d6a9cbb19ee 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -110,6 +110,7 @@ static void sys_default_init_connect(THD*, enum_var_type type);
static bool sys_update_init_slave(THD*, set_var*);
static void sys_default_init_slave(THD*, enum_var_type type);
static bool set_option_bit(THD *thd, set_var *var);
+static bool set_option_log_bin_bit(THD *thd, set_var *var);
static bool set_option_autocommit(THD *thd, set_var *var);
static int check_log_update(THD *thd, set_var *var);
static bool set_log_update(THD *thd, set_var *var);
@@ -729,7 +730,7 @@ static sys_var_thd_bit sys_log_update(&vars, "sql_log_update",
OPTION_BIN_LOG);
static sys_var_thd_bit sys_log_binlog(&vars, "sql_log_bin",
check_log_update,
- set_option_bit,
+ set_option_log_bin_bit,
OPTION_BIN_LOG);
static sys_var_thd_bit sys_sql_warnings(&vars, "sql_warnings", 0,
set_option_bit,
@@ -3033,6 +3034,16 @@ static bool set_option_bit(THD *thd, set_var *var)
return 0;
}
+/*
+ Functions to be only used to update thd->options OPTION_BIN_LOG bit
+*/
+static bool set_option_log_bin_bit(THD *thd, set_var *var)
+{
+ set_option_bit(thd, var);
+ if (!thd->in_sub_stmt)
+ thd->sql_log_bin_toplevel= thd->options & OPTION_BIN_LOG;
+ return 0;
+}
static bool set_option_autocommit(THD *thd, set_var *var)
{
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 5dc75c340ea..aa1521acab6 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6154,3 +6154,26 @@ WARN_PLUGIN_BUSY
ER_VARIABLE_IS_READONLY
eng "%s variable '%s' is read-only. Use SET %s to assign the value"
+
+ER_WARN_ENGINE_TRANSACTION_ROLLBACK
+ eng "Storage engine %s does not support rollback for this statement. Transaction rolled back and must be restarted"
+
+ER_SLAVE_HEARTBEAT_FAILURE
+ eng "Unexpected master's heartbeat data: %s"
+ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
+ eng "The requested value for the heartbeat period %s %s"
+
+ER_NDB_REPLICATION_SCHEMA_ERROR
+ eng "Bad schema for mysql.ndb_replication table. Message: %-.64s"
+ER_CONFLICT_FN_PARSE_ERROR
+ eng "Error in parsing conflict function. Message: %-.64s"
+ER_EXCEPTIONS_WRITE_ERROR
+ eng "Write to exceptions table failed. Message: %-.128s""
+
+ER_TOO_LONG_TABLE_COMMENT
+ eng "Comment for table '%-.64s' is too long (max = %lu)"
+ por "Comentário para a tabela '%-.64s' é longo demais (max = %lu)"
+
+ER_TOO_LONG_FIELD_COMMENT
+ eng "Comment for field '%-.64s' is too long (max = %lu)"
+ por "Comentário para o campo '%-.64s' é longo demais (max = %lu)"
diff --git a/sql/sp.cc b/sql/sp.cc
index cc545992857..b2c7c389136 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -936,10 +936,12 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
ret= SP_INTERNAL_ERROR;
goto done;
}
-
+ /* restore sql_mode when binloging */
+ thd->variables.sql_mode= saved_mode;
/* Such a statement can always go directly to binlog, no trans cache */
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
log_query.c_ptr(), log_query.length(), FALSE, FALSE);
+ thd->variables.sql_mode= 0;
}
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 4a5b75c4f78..25907d4ec20 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -418,6 +418,43 @@ TYPELIB query_cache_type_typelib=
array_elements(query_cache_type_names)-1,"", query_cache_type_names, NULL
};
+
+/**
+ Helper function for determine if a SELECT statement has a SQL_NO_CACHE
+ directive.
+
+ @param sql A pointer to the first white space character after SELECT
+
+ @return
+ @retval TRUE The character string contains SQL_NO_CACHE
+ @retval FALSE No directive found.
+*/
+
+static bool has_no_cache_directive(char *sql)
+{
+ int i=0;
+ while (sql[i] == ' ')
+ ++i;
+
+ if (my_toupper(system_charset_info, sql[i]) == 'S' &&
+ my_toupper(system_charset_info, sql[i+1]) == 'Q' &&
+ my_toupper(system_charset_info, sql[i+2]) == 'L' &&
+ my_toupper(system_charset_info, sql[i+3]) == '_' &&
+ my_toupper(system_charset_info, sql[i+4]) == 'N' &&
+ my_toupper(system_charset_info, sql[i+5]) == 'O' &&
+ my_toupper(system_charset_info, sql[i+6]) == '_' &&
+ my_toupper(system_charset_info, sql[i+7]) == 'C' &&
+ my_toupper(system_charset_info, sql[i+8]) == 'A' &&
+ my_toupper(system_charset_info, sql[i+9]) == 'C' &&
+ my_toupper(system_charset_info, sql[i+10]) == 'H' &&
+ my_toupper(system_charset_info, sql[i+11]) == 'E' &&
+ my_toupper(system_charset_info, sql[i+12]) == ' ')
+ return TRUE;
+
+ return FALSE;
+}
+
+
/*****************************************************************************
Query_cache_block_table method(s)
*****************************************************************************/
@@ -1233,6 +1270,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
goto err;
}
+
+ if (query_length > 20 && has_no_cache_directive(&sql[i+6]))
+ {
+ /*
+ We do not increase 'refused' statistics here since it will be done
+ later when the query is parsed.
+ */
+ DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
+ goto err;
+ }
}
STRUCT_LOCK(&structure_guard_mutex);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 597478933d6..cd00d0e20f1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -538,6 +538,7 @@ THD::THD()
Open_tables_state(refresh_version), rli_fake(0),
lock_id(&main_lock_id),
user_time(0), in_sub_stmt(0),
+ sql_log_bin_toplevel(false),
binlog_table_maps(0), binlog_flags(0UL),
table_map_for_update(0),
arg_of_last_insert_id_function(FALSE),
@@ -787,6 +788,7 @@ void THD::init(void)
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
+ sql_log_bin_toplevel= options & OPTION_BIN_LOG;
}
@@ -3662,7 +3664,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
If we are in statement mode and trying to log an unsafe statement,
we should print a warning.
*/
- if (lex->is_stmt_unsafe() &&
+ if (sql_log_bin_toplevel && lex->is_stmt_unsafe() &&
variables.binlog_format == BINLOG_FORMAT_STMT)
{
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3439e5b4f74..0a33d2767f5 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1350,6 +1350,8 @@ public:
/* <> 0 if we are inside of trigger or stored function. */
uint in_sub_stmt;
+ /* TRUE when the current top has SQL_LOG_BIN ON */
+ bool sql_log_bin_toplevel;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 9619d26893c..19a19f2b6fb 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1559,6 +1559,7 @@ void st_select_lex::init_query()
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0;
link_next= 0;
+ lock_option= TL_READ_DEFAULT;
}
void st_select_lex::init_select()
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ed6b9e7d8df..a48b99d07c7 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -688,6 +688,15 @@ public:
int cur_pos_in_select_list;
List<udf_func> udf_list; /* udf function calls stack */
+
+ /**
+ Per sub-query locking strategy.
+ Note: This variable might interfer with the corresponding statement-level
+ variable Lex::lock_option because on how different parser rules depend
+ on eachother.
+ */
+ thr_lock_type lock_option;
+
/*
This is a copy of the original JOIN USING list that comes from
the parser. The parser :
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f7d6d5bac4d..f7e895d150f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5580,6 +5580,14 @@ void mysql_reset_thd_for_next_command(THD *thd)
}
+/**
+ Resets the lex->current_select object.
+ @note It is assumed that lex->current_select != NULL
+
+ This function is a wrapper around select_lex->init_select() with an added
+ check for the special situation when using INTO OUTFILE and LOAD DATA.
+*/
+
void
mysql_init_select(LEX *lex)
{
@@ -5594,6 +5602,18 @@ mysql_init_select(LEX *lex)
}
+/**
+ Used to allocate a new SELECT_LEX object on the current thd mem_root and
+ link it into the relevant lists.
+
+ This function is always followed by mysql_init_select.
+
+ @see mysql_init_select
+
+ @retval TRUE An error occurred
+ @retval FALSE The new SELECT_LEX was successfully allocated.
+*/
+
bool
mysql_new_select(LEX *lex, bool move_down)
{
@@ -6411,7 +6431,6 @@ 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;
tables;
tables= tables->next_local)
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 942b131b301..3d702833620 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3796,8 +3796,19 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
cs);
table->field[4]->store((longlong) count, TRUE);
field->sql_type(type);
- table->field[14]->store(type.ptr(), type.length(), cs);
+ table->field[14]->store(type.ptr(), type.length(), cs);
+ /*
+ MySQL column type has the following format:
+ base_type [(dimension)] [unsigned] [zerofill].
+ For DATA_TYPE column we extract only base type.
+ */
tmp_buff= strchr(type.ptr(), '(');
+ if (!tmp_buff)
+ /*
+ if there is no dimention part then check the presence of
+ [unsigned] [zerofill] attributes and cut them of if exist.
+ */
+ tmp_buff= strchr(type.ptr(), ' ');
table->field[7]->store(type.ptr(),
(tmp_buff ? tmp_buff - type.ptr() :
type.length()), cs);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 12e9357f533..60714348d03 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4297,7 +4297,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
- result_code= HA_ADMIN_CORRUPT;
+ if (thd->main_da.is_error() &&
+ (thd->main_da.sql_errno() == ER_NO_SUCH_TABLE ||
+ thd->main_da.sql_errno() == ER_FILE_NOT_FOUND))
+ /* A missing table is just issued as a failed command */
+ result_code= HA_ADMIN_FAILED;
+ else
+ /* Default failure code is corrupt table */
+ result_code= HA_ADMIN_CORRUPT;
goto send_result;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 371a146696d..e56ff7c6ad7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6489,7 +6489,8 @@ select_option:
{
if (check_simple_select())
MYSQL_YYABORT;
- Lex->lock_option= TL_READ_HIGH_PRIORITY;
+ Lex->lock_option= TL_READ_HIGH_PRIORITY;
+ Lex->current_select->lock_option= TL_READ_HIGH_PRIORITY;
}
| DISTINCT { Select->options|= SELECT_DISTINCT; }
| SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
@@ -6535,6 +6536,7 @@ select_lock_type:
{
LEX *lex=Lex;
lex->current_select->set_lock_for_tables(TL_WRITE);
+ lex->current_select->lock_option= TL_WRITE;
lex->safe_to_cache_query=0;
}
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
@@ -6542,6 +6544,7 @@ select_lock_type:
LEX *lex=Lex;
lex->current_select->
set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
+ lex->current_select->lock_option= TL_READ_WITH_SHARED_LOCKS;
lex->safe_to_cache_query=0;
}
;
@@ -12909,6 +12912,18 @@ subselect_start:
subselect_end:
{
LEX *lex=Lex;
+ /*
+ Set the required lock level for the tables associated with the
+ current sub-select. This will overwrite previous lock options set
+ using st_select_lex::add_table_to_list in any of the following
+ rules: single_multi, table_wild_one, load_data, table_alias_ref,
+ table_factor.
+ The default lock level is TL_READ_DEFAULT but it can be modified
+ with query options specific for a certain (sub-)SELECT.
+ */
+ lex->current_select->
+ set_lock_for_tables(lex->current_select->lock_option);
+
lex->pop_context();
SELECT_LEX *child= lex->current_select;
lex->current_select = lex->current_select->return_after_parsing();
diff --git a/sql/unireg.cc b/sql/unireg.cc
index da018ebec3d..51293184ad8 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -229,16 +229,16 @@ bool mysql_create_frm(THD *thd, const char *file_name,
create_info->comment.length, 60);
if (tmp_len < create_info->comment.length)
{
- (void) my_snprintf(buff, sizeof(buff), "Too long comment for table '%s'",
- table);
if ((thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
{
- my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), table, tmp_len);
goto err;
}
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ ER_TOO_LONG_TABLE_COMMENT,
+ ER(ER_TOO_LONG_TABLE_COMMENT),
+ table, tmp_len);
create_info->comment.length= tmp_len;
}
@@ -613,17 +613,16 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type,
255);
if (tmp_len < field->comment.length)
{
- char buff[128];
- (void) my_snprintf(buff,sizeof(buff), "Too long comment for field '%s'",
- field->field_name);
if ((current_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
{
- my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, tmp_len);
DBUG_RETURN(1);
}
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ ER_TOO_LONG_FIELD_COMMENT,
+ ER(ER_TOO_LONG_FIELD_COMMENT),
+ field->field_name, tmp_len);
field->comment.length= tmp_len;
}