Commit c235de12 authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-6394: ANALYZE DELETE .. RETURNING fails with ERROR 2027 Malformed packet (now, the code)

Forgot the code
parent 9394f2f9
...@@ -258,8 +258,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -258,8 +258,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (mysql_prepare_delete(thd, table_list, select_lex->with_wild, if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
select_lex->item_list, &conds)) select_lex->item_list, &conds))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
(void) result->prepare(select_lex->item_list, NULL); if (with_select)
(void) result->prepare(select_lex->item_list, NULL);
if (thd->lex->current_select->first_cond_optimization) if (thd->lex->current_select->first_cond_optimization)
{ {
...@@ -672,17 +673,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -672,17 +673,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
} }
DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
if (thd->lex->analyze_stmt)
goto emit_explain_and_leave;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
if (error < 0 || if (error < 0 ||
(thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
{ {
if (!with_select) if (thd->lex->analyze_stmt)
my_ok(thd, deleted); {
else error= 0;
goto send_nothing_and_leave;
}
if (with_select)
result->send_eof(); result->send_eof();
else
my_ok(thd, deleted);
DBUG_PRINT("info",("%ld records deleted",(long) deleted)); DBUG_PRINT("info",("%ld records deleted",(long) deleted));
} }
DBUG_RETURN(error >= 0 || thd->is_error()); DBUG_RETURN(error >= 0 || thd->is_error());
...@@ -695,13 +700,17 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -695,13 +700,17 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
*/ */
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
emit_explain_and_leave: send_nothing_and_leave:
int err2= thd->lex->explain->send_explain(thd); /*
ANALYZE DELETE jumps here. We can't send explain right here, because
we might be using ANALYZE DELETE ...RETURNING, in which case we have
Protocol_discard active.
*/
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
//table->set_keyread(false); //table->set_keyread(false);
DBUG_RETURN((err2 || thd->is_error() || thd->killed) ? 1 : 0); DBUG_RETURN((thd->is_error() || thd->killed) ? 1 : 0);
} }
......
...@@ -3567,12 +3567,47 @@ case SQLCOM_PREPARE: ...@@ -3567,12 +3567,47 @@ case SQLCOM_PREPARE:
unit->set_limit(select_lex); unit->set_limit(select_lex);
MYSQL_DELETE_START(thd->query()); MYSQL_DELETE_START(thd->query());
if (!(sel_result= lex->result) && !(sel_result= new select_send())) Protocol *save_protocol;
return 1; bool replaced_protocol= false;
if (!select_lex->item_list.is_empty())
{
/* This is DELETE ... RETURNING. It will return output to the client */
if (thd->lex->analyze_stmt)
{
/*
Actually, it is ANALYZE .. DELETE .. RETURNING. We need to produce
output and then discard it.
*/
sel_result= new select_send_analyze();
replaced_protocol= true;
save_protocol= thd->protocol;
thd->protocol= new Protocol_discard(thd);
}
else
{
if (!(sel_result= lex->result) && !(sel_result= new select_send()))
return 1;
}
}
res = mysql_delete(thd, all_tables, res = mysql_delete(thd, all_tables,
select_lex->where, &select_lex->order_list, select_lex->where, &select_lex->order_list,
unit->select_limit_cnt, select_lex->options, unit->select_limit_cnt, select_lex->options,
sel_result); sel_result);
if (replaced_protocol)
{
delete thd->protocol;
thd->protocol= save_protocol;
}
if (thd->lex->analyze_stmt || thd->lex->describe)
{
if (!res)
res= thd->lex->explain->send_explain(thd);
}
delete sel_result; delete sel_result;
MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func()); MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
break; break;
......
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