-
Oystein Grovlen authored
Part#2: Add support for SEMIJOIN/_SEMIJOIN and SUBQUERY hints (Below are commit comments for several commits that have been squashed into one) Part#2: Add support for SEMIJOIN/NO_SEMIJOIN hints (Parsing of SUBQUERY hint added, but not the functionality) sql/lex.h Added symbols for new optimizer hint keywords Fixed some typos in comments sql/sql_hints.yy Added parser rules for query block level hints in general, and specific rules for SEMIJOIN, NO_SEMIJOIN, and SUBQUERY hints sql/parse_tree_hints.h sql/parse_tree_hints.cc Added parse tree class for query block hints and enums for the strategies that can be used as arguments to hints sql/opt_hints.h sql/opt_hints.cc Added pointers to Opt_hints_qb for parse tree classes for SEMIJOIN/NO_SEMIJOIN and SUBQUERY hints. Added functions semijoin_enabled() and sj_enabled_strategies() to be used to compute effects of semijoin hints a query block. sql/sql_lex.h sql/sql_lex.cc Added private functions semijoin_enabled() and sj_enabled_strategies() to st_select_lex class. If query block level hints are defined for this query block, calls are forwarded to corresponding Opt_hints_qb functions. Otherwise, return value is based on optimizer_switch setting. sql/sql_resolver.cc In resolve_subquery() call semijoin_enabled() instead of checking optimizer_switch directly. In convert_subquery_to_semijoin() call sj_enabled_strategies() to determine which semi-join strategies may be used. Stored this information in the NESTED_JOIN object of corresponding semijoin nest. sql/table.h Added member sj_enabled_strategies to NESTED_JOIN to be used to store which semijoin strategies may be used. sql/sql_planner.cc Change code that checks which semijoin strategies may be used to use NESTED_JOIN::sj_enabled_strategies of the corresponding semijoin nest instead of optimizer_switch. Added optimizer trace for the case where new plan is cheaper but contains disabled strategy. Changed wording of optimizer trace for case when a less cheap plan is selected. sql/sql_optimizer.cc Change code that checks which semijoin strategies may be used to use NESTED_JOIN::sj_enabled_strategies of the corresponding semijoin nest instead of optimizer_switch. mysql-test/r/opt_hints_subquery.result mysql-test/t/opt_hints_subquery.test Tests for subquery hints mysql-test/suite/opt_trace/r/subquery_no_prot.result mysql-test/suite/opt_trace/r/subquery_ps_prot.result Changes to optimizer trace (see sql_planner.cc) WL#8244 Hints for subquery strategies. Part#2 followup: Fix friend declaration Prior to c++11, friend declaration of a class needs to contain the "class" word. WL#8244 Hints for subquery strategies. Part#3: Add support for SUBQUERY hint sql/sql_hints.yy Changed parser rules for SUBQUERY hint according to WL specifications. (It is not possible to list multiple strategies for this hint.) sql/parse_tree_hints.cc PT_qb_level_hint::contextualize() Added checks that makes sure that only one SEMIJOIN, NO_SEMIJOIN, and SUBQUERY hint is registered per query block. PT_qb_level_hint::append_args() Added handling of SUBQUERY argument (removed previous dummy implementation) sql/opt_hints.h sql/opt_hints.cc Added function Opt_hints_qb::subq_strategy() that returns which subquery execution strategy to use if SUBQUERY hint is specified. Modified Opt_hints_qb::semijoin_enabled() to take SUBQUERY hints into account. sql/sql_lex.h sql/sql_lex.cc Added function st_select_lex::subq_strategy() that return which subquery strategies may be used for the query block Added some missing documentation to functions added in Part#2. sql/sql_optimizer.cc Use st_select_lex::subq_strategy() instead of checking optimizer_switch settings directly when determining which subquery execution strategy to use. mysql-test/r/opt_hints_subquery.result mysql-test/t/opt_hints_subquery.test Tests for SUBQUERY hint plus a few additional tests for SEMIJOIN/NO_SEMIJOIN WL#8244 Hints for subquery strategies. Fixed a warning WL#8244 Hints for subquery strategies. Addendum#1: Fix review comments from Guilhem sql/sql_hints.yy Use same grammar rule for SEMIJOIN/NO_SEMIJOIN hints with and without list of strategies. Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. subq => subquery in names sql/parse_tree_hints.h Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. All enum types shouled have prefix enum_ according to code standard. subq => subquery in names Removed trailing white space sql/parse_tree_hints.cc Restructured PT_qb_level_hint::contextualize() and PT_qb_level_hint::append_args() sql/opt_hints.h subq => subquery in names Fixed comments Removed trailing white-space sql/opt_hints.cc Restructured Opt_hints_qb::semijoin_enabled() and Opt_hints_qb::subquery_strategy() Removed trailing white-space sql/sql_lex.h subq => subquery in names Removed trailing white-space sql/sql_lex.cc Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. Restructured st_select_lex::semijoin_enabled() subq => subquery in names Removed trailing white-space sql/sql_planner.h Changed doc for found_plan_with_allowed_sj sql/sql_planner.cc consider_plan(): check semijoin nest of all tables in DW range for allowed strategies, not just the first table. (In case tables of multiple sj nests are interleaved.) best_extension_by_limited_search(): No need to check has_sj when deciding on pruning. If there is no semijoin, found_plan_with_allowed_sj will be set to true when first plan is found. Fix in optimizer_trace: plan_use_disabled_strategy => plan_uses_disabled_strategy Removed redundant comments Removed trailing white-space sql/sql_optimizer.cc subq => subquery in names Removed trailing white-space sql/table.h Changed doc for sj_enabled_strategies mysql-test/t/opt_hints_subquery.test Fixed typos in comment statements mysql-test/r/opt_hints_subquery.result Plan changes due to change in consider_plan() Fixed typos in comment statements mysql-test/suite/opt_trace/r/subquery_no_prot.result mysql-test/suite/opt_trace/r/subquery_ps_prot.result Fixed a grammatical error in Optimizer Trace output WL#8244 Hints for subquery strategies. Addendum#2: More review comments from Guilhem sql/sql_hints.yy Use Item_exists_subselect::enum_exec_method instead of PT_hint_subquery::enum_strategy. sql/parse_tree_hints.h Use Item_exists_subselect::enum_exec_method instead of PT_hint_subquery::enum_strategy. Renamed flag/flags() to args/get_args() in PT_qb_level_hint sql/parse_tree_hints.cc Renamed flag/flags() to args/get_args() in PT_qb_level_hint Updated some comments sql/opt_hints.h Renamed flag/flags() to args/get_args() in PT_qb_level_hint Changed get_complex_hints argument from uint to opt_hints_enum Some corrections to function docs sql/opt_hints.cc Renamed flag/flags() to args/get_args() in PT_qb_level_hint Changed get_complex_hints argument from uint to opt_hints_enum Restructured if-tests of Opt_hints_qb::sj_enabled_strategies() and Opt_hints_qb::subquery_strategy() sql/sql_lex.h Added doc for opt_hints_qb sql/sql_lex.cc Move initialization of opt_hints_qb to constructor Restructured if-tests of st_select_lex::subquery_strategy() and st_select_lex::sj_enabled_strategies() sql/sql_planner.cc Updated a comment sql/sql_resolver.cc In setup_tables(): No need to access hints through context.select_lex within st_select_lex. mysql-test/t/opt_hints_subquery.test mysql-test/r/opt_hints_subquery.result Change comment for query to explain why LooseScan can not be used WL#8244 Hints for subquery strategies. Cleanup Reformatted opt_hints_subquery to use uppercase of SQL reserved words. Removed trailing whitespace WL#8244 Hints for subquery strategies. Addendum#3 Changes in optimizer_switch after prepare should be reflected in available semijoin strategies for execution. (This WL should not change how things work without hints.) Hence, enable subquery strategies needs to be recomputed on every execution instead of during semijoin transformation. sql/sql_lex.h sql/sql_lex.cc Replaced sj_enabled_strategies() with update_semijoin_strategies(). The new function iterates over all semijoin nests and recomputes the enabled strategies and store result in the corresponding nested_join object. Query block level hints are located from first table of semijoin nest since original select_lex was lost during semijoin transformation. sql/sql_optimizer.cc Call update_semijoin_strategies() from JOIN::optimize() so that it is recomputed on every execution. sql/sql_resolver.cc No longer compute available strategies during semijoin transformation since it will be recomputed later anyways. setup_tables() should only call adjust_table_hints() on first execution. Otherwise, one may adjust hints after semijoin transformation. This would be wrong since tables need to refer to the hints of the original query block. sql/sql_parse.cc Initialize TABLE_LIST hint pointers in st_select_lex::add_table_to_list() mysql-test/t/opt_hints_subquery.test mysql-test/r/opt_hints_subquery.result Update tests to reflect changed behavior WL#8244 Hints for subquery strategies. Addendum#4 Addressing review comments from Guilhem on Addendum#3. sql/sql_lex.cc No need to check table pointer. There is always at least one table per nest Fixed comments sql/sql_lex.h Fixed typo sql/sql_parse.cc Removed the added initialization of TABLE_LIST members. They are automatically zeroed by calloc. WL#8244 Hints for subquery strategies. Addendum#5.7 Result changes when porting to 5.7 branch.
Oystein Grovlen authoredPart#2: Add support for SEMIJOIN/_SEMIJOIN and SUBQUERY hints (Below are commit comments for several commits that have been squashed into one) Part#2: Add support for SEMIJOIN/NO_SEMIJOIN hints (Parsing of SUBQUERY hint added, but not the functionality) sql/lex.h Added symbols for new optimizer hint keywords Fixed some typos in comments sql/sql_hints.yy Added parser rules for query block level hints in general, and specific rules for SEMIJOIN, NO_SEMIJOIN, and SUBQUERY hints sql/parse_tree_hints.h sql/parse_tree_hints.cc Added parse tree class for query block hints and enums for the strategies that can be used as arguments to hints sql/opt_hints.h sql/opt_hints.cc Added pointers to Opt_hints_qb for parse tree classes for SEMIJOIN/NO_SEMIJOIN and SUBQUERY hints. Added functions semijoin_enabled() and sj_enabled_strategies() to be used to compute effects of semijoin hints a query block. sql/sql_lex.h sql/sql_lex.cc Added private functions semijoin_enabled() and sj_enabled_strategies() to st_select_lex class. If query block level hints are defined for this query block, calls are forwarded to corresponding Opt_hints_qb functions. Otherwise, return value is based on optimizer_switch setting. sql/sql_resolver.cc In resolve_subquery() call semijoin_enabled() instead of checking optimizer_switch directly. In convert_subquery_to_semijoin() call sj_enabled_strategies() to determine which semi-join strategies may be used. Stored this information in the NESTED_JOIN object of corresponding semijoin nest. sql/table.h Added member sj_enabled_strategies to NESTED_JOIN to be used to store which semijoin strategies may be used. sql/sql_planner.cc Change code that checks which semijoin strategies may be used to use NESTED_JOIN::sj_enabled_strategies of the corresponding semijoin nest instead of optimizer_switch. Added optimizer trace for the case where new plan is cheaper but contains disabled strategy. Changed wording of optimizer trace for case when a less cheap plan is selected. sql/sql_optimizer.cc Change code that checks which semijoin strategies may be used to use NESTED_JOIN::sj_enabled_strategies of the corresponding semijoin nest instead of optimizer_switch. mysql-test/r/opt_hints_subquery.result mysql-test/t/opt_hints_subquery.test Tests for subquery hints mysql-test/suite/opt_trace/r/subquery_no_prot.result mysql-test/suite/opt_trace/r/subquery_ps_prot.result Changes to optimizer trace (see sql_planner.cc) WL#8244 Hints for subquery strategies. Part#2 followup: Fix friend declaration Prior to c++11, friend declaration of a class needs to contain the "class" word. WL#8244 Hints for subquery strategies. Part#3: Add support for SUBQUERY hint sql/sql_hints.yy Changed parser rules for SUBQUERY hint according to WL specifications. (It is not possible to list multiple strategies for this hint.) sql/parse_tree_hints.cc PT_qb_level_hint::contextualize() Added checks that makes sure that only one SEMIJOIN, NO_SEMIJOIN, and SUBQUERY hint is registered per query block. PT_qb_level_hint::append_args() Added handling of SUBQUERY argument (removed previous dummy implementation) sql/opt_hints.h sql/opt_hints.cc Added function Opt_hints_qb::subq_strategy() that returns which subquery execution strategy to use if SUBQUERY hint is specified. Modified Opt_hints_qb::semijoin_enabled() to take SUBQUERY hints into account. sql/sql_lex.h sql/sql_lex.cc Added function st_select_lex::subq_strategy() that return which subquery strategies may be used for the query block Added some missing documentation to functions added in Part#2. sql/sql_optimizer.cc Use st_select_lex::subq_strategy() instead of checking optimizer_switch settings directly when determining which subquery execution strategy to use. mysql-test/r/opt_hints_subquery.result mysql-test/t/opt_hints_subquery.test Tests for SUBQUERY hint plus a few additional tests for SEMIJOIN/NO_SEMIJOIN WL#8244 Hints for subquery strategies. Fixed a warning WL#8244 Hints for subquery strategies. Addendum#1: Fix review comments from Guilhem sql/sql_hints.yy Use same grammar rule for SEMIJOIN/NO_SEMIJOIN hints with and without list of strategies. Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. subq => subquery in names sql/parse_tree_hints.h Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. All enum types shouled have prefix enum_ according to code standard. subq => subquery in names Removed trailing white space sql/parse_tree_hints.cc Restructured PT_qb_level_hint::contextualize() and PT_qb_level_hint::append_args() sql/opt_hints.h subq => subquery in names Fixed comments Removed trailing white-space sql/opt_hints.cc Restructured Opt_hints_qb::semijoin_enabled() and Opt_hints_qb::subquery_strategy() Removed trailing white-space sql/sql_lex.h subq => subquery in names Removed trailing white-space sql/sql_lex.cc Removed Pt_hint_sj::Strategy. Use OPTIMIZER_SWITCH_* values instead. Restructured st_select_lex::semijoin_enabled() subq => subquery in names Removed trailing white-space sql/sql_planner.h Changed doc for found_plan_with_allowed_sj sql/sql_planner.cc consider_plan(): check semijoin nest of all tables in DW range for allowed strategies, not just the first table. (In case tables of multiple sj nests are interleaved.) best_extension_by_limited_search(): No need to check has_sj when deciding on pruning. If there is no semijoin, found_plan_with_allowed_sj will be set to true when first plan is found. Fix in optimizer_trace: plan_use_disabled_strategy => plan_uses_disabled_strategy Removed redundant comments Removed trailing white-space sql/sql_optimizer.cc subq => subquery in names Removed trailing white-space sql/table.h Changed doc for sj_enabled_strategies mysql-test/t/opt_hints_subquery.test Fixed typos in comment statements mysql-test/r/opt_hints_subquery.result Plan changes due to change in consider_plan() Fixed typos in comment statements mysql-test/suite/opt_trace/r/subquery_no_prot.result mysql-test/suite/opt_trace/r/subquery_ps_prot.result Fixed a grammatical error in Optimizer Trace output WL#8244 Hints for subquery strategies. Addendum#2: More review comments from Guilhem sql/sql_hints.yy Use Item_exists_subselect::enum_exec_method instead of PT_hint_subquery::enum_strategy. sql/parse_tree_hints.h Use Item_exists_subselect::enum_exec_method instead of PT_hint_subquery::enum_strategy. Renamed flag/flags() to args/get_args() in PT_qb_level_hint sql/parse_tree_hints.cc Renamed flag/flags() to args/get_args() in PT_qb_level_hint Updated some comments sql/opt_hints.h Renamed flag/flags() to args/get_args() in PT_qb_level_hint Changed get_complex_hints argument from uint to opt_hints_enum Some corrections to function docs sql/opt_hints.cc Renamed flag/flags() to args/get_args() in PT_qb_level_hint Changed get_complex_hints argument from uint to opt_hints_enum Restructured if-tests of Opt_hints_qb::sj_enabled_strategies() and Opt_hints_qb::subquery_strategy() sql/sql_lex.h Added doc for opt_hints_qb sql/sql_lex.cc Move initialization of opt_hints_qb to constructor Restructured if-tests of st_select_lex::subquery_strategy() and st_select_lex::sj_enabled_strategies() sql/sql_planner.cc Updated a comment sql/sql_resolver.cc In setup_tables(): No need to access hints through context.select_lex within st_select_lex. mysql-test/t/opt_hints_subquery.test mysql-test/r/opt_hints_subquery.result Change comment for query to explain why LooseScan can not be used WL#8244 Hints for subquery strategies. Cleanup Reformatted opt_hints_subquery to use uppercase of SQL reserved words. Removed trailing whitespace WL#8244 Hints for subquery strategies. Addendum#3 Changes in optimizer_switch after prepare should be reflected in available semijoin strategies for execution. (This WL should not change how things work without hints.) Hence, enable subquery strategies needs to be recomputed on every execution instead of during semijoin transformation. sql/sql_lex.h sql/sql_lex.cc Replaced sj_enabled_strategies() with update_semijoin_strategies(). The new function iterates over all semijoin nests and recomputes the enabled strategies and store result in the corresponding nested_join object. Query block level hints are located from first table of semijoin nest since original select_lex was lost during semijoin transformation. sql/sql_optimizer.cc Call update_semijoin_strategies() from JOIN::optimize() so that it is recomputed on every execution. sql/sql_resolver.cc No longer compute available strategies during semijoin transformation since it will be recomputed later anyways. setup_tables() should only call adjust_table_hints() on first execution. Otherwise, one may adjust hints after semijoin transformation. This would be wrong since tables need to refer to the hints of the original query block. sql/sql_parse.cc Initialize TABLE_LIST hint pointers in st_select_lex::add_table_to_list() mysql-test/t/opt_hints_subquery.test mysql-test/r/opt_hints_subquery.result Update tests to reflect changed behavior WL#8244 Hints for subquery strategies. Addendum#4 Addressing review comments from Guilhem on Addendum#3. sql/sql_lex.cc No need to check table pointer. There is always at least one table per nest Fixed comments sql/sql_lex.h Fixed typo sql/sql_parse.cc Removed the added initialization of TABLE_LIST members. They are automatically zeroed by calloc. WL#8244 Hints for subquery strategies. Addendum#5.7 Result changes when porting to 5.7 branch.
Loading