Skip to content
  • Gleb Shchepa's avatar
    d658107d
    Bug#21286261: QUERY DIGEST DOES NOT REFLECT NEW OPTIMIZER HINTS · d658107d
    Gleb Shchepa authored
    When processing statements with hint comments (/*+...*/), the
    digest calculation was skipped for hint expressions, so the same
    statement had identical digests with and without hints.
    Also, the normalized query text missed hint expressions
    in the performance_schema.events_statements_history table.
    
    The fix updates several parts of the server:
    
    1. The gen_lex_token.cc token information file generator:
    some tricks to add hint parser internals(*) to the global token
    list (lex_token_array) have been introduced.
    
    *) Hint parser internals:
     a. Hint keywords: their integer token values may interfere with
        token values of the main SQL parser, so the TOK_HINT_ADJUST()
        adjustment macro has been introduced to resolve ambiguities.
     b. Tokens for "/*+" and "*/" hint comment delimiters to represent in
        the normalized query text.
     c. The TOK_IDENT_AT token to distinguish unqualified identifiers
        from table names in the table@query_block_name expression.
        Such a special token is necessary to generate normalized
        query texts without a space character between the
        table name and the "@" sign:
    
          "`table` @`qb_name`" is wrong,
          "`table`@`qb_name`"  is correct.
    
    2. The sql_digest.cc digest calculator and query text normalizer:
    the support for the TOK_IDENT_AT token has been added to not output
    a space between a table name and a "@query_block_name" suffix.
    
    3. The main lexer (sql_lex.{h,cc}):
    the Lex_input_stream::skip_digest flag has been introduced to
    append tokens to a digest buffer in correct order: add a
    hintable SQL keyword (SELECT, INSERT, UPDATE...) first, then add
    a hint expression (/*+ ... */).
    
    4. The hint parser (sql_lex_hints.{h,cc}):
    the Hint_scanner::add_hint_token_digest() function has been
    added to translate hint parser tokens into main parser-compatible
    ones and to add them into a digest buffer.
    
    5. Minor code cleanups:
    lex.h and sql_hints.yy: unused token declarations have been removed.
    d658107d
    Bug#21286261: QUERY DIGEST DOES NOT REFLECT NEW OPTIMIZER HINTS
    Gleb Shchepa authored
    When processing statements with hint comments (/*+...*/), the
    digest calculation was skipped for hint expressions, so the same
    statement had identical digests with and without hints.
    Also, the normalized query text missed hint expressions
    in the performance_schema.events_statements_history table.
    
    The fix updates several parts of the server:
    
    1. The gen_lex_token.cc token information file generator:
    some tricks to add hint parser internals(*) to the global token
    list (lex_token_array) have been introduced.
    
    *) Hint parser internals:
     a. Hint keywords: their integer token values may interfere with
        token values of the main SQL parser, so the TOK_HINT_ADJUST()
        adjustment macro has been introduced to resolve ambiguities.
     b. Tokens for "/*+" and "*/" hint comment delimiters to represent in
        the normalized query text.
     c. The TOK_IDENT_AT token to distinguish unqualified identifiers
        from table names in the table@query_block_name expression.
        Such a special token is necessary to generate normalized
        query texts without a space character between the
        table name and the "@" sign:
    
          "`table` @`qb_name`" is wrong,
          "`table`@`qb_name`"  is correct.
    
    2. The sql_digest.cc digest calculator and query text normalizer:
    the support for the TOK_IDENT_AT token has been added to not output
    a space between a table name and a "@query_block_name" suffix.
    
    3. The main lexer (sql_lex.{h,cc}):
    the Lex_input_stream::skip_digest flag has been introduced to
    append tokens to a digest buffer in correct order: add a
    hintable SQL keyword (SELECT, INSERT, UPDATE...) first, then add
    a hint expression (/*+ ... */).
    
    4. The hint parser (sql_lex_hints.{h,cc}):
    the Hint_scanner::add_hint_token_digest() function has been
    added to translate hint parser tokens into main parser-compatible
    ones and to add them into a digest buffer.
    
    5. Minor code cleanups:
    lex.h and sql_hints.yy: unused token declarations have been removed.
Loading