25 #include "my_global.h"
33 #include "sql_get_diagnostics.h"
34 #include "sql_string.h"
38 #include "../sql/sql_yacc.h"
39 #include "../storage/perfschema/pfs_lex_token.h"
46 #define LEX_YYSTYPE YYSTYPE
66 bool flag_statements_digest=
true;
71 volatile uint32 digest_index= 1;
74 static bool digest_hash_inited=
false;
94 statements_digest_stat_array=
97 if (unlikely(statements_digest_stat_array == NULL))
100 for (index= 0; index < digest_max; index++)
109 void cleanup_digest(
void)
112 pfs_free(statements_digest_stat_array);
113 statements_digest_stat_array= NULL;
117 static uchar *digest_hash_get_key(
const uchar *
entry,
size_t *length,
124 DBUG_ASSERT(typed_entry != NULL);
125 digest= *typed_entry;
126 DBUG_ASSERT(digest != NULL);
129 return const_cast<uchar*
> (
reinterpret_cast<const uchar*
> (result));
138 int init_digest_hash(
void)
140 if ((! digest_hash_inited) && (digest_max > 0))
143 LF_HASH_UNIQUE, 0, 0, digest_hash_get_key,
145 digest_hash.size= digest_max;
146 digest_hash_inited=
true;
151 void cleanup_digest_hash(
void)
153 if (digest_hash_inited)
155 lf_hash_destroy(&digest_hash);
156 digest_hash_inited=
false;
164 if (!digest_hash_inited)
173 PSI_digest_storage *digest_storage,
174 const char *schema_name,
175 uint schema_name_length)
177 if (statements_digest_stat_array == NULL)
180 if (digest_storage->m_byte_count <= 0)
183 LF_PINS *pins= get_digest_hash_pins(thread);
184 if (unlikely(pins == NULL))
193 memset(& hash_key, 0,
sizeof(hash_key));
196 (
char *) digest_storage->m_token_array,
197 digest_storage->m_byte_count);
199 hash_key.m_schema_name_length= schema_name_length;
200 if (schema_name_length > 0)
201 memcpy(hash_key.m_schema_name, schema_name, schema_name_length);
206 const uint retry_max= 3;
210 ulonglong now= my_micro_time();
216 (lf_hash_search(&digest_hash, pins,
219 if (entry && (entry != MY_ERRPTR))
223 pfs->m_last_seen= now;
224 lf_hash_search_unpin(pins);
228 lf_hash_search_unpin(pins);
231 if (digest_index == 0)
234 pfs= &statements_digest_stat_array[0];
238 pfs->m_last_seen= now;
243 if (safe_index >= digest_max)
247 pfs= &statements_digest_stat_array[0];
251 pfs->m_last_seen= now;
256 pfs= &statements_digest_stat_array[safe_index];
268 pfs->m_last_seen= now;
270 res= lf_hash_insert(&digest_hash, pins, &pfs);
271 if (likely(res == 0))
279 if (++retry_count > retry_max)
295 LF_PINS *pins= get_digest_hash_pins(thread);
296 if (unlikely(pins == NULL))
303 (lf_hash_search(&digest_hash, pins,
306 if (entry && (entry != MY_ERRPTR))
308 lf_hash_delete(&digest_hash, pins,
311 lf_hash_search_unpin(pins);
332 void reset_esms_by_digest()
336 if (statements_digest_stat_array == NULL)
339 PFS_thread *thread= PFS_thread::get_current_thread();
340 if (unlikely(thread == NULL))
344 for (index= 0; index < digest_max; index++)
360 void get_digest_text(
char* digest_text, PSI_digest_storage* digest_storage)
362 DBUG_ASSERT(digest_storage != NULL);
363 bool truncated=
false;
364 int byte_count= digest_storage->m_byte_count;
365 char *digest_output= digest_text;
369 lex_token_string *tok_data;
373 if (byte_count <= 0 || byte_count > PSI_MAX_DIGEST_STORAGE_SIZE)
380 const CHARSET_INFO *from_cs= get_charset(digest_storage->m_charset_number, MYF(0));
397 const uint max_converted_size= PSI_MAX_DIGEST_STORAGE_SIZE * 4;
398 char id_buffer[max_converted_size];
401 bool convert_text= !my_charset_same(from_cs, to_cs);
403 DBUG_ASSERT(byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
405 while ((current_byte < byte_count) &&
406 (bytes_available > 0) &&
409 current_byte=
read_token(digest_storage, current_byte, &tok);
411 if (tok <= 0 || tok >= array_elements(lex_token_array))
417 tok_data= &lex_token_array[tok];
435 if (to_cs->mbmaxlen*id_len > max_converted_size)
441 id_length= my_convert(id_buffer, max_converted_size, to_cs,
442 id_ptr, id_len, from_cs, &err_cs);
443 id_string= id_buffer;
451 if (id_length == 0 || err_cs != 0)
457 bytes_needed= id_length + (tok == IDENT ? 1 : 3);
458 if (bytes_needed <= bytes_available)
460 if (tok == IDENT_QUOTED)
461 *digest_output++=
'`';
464 memcpy(digest_output, id_string, id_length);
465 digest_output+= id_length;
467 if (tok == IDENT_QUOTED)
468 *digest_output++=
'`';
469 *digest_output++=
' ';
470 bytes_available-= bytes_needed;
485 int tok_length= tok_data->m_token_length;
486 bytes_needed= tok_length + 1;
488 if (bytes_needed <= bytes_available)
490 strncpy(digest_output, tok_data->m_token_string, tok_length);
491 digest_output+= tok_length;
492 *digest_output++=
' ';
493 bytes_available-= bytes_needed;
504 if (digest_storage->m_full || truncated)
506 strcpy(digest_output,
"...");
510 *digest_output=
'\0';
513 static inline uint peek_token(
const PSI_digest_storage *digest,
int index)
516 DBUG_ASSERT(index >= 0);
517 DBUG_ASSERT(index + PFS_SIZE_OF_A_TOKEN <= digest->m_byte_count);
518 DBUG_ASSERT(digest->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
520 token= ((digest->m_token_array[index + 1])<<8) | digest->m_token_array[
index];
528 static inline void peek_last_two_tokens(
const PSI_digest_storage* digest_storage,
529 int last_id_index, uint *t1, uint *t2)
531 int byte_count= digest_storage->m_byte_count;
532 int peek_index= byte_count - PFS_SIZE_OF_A_TOKEN;
534 if (last_id_index <= peek_index)
537 *t1= peek_token(digest_storage, peek_index);
539 peek_index-= PFS_SIZE_OF_A_TOKEN;
540 if (last_id_index <= peek_index)
543 *t2= peek_token(digest_storage, peek_index);
557 struct PSI_digest_locker* pfs_digest_start_v1(PSI_statement_locker *locker)
559 PSI_statement_locker_state *statement_state;
560 statement_state=
reinterpret_cast<PSI_statement_locker_state*
> (locker);
561 DBUG_ASSERT(statement_state != NULL);
563 if (statement_state->m_discarded)
568 PSI_digest_locker_state *digest_state;
569 digest_state= &statement_state->m_digest_state;
570 return reinterpret_cast<PSI_digest_locker*
> (digest_state);
576 PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker,
578 OPAQUE_LEX_YYSTYPE *yylval)
580 PSI_digest_locker_state *state= NULL;
581 PSI_digest_storage *digest_storage= NULL;
583 state=
reinterpret_cast<PSI_digest_locker_state*
> (locker);
584 DBUG_ASSERT(state != NULL);
586 digest_storage= &state->m_digest_storage;
592 if (digest_storage->m_full || token == END_OF_INPUT)
619 token= TOK_PFS_GENERIC_VALUE;
624 peek_last_two_tokens(digest_storage, state->m_last_id_index,
625 &last_token, &last_token2);
627 if ((last_token2 == TOK_PFS_GENERIC_VALUE ||
628 last_token2 == TOK_PFS_GENERIC_VALUE_LIST ||
629 last_token2 == NULL_SYM) &&
641 digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN;
642 token= TOK_PFS_GENERIC_VALUE_LIST;
652 peek_last_two_tokens(digest_storage, state->m_last_id_index,
653 &last_token, &last_token2);
655 if (last_token == TOK_PFS_GENERIC_VALUE &&
663 digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN;
664 token= TOK_PFS_ROW_SINGLE_VALUE;
667 peek_last_two_tokens(digest_storage, state->m_last_id_index,
668 &last_token, &last_token2);
670 if ((last_token2 == TOK_PFS_ROW_SINGLE_VALUE ||
671 last_token2 == TOK_PFS_ROW_SINGLE_VALUE_LIST) &&
683 digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN;
684 token= TOK_PFS_ROW_SINGLE_VALUE_LIST;
687 else if (last_token == TOK_PFS_GENERIC_VALUE_LIST &&
695 digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN;
696 token= TOK_PFS_ROW_MULTIPLE_VALUE;
699 peek_last_two_tokens(digest_storage, state->m_last_id_index,
700 &last_token, &last_token2);
702 if ((last_token2 == TOK_PFS_ROW_MULTIPLE_VALUE ||
703 last_token2 == TOK_PFS_ROW_MULTIPLE_VALUE_LIST) &&
715 digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN;
716 token= TOK_PFS_ROW_MULTIPLE_VALUE_LIST;
728 LEX_YYSTYPE *lex_token= (LEX_YYSTYPE*) yylval;
729 char *yytext= lex_token->lex_str.str;
730 int yylen= lex_token->lex_str.length;
736 state->m_last_id_index= digest_storage->m_byte_count;