Skip to content
Permalink
Browse files
MDEV-23825 Join select_handler and Pushdown_select + XPand changes
  • Loading branch information
abarkov committed Sep 27, 2020
1 parent d111e6a commit 080522d
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 80 deletions.
@@ -21,10 +21,10 @@


/**
The methods of the Pushdown_select class.
The methods of the select_handler class.
The objects of this class are used for pushdown of the select queries
into engines. The main method of the class is Pushdown_select::execute()
into engines. The main method of the class is select_handler::execute()
that initiates execution of a select query by a foreign engine, receives the
rows of the result set, put it in a buffer of a temporary table and send
them from the buffer directly into output.
@@ -36,51 +36,55 @@
*/


Pushdown_select::Pushdown_select(SELECT_LEX *sel, select_handler *h)
: select(sel), handler(h)
{
is_analyze= handler->thd->lex->analyze_stmt;
}
select_handler::select_handler(THD *thd_arg, handlerton *ht_arg)
: thd(thd_arg), ht(ht_arg), table(NULL),
is_analyze(thd_arg->lex->analyze_stmt)
{}


Pushdown_select::~Pushdown_select()
select_handler::~select_handler()
{
if (handler->table)
free_tmp_table(handler->thd, handler->table);
delete handler;
select->select_h= NULL;
if (table)
free_tmp_table(thd, table);
}


bool Pushdown_select::init()
TABLE *select_handler::create_tmp_table(THD *thd, SELECT_LEX *select)
{
DBUG_ENTER("select_handler::create_tmp_table");
List<Item> types;
TMP_TABLE_PARAM tmp_table_param;
THD *thd= handler->thd;
DBUG_ENTER("Pushdown_select::init");
if (select->master_unit()->join_union_item_types(thd, types, 1))
DBUG_RETURN(true);
DBUG_RETURN(NULL);
tmp_table_param.init();
tmp_table_param.field_count= types.elements;

handler->table= create_tmp_table(thd, &tmp_table_param, types,
TABLE *table= ::create_tmp_table(thd, &tmp_table_param, types,
(ORDER *) 0, false, 0,
TMP_TABLE_ALL_COLUMNS, 1,
&empty_clex_str, true, false);
if (!handler->table)
DBUG_RETURN(true);
if (handler->table->fill_item_list(&result_columns))
DBUG_RETURN(table);
}


bool select_handler::prepare()
{
DBUG_ENTER("select_handler::prepare");
/*
Some engines (e.g. XPand) initialize "table" on their own.
So we need to create a temporary table only if "table" is NULL.
*/
if (!table && !(table= create_tmp_table(thd, select)))
DBUG_RETURN(true);
DBUG_RETURN(false);
DBUG_RETURN(table->fill_item_list(&result_columns));
}


bool Pushdown_select::send_result_set_metadata()
bool select_handler::send_result_set_metadata()
{
DBUG_ENTER("Pushdown_select::send_result_set_metadata");
DBUG_ENTER("select_handler::send_result_set_metadata");

#ifdef WITH_WSREP
THD *thd= handler->thd;
if (WSREP(thd) && thd->wsrep_retry_query)
{
WSREP_DEBUG("skipping select metadata");
@@ -96,7 +100,7 @@ bool Pushdown_select::send_result_set_metadata()
}


bool Pushdown_select::send_data()
bool select_handler::send_data()
{
DBUG_ENTER("Pushdown_select::send_data");

@@ -107,48 +111,47 @@ bool Pushdown_select::send_data()
}


bool Pushdown_select::send_eof()
bool select_handler::send_eof()
{
DBUG_ENTER("Pushdown_select::send_eof");
DBUG_ENTER("select_handler::send_eof");

if (select->join->result->send_eof())
DBUG_RETURN(true);
DBUG_RETURN(false);
}


int Pushdown_select::execute()
int select_handler::execute()
{
int err;
THD *thd= handler->thd;

DBUG_ENTER("Pushdown_select::execute");
DBUG_ENTER("select_handler::execute");

if ((err= handler->init_scan()))
if ((err= init_scan()))
goto error;

if (is_analyze)
{
handler->end_scan();
end_scan();
DBUG_RETURN(0);
}

if (send_result_set_metadata())
DBUG_RETURN(-1);

while (!(err= handler->next_row()))
while (!(err= next_row()))
{
if (thd->check_killed() || send_data())
{
handler->end_scan();
end_scan();
DBUG_RETURN(-1);
}
}

if (err != 0 && err != HA_ERR_END_OF_FILE)
goto error;

if ((err= handler->end_scan()))
if ((err= end_scan()))
goto error_2;

if (send_eof())
@@ -157,9 +160,9 @@ int Pushdown_select::execute()
DBUG_RETURN(0);

error:
handler->end_scan();
end_scan();
error_2:
handler->print_error(err, MYF(0));
print_error(err, MYF(0));
DBUG_RETURN(-1); // Error not sent to client
}

@@ -41,12 +41,24 @@ class select_handler
The table is actually never filled. Only its record buffer is used.
*/
TABLE *table;
List<Item> result_columns;

select_handler(THD *thd_arg, handlerton *ht_arg)
: thd(thd_arg), ht(ht_arg), table(0) {}
bool is_analyze;

virtual ~select_handler() {}
bool send_result_set_metadata();
bool send_data();

select_handler(THD *thd_arg, handlerton *ht_arg);

virtual ~select_handler();

int execute();

virtual bool prepare();

static TABLE *create_tmp_table(THD *thd, SELECT_LEX *sel);

protected:
/*
Functions to scan the select result set.
All these returns 0 if ok, error code in case of error.
@@ -67,6 +79,8 @@ class select_handler

/* Report errors */
virtual void print_error(int error, myf errflag);

bool send_eof();
};

#endif /* SELECT_HANDLER_INCLUDED */
@@ -1334,10 +1334,8 @@ class st_select_lex: public st_select_lex_node
table_value_constr *tvc;
bool in_tvc;

/* The interface employed to execute the select query by a foreign engine */
select_handler *select_h;
/* The object used to organize execution of the query by a foreign engine */
Pushdown_select *pushdown_select;
select_handler *pushdown_select;

/** System Versioning */
public:
@@ -1608,7 +1608,7 @@ int JOIN::optimize()
if (!(select_options & SELECT_DESCRIBE))
{
/* Prepare to execute the query pushed into a foreign engine */
res= select_lex->pushdown_select->init();
res= select_lex->pushdown_select->prepare();
}
with_two_phase_optimization= false;
}
@@ -4632,19 +4632,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
}

/* Look for a table owned by an engine with the select_handler interface */
select_lex->select_h= select_lex->find_select_handler(thd);
if (select_lex->select_h)
{
/* Create a Pushdown_select object for later execution of the query */
if (!(select_lex->pushdown_select=
new (thd->mem_root) Pushdown_select(select_lex,
select_lex->select_h)))
{
delete select_lex->select_h;
select_lex->select_h= NULL;
DBUG_RETURN(TRUE);
}
}
select_lex->pushdown_select= select_lex->find_select_handler(thd);

if ((err= join->optimize()))
{
@@ -2517,29 +2517,6 @@ class Pushdown_derived: public Sql_alloc
class select_handler;


class Pushdown_select: public Sql_alloc
{
private:
bool is_analyze;
List<Item> result_columns;
bool send_result_set_metadata();
bool send_data();
bool send_eof();

public:
SELECT_LEX *select;
select_handler *handler;

Pushdown_select(SELECT_LEX *sel, select_handler *h);

~Pushdown_select();

bool init();

int execute();
};


bool test_if_order_compatible(SQL_I_List<ORDER> &a, SQL_I_List<ORDER> &b);
int test_if_group_changed(List<Cached_item> &list);
int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort);

0 comments on commit 080522d

Please sign in to comment.