From e4af72bd5d2aeb16a343e4160843eb1d10203bc7 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 10 Sep 2024 18:59:08 +0300 Subject: [PATCH] MDEV-33281 Optimizer hints cleanup: add `const` specifiers, comments --- sql/opt_hints.cc | 12 +++++----- sql/opt_hints.h | 45 ++++++++++++++++++++++++++++++++++- sql/opt_hints_parser.h | 54 +++++++++++++++++++++--------------------- sql/simple_parser.h | 35 +++++++++++++++++++++++++++ sql/sql_lex.h | 2 +- 5 files changed, 113 insertions(+), 35 deletions(-) diff --git a/sql/opt_hints.cc b/sql/opt_hints.cc index 93665943362..b50fb3130af 100644 --- a/sql/opt_hints.cc +++ b/sql/opt_hints.cc @@ -685,7 +685,7 @@ bool Optimizer_hint_parser::Qb_name_hint::resolve(Parse_context *pc) const } -bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc) +bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc) const { if (pc->thd->lex->create_view) { @@ -699,20 +699,20 @@ bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc) if (!get_qb_hints(pc)) return true; - List_iterator_fast li(*this); - while(Optimizer_hint_parser::Hint *hint= li++) + for (Hint_list::const_iterator li= this->cbegin(); li != this->cend(); ++li) { - if (const Table_level_hint &table_hint= *hint) + const Optimizer_hint_parser::Hint &hint= *li; + if (const Table_level_hint &table_hint= hint) { if (table_hint.resolve(pc)) return true; } - else if (const Index_level_hint &index_hint= *hint) + else if (const Index_level_hint &index_hint= hint) { if (index_hint.resolve(pc)) return true; } - else if (const Qb_name_hint &qb_hint= *hint) + else if (const Qb_name_hint &qb_hint= hint) { if (qb_hint.resolve(pc)) return true; diff --git a/sql/opt_hints.h b/sql/opt_hints.h index 548a91ed227..cc87feaf605 100644 --- a/sql/opt_hints.h +++ b/sql/opt_hints.h @@ -15,7 +15,50 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* - Parse tree node classes for optimizer hint syntax + HintsArchitecture + + == Parsing == + Hints have a separate parser, see sql/opt_hint_parser.{h,cc} + The parser is invoked separately for each occurence of + + SELECT / *+ hint_body * / ... + + in the query. The result of parsing is saved in + SELECT_LEX::parsed_optimizer_hints. + + == Hint "resolution" == + + This is done using "resolve" method of parsed data structures + This process + - Creates interpreted hint structures: Opt_hints_global, Opt_hints_qb, + Opt_hints_table, Opt_hints_key. + - Interprets QB_NAME hints and assigns Query Block names. + - Table-level hints are put into their Query Block's Opt_hints_qb object. + - Index-level hints are put into their table's Opt_hints_table object. + + == Hint "adjustment" == + + During Name Resolution, setup_tables() calls adjust_table_hints() for each + table and sets TABLE_LIST::opt_hints_table to point to its Opt_hints_table. + + == Hint hierarchy == + + Hints have this hierarchy, parent to child: + + Opt_hints_global + Opt_hints_qb + Opt_hints_table + Opt_hints_key + + For some hints, one needs to check the hint's base object and its parent. For + example, MRR can be disabled on a per-index or a per-table basis. + + == How the optimizer checks hints == + + The optimizer checks what hints specify using these calls: + hint_table_state() + hint_table_state_or_fallback() + hint_key_state() */ diff --git a/sql/opt_hints_parser.h b/sql/opt_hints_parser.h index 4fc9bdc9d0f..368a5b26d75 100644 --- a/sql/opt_hints_parser.h +++ b/sql/opt_hints_parser.h @@ -218,29 +218,29 @@ public: private: - using PARSER= Optimizer_hint_parser; // for a shorter notation + using Parser= Optimizer_hint_parser; // for a shorter notation // Rules consisting of a single token - class TokenAT: public TOKEN + class TokenAT: public TOKEN { public: using TOKEN::TOKEN; }; - class TokenEOF: public TOKEN + class TokenEOF: public TOKEN { public: using TOKEN::TOKEN; }; - class Keyword_QB_NAME: public TOKEN + class Keyword_QB_NAME: public TOKEN { public: using TOKEN::TOKEN; }; - class Identifier: public TOKEN + class Identifier: public TOKEN { public: using TOKEN::TOKEN; @@ -258,13 +258,13 @@ private: } }; - class LParen: public TOKEN + class LParen: public TOKEN { public: using TOKEN::TOKEN; }; - class RParen: public TOKEN + class RParen: public TOKEN { public: using TOKEN::TOKEN; @@ -285,7 +285,7 @@ private: id == TokenID::keyword_NO_BNL; } }; - class Table_level_hint_type: public TokenChoice { public: @@ -305,7 +305,7 @@ private: id == TokenID::keyword_NO_MRR; } }; - class Index_level_hint_type: public TokenChoice { public: @@ -343,7 +343,7 @@ private: /* at_query_block_name ::= @ query_block_name */ - class At_query_block_name: public AND2 + class At_query_block_name: public AND2 { public: using AND2::AND2; @@ -353,7 +353,7 @@ private: /* opt_qb_name ::= [ @ query_block_name ] */ - class Opt_qb_name: public OPT + class Opt_qb_name: public OPT { public: using OPT::OPT; @@ -362,7 +362,7 @@ private: /* hint_param_table ::= table_name opt_qb_name */ - class Hint_param_table: public AND2 + class Hint_param_table: public AND2 { public: using AND2::AND2; @@ -382,7 +382,7 @@ private: size_t count() const { return elements; } }; - class Opt_hint_param_table_list: public LIST @@ -403,7 +403,7 @@ private: size_t count() const { return elements; } }; - class Opt_table_name_list: public LIST { @@ -425,7 +425,7 @@ private: size_t count() const { return elements; } }; - class Opt_hint_param_index_list: public LIST @@ -439,7 +439,7 @@ private: hint_param_table_ext ::= hint_param_table | @ query_block_name table_name */ - class At_query_block_name_table_name: public AND2 { @@ -465,7 +465,7 @@ private: } }; - class Hint_param_table_ext: public OR2C @@ -480,7 +480,7 @@ private: @ query_block_name opt_table_name_list */ class At_query_block_name_opt_table_name_list: public AND2< - PARSER, + Parser, At_query_block_name, Opt_table_name_list> { @@ -494,7 +494,7 @@ private: | opt_hint_param_table_list */ class Table_level_hint_body: public OR2< - PARSER, + Parser, At_query_block_name_opt_table_name_list, Opt_hint_param_table_list> { @@ -503,7 +503,7 @@ private: }; // table_level_hint ::= table_level_hint_type ( table_level_hint_body ) - class Table_level_hint: public AND4 { @@ -527,7 +527,7 @@ private: // index_level_hint ::= index_level_hint_type ( index_level_hint_body ) - class Index_level_hint: public AND4 @@ -579,13 +579,13 @@ private: size_t count() const { return elements; } }; - class Hint_list: public LIST { public: using LIST::LIST; - bool resolve(Parse_context *pc); + bool resolve(Parse_context *pc) const; }; public: @@ -593,7 +593,7 @@ public: The main rule: hints ::= hint_list EOF */ - class Hints: public AND2 + class Hints: public AND2 { public: using AND2::AND2; diff --git a/sql/simple_parser.h b/sql/simple_parser.h index 13cd86242bf..a49b716182c 100644 --- a/sql/simple_parser.h +++ b/sql/simple_parser.h @@ -21,6 +21,41 @@ #include "simple_tokenizer.h" +/* + A set of templates for constructing a recursive-descent LL(1) parser. + + One is supposed to define classes corresponding to grammar productions. + The class should inherit from the grammar rule template. For example, a + grammar rule + + foo := bar, baz + + is implemented with + + class Bar ... ; // "bar" is parsed into Bar object + class Baz ... ; // "baz" is parsed into Baz object + + // "foo" is parsed into a Foo object. + class Foo: public Parser_templates::AND2 { + using AND2::AND2; + ... + }; + + Parsing code is generated by inheriting AND2's constructors with "using" like + shown above. All grammar rule-based classes should also have + - a capability to construct an "empty"(i.e. invalid) object with the default + constructor. This will be invoked when parsing fails. + - operator bool() which returns true if the object is non-empty (i.e. valid) + and false otherwise. + + Parsing is done by constructing parser output from the parser object: + + Foo parsed_output(parser); + + PARSER_Impl here is a class implementing a tokenizer and error condition + storage, like Extended_string_tokenizer. +*/ + class Parser_templates { protected: diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 88362482859..50bd1874ddd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1273,7 +1273,7 @@ public: /* it is for correct printing SELECT options */ thr_lock_type lock_type; - Optimizer_hint_parser_output *parsed_optimizer_hints; + const Optimizer_hint_parser_output *parsed_optimizer_hints; /** System Versioning */ int vers_setup_conds(THD *thd, TABLE_LIST *tables);