summaryrefslogtreecommitdiff
path: root/storage/perfschema
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2015-01-21 14:53:40 +0100
committerSergei Golubchik <sergii@pisem.net>2015-01-21 14:53:40 +0100
commitb0a8e0735746245e00eb4a57e83ebffdc4fee7ea (patch)
tree5a938ca57ed5edf58ab7e455e83006b35b525bf9 /storage/perfschema
parent78e131d4930bb028839d2ede0341f134c545b750 (diff)
parent05c002d0ffc003dfe6646f785dabef0c440da3d1 (diff)
downloadmariadb-git-b0a8e0735746245e00eb4a57e83ebffdc4fee7ea.tar.gz
P_S 5.6.22
Diffstat (limited to 'storage/perfschema')
-rw-r--r--storage/perfschema/gen_pfs_lex_token.cc96
-rw-r--r--storage/perfschema/pfs_digest.cc59
2 files changed, 146 insertions, 9 deletions
diff --git a/storage/perfschema/gen_pfs_lex_token.cc b/storage/perfschema/gen_pfs_lex_token.cc
index 7581255b284..c67f2920b75 100644
--- a/storage/perfschema/gen_pfs_lex_token.cc
+++ b/storage/perfschema/gen_pfs_lex_token.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,10 +36,13 @@
See also YYMAXUTOK.
*/
#define MY_MAX_TOKEN 1000
+/** Generated token. */
struct gen_lex_token_string
{
const char *m_token_string;
int m_token_length;
+ bool m_append_space;
+ bool m_start_expr;
};
gen_lex_token_string compiled_token_array[MY_MAX_TOKEN];
@@ -76,6 +79,13 @@ void set_token(int tok, const char *str)
compiled_token_array[tok].m_token_string= str;
compiled_token_array[tok].m_token_length= strlen(str);
+ compiled_token_array[tok].m_append_space= true;
+ compiled_token_array[tok].m_start_expr= false;
+}
+
+void set_start_expr_token(int tok)
+{
+ compiled_token_array[tok].m_start_expr= true;
}
void compute_tokens()
@@ -91,6 +101,8 @@ void compute_tokens()
{
compiled_token_array[tok].m_token_string= "(unknown)";
compiled_token_array[tok].m_token_length= 9;
+ compiled_token_array[tok].m_append_space= true;
+ compiled_token_array[tok].m_start_expr= false;
}
/*
@@ -102,6 +114,7 @@ void compute_tokens()
str[0]= (char) tok;
compiled_token_array[tok].m_token_string= str;
compiled_token_array[tok].m_token_length= 1;
+ compiled_token_array[tok].m_append_space= true;
}
max_token_seen= 255;
@@ -202,6 +215,71 @@ void compute_tokens()
max_token_seen++;
tok_pfs_unused= max_token_seen;
set_token(tok_pfs_unused, "UNUSED");
+
+ /*
+ Fix whitespace for some special tokens.
+ */
+
+ /*
+ The lexer parses "@@variable" as '@', '@', 'variable',
+ returning a token for '@' alone.
+
+ This is incorrect, '@' is not really a token,
+ because the syntax "@ @ variable" (with spaces) is not accepted:
+ The lexer keeps some internal state after the '@' fake token.
+
+ To work around this, digest text are printed as "@@variable".
+ */
+ compiled_token_array[(int) '@'].m_append_space= false;
+
+ /*
+ Define additional properties for tokens.
+
+ List all the token that are followed by an expression.
+ This is needed to differentiate unary from binary
+ '+' and '-' operators, because we want to:
+ - reduce <unary +> <NUM> to <?>,
+ - preserve <...> <binary +> <NUM> as is.
+ */
+ set_start_expr_token('(');
+ set_start_expr_token(',');
+ set_start_expr_token(EVERY_SYM);
+ set_start_expr_token(AT_SYM);
+ set_start_expr_token(STARTS_SYM);
+ set_start_expr_token(ENDS_SYM);
+ set_start_expr_token(DEFAULT);
+ set_start_expr_token(RETURN_SYM);
+ set_start_expr_token(IF);
+ set_start_expr_token(ELSEIF_SYM);
+ set_start_expr_token(CASE_SYM);
+ set_start_expr_token(WHEN_SYM);
+ set_start_expr_token(WHILE_SYM);
+ set_start_expr_token(UNTIL_SYM);
+ set_start_expr_token(SELECT_SYM);
+
+ set_start_expr_token(OR_SYM);
+ set_start_expr_token(OR2_SYM);
+ set_start_expr_token(XOR);
+ set_start_expr_token(AND_SYM);
+ set_start_expr_token(AND_AND_SYM);
+ set_start_expr_token(NOT_SYM);
+ set_start_expr_token(BETWEEN_SYM);
+ set_start_expr_token(LIKE);
+ set_start_expr_token(REGEXP);
+
+ set_start_expr_token('|');
+ set_start_expr_token('&');
+ set_start_expr_token(SHIFT_LEFT);
+ set_start_expr_token(SHIFT_RIGHT);
+ set_start_expr_token('+');
+ set_start_expr_token('-');
+ set_start_expr_token(INTERVAL_SYM);
+ set_start_expr_token('*');
+ set_start_expr_token('/');
+ set_start_expr_token('%');
+ set_start_expr_token(DIV_SYM);
+ set_start_expr_token(MOD_SYM);
+ set_start_expr_token('^');
}
void print_tokens()
@@ -214,20 +292,26 @@ void print_tokens()
for (tok= 0; tok<256; tok++)
{
- printf("/* %03d */ { \"\\x%02x\", 1},\n", tok, tok);
+ printf("/* %03d */ { \"\\x%02x\", 1, %s, %s},\n",
+ tok,
+ tok,
+ compiled_token_array[tok].m_append_space ? "true" : "false",
+ compiled_token_array[tok].m_start_expr ? "true" : "false");
}
printf("/* PART 2: named tokens. */\n");
for (tok= 256; tok<= max_token_seen; tok++)
{
- printf("/* %03d */ { \"%s\", %d},\n",
+ printf("/* %03d */ { \"%s\", %d, %s, %s},\n",
tok,
compiled_token_array[tok].m_token_string,
- compiled_token_array[tok].m_token_length);
+ compiled_token_array[tok].m_token_length,
+ compiled_token_array[tok].m_append_space ? "true" : "false",
+ compiled_token_array[tok].m_start_expr ? "true" : "false");
}
- printf("/* DUMMY */ { \"\", 0}\n");
+ printf("/* DUMMY */ { \"\", 0, false, false}\n");
printf("};\n");
printf("/* PFS specific tokens. */\n");
@@ -254,6 +338,8 @@ int main(int argc,char **argv)
printf("{\n");
printf(" const char *m_token_string;\n");
printf(" int m_token_length;\n");
+ printf(" bool m_append_space;\n");
+ printf(" bool m_start_expr;\n");
printf("};\n");
printf("typedef struct lex_token_string lex_token_string;\n");
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 473f4edce7a..c3c52bbd56d 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -602,16 +602,67 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker,
switch (token)
{
- case BIN_NUM:
+ case NUM:
+ case LONG_NUM:
+ case ULONGLONG_NUM:
case DECIMAL_NUM:
case FLOAT_NUM:
+ case BIN_NUM:
case HEX_NUM:
+ {
+ bool found_unary;
+ do
+ {
+ found_unary= false;
+ peek_last_two_tokens(digest_storage, state->m_last_id_index,
+ &last_token, &last_token2);
+
+ if ((last_token == '-') || (last_token == '+'))
+ {
+ /*
+ We need to differentiate:
+ - a <unary minus> operator
+ - a <unary plus> operator
+ from
+ - a <binary minus> operator
+ - a <binary plus> operator
+ to only reduce "a = -1" to "a = ?", and not change "b - 1" to "b ?"
+
+ Binary operators are found inside an expression,
+ while unary operators are found at the beginning of an expression, or after operators.
+
+ To achieve this, every token that is followed by an <expr> expression
+ in the SQL grammar is flagged.
+ See sql/sql_yacc.yy
+ See sql/gen_lex_token.cc
+
+ For example,
+ "(-1)" is parsed as "(", "-", NUM, ")", and lex_token_array["("].m_start_expr is true,
+ so reduction of the "-" NUM is done, the result is "(?)".
+ "(a-1)" is parsed as "(", ID, "-", NUM, ")", and lex_token_array[ID].m_start_expr is false,
+ so the operator is binary, no reduction is done, and the result is "(a-?)".
+ */
+ if (lex_token_array[last_token2].m_start_expr)
+ {
+ /*
+ REDUCE:
+ TOK_PFS_GENERIC_VALUE := (UNARY_PLUS | UNARY_MINUS) (NUM | LOG_NUM | ... | FLOAT_NUM)
+
+ REDUCE:
+ TOK_PFS_GENERIC_VALUE := (UNARY_PLUS | UNARY_MINUS) TOK_PFS_GENERIC_VALUE
+ */
+ token= TOK_PFS_GENERIC_VALUE;
+ digest_storage->m_byte_count-= PFS_SIZE_OF_A_TOKEN;
+ found_unary= true;
+ }
+ }
+ } while (found_unary);
+ }
+ /* fall through, for case NULL_SYM below */
case LEX_HOSTNAME:
- case LONG_NUM:
- case NUM:
case TEXT_STRING:
case NCHAR_STRING:
- case ULONGLONG_NUM:
+ case PARAM_MARKER:
{
/*
REDUCE: