diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a14a3da8391..891ff5b8c7e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2797,18 +2797,29 @@ unsent_create_error: lex->duplicates); if (thd->net.report_error) res= -1; - break; + if (res != 2) + break; case SQLCOM_UPDATE_MULTI: { + bool converted= 0; DBUG_ASSERT(first_table == all_tables && first_table != 0); - if ((res= multi_update_precheck(thd, all_tables))) - break; + if (res != 2) + { + if ((res= multi_update_precheck(thd, all_tables))) + break; + } + else + { + res= 0; + converted= 1; + } res= mysql_multi_update(thd, all_tables, &select_lex->item_list, &lex->value_list, select_lex->where, select_lex->options, - lex->duplicates, unit, select_lex); + lex->duplicates, unit, select_lex, + converted); break; } case SQLCOM_REPLACE: @@ -2846,35 +2857,28 @@ unsent_create_error: if (!(res= open_and_lock_tables(thd, all_tables))) { - /* - Is table which we are changing used somewhere in other parts of - query - */ - if (unique_table(first_table, all_tables->next_global)) - { - /* Using same table for INSERT and SELECT */ - select_lex->options |= OPTION_BUFFER_RESULT; - } + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*)first_table->next_local; - if ((res= mysql_insert_select_prepare(thd))) - break; - if ((result= new select_insert(first_table, first_table->table, - &lex->field_list, lex->duplicates, - lex->duplicates == DUP_IGNORE))) + res= mysql_insert_select_prepare(thd); + if (!res && (result= new select_insert(first_table, first_table->table, + &lex->field_list, + lex->duplicates, + lex->duplicates == DUP_IGNORE))) { - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_table->next_local; + TABLE_LIST *first_select_table; + /* insert/replace from SELECT give its SELECT_LEX for SELECT, and item_list belong to SELECT */ lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; res= handle_select(thd, lex, result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_table; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; delete result; } + /* revert changes for SP */ + lex->select_lex.table_list.first= (byte*) first_table; if (thd->net.report_error) res= -1; } @@ -2935,8 +2939,20 @@ unsent_create_error: } thd->proc_info="init"; - if ((res= open_and_lock_tables(thd, all_tables)) || - (res= mysql_multi_delete_prepare(thd))) + if ((res= open_and_lock_tables(thd, all_tables))) + break; + + if (!first_table->table) + { + DBUG_ASSERT(first_table->view && + first_table->ancestor && first_table->ancestor->next_local); + my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), + first_table->view_db.str, first_table->view_name.str); + res= -1; + break; + } + + if ((res= mysql_multi_delete_prepare(thd))) break; if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, |