1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-21887: federatedx crashes on SELECT ... INTO query in select_handler code

Backport to 10.4:

- Don't try to push down SELECTs that have a side effect

- In case the storage engine did support pushdown of SELECT with an INTO
  clause, write the rows we've got from it into select->join->result,
  and not thd->protocol.  This way, SELECT ... INTO ... FROM
  smart_engine_table will put the result into where instructed, and
  NOT send it to the client.
This commit is contained in:
Sergei Petrunia
2020-03-26 15:01:44 +03:00
parent 1c8de231a3
commit af4b2ae858
4 changed files with 57 additions and 24 deletions

View File

@ -77,18 +77,17 @@ bool Pushdown_select::init()
bool Pushdown_select::send_result_set_metadata()
{
THD *thd= handler->thd;
Protocol *protocol= thd->protocol;
DBUG_ENTER("Pushdown_select::send_result_set_metadata");
#ifdef WITH_WSREP
THD *thd= handler->thd;
if (WSREP(thd) && thd->wsrep_retry_query)
{
WSREP_DEBUG("skipping select metadata");
DBUG_RETURN(false);
}
#endif /* WITH_WSREP */
if (protocol->send_result_set_metadata(&result_columns,
if (select->join->result->send_result_set_metadata(result_columns,
Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
DBUG_RETURN(true);
@ -100,23 +99,13 @@ bool Pushdown_select::send_result_set_metadata()
bool Pushdown_select::send_data()
{
THD *thd= handler->thd;
Protocol *protocol= thd->protocol;
DBUG_ENTER("Pushdown_select::send_data");
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(false);
protocol->prepare_for_resend();
if (protocol->send_result_set_row(&result_columns))
{
protocol->remove_last_row();
if (select->join->result->send_data(result_columns))
DBUG_RETURN(true);
}
thd->inc_sent_row_count(1);
if (thd->vio_ok())
DBUG_RETURN(protocol->write());
DBUG_RETURN(false);
}
@ -124,16 +113,10 @@ bool Pushdown_select::send_data()
bool Pushdown_select::send_eof()
{
THD *thd= handler->thd;
DBUG_ENTER("Pushdown_select::send_eof");
/*
Don't send EOF if we're in error condition (which implies we've already
sent or are sending an error)
*/
if (thd->is_error())
if (select->join->result->send_eof())
DBUG_RETURN(true);
::my_eof(thd);
DBUG_RETURN(false);
}