mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge to mysql-next-mr
This commit is contained in:
134
sql/sql_table.cc
134
sql/sql_table.cc
@ -72,7 +72,7 @@ static void wait_for_kill_signal(THD *thd)
|
||||
@brief Helper function for explain_filename
|
||||
*/
|
||||
static char* add_identifier(char *to_p, const char * end_p,
|
||||
const char* name, uint name_len, int errcode)
|
||||
const char* name, uint name_len, bool add_quotes)
|
||||
{
|
||||
uint res;
|
||||
uint errors;
|
||||
@ -92,18 +92,44 @@ static char* add_identifier(char *to_p, const char * end_p,
|
||||
res= strconvert(&my_charset_filename, conv_name, system_charset_info,
|
||||
conv_string, FN_REFLEN, &errors);
|
||||
if (!res || errors)
|
||||
{
|
||||
DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors));
|
||||
conv_name= name;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string));
|
||||
conv_name= conv_string;
|
||||
}
|
||||
|
||||
if (errcode)
|
||||
to_p+= my_snprintf(to_p, end_p - to_p, ER(errcode), conv_name);
|
||||
if (add_quotes && (end_p - to_p > 2))
|
||||
{
|
||||
*(to_p++)= '`';
|
||||
while (*conv_name && (end_p - to_p - 1) > 0)
|
||||
{
|
||||
uint length= my_mbcharlen(system_charset_info, *conv_name);
|
||||
if (!length)
|
||||
length= 1;
|
||||
if (length == 1 && *conv_name == '`')
|
||||
{
|
||||
if ((end_p - to_p) < 3)
|
||||
break;
|
||||
*(to_p++)= '`';
|
||||
*(to_p++)= *(conv_name++);
|
||||
}
|
||||
else if (((long) length) < (end_p - to_p))
|
||||
{
|
||||
to_p= strnmov(to_p, conv_name, length);
|
||||
conv_name+= length;
|
||||
}
|
||||
else
|
||||
break; /* string already filled */
|
||||
}
|
||||
to_p= strnmov(to_p, "`", end_p - to_p);
|
||||
}
|
||||
else
|
||||
to_p+= my_snprintf(to_p, end_p - to_p, "`%s`", conv_name);
|
||||
return to_p;
|
||||
to_p= strnmov(to_p, conv_name, end_p - to_p);
|
||||
DBUG_RETURN(to_p);
|
||||
}
|
||||
|
||||
|
||||
@ -135,6 +161,8 @@ static char* add_identifier(char *to_p, const char * end_p,
|
||||
[,[ Temporary| Renamed] Partition `p`
|
||||
[, Subpartition `sp`]] *|
|
||||
(| is really a /, and it is all in one line)
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING ->
|
||||
same as above but no quotes are added.
|
||||
|
||||
@retval Length of returned string
|
||||
*/
|
||||
@ -245,28 +273,39 @@ uint explain_filename(const char *from,
|
||||
part_name_len-= 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
table_name_len= strlen(table_name);
|
||||
if (db_name)
|
||||
{
|
||||
if (explain_mode == EXPLAIN_ALL_VERBOSE)
|
||||
{
|
||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len,
|
||||
ER_DATABASE_NAME);
|
||||
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len, 1);
|
||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len, 0);
|
||||
to_p= add_identifier(to_p, end_p, db_name, db_name_len,
|
||||
(explain_mode !=
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
||||
to_p= strnmov(to_p, ".", end_p - to_p);
|
||||
}
|
||||
}
|
||||
if (explain_mode == EXPLAIN_ALL_VERBOSE)
|
||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len,
|
||||
ER_TABLE_NAME);
|
||||
{
|
||||
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len, 1);
|
||||
}
|
||||
else
|
||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len, 0);
|
||||
to_p= add_identifier(to_p, end_p, table_name, table_name_len,
|
||||
(explain_mode !=
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
||||
if (part_name)
|
||||
{
|
||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
|
||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
|
||||
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
|
||||
to_p= strnmov(to_p, " /* ", end_p - to_p);
|
||||
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
|
||||
to_p= strnmov(to_p, " ", end_p - to_p);
|
||||
@ -280,15 +319,22 @@ uint explain_filename(const char *from,
|
||||
to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, " ", end_p - to_p);
|
||||
}
|
||||
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(to_p, end_p, part_name, part_name_len,
|
||||
ER_PARTITION_NAME);
|
||||
(explain_mode !=
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
||||
if (subpart_name)
|
||||
{
|
||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len,
|
||||
ER_SUBPARTITION_NAME);
|
||||
(explain_mode !=
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
|
||||
}
|
||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
|
||||
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
|
||||
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
|
||||
to_p= strnmov(to_p, " */", end_p - to_p);
|
||||
}
|
||||
DBUG_PRINT("exit", ("to '%s'", to));
|
||||
@ -1726,6 +1772,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
|
||||
my_bool drop_temporary)
|
||||
{
|
||||
bool error= FALSE, need_start_waiters= FALSE;
|
||||
Drop_table_error_handler err_handler(thd->get_internal_handler());
|
||||
DBUG_ENTER("mysql_rm_table");
|
||||
|
||||
/* mark for close and remove all cached entries */
|
||||
@ -1746,7 +1793,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
|
||||
LOCK_open during wait_if_global_read_lock(), other threads could not
|
||||
close their tables. This would make a pretty deadlock.
|
||||
*/
|
||||
thd->push_internal_handler(&err_handler);
|
||||
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
|
||||
thd->pop_internal_handler();
|
||||
|
||||
|
||||
if (need_start_waiters)
|
||||
start_waiting_global_read_lock(thd);
|
||||
@ -1848,9 +1898,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Don't give warnings for not found errors, as we already generate notes */
|
||||
thd->no_warnings_for_error= 1;
|
||||
|
||||
for (table= tables; table; table= table->next_local)
|
||||
{
|
||||
char *db=table->db;
|
||||
@ -2099,7 +2146,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
err_with_placeholders:
|
||||
unlock_table_names(thd, tables, (TABLE_LIST*) 0);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
thd->no_warnings_for_error= 0;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -4593,17 +4639,17 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
if (!table->table)
|
||||
{
|
||||
DBUG_PRINT("admin", ("open table failed"));
|
||||
if (!thd->warn_list.elements)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
if (thd->warning_info->is_empty())
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
|
||||
/* if it was a view will check md5 sum */
|
||||
if (table->view &&
|
||||
view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
|
||||
if (thd->main_da.is_error() &&
|
||||
(thd->main_da.sql_errno() == ER_NO_SUCH_TABLE ||
|
||||
thd->main_da.sql_errno() == ER_FILE_NOT_FOUND))
|
||||
if (thd->stmt_da->is_error() &&
|
||||
(thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE ||
|
||||
thd->stmt_da->sql_errno() == ER_FILE_NOT_FOUND))
|
||||
/* A missing table is just issued as a failed command */
|
||||
result_code= HA_ADMIN_FAILED;
|
||||
else
|
||||
@ -4645,7 +4691,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
thd->main_da.reset_diagnostics_area();
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
continue;
|
||||
/* purecov: end */
|
||||
}
|
||||
@ -4705,8 +4751,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
we will store the error message in a result set row
|
||||
and then clear.
|
||||
*/
|
||||
if (thd->main_da.is_ok())
|
||||
thd->main_da.reset_diagnostics_area();
|
||||
if (thd->stmt_da->is_ok())
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
goto send_result;
|
||||
}
|
||||
}
|
||||
@ -4720,21 +4766,21 @@ send_result:
|
||||
lex->cleanup_after_one_table_open();
|
||||
thd->clear_error(); // these errors shouldn't get client
|
||||
{
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
|
||||
MYSQL_ERROR *err;
|
||||
while ((err= it++))
|
||||
{
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(table_name, system_charset_info);
|
||||
protocol->store((char*) operator_name, system_charset_info);
|
||||
protocol->store(warning_level_names[err->level].str,
|
||||
warning_level_names[err->level].length,
|
||||
protocol->store(warning_level_names[err->get_level()].str,
|
||||
warning_level_names[err->get_level()].length,
|
||||
system_charset_info);
|
||||
protocol->store(err->msg, system_charset_info);
|
||||
protocol->store(err->get_message_text(), system_charset_info);
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
}
|
||||
mysql_reset_errors(thd, true);
|
||||
thd->warning_info->clear_warning_info(thd->query_id);
|
||||
}
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(table_name, system_charset_info);
|
||||
@ -4829,8 +4875,8 @@ send_result_message:
|
||||
we will store the error message in a result set row
|
||||
and then clear.
|
||||
*/
|
||||
if (thd->main_da.is_ok())
|
||||
thd->main_da.reset_diagnostics_area();
|
||||
if (thd->stmt_da->is_ok())
|
||||
thd->stmt_da->reset_diagnostics_area();
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
if (!result_code) // recreation went ok
|
||||
@ -4848,7 +4894,7 @@ send_result_message:
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
if (thd->is_error())
|
||||
{
|
||||
const char *err_msg= thd->main_da.message();
|
||||
const char *err_msg= thd->stmt_da->message();
|
||||
if (!thd->vio_ok())
|
||||
{
|
||||
sql_print_error("%s", err_msg);
|
||||
@ -5172,6 +5218,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
char tmp_path[FN_REFLEN];
|
||||
#endif
|
||||
char ts_name[FN_LEN + 1];
|
||||
myf flags= MY_DONT_OVERWRITE_FILE;
|
||||
DBUG_ENTER("mysql_create_like_table");
|
||||
|
||||
|
||||
@ -5228,8 +5275,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
|
||||
DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
|
||||
|
||||
if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
|
||||
flags|= MY_SYNC;
|
||||
|
||||
/*
|
||||
Create a new table by copying from source table
|
||||
and sync the new table if the flag MY_SYNC is set
|
||||
|
||||
Altough exclusive name-lock on target table protects us from concurrent
|
||||
DML and DDL operations on it we still want to wrap .FRM creation and call
|
||||
@ -5250,7 +5301,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
|
||||
else if (my_copy(src_path, dst_path, flags))
|
||||
{
|
||||
if (my_errno == ENOENT)
|
||||
my_error(ER_BAD_DB_ERROR,MYF(0),db);
|
||||
@ -7443,7 +7494,8 @@ err:
|
||||
the table to be altered isn't empty.
|
||||
Report error here.
|
||||
*/
|
||||
if (alter_info->error_if_not_empty && thd->row_count)
|
||||
if (alter_info->error_if_not_empty &&
|
||||
thd->warning_info->current_row_for_warning())
|
||||
{
|
||||
const char *f_val= 0;
|
||||
enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
|
||||
@ -7464,7 +7516,7 @@ err:
|
||||
}
|
||||
bool save_abort_on_warning= thd->abort_on_warning;
|
||||
thd->abort_on_warning= TRUE;
|
||||
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
f_val, strlength(f_val), t_type,
|
||||
alter_info->datetime_field->field_name);
|
||||
thd->abort_on_warning= save_abort_on_warning;
|
||||
@ -7611,7 +7663,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
|
||||
if (ignore)
|
||||
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
thd->row_count= 0;
|
||||
thd->warning_info->reset_current_row_for_warning();
|
||||
restore_record(to, s->default_values); // Create empty record
|
||||
while (!(error=info.read_record(&info)))
|
||||
{
|
||||
@ -7621,7 +7673,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
thd->row_count++;
|
||||
/* Return error if source table isn't empty. */
|
||||
if (error_if_not_empty)
|
||||
{
|
||||
@ -7671,6 +7722,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
}
|
||||
else
|
||||
found_count++;
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
}
|
||||
end_read_record(&info);
|
||||
free_io_cache(from);
|
||||
|
Reference in New Issue
Block a user