mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Manual merge 5.0->5.1
This commit is contained in:
@ -4100,7 +4100,43 @@ unsent_create_error:
|
||||
thd->variables.select_limit= HA_POS_ERROR;
|
||||
|
||||
thd->row_count_func= 0;
|
||||
tmp_disable_binlog(thd); /* don't binlog the substatements */
|
||||
res= sp->execute_procedure(thd, &lex->value_list);
|
||||
reenable_binlog(thd);
|
||||
|
||||
/*
|
||||
We write CALL to binlog; on the opposite we didn't write the
|
||||
substatements. That choice is necessary because the substatements
|
||||
may use local vars.
|
||||
Binlogging should happen when all tables are locked. They are locked
|
||||
just above, and unlocked by close_thread_tables(). All tables which
|
||||
are to be updated are locked like with a table-level write lock, and
|
||||
this also applies to InnoDB (I tested - note that it reduces
|
||||
InnoDB's concurrency as we don't use row-level locks). So binlogging
|
||||
below is safe.
|
||||
Note the limitation: if the SP returned an error, but still did some
|
||||
updates, we do NOT binlog it. This is because otherwise "permission
|
||||
denied", "table does not exist" etc would stop the slave quite
|
||||
often. There is no easy way to know if the SP updated something
|
||||
(even no_trans_update is not suitable, as it may be a transactional
|
||||
autocommit update which happened, and no_trans_update covers only
|
||||
INSERT/UPDATE/LOAD).
|
||||
*/
|
||||
if (mysql_bin_log.is_open() &&
|
||||
(sp->m_chistics->daccess == SP_CONTAINS_SQL ||
|
||||
sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
|
||||
{
|
||||
if (res)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||
else
|
||||
{
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If warnings have been cleared, we have to clear total_warn_count
|
||||
@ -4156,14 +4192,32 @@ unsent_create_error:
|
||||
sp->m_name.str, 0))
|
||||
goto error;
|
||||
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
|
||||
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
||||
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
|
||||
else
|
||||
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
|
||||
if (!trust_routine_creators && mysql_bin_log.is_open() &&
|
||||
!sp->m_chistics->detistic &&
|
||||
(chistics.daccess == SP_CONTAINS_SQL ||
|
||||
chistics.daccess == SP_MODIFIES_SQL_DATA))
|
||||
{
|
||||
my_message(ER_BINLOG_UNSAFE_ROUTINE,
|
||||
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
|
||||
result= SP_INTERNAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
||||
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
|
||||
else
|
||||
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
|
||||
}
|
||||
}
|
||||
switch (result)
|
||||
{
|
||||
case SP_OK:
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SP_KEY_NOT_FOUND:
|
||||
@ -4240,6 +4294,12 @@ unsent_create_error:
|
||||
switch (result)
|
||||
{
|
||||
case SP_OK:
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SP_KEY_NOT_FOUND:
|
||||
@ -4498,6 +4558,7 @@ unsent_create_error:
|
||||
break;
|
||||
}
|
||||
thd->proc_info="query end";
|
||||
/* Two binlog-related cleanups: */
|
||||
if (thd->one_shot_set)
|
||||
{
|
||||
/*
|
||||
@ -5413,9 +5474,14 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
|
||||
}
|
||||
new_field->pack_length=
|
||||
my_decimal_get_binary_size(new_field->length, new_field->decimals);
|
||||
if (new_field->length <= DECIMAL_MAX_LENGTH &&
|
||||
if (new_field->length <= DECIMAL_MAX_PRECISION &&
|
||||
new_field->length >= new_field->decimals)
|
||||
{
|
||||
new_field->length=
|
||||
my_decimal_precision_to_length(new_field->length, new_field->decimals,
|
||||
type_modifier & UNSIGNED_FLAG);
|
||||
break;
|
||||
}
|
||||
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
|
||||
DBUG_RETURN(NULL);
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
|
Reference in New Issue
Block a user