mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Manual merge from mysql-trunk.
Conflicts: - client/mysqltest.cc - mysql-test/collections/default.experimental - mysql-test/suite/rpl/t/disabled.def - sql/mysqld.cc - sql/opt_range.cc - sql/sp.cc - sql/sql_acl.cc - sql/sql_partition.cc - sql/sql_table.cc
This commit is contained in:
@ -107,8 +107,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view);
|
||||
1 Error
|
||||
*/
|
||||
|
||||
bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
|
||||
table_map *map)
|
||||
bool check_view_single_update(List<Item> &fields, List<Item> *values,
|
||||
TABLE_LIST *view, table_map *map)
|
||||
{
|
||||
/* it is join view => we need to find the table for update */
|
||||
List_iterator_fast<Item> it(fields);
|
||||
@ -119,6 +119,17 @@ bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
|
||||
while ((item= it++))
|
||||
tables|= item->used_tables();
|
||||
|
||||
if (values)
|
||||
{
|
||||
it.init(*values);
|
||||
while ((item= it++))
|
||||
tables|= item->used_tables();
|
||||
}
|
||||
|
||||
/* Convert to real table bits */
|
||||
tables&= ~PSEUDO_TABLE_BITS;
|
||||
|
||||
|
||||
/* Check found map against provided map */
|
||||
if (*map)
|
||||
{
|
||||
@ -165,7 +176,9 @@ error:
|
||||
|
||||
static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||
List<Item> &fields, List<Item> &values,
|
||||
bool check_unique, table_map *map)
|
||||
bool check_unique,
|
||||
bool fields_and_values_from_different_maps,
|
||||
table_map *map)
|
||||
{
|
||||
TABLE *table= table_list->table;
|
||||
|
||||
@ -238,7 +251,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
|
||||
{
|
||||
if (check_view_single_update(fields, table_list, map))
|
||||
if (check_view_single_update(fields,
|
||||
fields_and_values_from_different_maps ?
|
||||
(List<Item>*) 0 : &values,
|
||||
table_list, map))
|
||||
return -1;
|
||||
table= table_list->table;
|
||||
}
|
||||
@ -298,7 +314,8 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||
*/
|
||||
|
||||
static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
||||
List<Item> &update_fields, table_map *map)
|
||||
List<Item> &update_fields,
|
||||
List<Item> &update_values, table_map *map)
|
||||
{
|
||||
TABLE *table= insert_table_list->table;
|
||||
my_bool timestamp_mark= 0;
|
||||
@ -318,7 +335,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
||||
return -1;
|
||||
|
||||
if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE &&
|
||||
check_view_single_update(update_fields, insert_table_list, map))
|
||||
check_view_single_update(update_fields, &update_values,
|
||||
insert_table_list, map))
|
||||
return -1;
|
||||
|
||||
if (table->timestamp_field)
|
||||
@ -826,7 +844,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
error=write_record(thd, table ,&info);
|
||||
if (error)
|
||||
break;
|
||||
thd->row_count++;
|
||||
thd->warning_info->inc_current_row_for_warning();
|
||||
}
|
||||
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
@ -965,10 +983,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
if (ignore)
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
|
||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||
(ulong) (info.records - info.copied),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
else
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.deleted + updated), (ulong) thd->cuted_fields);
|
||||
(ulong) (info.deleted + updated),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
thd->row_count_func= info.copied + info.deleted + updated;
|
||||
::my_ok(thd, (ulong) thd->row_count_func, id, buff);
|
||||
}
|
||||
@ -1256,9 +1276,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||
table_list->next_local= 0;
|
||||
context->resolve_in_table_list_only(table_list);
|
||||
|
||||
res= check_insert_fields(thd, context->table_list, fields, *values,
|
||||
!insert_into_view, &map) ||
|
||||
setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
|
||||
res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) ||
|
||||
check_insert_fields(thd, context->table_list, fields, *values,
|
||||
!insert_into_view, 0, &map));
|
||||
|
||||
if (!res && check_fields)
|
||||
{
|
||||
@ -1271,18 +1291,19 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||
thd->abort_on_warning= saved_abort_on_warning;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
|
||||
|
||||
if (!res && duplic == DUP_UPDATE)
|
||||
{
|
||||
select_lex->no_wrap_view_item= TRUE;
|
||||
res= check_update_fields(thd, context->table_list, update_fields, &map);
|
||||
res= check_update_fields(thd, context->table_list, update_fields,
|
||||
update_values, &map);
|
||||
select_lex->no_wrap_view_item= FALSE;
|
||||
}
|
||||
|
||||
/* Restore the current context. */
|
||||
ctx_state.restore_state(context, table_list);
|
||||
|
||||
if (!res)
|
||||
res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
|
||||
}
|
||||
|
||||
if (res)
|
||||
@ -1971,7 +1992,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
||||
main thread. Use of my_message will enable stored
|
||||
procedures continue handlers.
|
||||
*/
|
||||
my_message(di->thd.main_da.sql_errno(), di->thd.main_da.message(),
|
||||
my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(),
|
||||
MYF(0));
|
||||
}
|
||||
di->unlock();
|
||||
@ -2048,7 +2069,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
||||
goto error;
|
||||
if (dead)
|
||||
{
|
||||
my_message(thd.main_da.sql_errno(), thd.main_da.message(), MYF(0));
|
||||
my_message(thd.stmt_da->sql_errno(), thd.stmt_da->message(), MYF(0));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -2297,8 +2318,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
|
||||
if (init_thr_lock() || thd->store_globals())
|
||||
{
|
||||
/* Can't use my_error since store_globals has perhaps failed */
|
||||
thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES));
|
||||
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES), NULL);
|
||||
thd->fatal_error();
|
||||
goto err;
|
||||
}
|
||||
@ -2512,21 +2533,16 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
||||
since it does not find one in the list.
|
||||
*/
|
||||
pthread_mutex_lock(&di->mutex);
|
||||
#if !defined( __WIN__) /* Win32 calls this in pthread_create */
|
||||
if (my_thread_init())
|
||||
{
|
||||
/* Can't use my_error since store_globals has not yet been called */
|
||||
thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES));
|
||||
thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES), NULL);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
handle_delayed_insert_impl(thd, di);
|
||||
|
||||
#ifndef __WIN__
|
||||
end:
|
||||
#endif
|
||||
/*
|
||||
di should be unlinked from the thread handler list and have no active
|
||||
clients
|
||||
@ -2748,6 +2764,12 @@ bool Delayed_insert::handle_inserts(void)
|
||||
thread_safe_increment(delayed_insert_writes,&LOCK_delayed_status);
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
/*
|
||||
Reset the table->auto_increment_field_not_null as it is valid for
|
||||
only one row.
|
||||
*/
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
|
||||
delete row;
|
||||
/*
|
||||
Let READ clients do something once in a while
|
||||
@ -2769,7 +2791,7 @@ bool Delayed_insert::handle_inserts(void)
|
||||
{
|
||||
/* This should never happen */
|
||||
table->file->print_error(error,MYF(0));
|
||||
sql_print_error("%s", thd.main_da.message());
|
||||
sql_print_error("%s", thd.stmt_da->message());
|
||||
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
|
||||
goto err;
|
||||
}
|
||||
@ -2811,7 +2833,7 @@ bool Delayed_insert::handle_inserts(void)
|
||||
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
|
||||
{ // This shouldn't happen
|
||||
table->file->print_error(error,MYF(0));
|
||||
sql_print_error("%s", thd.main_da.message());
|
||||
sql_print_error("%s", thd.stmt_da->message());
|
||||
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
|
||||
goto err;
|
||||
}
|
||||
@ -2950,9 +2972,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
we are fixing fields from insert list.
|
||||
*/
|
||||
lex->current_select= &lex->select_lex;
|
||||
res= check_insert_fields(thd, table_list, *fields, values,
|
||||
!insert_into_view, &map) ||
|
||||
setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0);
|
||||
res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) ||
|
||||
check_insert_fields(thd, table_list, *fields, values,
|
||||
!insert_into_view, 1, &map));
|
||||
|
||||
if (!res && fields->elements)
|
||||
{
|
||||
@ -2979,7 +3001,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
|
||||
lex->select_lex.no_wrap_view_item= TRUE;
|
||||
res= res || check_update_fields(thd, context->table_list,
|
||||
*info.update_fields, &map);
|
||||
*info.update_fields, *info.update_values,
|
||||
&map);
|
||||
lex->select_lex.no_wrap_view_item= FALSE;
|
||||
/*
|
||||
When we are not using GROUP BY and there are no ungrouped aggregate functions
|
||||
@ -3279,10 +3302,12 @@ bool select_insert::send_eof()
|
||||
char buff[160];
|
||||
if (info.ignore)
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||
(ulong) (info.records - info.copied),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
else
|
||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||
(ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
|
||||
(ulong) (info.deleted+info.updated),
|
||||
(ulong) thd->warning_info->statement_warn_count());
|
||||
thd->row_count_func= info.copied + info.deleted +
|
||||
((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
|
||||
info.touched : info.updated);
|
||||
@ -3855,6 +3880,7 @@ void select_create::abort()
|
||||
{
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
if (!create_info->table_existed)
|
||||
drop_open_table(thd, table, create_table->db, create_table->table_name);
|
||||
table=0; // Safety
|
||||
|
Reference in New Issue
Block a user