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>
20class 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*/
29struct 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 ... &lt;non-id-token&gt; &lt;non-id-token&gt; &lt;id-token&gt; &lt;id_len&gt; &lt;id_text&gt; ...
41 For Example:
42 SELECT * FROM T1;
43 &lt;SELECT_TOKEN&gt; &lt;*&gt; &lt;FROM_TOKEN&gt; &lt;ID_TOKEN&gt; &lt;2&gt; &lt;T1&gt;
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};
103typedef 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*/
110void 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*/
125void compute_digest_text(const sql_digest_storage *digest_storage,
126 String *digest_text);
127
128#endif
129
130