Commit b1c2c4ee authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-10014 Add RETURNING to INSERT

post-review fixes:
* test for dependent subqueries
* test for triggers and routines
* disallow INSERT...RETURNING in triggers and stored functions
* don't return anything if INSERT IGNORE ignored an error
parent 904dc934
...@@ -25,10 +25,10 @@ FROM t2 WHERE id2=1); ...@@ -25,10 +25,10 @@ FROM t2 WHERE id2=1);
FROM t2 WHERE id2=1) FROM t2 WHERE id2=1)
a a
INSERT INTO t1(id1,val1) VALUES(5,'e') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1(id1,val1) VALUES(5,'e') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-2);
(SELECT GROUP_CONCAT(val2) (SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1) FROM t2 GROUP BY id2 HAVING id2=id1-2)
NULL c
PREPARE stmt FROM "INSERT INTO t1 (id1,val1) VALUES (6,'f') RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 (id1,val1) VALUES (6,'f') RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
(SELECT id2 FROM t2 WHERE val2='b') (SELECT id2 FROM t2 WHERE val2='b')
...@@ -110,11 +110,11 @@ FROM t2 WHERE id2=1) ...@@ -110,11 +110,11 @@ FROM t2 WHERE id2=1)
a a
a a
INSERT INTO t1 VALUES (9,'i'),(10,'j') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1 VALUES (9,'i'),(10,'j') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-8);
(SELECT GROUP_CONCAT(val2) (SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1) FROM t2 GROUP BY id2 HAVING id2=id1-8)
NULL a
NULL b
PREPARE stmt FROM "INSERT INTO t1 VALUES (11,'k'),(12,'l') RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 VALUES (11,'k'),(12,'l') RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
(SELECT id2 FROM t2 WHERE val2='b') (SELECT id2 FROM t2 WHERE val2='b')
...@@ -200,9 +200,9 @@ RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1); ...@@ -200,9 +200,9 @@ RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1);
(SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1) (SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1)
a a
INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='e' INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='e'
RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id2+1); RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id);
(SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id2+1) (SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id)
NULL b
PREPARE stmt FROM "INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE PREPARE stmt FROM "INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE
KEY UPDATE val='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; KEY UPDATE val='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
...@@ -274,10 +274,10 @@ FROM t2 WHERE id2=1); ...@@ -274,10 +274,10 @@ FROM t2 WHERE id2=1);
FROM t2 WHERE id2=1) FROM t2 WHERE id2=1)
a a
INSERT INTO t1 SET id1= 5, val1='e' RETURNING (SELECT GROUP_CONCAT(val2) INSERT INTO t1 SET id1= 5, val1='e' RETURNING (SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-3);
(SELECT GROUP_CONCAT(val2) (SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1) FROM t2 GROUP BY id2 HAVING id2=id1-3)
NULL b
PREPARE stmt FROM "INSERT INTO t1 SET id1= 6, val1='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 SET id1= 6, val1='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
(SELECT id2 FROM t2 WHERE val2='b') (SELECT id2 FROM t2 WHERE val2='b')
...@@ -302,7 +302,6 @@ id1 val1 ...@@ -302,7 +302,6 @@ id1 val1
8 n 8 n
INSERT IGNORE INTO t1 SET id1= 8, val1= 'h' RETURNING *; INSERT IGNORE INTO t1 SET id1= 8, val1= 'h' RETURNING *;
id1 val1 id1 val1
8 h
Warnings: Warnings:
Warning 1062 Duplicate entry '8' for key 'PRIMARY' Warning 1062 Duplicate entry '8' for key 'PRIMARY'
EXPLAIN INSERT INTO t1 SET id1=9, val1='i' RETURNING id1; EXPLAIN INSERT INTO t1 SET id1=9, val1='i' RETURNING id1;
...@@ -405,14 +404,7 @@ id2 val2 ...@@ -405,14 +404,7 @@ id2 val2
8 n 8 n
INSERT IGNORE INTO v2 SELECT * FROM v1 RETURNING *; INSERT IGNORE INTO v2 SELECT * FROM v1 RETURNING *;
id2 val2 id2 val2
1 a
2 b
3 c
4 d
5 e 5 e
6 f
7 g
8 n
26 Z 26 Z
12 l 12 l
Warnings: Warnings:
...@@ -552,6 +544,32 @@ ERROR 21000: Operand should contain 1 column(s) ...@@ -552,6 +544,32 @@ ERROR 21000: Operand should contain 1 column(s)
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id2 FROM t2); id2 FROM t2);
ERROR 21000: Subquery returns more than 1 row ERROR 21000: Subquery returns more than 1 row
#
# TRIGGER
#
CREATE TRIGGER bi1 before insert on t1 for each row set NEW.val1= 'z';
INSERT INTO t1 VALUES (4, 'd'), (5, 'e') RETURNING *;
id1 val1
4 z
5 z
CREATE TRIGGER bi2 before insert on t2 for each row
INSERT INTO t1 VALUES (NEW.id2, NEW.val2) RETURNING *;
ERROR 0A000: Not allowed to return a result set from a trigger
#
# SP
#
CREATE FUNCTION f1(arg INT) RETURNS TEXT
BEGIN
INSERT INTO t1 VALUES (arg, arg) RETURNING *;
RETURN arg;
END|
ERROR 0A000: Not allowed to return a result set from a function
CREATE PROCEDURE sp1(arg INT)
INSERT INTO t1 VALUES (arg, arg) RETURNING *;
CALL sp1(0);
id1 val1
0 z
DROP PROCEDURE sp1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE ins_duplicate; DROP TABLE ins_duplicate;
......
...@@ -25,7 +25,7 @@ id1 && id1, id1 | id1, UPPER(val1),f(id1); ...@@ -25,7 +25,7 @@ id1 && id1, id1 | id1, UPPER(val1),f(id1);
INSERT INTO t1(id1,val1) VALUES (4,'d') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1(id1,val1) VALUES (4,'d') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 WHERE id2=1); FROM t2 WHERE id2=1);
INSERT INTO t1(id1,val1) VALUES(5,'e') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1(id1,val1) VALUES(5,'e') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-2);
PREPARE stmt FROM "INSERT INTO t1 (id1,val1) VALUES (6,'f') RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 (id1,val1) VALUES (6,'f') RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
DELETE FROM t1 WHERE id1=6; DELETE FROM t1 WHERE id1=6;
...@@ -53,7 +53,7 @@ id1 && id1, id1|id1, UPPER(val1),f(id1); ...@@ -53,7 +53,7 @@ id1 && id1, id1|id1, UPPER(val1),f(id1);
INSERT INTO t1 VALUES (7,'g'),(8,'h') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1 VALUES (7,'g'),(8,'h') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 WHERE id2=1); FROM t2 WHERE id2=1);
INSERT INTO t1 VALUES (9,'i'),(10,'j') RETURNING(SELECT GROUP_CONCAT(val2) INSERT INTO t1 VALUES (9,'i'),(10,'j') RETURNING(SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-8);
PREPARE stmt FROM "INSERT INTO t1 VALUES (11,'k'),(12,'l') RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 VALUES (11,'k'),(12,'l') RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
DELETE FROM t1 WHERE val1 IN ('k','l'); DELETE FROM t1 WHERE val1 IN ('k','l');
...@@ -81,7 +81,7 @@ RETURNING id+id AS total, val, id && id, id|id, UPPER(val),f(id); ...@@ -81,7 +81,7 @@ RETURNING id+id AS total, val, id && id, id|id, UPPER(val),f(id);
INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='d' INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='d'
RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1); RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 WHERE id2=1);
INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='e' INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE KEY UPDATE val='e'
RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id2+1); RETURNING (SELECT GROUP_CONCAT(val2) FROM t2 GROUP BY id2 HAVING id2=id);
PREPARE stmt FROM "INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE PREPARE stmt FROM "INSERT INTO ins_duplicate VALUES (2,'b') ON DUPLICATE
KEY UPDATE val='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; KEY UPDATE val='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
...@@ -114,7 +114,7 @@ id1 && id1, id1|id1, UPPER(val1),f(id1); ...@@ -114,7 +114,7 @@ id1 && id1, id1|id1, UPPER(val1),f(id1);
INSERT INTO t1 SET id1= 4, val1= 'd' RETURNING (SELECT GROUP_CONCAT(val2) INSERT INTO t1 SET id1= 4, val1= 'd' RETURNING (SELECT GROUP_CONCAT(val2)
FROM t2 WHERE id2=1); FROM t2 WHERE id2=1);
INSERT INTO t1 SET id1= 5, val1='e' RETURNING (SELECT GROUP_CONCAT(val2) INSERT INTO t1 SET id1= 5, val1='e' RETURNING (SELECT GROUP_CONCAT(val2)
FROM t2 GROUP BY id2 HAVING id2=id2+1); FROM t2 GROUP BY id2 HAVING id2=id1-3);
PREPARE stmt FROM "INSERT INTO t1 SET id1= 6, val1='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')"; PREPARE stmt FROM "INSERT INTO t1 SET id1= 6, val1='f' RETURNING (SELECT id2 FROM t2 WHERE val2='b')";
EXECUTE stmt; EXECUTE stmt;
DELETE FROM t1 WHERE val1='f'; DELETE FROM t1 WHERE val1='f';
...@@ -272,6 +272,34 @@ INSERT INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT ...@@ -272,6 +272,34 @@ INSERT INTO t2(id2, val2) SELECT * FROM t1 WHERE id1=2 RETURNING(SELECT
INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT INSERT INTO t2(id2,val2) SELECT * FROM t1 WHERE id1=2 RETURNING (SELECT
id2 FROM t2); id2 FROM t2);
--echo #
--echo # TRIGGER
--echo #
CREATE TRIGGER bi1 before insert on t1 for each row set NEW.val1= 'z';
INSERT INTO t1 VALUES (4, 'd'), (5, 'e') RETURNING *;
--error ER_SP_NO_RETSET
CREATE TRIGGER bi2 before insert on t2 for each row
INSERT INTO t1 VALUES (NEW.id2, NEW.val2) RETURNING *;
--echo #
--echo # SP
--echo #
delimiter |;
--error ER_SP_NO_RETSET
CREATE FUNCTION f1(arg INT) RETURNS TEXT
BEGIN
INSERT INTO t1 VALUES (arg, arg) RETURNING *;
RETURN arg;
END|
delimiter ;|
CREATE PROCEDURE sp1(arg INT)
INSERT INTO t1 VALUES (arg, arg) RETURNING *;
CALL sp1(0);
DROP PROCEDURE sp1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE ins_duplicate; DROP TABLE ins_duplicate;
......
...@@ -290,6 +290,10 @@ sp_get_flags_for_command(LEX *lex) ...@@ -290,6 +290,10 @@ sp_get_flags_for_command(LEX *lex)
break; break;
case SQLCOM_DELETE: case SQLCOM_DELETE:
case SQLCOM_DELETE_MULTI: 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: DELETE normally doesn't return resultset, but there are 3 exceptions:
...@@ -297,8 +301,7 @@ sp_get_flags_for_command(LEX *lex) ...@@ -297,8 +301,7 @@ sp_get_flags_for_command(LEX *lex)
- EXPLAIN DELETE ... - EXPLAIN DELETE ...
- ANALYZE DELETE ... - ANALYZE DELETE ...
*/ */
if (lex->first_select_lex()->item_list.is_empty() && if (!lex->has_returning() && !lex->describe && !lex->analyze_stmt)
!lex->describe && !lex->analyze_stmt)
flags= 0; flags= 0;
else else
flags= sp_head::MULTI_RESULTS; flags= sp_head::MULTI_RESULTS;
...@@ -306,10 +309,6 @@ sp_get_flags_for_command(LEX *lex) ...@@ -306,10 +309,6 @@ sp_get_flags_for_command(LEX *lex)
} }
case SQLCOM_UPDATE: case SQLCOM_UPDATE:
case SQLCOM_UPDATE_MULTI: case SQLCOM_UPDATE_MULTI:
case SQLCOM_INSERT:
case SQLCOM_REPLACE:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{ {
if (!lex->describe && !lex->analyze_stmt) if (!lex->describe && !lex->analyze_stmt)
flags= 0; flags= 0;
......
...@@ -1076,21 +1076,9 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, ...@@ -1076,21 +1076,9 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
} }
else else
#endif #endif
error=write_record(thd, table ,&info); error= write_record(thd, table, &info, result);
if (unlikely(error)) if (unlikely(error))
break; 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(); thd->get_stmt_da()->inc_current_row_for_warning();
} }
its.rewind(); its.rewind();
...@@ -1688,6 +1676,7 @@ int vers_insert_history_row(TABLE *table) ...@@ -1688,6 +1676,7 @@ int vers_insert_history_row(TABLE *table)
info - COPY_INFO structure describing handling of duplicates info - COPY_INFO structure describing handling of duplicates
and which is used for counting number of records inserted and which is used for counting number of records inserted
and deleted. and deleted.
sink - result sink for the RETURNING clause
NOTE NOTE
Once this record will be written to table after insert trigger will Once this record will be written to table after insert trigger will
...@@ -1704,7 +1693,7 @@ int vers_insert_history_row(TABLE *table) ...@@ -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; int error, trg_error= 0;
char *key=0; char *key=0;
...@@ -1750,7 +1739,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1750,7 +1739,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (info->ignore) if (info->ignore)
{ {
table->file->print_error(error, MYF(ME_WARNING)); 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; goto err;
} }
...@@ -1856,7 +1845,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1856,7 +1845,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
res= info->table_list->view_check_option(table->in_use, info->ignore); res= info->table_list->view_check_option(table->in_use, info->ignore);
if (res == VIEW_CHECK_SKIP) if (res == VIEW_CHECK_SKIP)
goto ok_or_after_trg_err; goto after_trg_or_ignored_err;
if (res == VIEW_CHECK_ERROR) if (res == VIEW_CHECK_ERROR)
goto before_trg_err; goto before_trg_err;
...@@ -1874,7 +1863,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1874,7 +1863,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (!(thd->variables.old_behavior & if (!(thd->variables.old_behavior &
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_WARNING)); table->file->print_error(error, MYF(ME_WARNING));
goto ok_or_after_trg_err; goto after_trg_or_ignored_err;
} }
goto err; goto err;
} }
...@@ -1893,7 +1882,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1893,7 +1882,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
trg_error= 1; trg_error= 1;
restore_record(table, record[2]); restore_record(table, record[2]);
goto ok_or_after_trg_err; goto after_trg_or_ignored_err;
} }
restore_record(table, record[2]); restore_record(table, record[2]);
} }
...@@ -1934,7 +1923,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -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); table->file->restore_auto_increment(prev_insert_id_for_cur_row);
} }
goto ok_or_after_trg_err; goto ok;
} }
else /* DUP_REPLACE */ else /* DUP_REPLACE */
{ {
...@@ -2019,7 +2008,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -2019,7 +2008,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
TRG_ACTION_AFTER, TRUE)) TRG_ACTION_AFTER, TRUE))
{ {
trg_error= 1; trg_error= 1;
goto ok_or_after_trg_err; goto after_trg_or_ignored_err;
} }
/* Let us attempt do write_row() once more */ /* Let us attempt do write_row() once more */
} }
...@@ -2055,7 +2044,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -2055,7 +2044,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_WARNING)); table->file->print_error(error, MYF(ME_WARNING));
table->file->restore_auto_increment(); table->file->restore_auto_increment();
goto ok_or_after_trg_err; goto after_trg_or_ignored_err;
} }
after_trg_n_copied_inc: after_trg_n_copied_inc:
...@@ -2065,7 +2054,17 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -2065,7 +2054,17 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->triggers->process_triggers(thd, TRG_EVENT_INSERT, table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, TRUE)); 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) if (key)
my_safe_afree(key,table->s->max_unique_length); my_safe_afree(key,table->s->max_unique_length);
if (!table->file->has_transactions()) if (!table->file->has_transactions())
...@@ -3413,7 +3412,7 @@ bool Delayed_insert::handle_inserts(void) ...@@ -3413,7 +3412,7 @@ bool Delayed_insert::handle_inserts(void)
VCOL_UPDATE_FOR_WRITE); 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 info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status); thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
...@@ -3908,16 +3907,7 @@ int select_insert::send_data(List<Item> &values) ...@@ -3908,16 +3907,7 @@ int select_insert::send_data(List<Item> &values)
} }
} }
error= write_record(thd, table, &info); error= write_record(thd, table, &info, sel_result);
/*
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);
}
table->vers_write= table->versioned(); table->vers_write= table->versioned();
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
......
...@@ -38,7 +38,8 @@ void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type, ...@@ -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, int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list); TABLE_LIST *table_list);
int vers_insert_history_row(TABLE *table); 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); void kill_delayed_threads(void);
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment