summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Nozdrin <roman.nozdrin@mariadb.com>2021-01-26 09:36:18 +0000
committerRoman Nozdrin <roman.nozdrin@mariadb.com>2021-01-26 14:07:14 +0000
commit0565d199737a8412d592c32f315eced33efac7e4 (patch)
tree1ba7ee145210035158be165ef1f6318f0cd2e52d
parent927a882341eb1087e71d64de4e8cd89ab520de89 (diff)
downloadmariadb-git-0565d199737a8412d592c32f315eced33efac7e4.tar.gz
MDEV-24298 Select Handler now process INSERT..SELECT with a single derived at
the top level
-rw-r--r--sql/sql_select.cc99
1 files changed, 58 insertions, 41 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 74b83594a65..01ca12aa371 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4540,6 +4540,63 @@ void JOIN::cleanup_item_list(List<Item> &items) const
/**
+ @brief
+ Look for provision of the select_handler interface by a foreign engine
+
+ @param thd The thread handler
+
+ @details
+ The function checks that this is an upper level select and if so looks
+ through its tables searching for one whose handlerton owns a
+ create_select call-back function. If the call of this function returns
+ a select_handler interface object then the server will push the select
+ query into this engine.
+ This is a responsibility of the create_select call-back function to
+ check whether the engine can execute the query.
+
+ @retval the found select_handler if the search is successful
+ 0 otherwise
+*/
+
+select_handler *find_select_handler(THD *thd,
+ SELECT_LEX* select_lex)
+{
+ if (select_lex->next_select())
+ return 0;
+ if (select_lex->master_unit()->outer_select())
+ return 0;
+
+ TABLE_LIST *tbl= nullptr;
+ // For SQLCOM_INSERT_SELECT the server takes TABLE_LIST
+ // from thd->lex->query_tables and skips its first table
+ // b/c it is the target table for the INSERT..SELECT.
+ if (thd->lex->sql_command != SQLCOM_INSERT_SELECT)
+ {
+ tbl= select_lex->join->tables_list;
+ }
+ else if (thd->lex->query_tables &&
+ thd->lex->query_tables->next_global)
+ {
+ tbl= thd->lex->query_tables->next_global;
+ }
+ else
+ return 0;
+
+ for (;tbl; tbl= tbl->next_global)
+ {
+ if (!tbl->table)
+ continue;
+ handlerton *ht= tbl->table->file->partition_ht();
+ if (!ht->create_select)
+ continue;
+ select_handler *sh= ht->create_select(thd, select_lex);
+ return sh;
+ }
+ return 0;
+}
+
+
+/**
An entry point to single-unit select (a select without UNION).
@param thd thread handler
@@ -4643,7 +4700,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->pushdown_select= select_lex->find_select_handler(thd);
+ select_lex->pushdown_select= find_select_handler(thd, select_lex);
if ((err= join->optimize()))
{
@@ -29061,46 +29118,6 @@ void JOIN_TAB::partial_cleanup()
free_cache(&read_record);
}
-
-/**
- @brief
- Look for provision of the select_handler interface by a foreign engine
-
- @param thd The thread handler
-
- @details
- The function checks that this is an upper level select and if so looks
- through its tables searching for one whose handlerton owns a
- create_select call-back function. If the call of this function returns
- a select_handler interface object then the server will push the select
- query into this engine.
- This is a responsibility of the create_select call-back function to
- check whether the engine can execute the query.
-
- @retval the found select_handler if the search is successful
- 0 otherwise
-*/
-
-select_handler *SELECT_LEX::find_select_handler(THD *thd)
-{
- if (next_select())
- return 0;
- if (master_unit()->outer_select())
- return 0;
- for (TABLE_LIST *tbl= join->tables_list; tbl; tbl= tbl->next_global)
- {
- if (!tbl->table)
- continue;
- handlerton *ht= tbl->table->file->partition_ht();
- if (!ht->create_select)
- continue;
- select_handler *sh= ht->create_select(thd, this);
- return sh;
- }
- return 0;
-}
-
-
/**
@brief
Construct not null conditions for provingly not nullable fields