diff options
author | unknown <monty@mysql.com> | 2005-07-03 14:17:52 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-07-03 14:17:52 +0300 |
commit | eeee5fb10b59f6580ebcb08ebd82d0b75c66aa8f (patch) | |
tree | bf06496ea5d097316e5972a5cf4c4d5f674fb90b /sql/sql_insert.cc | |
parent | 6d9bc9c8b71acd82aa79ae580271e7dc4012e5a4 (diff) | |
parent | c7ab92c28a535d2419ffa906042fff7e476df972 (diff) | |
download | mariadb-git-eeee5fb10b59f6580ebcb08ebd82d0b75c66aa8f.tar.gz |
Merge with 4.1
Makefile.am:
Auto merged
myisam/mi_create.c:
Auto merged
myisam/mi_open.c:
Auto merged
mysql-test/r/ctype_utf8.result:
Auto merged
mysys/thr_alarm.c:
Auto merged
VC++Files/sql/mysqld.dsp:
Keep old
client/mysqldump.c:
Manual merge
client/mysqltest.c:
Automatic merge
configure.in:
Manual merge
mysql-test/r/ctype_ucs.result:
Auto merge
mysql-test/r/func_str.result:
Auto merge
mysql-test/r/group_by.result:
Auto merge
mysql-test/r/insert_select.result:
Auto merge
mysql-test/r/insert_update.result:
Auto merge
mysql-test/r/lowercase_table2.result:
Auto merge
mysql-test/r/select.result:
Manual merge
mysql-test/r/variables.result:
Auto merge
mysql-test/t/ctype_ucs.test:
Auto merge
mysql-test/t/func_str.test:
Auto merge
mysql-test/t/group_by.test:
Auto merge
mysql-test/t/insert_select.test:
Auto merge
mysql-test/t/insert_update.test:
Auto merge
mysql-test/t/ndb_alter_table.test:
Auto merge
mysql-test/t/select.test:
Auto merge
mysql-test/t/variables.test:
Auto merge
mysys/my_access.c:
Auto merge
scripts/make_win_src_distribution.sh:
Auto merge
sql/field.cc:
Manual merge
sql/ha_ndbcluster.cc:
Auto merge
sql/handler.cc:
Auto merge
sql/item.cc:
Auto merge
sql/item.h:
Manual merge
sql/item_cmpfunc.h:
Auto merge
sql/item_strfunc.cc:
Auto merge
sql/item_strfunc.h:
Auto merge
sql/mysql_priv.h:
manual merge
sql/mysqld.cc:
manual merge
sql/opt_range.cc:
manual merge
sql/set_var.cc:
Auto merge
sql/sql_base.cc:
manual merge
Restore processing of ON DUPLICATE KEY UPDATE
sql/sql_insert.cc:
manual merge
Restore processing of ON DUPLICATE KEY UPDATE
Simplify mysql_prepare_insert by using local variable for select_lex and save old values just before they are changed
sql/sql_parse.cc:
Restore processing of ON DUPLICATE KEY UPDATE
sql/sql_prepare.cc:
New ON DUPLICATE KEY UPDATE handling
sql/sql_select.cc:
manual merge
sql/sql_table.cc:
auto merge
sql/sql_yacc.yy:
auto merge
strings/ctype-ucs2.c:
auto merge
strings/ctype-utf8.c:
auto merge
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 85 |
1 files changed, 60 insertions, 25 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 53c47706734..adb1eb01292 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -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, |