| 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 | |