diff options
author | Roman Nozdrin <roman.nozdrin@mariadb.com> | 2021-01-26 09:36:18 +0000 |
---|---|---|
committer | Roman Nozdrin <roman.nozdrin@mariadb.com> | 2021-01-26 14:07:14 +0000 |
commit | 0565d199737a8412d592c32f315eced33efac7e4 (patch) | |
tree | 1ba7ee145210035158be165ef1f6318f0cd2e52d | |
parent | 927a882341eb1087e71d64de4e8cd89ab520de89 (diff) | |
download | mariadb-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.cc | 99 |
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 |