summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sp_head.cc11
-rw-r--r--sql/sql_insert.cc56
-rw-r--r--sql/sql_insert.h3
3 files changed, 30 insertions, 40 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1968ba83101..8c07a060f30 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -290,6 +290,10 @@ sp_get_flags_for_command(LEX *lex)
break;
case SQLCOM_DELETE:
case SQLCOM_DELETE_MULTI:
+ case SQLCOM_INSERT:
+ case SQLCOM_REPLACE:
+ case SQLCOM_REPLACE_SELECT:
+ case SQLCOM_INSERT_SELECT:
{
/*
DELETE normally doesn't return resultset, but there are 3 exceptions:
@@ -297,8 +301,7 @@ sp_get_flags_for_command(LEX *lex)
- EXPLAIN DELETE ...
- ANALYZE DELETE ...
*/
- if (lex->first_select_lex()->item_list.is_empty() &&
- !lex->describe && !lex->analyze_stmt)
+ if (!lex->has_returning() && !lex->describe && !lex->analyze_stmt)
flags= 0;
else
flags= sp_head::MULTI_RESULTS;
@@ -306,10 +309,6 @@ sp_get_flags_for_command(LEX *lex)
}
case SQLCOM_UPDATE:
case SQLCOM_UPDATE_MULTI:
- case SQLCOM_INSERT:
- case SQLCOM_REPLACE:
- case SQLCOM_REPLACE_SELECT:
- case SQLCOM_INSERT_SELECT:
{
if (!lex->describe && !lex->analyze_stmt)
flags= 0;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index ba7bf4c44c7..7be005bd79b 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1076,21 +1076,9 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
}
else
#endif
- error=write_record(thd, table ,&info);
+ error= write_record(thd, table, &info, result);
if (unlikely(error))
break;
- /*
- We send the row after writing it to the table so that the
- correct values are sent to the client. Otherwise it won't show
- autoinc values (generated inside the handler::ha_write()) and
- values updated in ON DUPLICATE KEY UPDATE (handled inside
- write_record()).
- */
- if (returning && result->send_data(returning->item_list) < 0)
- {
- error= 1;
- break;
- }
thd->get_stmt_da()->inc_current_row_for_warning();
}
its.rewind();
@@ -1688,6 +1676,7 @@ int vers_insert_history_row(TABLE *table)
info - COPY_INFO structure describing handling of duplicates
and which is used for counting number of records inserted
and deleted.
+ sink - result sink for the RETURNING clause
NOTE
Once this record will be written to table after insert trigger will
@@ -1704,7 +1693,7 @@ int vers_insert_history_row(TABLE *table)
*/
-int write_record(THD *thd, TABLE *table,COPY_INFO *info)
+int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink)
{
int error, trg_error= 0;
char *key=0;
@@ -1750,7 +1739,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (info->ignore)
{
table->file->print_error(error, MYF(ME_WARNING));
- goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */
+ goto after_trg_or_ignored_err; /* Ignoring a not fatal error */
}
goto err;
}
@@ -1856,7 +1845,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
res= info->table_list->view_check_option(table->in_use, info->ignore);
if (res == VIEW_CHECK_SKIP)
- goto ok_or_after_trg_err;
+ goto after_trg_or_ignored_err;
if (res == VIEW_CHECK_ERROR)
goto before_trg_err;
@@ -1874,7 +1863,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (!(thd->variables.old_behavior &
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_WARNING));
- goto ok_or_after_trg_err;
+ goto after_trg_or_ignored_err;
}
goto err;
}
@@ -1893,7 +1882,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->file->print_error(error, MYF(0));
trg_error= 1;
restore_record(table, record[2]);
- goto ok_or_after_trg_err;
+ goto after_trg_or_ignored_err;
}
restore_record(table, record[2]);
}
@@ -1934,7 +1923,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
{
table->file->restore_auto_increment(prev_insert_id_for_cur_row);
}
- goto ok_or_after_trg_err;
+ goto ok;
}
else /* DUP_REPLACE */
{
@@ -2019,7 +2008,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
TRG_ACTION_AFTER, TRUE))
{
trg_error= 1;
- goto ok_or_after_trg_err;
+ goto after_trg_or_ignored_err;
}
/* Let us attempt do write_row() once more */
}
@@ -2055,7 +2044,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_WARNING));
table->file->restore_auto_increment();
- goto ok_or_after_trg_err;
+ goto after_trg_or_ignored_err;
}
after_trg_n_copied_inc:
@@ -2065,7 +2054,17 @@ after_trg_n_copied_inc:
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, TRUE));
-ok_or_after_trg_err:
+ok:
+ /*
+ We send the row after writing it to the table so that the
+ correct values are sent to the client. Otherwise it won't show
+ autoinc values (generated inside the handler::ha_write()) and
+ values updated in ON DUPLICATE KEY UPDATE.
+ */
+ if (sink && sink->send_data(thd->lex->returning()->item_list) < 0)
+ trg_error= 1;
+
+after_trg_or_ignored_err:
if (key)
my_safe_afree(key,table->s->max_unique_length);
if (!table->file->has_transactions())
@@ -3413,7 +3412,7 @@ bool Delayed_insert::handle_inserts(void)
VCOL_UPDATE_FOR_WRITE);
}
- if (unlikely(tmp_error) || unlikely(write_record(&thd, table, &info)))
+ if (unlikely(tmp_error || write_record(&thd, table, &info, NULL)))
{
info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
@@ -3908,16 +3907,7 @@ int select_insert::send_data(List<Item> &values)
}
}
- error= write_record(thd, table, &info);
- /*
- Sending the result set to the cliet after writing record. The reason is
- same as other variants of insert.
- */
- if (sel_result && sel_result->send_data(thd->lex->returning()->item_list) < 0)
- {
- error= 1;
- DBUG_RETURN(1);
- }
+ error= write_record(thd, table, &info, sel_result);
table->vers_write= table->versioned();
table->auto_increment_field_not_null= FALSE;
diff --git a/sql/sql_insert.h b/sql/sql_insert.h
index 5b86f09d13b..977a0eb23c8 100644
--- a/sql/sql_insert.h
+++ b/sql/sql_insert.h
@@ -38,7 +38,8 @@ void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type,
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list);
int vers_insert_history_row(TABLE *table);
-int write_record(THD *thd, TABLE *table, COPY_INFO *info);
+int write_record(THD *thd, TABLE *table, COPY_INFO *info,
+ select_result *returning= NULL);
void kill_delayed_threads(void);
#ifdef EMBEDDED_LIBRARY