1 | /* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software Foundation, |
14 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ |
15 | |
16 | #ifndef SQL_DIGEST_H |
17 | #define SQL_DIGEST_H |
18 | |
19 | #include <string.h> |
20 | class String; |
21 | #include "my_md5.h" |
22 | |
23 | #define MAX_DIGEST_STORAGE_SIZE (1024*1024) |
24 | |
25 | /** |
26 | Structure to store token count/array for a statement |
27 | on which digest is to be calculated. |
28 | */ |
29 | struct sql_digest_storage |
30 | { |
31 | bool m_full; |
32 | uint m_byte_count; |
33 | unsigned char m_md5[MD5_HASH_SIZE]; |
34 | /** Character set number. */ |
35 | uint m_charset_number; |
36 | /** |
37 | Token array. |
38 | Token array is an array of bytes to store tokens received during parsing. |
39 | Following is the way token array is formed. |
40 | ... <non-id-token> <non-id-token> <id-token> <id_len> <id_text> ... |
41 | For Example: |
42 | SELECT * FROM T1; |
43 | <SELECT_TOKEN> <*> <FROM_TOKEN> <ID_TOKEN> <2> <T1> |
44 | |
45 | @note Only the first @c m_byte_count bytes are initialized, |
46 | out of @c m_token_array_length. |
47 | */ |
48 | unsigned char *m_token_array; |
49 | /* Length of the token array to be considered for DIGEST_TEXT calculation. */ |
50 | uint m_token_array_length; |
51 | |
52 | sql_digest_storage() |
53 | { |
54 | reset(NULL, 0); |
55 | } |
56 | |
57 | inline void reset(unsigned char *token_array, size_t length) |
58 | { |
59 | m_token_array= token_array; |
60 | m_token_array_length= (uint)length; |
61 | reset(); |
62 | } |
63 | |
64 | inline void reset() |
65 | { |
66 | m_full= false; |
67 | m_byte_count= 0; |
68 | m_charset_number= 0; |
69 | memset(m_md5, 0, MD5_HASH_SIZE); |
70 | } |
71 | |
72 | inline bool is_empty() |
73 | { |
74 | return (m_byte_count == 0); |
75 | } |
76 | |
77 | inline void copy(const sql_digest_storage *from) |
78 | { |
79 | /* |
80 | Keep in mind this is a dirty copy of something that may change, |
81 | as the thread producing the digest is executing concurrently, |
82 | without any lock enforced. |
83 | */ |
84 | uint byte_count_copy= m_token_array_length < from->m_byte_count ? |
85 | m_token_array_length : from->m_byte_count; |
86 | |
87 | if (byte_count_copy > 0) |
88 | { |
89 | m_full= from->m_full; |
90 | m_byte_count= byte_count_copy; |
91 | m_charset_number= from->m_charset_number; |
92 | memcpy(m_token_array, from->m_token_array, m_byte_count); |
93 | memcpy(m_md5, from->m_md5, MD5_HASH_SIZE); |
94 | } |
95 | else |
96 | { |
97 | m_full= false; |
98 | m_byte_count= 0; |
99 | m_charset_number= 0; |
100 | } |
101 | } |
102 | }; |
103 | typedef struct sql_digest_storage sql_digest_storage; |
104 | |
105 | /** |
106 | Compute a digest hash. |
107 | @param digest_storage The digest |
108 | @param [out] md5 The computed digest hash. This parameter is a buffer of size @c MD5_HASH_SIZE. |
109 | */ |
110 | void compute_digest_md5(const sql_digest_storage *digest_storage, unsigned char *md5); |
111 | |
112 | /** |
113 | Compute a digest text. |
114 | A 'digest text' is a textual representation of a query, |
115 | where: |
116 | - comments are removed, |
117 | - non significant spaces are removed, |
118 | - literal values are replaced with a special '?' marker, |
119 | - lists of values are collapsed using a shorter notation |
120 | @param digest_storage The digest |
121 | @param [out] digest_text |
122 | @param digest_text_length Size of @c digest_text. |
123 | @param [out] truncated true if the text representation was truncated |
124 | */ |
125 | void compute_digest_text(const sql_digest_storage *digest_storage, |
126 | String *digest_text); |
127 | |
128 | #endif |
129 | |
130 | |