mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge with 4.1
This commit is contained in:
@ -327,7 +327,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->used_tables=0;
|
||||
values= its++;
|
||||
|
||||
if (mysql_prepare_insert(thd, table_list, table, fields, values,
|
||||
if (mysql_prepare_insert(thd, table_list, table_list, table, fields, values,
|
||||
update_fields, update_values, duplic, &unused_conds,
|
||||
FALSE))
|
||||
goto abort;
|
||||
@ -734,28 +734,43 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
||||
mysql_prepare_insert()
|
||||
thd Thread handler
|
||||
table_list Global/local table list
|
||||
table Table to insert into (can be NULL if table should be taken from
|
||||
table_list->table)
|
||||
dup_table_list Tables to be used in ON DUPLICATE KEY
|
||||
It's either all global tables or only the table we
|
||||
insert into, depending on if we are using GROUP BY
|
||||
in the SELECT clause).
|
||||
table Table to insert into (can be NULL if table should
|
||||
be taken from table_list->table)
|
||||
where Where clause (for insert ... select)
|
||||
select_insert TRUE if INSERT ... SELECT statement
|
||||
|
||||
TODO (in far future)
|
||||
In cases of:
|
||||
INSERT INTO t1 SELECT a, sum(a) as sum1 from t2 GROUP BY a
|
||||
ON DUPLICATE KEY ...
|
||||
we should be able to refer to sum1 in the ON DUPLICATE KEY part
|
||||
|
||||
WARNING
|
||||
You MUST set table->insert_values to 0 after calling this function
|
||||
before releasing the table object.
|
||||
|
||||
RETURN VALUE
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST *dup_table_list, TABLE *table,
|
||||
List<Item> &fields, List_item *values,
|
||||
List<Item> &update_fields, List<Item> &update_values,
|
||||
enum_duplicates duplic,
|
||||
COND **where, bool select_insert)
|
||||
{
|
||||
TABLE_LIST *save_table_list= thd->lex->select_lex.context.table_list;
|
||||
SELECT_LEX= &thd->lex->select_lex;
|
||||
TABLE_LIST *save_table_list;
|
||||
TABLE_LIST *save_next_local;
|
||||
bool insert_into_view= (table_list->view != 0);
|
||||
bool save_resolve_in_select_list=
|
||||
thd->lex->select_lex.context.resolve_in_select_list;
|
||||
bool save_resolve_in_select_list;
|
||||
bool res;
|
||||
TABLE_LIST *next_local;
|
||||
DBUG_ENTER("mysql_prepare_insert");
|
||||
DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
|
||||
(ulong)table_list, (ulong)table,
|
||||
@ -768,7 +783,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
*/
|
||||
if (!select_insert)
|
||||
{
|
||||
for (SELECT_LEX_UNIT *un= thd->lex->select_lex.first_inner_unit();
|
||||
for (SELECT_LEX_UNIT *un= select_lex->first_inner_unit();
|
||||
un;
|
||||
un= un->next_unit())
|
||||
{
|
||||
@ -792,23 +807,30 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
select_insert))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
next_local= table_list->next_local;
|
||||
save_table_list= select_lex->context.table_list;
|
||||
save_resolve_in_select_list= select_lex->context.resolve_in_select_list;
|
||||
save_next_local= table_list->next_local;
|
||||
|
||||
table_list->next_local= 0;
|
||||
thd->lex->select_lex.context.resolve_in_table_list_only(table_list);
|
||||
select_lex->context.resolve_in_table_list_only(table_list);
|
||||
if ((values && check_insert_fields(thd, table_list, fields, *values,
|
||||
!insert_into_view)) ||
|
||||
(values && setup_fields(thd, 0, *values, 0, 0, 0)) ||
|
||||
(duplic == DUP_UPDATE &&
|
||||
((thd->lex->select_lex.no_wrap_view_item= TRUE,
|
||||
(res= check_update_fields(thd, table_list, update_fields)),
|
||||
thd->lex->select_lex.no_wrap_view_item= FALSE,
|
||||
res) ||
|
||||
setup_fields(thd, 0, update_values, 1, 0, 0))))
|
||||
DBUG_RETURN(TRUE);
|
||||
table_list->next_local= next_local;
|
||||
thd->lex->select_lex.context.table_list= save_table_list;
|
||||
thd->lex->select_lex.context.resolve_in_select_list=
|
||||
save_resolve_in_select_list;
|
||||
setup_fields(thd, 0, update_values, 1, 0, 0))
|
||||
res= TRUE;
|
||||
else if (duplic == DUP_UPDATE)
|
||||
{
|
||||
select_lex->context.resolve_in_table_list_only(dup_table_list);
|
||||
select_lex->no_wrap_view_item= TRUE;
|
||||
res= check_update_fields(thd, table_list, update_fields);
|
||||
select_lex->no_wrap_view_item= FALSE;
|
||||
}
|
||||
table_list->next_local= save_next_local;
|
||||
select_lex->context.table_list= save_table_list;
|
||||
select_lex->context.resolve_in_select_list= save_resolve_in_select_list;
|
||||
if (res)
|
||||
DBUG_RETURN(res);
|
||||
|
||||
if (!table)
|
||||
table= table_list->table;
|
||||
|
||||
@ -820,8 +842,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
thd->lex->select_lex.fix_prepare_information(thd, &fake_conds);
|
||||
thd->lex->select_lex.first_execution= 0;
|
||||
select_lex->fix_prepare_information(thd, &fake_conds);
|
||||
select_lex->first_execution= 0;
|
||||
}
|
||||
if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
|
||||
table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
|
||||
@ -1992,12 +2014,25 @@ bool mysql_insert_select_prepare(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
TABLE_LIST *first_select_leaf_table;
|
||||
TABLE_LIST dup_tables;
|
||||
DBUG_ENTER("mysql_insert_select_prepare");
|
||||
|
||||
/*
|
||||
SELECT_LEX do not belong to INSERT statement, so we can't add WHERE
|
||||
clause if table is VIEW
|
||||
*/
|
||||
if (mysql_prepare_insert(thd, lex->query_tables,
|
||||
|
||||
dup_tables= *lex->query_tables;
|
||||
if (lex->select_lex->group_list.elements != 0)
|
||||
{
|
||||
/*
|
||||
When we are using GROUP BY we can't refere to other tables in the
|
||||
ON DUPLICATE KEY part
|
||||
*/
|
||||
dup_tables.local_next= 0;
|
||||
}
|
||||
|
||||
if (mysql_prepare_insert(thd, lex->query_tables, &dup_tables
|
||||
lex->query_tables->table, lex->field_list, 0,
|
||||
lex->update_list, lex->value_list,
|
||||
lex->duplicates,
|
||||
|
Reference in New Issue
Block a user