Merge lp:~akopytov/percona-server/bug915814-5.5 into lp:percona-server/5.5
- bug915814-5.5
- Merge into 5.5
Proposed by
Alexey Kopytov
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Laurynas Biveinis | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 230 | ||||||||
Proposed branch: | lp:~akopytov/percona-server/bug915814-5.5 | ||||||||
Merge into: | lp:percona-server/5.5 | ||||||||
Diff against target: |
1805 lines (+448/-1188) 1 file modified
patches/query_cache_enhance.patch (+448/-1188) |
||||||||
To merge this branch: | bzr merge lp:~akopytov/percona-server/bug915814-5.5 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Review via email: mp+98997@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
There was another problem with the old patch that was caught by Jenkins. Link for the fixed version: http://
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
I'd prefer to have a #define or enum constant for the query buffer length, together with the layout-explaining comment, instead of two separate copies at around diff lines 348 and 942.
review:
Needs Fixing
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
On 25.03.12 14:16, Laurynas Biveinis wrote:
> I'd prefer to have a #define or enum constant for the query buffer length
Done.
http://
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'patches/query_cache_enhance.patch' |
2 | --- patches/query_cache_enhance.patch 2012-02-02 07:11:59 +0000 |
3 | +++ patches/query_cache_enhance.patch 2012-03-25 11:37:19 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -# name : query_cache_enhance.patch |
6 | +# name : query_cache_with_comments.patch |
7 | # introduced : 11 or before |
8 | # maintainer : Oleg |
9 | # |
10 | @@ -25,7 +25,7 @@ |
11 | +2010-11 - Ported to 5.5 |
12 | --- a/sql/mysqld.cc |
13 | +++ b/sql/mysqld.cc |
14 | -@@ -909,6 +909,7 @@ |
15 | +@@ -915,6 +915,7 @@ |
16 | #endif |
17 | #ifdef HAVE_QUERY_CACHE |
18 | ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE; |
19 | @@ -43,510 +43,252 @@ |
20 | extern ulonglong log_output_options; |
21 | extern ulong log_backup_output_options; |
22 | extern my_bool opt_log_queries_not_using_indexes; |
23 | +--- /dev/null |
24 | ++++ b/sql/query_strip_comments.h |
25 | +@@ -0,0 +1,37 @@ |
26 | ++#ifndef _SQL_QUERY_STRIPC_COMMENTS_H_ |
27 | ++#define _SQL_QUERY_STRIPC_COMMENTS_H_ |
28 | ++#ifdef HAVE_QUERY_CACHE |
29 | ++ |
30 | ++// implemented in sql_cache.cc |
31 | ++class QueryStripComments |
32 | ++{ |
33 | ++private: |
34 | ++ QueryStripComments(const QueryStripComments&); |
35 | ++ QueryStripComments& operator=(const QueryStripComments&); |
36 | ++public: |
37 | ++ QueryStripComments(); |
38 | ++ ~QueryStripComments(); |
39 | ++ void set(const char* a_query, uint a_query_length, uint a_additional_length); |
40 | ++ |
41 | ++ char* query() { return buffer; } |
42 | ++ uint query_length() { return length; } |
43 | ++private: |
44 | ++ void cleanup(); |
45 | ++private: |
46 | ++ char* buffer; |
47 | ++ uint length /*query length, not buffer length*/; |
48 | ++ uint buffer_length; |
49 | ++}; |
50 | ++class QueryStripComments_Backup |
51 | ++{ |
52 | ++public: |
53 | ++ QueryStripComments_Backup(THD* a_thd,QueryStripComments* qsc); |
54 | ++ ~QueryStripComments_Backup(); |
55 | ++private: |
56 | ++ THD* thd; |
57 | ++ char* query; |
58 | ++ uint length; |
59 | ++}; |
60 | ++ |
61 | ++#endif // HAVE_QUERY_CACHE |
62 | ++#endif // _SQL_QUERY_STRIPC_COMMENTS_H_ |
63 | --- a/sql/sql_cache.cc |
64 | +++ b/sql/sql_cache.cc |
65 | -@@ -344,6 +344,496 @@ |
66 | +@@ -344,6 +344,198 @@ |
67 | #include "probes_mysql.h" |
68 | #include "transaction.h" |
69 | |
70 | -+ |
71 | -+namespace query_comments_parser |
72 | -+{ |
73 | -+ |
74 | -+ |
75 | -+enum Kind |
76 | -+{ |
77 | -+ /* 'Empty' symbol - epsilon in classic parsers */ |
78 | -+ Empty, |
79 | -+ /* |
80 | -+ Special symbols: |
81 | -+ * exclamation comment: slash-star-exclamation comment-body star-slash |
82 | -+ * single-line and multi-line comments |
83 | -+ */ |
84 | -+ Special, |
85 | -+ /* Whitespaces: ' ' \t \r \n */ |
86 | -+ WhiteSpace, |
87 | -+ /* |
88 | -+ 1) C-style comment (slash-star comment-body star-slash) |
89 | -+ 2) signle-line comment: |
90 | -+ * sharp comment (sharp comment-body new-line) |
91 | -+ * minus-minus comment (minus-minus comment-body new-line) |
92 | -+ */ |
93 | -+ Comment, |
94 | -+ /* Not a special symbols (this symbols can't be before SELECT ). */ |
95 | -+ Another, |
96 | -+ /* Error: not-closed quotes, not-closed C-style comment, end-of-query */ |
97 | -+ Error |
98 | -+}; |
99 | -+ |
100 | -+ |
101 | -+/** |
102 | -+ Analyze kind of prefix of input string. |
103 | -+ |
104 | -+ @param where pointer to pointer to begin of string. After analyzing input |
105 | -+ string function skip analyzed prefix and return pointer to the next part |
106 | -+ of string in the @param where. |
107 | -+ |
108 | -+ @return kind of analyzed prefix. |
109 | ++#include "query_strip_comments.h" |
110 | ++ |
111 | ++/* |
112 | ++ Number of bytes to be allocated in a query cache buffer in addition to the |
113 | ++ query string length. |
114 | ++ |
115 | ++ The query buffer layout is: |
116 | ++ |
117 | ++ buffer :== |
118 | ++ <statement> The input statement(s) |
119 | ++ '\0' Terminating null char |
120 | ++ <db_length> Length of following current database name (size_t) |
121 | ++ <db_name> Name of current database |
122 | ++ <flags> Flags struct |
123 | +*/ |
124 | -+static Kind analyze(const char **where, const char *const end) |
125 | -+{ |
126 | -+ DBUG_ASSERT(where != NULL); |
127 | -+ DBUG_ASSERT(*where != NULL); |
128 | -+ const char*&to= *where; |
129 | -+ /* if empty */ |
130 | -+ if (*to == '\0') |
131 | -+ { |
132 | -+ return Empty; |
133 | -+ } |
134 | -+ |
135 | -+ /* current symbol */ |
136 | -+ char current= *to; |
137 | -+ |
138 | -+ switch (current) |
139 | -+ { |
140 | -+ case '\'': |
141 | -+ case '"': |
142 | -+ /* skip quote */ |
143 | -+ to++; |
144 | -+ /* search pair */ |
145 | -+ while (true) |
146 | ++#define QUERY_BUFFER_ADDITIONAL_LENGTH(db_length) \ |
147 | ++ (1 + sizeof(size_t) + db_length + QUERY_CACHE_FLAGS_SIZE) |
148 | ++ |
149 | ++QueryStripComments::QueryStripComments() |
150 | ++{ |
151 | ++ buffer = 0; |
152 | ++ length = 0; |
153 | ++ buffer_length = 0; |
154 | ++} |
155 | ++QueryStripComments::~QueryStripComments() |
156 | ++{ |
157 | ++ cleanup(); |
158 | ++} |
159 | ++ |
160 | ++inline bool query_strip_comments_is_white_space(char c) |
161 | ++{ |
162 | ++ return ((' ' == c) || ('\t' == c) || ('\r' == c) || ('\n' ==c )); |
163 | ++} |
164 | ++void QueryStripComments::set(const char* query, uint query_length, uint additional_length) |
165 | ++{ |
166 | ++ uint new_buffer_length = query_length + additional_length; |
167 | ++ if(new_buffer_length > buffer_length) |
168 | ++ { |
169 | ++ cleanup(); |
170 | ++ buffer = (char*)my_malloc(new_buffer_length,MYF(0)); |
171 | ++ } |
172 | ++ uint query_position = 0; |
173 | ++ uint position = 0; |
174 | ++ // Skip whitespaces from begin |
175 | ++ while((query_position < query_length) && query_strip_comments_is_white_space(query[query_position])) |
176 | ++ { |
177 | ++ ++query_position; |
178 | ++ } |
179 | ++ long int last_space = -1; |
180 | ++ while(query_position < query_length) |
181 | ++ { |
182 | ++ char current = query[query_position]; |
183 | ++ bool insert_space = false; // insert space to buffer, (IMPORTANT) don't update query_position |
184 | ++ switch(current) |
185 | + { |
186 | -+ /* check for pair of quote */ |
187 | -+ if (*to == current) |
188 | -+ { |
189 | -+ /* skip second quote */ |
190 | -+ to++; |
191 | -+ /* check for same symbol after second quote */ |
192 | -+ if (to < end && *to == current) |
193 | -+ { |
194 | -+ /* same symbol, skip it */ |
195 | -+ to++; |
196 | -+ /* check for end-of-line */ |
197 | -+ if (to == end) |
198 | -+ { |
199 | -+ /* not found - not closed quote */ |
200 | -+ return Error; |
201 | -+ } |
202 | -+ else |
203 | -+ { |
204 | -+ /* continue search of pair */ |
205 | ++ case '\'': |
206 | ++ case '"': |
207 | ++ { |
208 | ++ buffer[position++] = query[query_position++]; // copy current symbol |
209 | ++ while(query_position < query_length) |
210 | ++ { |
211 | ++ if(current == query[query_position]) // found pair quote |
212 | ++ { |
213 | ++ break; |
214 | ++ } |
215 | ++ buffer[position++] = query[query_position++]; // copy current symbol |
216 | ++ } |
217 | ++ break; |
218 | ++ } |
219 | ++ case '/': |
220 | ++ { |
221 | ++ if(((query_position + 2) < query_length) && ('*' == query[query_position+1]) && ('!' != query[query_position+2])) |
222 | ++ { |
223 | ++ query_position += 2; // skip "/*" |
224 | ++ do |
225 | ++ { |
226 | ++ if('*' == query[query_position] && '/' == query[query_position+1]) // check for "*/" |
227 | ++ { |
228 | ++ query_position += 2; // skip "*/" |
229 | ++ insert_space = true; |
230 | ++ break; |
231 | ++ } |
232 | ++ else |
233 | ++ { |
234 | ++ ++query_position; |
235 | ++ } |
236 | ++ } |
237 | ++ while(query_position < query_length); |
238 | ++ if(!insert_space) |
239 | ++ { |
240 | + continue; |
241 | + } |
242 | + } |
243 | -+ else |
244 | -+ { |
245 | -+ return Another; |
246 | -+ } |
247 | -+ } |
248 | -+ /* check for escaped symbols */ |
249 | -+ if (*to == '\\') |
250 | -+ { |
251 | -+ /* backslash, skip it */ |
252 | -+ to++; |
253 | -+ } |
254 | -+ /* check for end-of-line */ |
255 | -+ if (to == end) |
256 | -+ { |
257 | -+ /* not found - not closed quote */ |
258 | -+ return Error; |
259 | -+ } |
260 | -+ /* skip current symbol */ |
261 | -+ to++; |
262 | -+ } |
263 | -+ case '-': |
264 | -+ /* Skip minus */ |
265 | -+ to++; |
266 | -+ /* Check for second minus */ |
267 | -+ if (*to != '-') |
268 | -+ { |
269 | -+ /* Just minus */ |
270 | -+ return Another; |
271 | -+ } |
272 | -+ else |
273 | -+ { |
274 | -+ /* |
275 | -+ Prefix is minus-minus, next case-branch is processing |
276 | -+ single line comments. |
277 | -+ */ |
278 | -+ } |
279 | -+ case '#': |
280 | -+ /* |
281 | -+ This is single-line comment, it started by "#" or "--". |
282 | -+ Skip first symbol. |
283 | -+ */ |
284 | -+ to++; |
285 | -+ /* search new-line */ |
286 | -+ to= strchr(to, '\n'); |
287 | -+ if (NULL == to) |
288 | -+ { |
289 | -+ /* not found, end of the comment is the end of the query */ |
290 | -+ to= end; |
291 | -+ } |
292 | -+ else |
293 | -+ { |
294 | -+ /* skip end-of-line */ |
295 | -+ to++; |
296 | -+ } |
297 | -+ return Comment; |
298 | -+ case '/': |
299 | -+ /* skip slash */ |
300 | -+ to++; |
301 | -+ /* check for star */ |
302 | -+ if (*to == '*') |
303 | -+ { |
304 | -+ /* skip star */ |
305 | -+ to++; |
306 | -+ /* check for exclamation */ |
307 | -+ bool exclamation= (*to == '!'); |
308 | -+ /* search star-slash */ |
309 | -+ to= strstr(to, "*/"); |
310 | -+ if (NULL == to) |
311 | -+ { |
312 | -+ /* not found - not closed comment */ |
313 | -+ return Error; |
314 | -+ } |
315 | -+ else |
316 | -+ { |
317 | -+ /* found */ |
318 | -+ DBUG_ASSERT(to + 1 < end); |
319 | -+ DBUG_ASSERT(0 == strncmp(to, "*/", 2)); |
320 | -+ /* skip star-slash */ |
321 | -+ to++; |
322 | -+ to++; |
323 | -+ return (exclamation ? Special : Comment); |
324 | -+ } |
325 | -+ } |
326 | -+ else |
327 | -+ { |
328 | -+ /* just slash */ |
329 | -+ return Another; |
330 | -+ } |
331 | -+ case ' ': |
332 | -+ case '\t': |
333 | -+ case '\r': |
334 | -+ case '\n': |
335 | -+ { |
336 | -+ /* skip space */ |
337 | -+ to++; |
338 | -+ return WhiteSpace; |
339 | -+ } |
340 | -+ case '\\': |
341 | -+ { |
342 | -+ /* skip backslash */ |
343 | -+ to++; |
344 | -+ if (to == end) |
345 | -+ { |
346 | -+ /* |
347 | -+ query complete by backslash |
348 | -+ probable error? |
349 | -+ */ |
350 | -+ return Another; |
351 | -+ } |
352 | -+ else |
353 | -+ { |
354 | -+ /* skip after backslash symbol */ |
355 | -+ to++; |
356 | -+ return Another; |
357 | -+ } |
358 | -+ } |
359 | -+ case '(': |
360 | -+ case ')': |
361 | -+ { |
362 | -+ /* skip parenthese */ |
363 | -+ to++; |
364 | -+ return Special; |
365 | -+ } |
366 | -+ default: |
367 | -+ { |
368 | -+ /* skip symbol */ |
369 | -+ to++; |
370 | -+ return Another; |
371 | -+ } |
372 | -+ }; |
373 | -+} |
374 | -+ |
375 | -+ |
376 | -+static bool remove_comments_from_query(const char *const query, |
377 | -+ const size_t query_length, |
378 | -+ char *const result, |
379 | -+ size_t *result_length) |
380 | -+{ |
381 | -+ /* pointer to begin of parsed block */ |
382 | -+ const char *from= query; |
383 | -+ const char *to= query; |
384 | -+ /* pointer to end of the query */ |
385 | -+ const char *const end= query + query_length; |
386 | -+ /* pointer to last space */ |
387 | -+ const char *space= NULL; |
388 | -+ /* current position in result buffer */ |
389 | -+ char *current= result; |
390 | -+ while (true) |
391 | -+ { |
392 | -+ from= to; |
393 | -+ switch (analyze(&to, end)) |
394 | -+ { |
395 | -+ case Empty: |
396 | -+ { |
397 | -+ /* |
398 | -+ parse completed |
399 | -+ check for whitespace in the end |
400 | -+ */ |
401 | -+ if (current == space) |
402 | -+ { |
403 | -+ /* drop whitespace in the end of query */ |
404 | -+ --current; |
405 | -+ } |
406 | -+ /* result is null-terminated string */ |
407 | -+ *current= 0; |
408 | -+ /* set result length */ |
409 | -+ *result_length= current - result; |
410 | -+ /* all right */ |
411 | -+ return true; |
412 | -+ } |
413 | -+ case Comment: |
414 | -+ /* should just insert space instead of comment */ |
415 | -+ case WhiteSpace: |
416 | -+ if (space == current || from == query) |
417 | -+ { |
418 | -+ /* previous symbol was space */ |
419 | -+ } |
420 | -+ else |
421 | -+ { |
422 | -+ /* insert space to result buffer */ |
423 | -+ *current= ' '; |
424 | -+ /* switch after inserted space */ |
425 | -+ current++; |
426 | -+ } |
427 | -+ /* remember last-after-space position */ |
428 | -+ space= current; |
429 | -+ /* parse again */ |
430 | -+ continue; |
431 | -+ case Special: |
432 | -+ case Another: |
433 | -+ { |
434 | -+ /* calculate parsed block size */ |
435 | -+ size_t block_size= to - from; |
436 | -+ /* copy parsed block to result */ |
437 | -+ memcpy(current, from, block_size); |
438 | -+ /* switch result after copied block */ |
439 | -+ current+= block_size; |
440 | -+ /* switch after parsed block */ |
441 | -+ from= to; |
442 | -+ /* parse again */ |
443 | -+ continue; |
444 | -+ } |
445 | -+ case Error: |
446 | -+ default: |
447 | -+ { |
448 | -+ /* bad source query */ |
449 | -+ return false; |
450 | -+ } |
451 | -+ } |
452 | -+ } |
453 | -+} |
454 | -+ |
455 | -+ |
456 | -+static size_t skip_not_another(const char *const query, size_t query_length) |
457 | -+{ |
458 | -+ const char *from= query; |
459 | -+ const char *to= query; |
460 | -+ const char *const end= query + query_length; |
461 | -+ while (true) |
462 | -+ { |
463 | -+ switch (analyze(&to, end)) |
464 | -+ { |
465 | -+ case Error: |
466 | -+ return 0; |
467 | -+ case Empty: |
468 | -+ case Another: |
469 | -+ return (from - query); |
470 | -+ default: |
471 | -+ from= to; |
472 | -+ continue; |
473 | -+ }; |
474 | -+ } |
475 | -+} |
476 | -+ |
477 | -+ |
478 | -+static size_t skip_default(const char *const query, size_t /* query_length */) |
479 | -+{ |
480 | -+ size_t query_position= 0; |
481 | -+ /* |
482 | -+ Skip '(' characters in queries like following: |
483 | -+ (select a from t1) union (select a from t1); |
484 | -+ */ |
485 | -+ while (query[query_position]=='(') |
486 | -+ query_position++; |
487 | -+ return query_position; |
488 | -+} |
489 | -+ |
490 | -+ |
491 | -+} /* namespace query_comments_parser */ |
492 | -+ |
493 | -+class Query_Switcher |
494 | -+{ |
495 | -+private: |
496 | -+ Query_Switcher(const Query_Switcher&); |
497 | -+ Query_Switcher& operator=(const Query_Switcher&); |
498 | -+ |
499 | -+ |
500 | -+public: |
501 | -+ Query_Switcher(THD *thd) : |
502 | -+ target_query(&(thd_query_string(thd)->str)), |
503 | -+ target_length(&(thd_query_string(thd)->length)), |
504 | -+ backup_query(thd->query()), |
505 | -+ backup_length(thd->query_length()) |
506 | -+ { |
507 | -+ } |
508 | -+ |
509 | -+ Query_Switcher(char **query, |
510 | -+ size_t *length) : |
511 | -+ target_query(query), |
512 | -+ target_length(length), |
513 | -+ backup_query(*query), |
514 | -+ backup_length(*length) |
515 | -+ { |
516 | -+ } |
517 | -+public: |
518 | -+ void replace(Query_Without_Comments *query_without_comments) |
519 | -+ { |
520 | -+ *target_query= query_without_comments->query(); |
521 | -+ *target_length= query_without_comments->length(); |
522 | -+ } |
523 | -+ void restore() |
524 | -+ { |
525 | -+ *target_query= backup_query; |
526 | -+ *target_length= backup_length; |
527 | -+ } |
528 | -+private: |
529 | -+ char* *target_query; |
530 | -+ size_t *target_length; |
531 | -+public: |
532 | -+ char *const backup_query; |
533 | -+ size_t const backup_length; |
534 | -+}; |
535 | -+ |
536 | -+class Comments_Processor |
537 | -+{ |
538 | -+private: |
539 | -+ Comments_Processor(const Comments_Processor&); |
540 | -+ Comments_Processor& operator=(const Comments_Processor&); |
541 | -+ |
542 | -+ |
543 | -+public: |
544 | -+ Comments_Processor(THD *thd) : |
545 | -+ query_switcher (thd), |
546 | -+ db_length (thd->db_length), |
547 | -+ query_without_comments(&(thd->query_without_comments)), |
548 | -+ enabled (opt_query_cache_strip_comments), |
549 | -+ restore (false) |
550 | -+ { |
551 | -+ } |
552 | -+ |
553 | -+ |
554 | -+ Comments_Processor(Query_Without_Comments *current_query_without_comments, |
555 | -+ char **query, |
556 | -+ size_t *length, |
557 | -+ const size_t current_db_length) : |
558 | -+ query_switcher (query, length), |
559 | -+ db_length (current_db_length), |
560 | -+ query_without_comments(current_query_without_comments), |
561 | -+ enabled (opt_query_cache_strip_comments), |
562 | -+ restore (false) |
563 | -+ { |
564 | -+ } |
565 | -+ |
566 | -+ |
567 | -+ ~Comments_Processor() |
568 | -+ { |
569 | -+ restore_comments(); |
570 | -+ } |
571 | -+ |
572 | -+ |
573 | -+ size_t prefix_length() |
574 | -+ { |
575 | -+ using query_comments_parser::skip_not_another; |
576 | -+ using query_comments_parser::skip_default; |
577 | -+ if (enabled) |
578 | -+ { |
579 | -+ return skip_not_another(query_switcher.backup_query, |
580 | -+ query_switcher.backup_length); |
581 | -+ } |
582 | -+ else |
583 | -+ { |
584 | -+ return skip_default(query_switcher.backup_query, |
585 | -+ query_switcher.backup_length); |
586 | -+ } |
587 | -+ } |
588 | -+ |
589 | -+ |
590 | -+ bool remove_comments() |
591 | -+ { |
592 | -+ if (!enabled || restore) |
593 | -+ { |
594 | -+ return true; |
595 | -+ } |
596 | -+ /* Allocate memory for query rewrite */ |
597 | -+ if (!query_without_comments->allocate(query_switcher.backup_length, |
598 | -+ db_length)) |
599 | -+ { |
600 | -+ return false; |
601 | -+ } |
602 | -+ /* Remove comment from query */ |
603 | -+ size_t result_length; |
604 | -+ using query_comments_parser::remove_comments_from_query; |
605 | -+ if (!(restore= remove_comments_from_query(query_switcher.backup_query, |
606 | -+ query_switcher.backup_length, |
607 | -+ query_without_comments->query(), |
608 | -+ &result_length))) |
609 | -+ { |
610 | -+ return false; |
611 | -+ } |
612 | -+ query_without_comments->set_length(result_length); |
613 | -+ size_t db_length_from_query= |
614 | -+ *((size_t*)(query_switcher.backup_query + |
615 | -+ query_switcher.backup_length + 1)); |
616 | -+ *((size_t*)(query_without_comments->query() + |
617 | -+ result_length + 1))= db_length_from_query; |
618 | -+ /* Replace original query by striped */ |
619 | -+ query_switcher.replace(query_without_comments); |
620 | -+ return restore; |
621 | -+ } |
622 | -+ |
623 | -+ |
624 | -+ void restore_comments() |
625 | -+ { |
626 | -+ if (enabled && restore) |
627 | -+ { |
628 | -+ /* Replace striped query by original */ |
629 | -+ query_switcher.restore(); |
630 | -+ |
631 | -+ /* Clean query_without_comments */ |
632 | -+ query_without_comments->set_length(0); |
633 | -+ |
634 | -+ /* Mark as restored */ |
635 | -+ restore= false; |
636 | -+ } |
637 | -+ } |
638 | -+private: |
639 | -+ Query_Switcher query_switcher; |
640 | -+private: |
641 | -+ const size_t db_length; |
642 | -+private: |
643 | -+ Query_Without_Comments *query_without_comments; |
644 | -+ bool enabled; |
645 | -+ bool restore; |
646 | -+}; |
647 | ++ break; |
648 | ++ } |
649 | ++ case '-': |
650 | ++ { |
651 | ++ if(query[query_position+1] == '-') |
652 | ++ { |
653 | ++ ++query_position; // skip "-", and go to search of "\n" |
654 | ++ } |
655 | ++ else |
656 | ++ { |
657 | ++ break; |
658 | ++ } |
659 | ++ } |
660 | ++ case '#': |
661 | ++ { |
662 | ++ do |
663 | ++ { |
664 | ++ ++query_position; // skip current symbol (# or -) |
665 | ++ if('\n' == query[query_position]) // check for '\n' |
666 | ++ { |
667 | ++ ++query_position; // skip '\n' |
668 | ++ insert_space = true; |
669 | ++ break; |
670 | ++ } |
671 | ++ } |
672 | ++ while(query_position < query_length); |
673 | ++ if(insert_space) |
674 | ++ { |
675 | ++ break; |
676 | ++ } |
677 | ++ else |
678 | ++ { |
679 | ++ continue; |
680 | ++ } |
681 | ++ } |
682 | ++ default: |
683 | ++ if(query_strip_comments_is_white_space(current)) |
684 | ++ { |
685 | ++ insert_space = true; |
686 | ++ ++query_position; |
687 | ++ } |
688 | ++ break; // make gcc happy |
689 | ++ } |
690 | ++ if(insert_space) |
691 | ++ { |
692 | ++ if((uint) (last_space + 1) != position) |
693 | ++ { |
694 | ++ last_space = position; |
695 | ++ buffer[position++] = ' '; |
696 | ++ } |
697 | ++ } |
698 | ++ else if (query_position < query_length) |
699 | ++ { |
700 | ++ buffer[position++] = query[query_position++]; |
701 | ++ } |
702 | ++ } |
703 | ++ while((0 < position) && query_strip_comments_is_white_space(buffer[position - 1])) |
704 | ++ { |
705 | ++ --position; |
706 | ++ } |
707 | ++ buffer[position] = 0; |
708 | ++ length = position; |
709 | ++} |
710 | ++void QueryStripComments::cleanup() |
711 | ++{ |
712 | ++ if(buffer) |
713 | ++ { |
714 | ++ my_free(buffer); |
715 | ++ } |
716 | ++ buffer = 0; |
717 | ++ length = 0; |
718 | ++ buffer_length = 0; |
719 | ++} |
720 | ++QueryStripComments_Backup::QueryStripComments_Backup(THD* a_thd,QueryStripComments* qsc) |
721 | ++{ |
722 | ++ if(opt_query_cache_strip_comments) |
723 | ++ { |
724 | ++ thd = a_thd; |
725 | ++ query = thd->query(); |
726 | ++ length = thd->query_length(); |
727 | ++ qsc->set(query, length, QUERY_BUFFER_ADDITIONAL_LENGTH(thd->db_length)); |
728 | ++ *(size_t *) (qsc->query() + qsc->query_length() + 1)= thd->db_length; |
729 | ++ thd->set_query(qsc->query(),qsc->query_length()); |
730 | ++ } |
731 | ++ else |
732 | ++ { |
733 | ++ thd = 0; |
734 | ++ query = 0; |
735 | ++ length = 0; |
736 | ++ } |
737 | ++} |
738 | ++QueryStripComments_Backup::~QueryStripComments_Backup() |
739 | ++{ |
740 | ++ if(thd) |
741 | ++ { |
742 | ++ thd->set_query(query,length); |
743 | ++ } |
744 | ++} |
745 | + |
746 | #ifdef EMBEDDED_LIBRARY |
747 | #include "emb_qcache.h" |
748 | #endif |
749 | -@@ -454,7 +944,12 @@ |
750 | +@@ -454,7 +646,12 @@ |
751 | Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__); |
752 | DBUG_ENTER("Query_cache::try_lock"); |
753 | |
754 | -+ const char *old_proc_info= thd->proc_info; |
755 | ++ const char* old_proc_info= thd->proc_info; |
756 | + thd_proc_info(thd,"Waiting on query cache mutex"); |
757 | + DEBUG_SYNC(thd, "before_query_cache_mutex"); |
758 | mysql_mutex_lock(&structure_guard_mutex); |
759 | @@ -555,171 +297,191 @@ |
760 | while (1) |
761 | { |
762 | if (m_cache_lock_status == Query_cache::UNLOCKED) |
763 | -@@ -1274,6 +1769,8 @@ |
764 | +@@ -1274,6 +1471,8 @@ |
765 | unlock(); |
766 | DBUG_VOID_RETURN; |
767 | } |
768 | -+ Comments_Processor comments_processor(thd); |
769 | -+ comments_processor.remove_comments(); |
770 | ++ QueryStripComments *query_strip_comments = &(thd->query_strip_comments); |
771 | ++ QueryStripComments_Backup backup(thd,query_strip_comments); |
772 | |
773 | /* Key is query + database + flag */ |
774 | if (thd->db_length) |
775 | -@@ -1440,7 +1937,7 @@ |
776 | - */ |
777 | - |
778 | - int |
779 | --Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) |
780 | -+Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length_uint) |
781 | - { |
782 | - ulonglong engine_data; |
783 | - Query_cache_query *query; |
784 | -@@ -1452,6 +1949,11 @@ |
785 | +@@ -1451,6 +1650,9 @@ |
786 | + Query_cache_block_table *block_table, *block_table_end; |
787 | ulong tot_length; |
788 | Query_cache_query_flags flags; |
789 | ++ QueryStripComments *query_strip_comments = &(thd->query_strip_comments); |
790 | ++ char *sql_backup = sql; |
791 | ++ uint query_length_backup = query_length; |
792 | DBUG_ENTER("Query_cache::send_result_to_client"); |
793 | -+ size_t query_length= query_length_uint; |
794 | -+ Comments_Processor comments_processor(&(thd->query_without_comments), |
795 | -+ &sql, |
796 | -+ &query_length, |
797 | -+ thd->db_length); |
798 | |
799 | /* |
800 | - Testing 'query_cache_size' without a lock here is safe: the thing |
801 | -@@ -1471,13 +1973,7 @@ |
802 | - } |
803 | +@@ -1472,21 +1674,103 @@ |
804 | |
805 | { |
806 | -- uint i= 0; |
807 | + uint i= 0; |
808 | - /* |
809 | - Skip '(' characters in queries like following: |
810 | - (select a from t1) union (select a from t1); |
811 | - */ |
812 | - while (sql[i]=='(') |
813 | - i++; |
814 | -+ size_t i= comments_processor.prefix_length(); |
815 | - |
816 | - /* |
817 | - Test if the query is a SELECT |
818 | -@@ -1487,10 +1983,11 @@ |
819 | - frequently appeared in real life, consequently we can |
820 | - check all such queries, too. |
821 | - */ |
822 | -- if ((my_toupper(system_charset_info, sql[i]) != 'S' || |
823 | -- my_toupper(system_charset_info, sql[i + 1]) != 'E' || |
824 | -- my_toupper(system_charset_info, sql[i + 2]) != 'L') && |
825 | -- sql[i] != '/') |
826 | -+ if (!((i + 2 < query_length) && |
827 | -+ ((my_toupper(system_charset_info, sql[i]) == 'S' && |
828 | -+ my_toupper(system_charset_info, sql[i + 1]) == 'E' && |
829 | -+ my_toupper(system_charset_info, sql[i + 2]) == 'L') || |
830 | -+ sql[i] == '/'))) |
831 | - { |
832 | - DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); |
833 | - goto err; |
834 | -@@ -1543,6 +2040,7 @@ |
835 | ++ if(opt_query_cache_strip_comments) |
836 | ++ { |
837 | ++ /* Skip all comments and non-letter symbols */ |
838 | ++ uint& query_position = i; |
839 | ++ char* query = sql; |
840 | ++ while(query_position < query_length) |
841 | ++ { |
842 | ++ bool check = false; |
843 | ++ char current = query[query_position]; |
844 | ++ switch(current) |
845 | ++ { |
846 | ++ case '/': |
847 | ++ if(((query_position + 2) < query_length) && ('*' == query[query_position+1]) && ('!' != query[query_position+2])) |
848 | ++ { |
849 | ++ query_position += 2; // skip "/*" |
850 | ++ do |
851 | ++ { |
852 | ++ if('*' == query[query_position] && '/' == query[query_position+1]) // check for "*/" (without space) |
853 | ++ { |
854 | ++ query_position += 2; // skip "*/" (without space) |
855 | ++ break; |
856 | ++ } |
857 | ++ else |
858 | ++ { |
859 | ++ ++query_position; |
860 | ++ } |
861 | ++ } |
862 | ++ while(query_position < query_length); |
863 | ++ continue; // analyze current symbol |
864 | ++ } |
865 | ++ break; |
866 | ++ case '-': |
867 | ++ if(query[query_position+1] == '-') |
868 | ++ { |
869 | ++ ++query_position; // skip "-" |
870 | ++ } |
871 | ++ else |
872 | ++ { |
873 | ++ break; |
874 | ++ } |
875 | ++ case '#': |
876 | ++ do |
877 | ++ { |
878 | ++ ++query_position; // skip current symbol |
879 | ++ if('\n' == query[query_position]) // check for '\n' |
880 | ++ { |
881 | ++ ++query_position; // skip '\n' |
882 | ++ break; |
883 | ++ } |
884 | ++ } |
885 | ++ while(query_position < query_length); |
886 | ++ continue; // analyze current symbol |
887 | ++ case '\r': |
888 | ++ case '\n': |
889 | ++ case '\t': |
890 | ++ case ' ': |
891 | ++ case '(': |
892 | ++ case ')': |
893 | ++ break; |
894 | ++ default: |
895 | ++ check = true; |
896 | ++ break; // make gcc happy |
897 | ++ } // switch(current) |
898 | ++ if(check) |
899 | ++ { |
900 | ++ if(query_position + 2 < query_length) |
901 | ++ { |
902 | ++ // cacheable |
903 | ++ break; |
904 | ++ } |
905 | ++ else |
906 | ++ { |
907 | ++ DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); |
908 | ++ goto err; |
909 | ++ } |
910 | ++ } // if(check) |
911 | ++ ++query_position; |
912 | ++ } // while(query_position < query_length) |
913 | ++ } |
914 | ++ else // if(opt_query_cache_strip_comments) |
915 | ++ { |
916 | ++ /* |
917 | ++ Skip '(' characters in queries like following: |
918 | ++ (select a from t1) union (select a from t1); |
919 | ++ */ |
920 | ++ while (sql[i]=='(') |
921 | ++ i++; |
922 | + |
923 | +- /* |
924 | +- Test if the query is a SELECT |
925 | +- (pre-space is removed in dispatch_command). |
926 | ++ } // if(opt_query_cache_strip_comments) |
927 | ++ /* |
928 | ++ Test if the query is a SELECT |
929 | ++ (pre-space is removed in dispatch_command). |
930 | + |
931 | +- First '/' looks like comment before command it is not |
932 | +- frequently appeared in real life, consequently we can |
933 | +- check all such queries, too. |
934 | +- */ |
935 | ++ First '/' looks like comment before command it is not |
936 | ++ frequently appeared in real life, consequently we can |
937 | ++ check all such queries, too. |
938 | ++ */ |
939 | + if ((my_toupper(system_charset_info, sql[i]) != 'S' || |
940 | + my_toupper(system_charset_info, sql[i + 1]) != 'E' || |
941 | + my_toupper(system_charset_info, sql[i + 2]) != 'L') && |
942 | +@@ -1543,6 +1827,14 @@ |
943 | goto err_unlock; |
944 | |
945 | Query_cache_block *query_block; |
946 | -+ comments_processor.remove_comments(); |
947 | ++ if(opt_query_cache_strip_comments) |
948 | ++ { |
949 | ++ query_strip_comments->set(sql, query_length, |
950 | ++ QUERY_BUFFER_ADDITIONAL_LENGTH(thd->db_length)); |
951 | ++ sql = query_strip_comments->query(); |
952 | ++ query_length = query_strip_comments->query_length(); |
953 | ++ *(size_t *) (sql + query_length + 1)= thd->db_length; |
954 | ++ } |
955 | |
956 | tot_length= query_length + 1 + sizeof(size_t) + |
957 | thd->db_length + QUERY_CACHE_FLAGS_SIZE; |
958 | -@@ -1611,6 +2109,7 @@ |
959 | +@@ -1611,6 +1903,8 @@ |
960 | (uchar*) &flags, QUERY_CACHE_FLAGS_SIZE); |
961 | query_block = (Query_cache_block *) my_hash_search(&queries, (uchar*) sql, |
962 | tot_length); |
963 | -+ comments_processor.restore_comments(); |
964 | ++ sql = sql_backup; |
965 | ++ query_length = query_length_backup; |
966 | /* Quick abort on unlocked data */ |
967 | if (query_block == 0 || |
968 | query_block->query()->result() == 0 || |
969 | --- a/sql/sql_class.h |
970 | +++ b/sql/sql_class.h |
971 | -@@ -1485,6 +1485,74 @@ |
972 | - |
973 | - extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); |
974 | - |
975 | -+ |
976 | -+#ifdef HAVE_QUERY_CACHE |
977 | -+ |
978 | -+ |
979 | -+/* |
980 | -+ @class Query_Without_Comments |
981 | -+ This class provides way for safety (re)allocation |
982 | -+ a memory for a query without comments. |
983 | -+*/ |
984 | -+class Query_Without_Comments |
985 | -+{ |
986 | -+private: |
987 | -+ /* |
988 | -+ Denied copy and assigment for object of this class. |
989 | -+ */ |
990 | -+ Query_Without_Comments(const Query_Without_Comments&); |
991 | -+ Query_Without_Comments& operator=(const Query_Without_Comments&); |
992 | -+ |
993 | -+ |
994 | -+public: |
995 | -+ /* |
996 | -+ Constructor is filling fields by zero (no allocation). |
997 | -+ */ |
998 | -+ Query_Without_Comments(); |
999 | -+ |
1000 | -+ |
1001 | -+ /* |
1002 | -+ Destructor clean allocated memory |
1003 | -+ */ |
1004 | -+ ~Query_Without_Comments(); |
1005 | -+public: |
1006 | -+ |
1007 | -+ |
1008 | -+/* |
1009 | -+ (Re)allocate memory for query. Query length after that is 0. |
1010 | -+ */ |
1011 | -+ bool allocate(size_t query_length, size_t db_length); |
1012 | -+ |
1013 | -+ |
1014 | -+ /* |
1015 | -+ Set result query length, when query |
1016 | -+ without comments is copied to buffer. |
1017 | -+ */ |
1018 | -+ void set_length(size_t query_length); |
1019 | -+ |
1020 | -+ |
1021 | -+public: |
1022 | -+ /* |
1023 | -+ Result query. |
1024 | -+ */ |
1025 | -+ char* query(); |
1026 | -+ |
1027 | -+ |
1028 | -+ /* |
1029 | -+ Result query length |
1030 | -+ */ |
1031 | -+ size_t length(); |
1032 | -+ |
1033 | -+ |
1034 | -+private: |
1035 | -+ char* buffer; |
1036 | -+ size_t q_length; |
1037 | -+ size_t b_length; |
1038 | -+}; |
1039 | -+ |
1040 | -+ |
1041 | -+#endif /* HAVE_QUERY_CACHE */ |
1042 | -+ |
1043 | - /** |
1044 | - @class THD |
1045 | - For each client connection we create a separate thread with THD serving as |
1046 | -@@ -1542,6 +1610,7 @@ |
1047 | - struct st_mysql_stmt *current_stmt; |
1048 | - #endif |
1049 | - #ifdef HAVE_QUERY_CACHE |
1050 | -+ Query_Without_Comments query_without_comments; |
1051 | - Query_cache_tls query_cache_tls; |
1052 | - #endif |
1053 | - NET net; // client connection descriptor |
1054 | +@@ -40,6 +40,9 @@ |
1055 | + #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA, |
1056 | + THR_LOCK_INFO */ |
1057 | + |
1058 | ++#ifdef HAVE_QUERY_CACHE |
1059 | ++#include "query_strip_comments.h" |
1060 | ++#endif // HAVE_QUERY_CACHE |
1061 | + |
1062 | + class Reprepare_observer; |
1063 | + class Relay_log_info; |
1064 | +@@ -766,6 +769,9 @@ |
1065 | + statement lifetime. FIXME: must be const |
1066 | + */ |
1067 | + ulong id; |
1068 | ++#ifdef HAVE_QUERY_CACHE |
1069 | ++ QueryStripComments query_strip_comments; // see sql_cache.cc |
1070 | ++#endif //HAVE_QUERY_CACHE |
1071 | + |
1072 | + /* |
1073 | + MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to |
1074 | --- a/sql/sys_vars.cc |
1075 | +++ b/sql/sys_vars.cc |
1076 | -@@ -1888,6 +1888,11 @@ |
1077 | +@@ -1895,6 +1895,11 @@ |
1078 | NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), |
1079 | ON_UPDATE(fix_query_cache_size)); |
1080 | |
1081 | @@ -733,7 +495,7 @@ |
1082 | "Don't cache results that are bigger than this", |
1083 | --- /dev/null |
1084 | +++ b/mysql-test/include/percona_query_cache_with_comments.inc |
1085 | -@@ -0,0 +1,117 @@ |
1086 | +@@ -0,0 +1,95 @@ |
1087 | +--source include/percona_query_cache_with_comments_clear.inc |
1088 | +let $query=/* with comment first */select * from t1; |
1089 | +eval $query; |
1090 | @@ -827,30 +589,8 @@ |
1091 | +; |
1092 | +--source include/percona_query_cache_with_comments_eval.inc |
1093 | + |
1094 | -+let $query=select */* a comment \*/from t1; |
1095 | -+--source include/percona_query_cache_with_comments_eval.inc |
1096 | -+ |
1097 | -+let $query=select *# a comment \\ |
1098 | -+from t1; |
1099 | -+--source include/percona_query_cache_with_comments_eval.inc |
1100 | -+ |
1101 | -+let $query=select *-- a comment \\ |
1102 | -+from t1; |
1103 | -+--source include/percona_query_cache_with_comments_eval.inc |
1104 | -+ |
1105 | -+let $query=select "\\\\"" /* not a comment */" from t1; |
1106 | -+--source include/percona_query_cache_with_comments_eval.inc |
1107 | -+ |
1108 | -+let $query=select "\\\\"" /*! not a comment */" from t1; |
1109 | -+--source include/percona_query_cache_with_comments_eval.inc |
1110 | -+ |
1111 | -+# following two queries related to bug #856404. |
1112 | -+# There are different queries, but opt_query_cache_strip_comments thinks that they are equal. |
1113 | +let $query=select ' \' ' from t1; |
1114 | +--source include/percona_query_cache_with_comments_eval.inc |
1115 | -+ |
1116 | -+let $query=select ' \' /* comment inside quotes with internal backslash quote */' from t1; |
1117 | -+--source include/percona_query_cache_with_comments_eval.inc |
1118 | --- /dev/null |
1119 | +++ b/mysql-test/include/percona_query_cache_with_comments_begin.inc |
1120 | @@ -0,0 +1,12 @@ |
1121 | @@ -903,7 +643,7 @@ |
1122 | + |
1123 | --- /dev/null |
1124 | +++ b/mysql-test/r/percona_query_cache_with_comments.result |
1125 | -@@ -0,0 +1,1058 @@ |
1126 | +@@ -0,0 +1,866 @@ |
1127 | +set global query_cache_strip_comments=ON; |
1128 | +set GLOBAL query_cache_size=1355776; |
1129 | +drop table if exists t1; |
1130 | @@ -1737,228 +1477,36 @@ |
1131 | +Variable_name Value |
1132 | +Qcache_hits 50 |
1133 | +----------------------------------------------------- |
1134 | -+select */* a comment \*/from t1 |
1135 | -+----------------------------------------------------- |
1136 | -+show status like "Qcache_queries_in_cache"; |
1137 | -+Variable_name Value |
1138 | -+Qcache_queries_in_cache 1 |
1139 | -+show status like "Qcache_inserts"; |
1140 | -+Variable_name Value |
1141 | -+Qcache_inserts 1 |
1142 | -+show status like "Qcache_hits"; |
1143 | -+Variable_name Value |
1144 | -+Qcache_hits 50 |
1145 | -+select */* a comment \*/from t1; |
1146 | -+a |
1147 | -+1 |
1148 | -+2 |
1149 | -+3 |
1150 | -+select */* a comment \*/from t1; |
1151 | -+a |
1152 | -+1 |
1153 | -+2 |
1154 | -+3 |
1155 | -+show status like "Qcache_queries_in_cache"; |
1156 | -+Variable_name Value |
1157 | -+Qcache_queries_in_cache 1 |
1158 | -+show status like "Qcache_inserts"; |
1159 | -+Variable_name Value |
1160 | -+Qcache_inserts 1 |
1161 | -+show status like "Qcache_hits"; |
1162 | -+Variable_name Value |
1163 | -+Qcache_hits 52 |
1164 | -+----------------------------------------------------- |
1165 | -+select *# a comment \ |
1166 | -+from t1 |
1167 | -+----------------------------------------------------- |
1168 | -+show status like "Qcache_queries_in_cache"; |
1169 | -+Variable_name Value |
1170 | -+Qcache_queries_in_cache 1 |
1171 | -+show status like "Qcache_inserts"; |
1172 | -+Variable_name Value |
1173 | -+Qcache_inserts 1 |
1174 | -+show status like "Qcache_hits"; |
1175 | -+Variable_name Value |
1176 | -+Qcache_hits 52 |
1177 | -+select *# a comment \ |
1178 | -+from t1; |
1179 | -+a |
1180 | -+1 |
1181 | -+2 |
1182 | -+3 |
1183 | -+select *# a comment \ |
1184 | -+from t1; |
1185 | -+a |
1186 | -+1 |
1187 | -+2 |
1188 | -+3 |
1189 | -+show status like "Qcache_queries_in_cache"; |
1190 | -+Variable_name Value |
1191 | -+Qcache_queries_in_cache 1 |
1192 | -+show status like "Qcache_inserts"; |
1193 | -+Variable_name Value |
1194 | -+Qcache_inserts 1 |
1195 | -+show status like "Qcache_hits"; |
1196 | -+Variable_name Value |
1197 | -+Qcache_hits 54 |
1198 | -+----------------------------------------------------- |
1199 | -+select *-- a comment \ |
1200 | -+from t1 |
1201 | -+----------------------------------------------------- |
1202 | -+show status like "Qcache_queries_in_cache"; |
1203 | -+Variable_name Value |
1204 | -+Qcache_queries_in_cache 1 |
1205 | -+show status like "Qcache_inserts"; |
1206 | -+Variable_name Value |
1207 | -+Qcache_inserts 1 |
1208 | -+show status like "Qcache_hits"; |
1209 | -+Variable_name Value |
1210 | -+Qcache_hits 54 |
1211 | -+select *-- a comment \ |
1212 | -+from t1; |
1213 | -+a |
1214 | -+1 |
1215 | -+2 |
1216 | -+3 |
1217 | -+select *-- a comment \ |
1218 | -+from t1; |
1219 | -+a |
1220 | -+1 |
1221 | -+2 |
1222 | -+3 |
1223 | -+show status like "Qcache_queries_in_cache"; |
1224 | -+Variable_name Value |
1225 | -+Qcache_queries_in_cache 1 |
1226 | -+show status like "Qcache_inserts"; |
1227 | -+Variable_name Value |
1228 | -+Qcache_inserts 1 |
1229 | -+show status like "Qcache_hits"; |
1230 | -+Variable_name Value |
1231 | -+Qcache_hits 56 |
1232 | -+----------------------------------------------------- |
1233 | -+select "\\"" /* not a comment */" from t1 |
1234 | -+----------------------------------------------------- |
1235 | -+show status like "Qcache_queries_in_cache"; |
1236 | -+Variable_name Value |
1237 | -+Qcache_queries_in_cache 1 |
1238 | -+show status like "Qcache_inserts"; |
1239 | -+Variable_name Value |
1240 | -+Qcache_inserts 1 |
1241 | -+show status like "Qcache_hits"; |
1242 | -+Variable_name Value |
1243 | -+Qcache_hits 56 |
1244 | -+select "\\"" /* not a comment */" from t1; |
1245 | -+\" /* not a comment */ |
1246 | -+\" /* not a comment */ |
1247 | -+\" /* not a comment */ |
1248 | -+\" /* not a comment */ |
1249 | -+select "\\"" /* not a comment */" from t1; |
1250 | -+\" /* not a comment */ |
1251 | -+\" /* not a comment */ |
1252 | -+\" /* not a comment */ |
1253 | -+\" /* not a comment */ |
1254 | -+show status like "Qcache_queries_in_cache"; |
1255 | -+Variable_name Value |
1256 | -+Qcache_queries_in_cache 2 |
1257 | -+show status like "Qcache_inserts"; |
1258 | -+Variable_name Value |
1259 | -+Qcache_inserts 2 |
1260 | -+show status like "Qcache_hits"; |
1261 | -+Variable_name Value |
1262 | -+Qcache_hits 57 |
1263 | -+----------------------------------------------------- |
1264 | -+select "\\"" /*! not a comment */" from t1 |
1265 | -+----------------------------------------------------- |
1266 | -+show status like "Qcache_queries_in_cache"; |
1267 | -+Variable_name Value |
1268 | -+Qcache_queries_in_cache 2 |
1269 | -+show status like "Qcache_inserts"; |
1270 | -+Variable_name Value |
1271 | -+Qcache_inserts 2 |
1272 | -+show status like "Qcache_hits"; |
1273 | -+Variable_name Value |
1274 | -+Qcache_hits 57 |
1275 | -+select "\\"" /*! not a comment */" from t1; |
1276 | -+\" /*! not a comment */ |
1277 | -+\" /*! not a comment */ |
1278 | -+\" /*! not a comment */ |
1279 | -+\" /*! not a comment */ |
1280 | -+select "\\"" /*! not a comment */" from t1; |
1281 | -+\" /*! not a comment */ |
1282 | -+\" /*! not a comment */ |
1283 | -+\" /*! not a comment */ |
1284 | -+\" /*! not a comment */ |
1285 | -+show status like "Qcache_queries_in_cache"; |
1286 | -+Variable_name Value |
1287 | -+Qcache_queries_in_cache 3 |
1288 | -+show status like "Qcache_inserts"; |
1289 | -+Variable_name Value |
1290 | -+Qcache_inserts 3 |
1291 | -+show status like "Qcache_hits"; |
1292 | -+Variable_name Value |
1293 | -+Qcache_hits 58 |
1294 | -+----------------------------------------------------- |
1295 | +select ' \' ' from t1 |
1296 | +----------------------------------------------------- |
1297 | +show status like "Qcache_queries_in_cache"; |
1298 | +Variable_name Value |
1299 | -+Qcache_queries_in_cache 3 |
1300 | -+show status like "Qcache_inserts"; |
1301 | -+Variable_name Value |
1302 | -+Qcache_inserts 3 |
1303 | -+show status like "Qcache_hits"; |
1304 | -+Variable_name Value |
1305 | -+Qcache_hits 58 |
1306 | -+select ' \' ' from t1; |
1307 | -+' |
1308 | -+ ' |
1309 | -+ ' |
1310 | -+ ' |
1311 | -+select ' \' ' from t1; |
1312 | -+' |
1313 | -+ ' |
1314 | -+ ' |
1315 | -+ ' |
1316 | -+show status like "Qcache_queries_in_cache"; |
1317 | -+Variable_name Value |
1318 | -+Qcache_queries_in_cache 4 |
1319 | -+show status like "Qcache_inserts"; |
1320 | -+Variable_name Value |
1321 | -+Qcache_inserts 4 |
1322 | -+show status like "Qcache_hits"; |
1323 | -+Variable_name Value |
1324 | -+Qcache_hits 59 |
1325 | -+----------------------------------------------------- |
1326 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1 |
1327 | -+----------------------------------------------------- |
1328 | -+show status like "Qcache_queries_in_cache"; |
1329 | -+Variable_name Value |
1330 | -+Qcache_queries_in_cache 4 |
1331 | -+show status like "Qcache_inserts"; |
1332 | -+Variable_name Value |
1333 | -+Qcache_inserts 4 |
1334 | -+show status like "Qcache_hits"; |
1335 | -+Variable_name Value |
1336 | -+Qcache_hits 59 |
1337 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1; |
1338 | -+' /* comment inside quotes with internal backslash quote */ |
1339 | -+ ' /* comment inside quotes with internal backslash quote */ |
1340 | -+ ' /* comment inside quotes with internal backslash quote */ |
1341 | -+ ' /* comment inside quotes with internal backslash quote */ |
1342 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1; |
1343 | -+' /* comment inside quotes with internal backslash quote */ |
1344 | -+ ' /* comment inside quotes with internal backslash quote */ |
1345 | -+ ' /* comment inside quotes with internal backslash quote */ |
1346 | -+ ' /* comment inside quotes with internal backslash quote */ |
1347 | -+show status like "Qcache_queries_in_cache"; |
1348 | -+Variable_name Value |
1349 | -+Qcache_queries_in_cache 5 |
1350 | -+show status like "Qcache_inserts"; |
1351 | -+Variable_name Value |
1352 | -+Qcache_inserts 5 |
1353 | -+show status like "Qcache_hits"; |
1354 | -+Variable_name Value |
1355 | -+Qcache_hits 60 |
1356 | ++Qcache_queries_in_cache 1 |
1357 | ++show status like "Qcache_inserts"; |
1358 | ++Variable_name Value |
1359 | ++Qcache_inserts 1 |
1360 | ++show status like "Qcache_hits"; |
1361 | ++Variable_name Value |
1362 | ++Qcache_hits 50 |
1363 | ++select ' \' ' from t1; |
1364 | ++' |
1365 | ++ ' |
1366 | ++ ' |
1367 | ++ ' |
1368 | ++select ' \' ' from t1; |
1369 | ++' |
1370 | ++ ' |
1371 | ++ ' |
1372 | ++ ' |
1373 | ++show status like "Qcache_queries_in_cache"; |
1374 | ++Variable_name Value |
1375 | ++Qcache_queries_in_cache 2 |
1376 | ++show status like "Qcache_inserts"; |
1377 | ++Variable_name Value |
1378 | ++Qcache_inserts 2 |
1379 | ++show status like "Qcache_hits"; |
1380 | ++Variable_name Value |
1381 | ++Qcache_hits 51 |
1382 | +DROP TABLE t1; |
1383 | +SET GLOBAL query_cache_size=default; |
1384 | +set global query_cache_strip_comments=OFF; |
1385 | @@ -1988,7 +1536,7 @@ |
1386 | +SET GLOBAL query_cache_size= default; |
1387 | --- /dev/null |
1388 | +++ b/mysql-test/r/percona_query_cache_with_comments_disable.result |
1389 | -@@ -0,0 +1,1057 @@ |
1390 | +@@ -0,0 +1,865 @@ |
1391 | +set GLOBAL query_cache_size=1355776; |
1392 | +drop table if exists t1; |
1393 | +create table t1 (a int not null); |
1394 | @@ -2821,228 +2369,36 @@ |
1395 | +Variable_name Value |
1396 | +Qcache_hits 25 |
1397 | +----------------------------------------------------- |
1398 | -+select */* a comment \*/from t1 |
1399 | -+----------------------------------------------------- |
1400 | -+show status like "Qcache_queries_in_cache"; |
1401 | -+Variable_name Value |
1402 | -+Qcache_queries_in_cache 20 |
1403 | -+show status like "Qcache_inserts"; |
1404 | -+Variable_name Value |
1405 | -+Qcache_inserts 20 |
1406 | -+show status like "Qcache_hits"; |
1407 | -+Variable_name Value |
1408 | -+Qcache_hits 25 |
1409 | -+select */* a comment \*/from t1; |
1410 | -+a |
1411 | -+1 |
1412 | -+2 |
1413 | -+3 |
1414 | -+select */* a comment \*/from t1; |
1415 | -+a |
1416 | -+1 |
1417 | -+2 |
1418 | -+3 |
1419 | -+show status like "Qcache_queries_in_cache"; |
1420 | -+Variable_name Value |
1421 | -+Qcache_queries_in_cache 21 |
1422 | -+show status like "Qcache_inserts"; |
1423 | -+Variable_name Value |
1424 | -+Qcache_inserts 21 |
1425 | -+show status like "Qcache_hits"; |
1426 | -+Variable_name Value |
1427 | -+Qcache_hits 26 |
1428 | -+----------------------------------------------------- |
1429 | -+select *# a comment \ |
1430 | -+from t1 |
1431 | -+----------------------------------------------------- |
1432 | -+show status like "Qcache_queries_in_cache"; |
1433 | -+Variable_name Value |
1434 | -+Qcache_queries_in_cache 21 |
1435 | -+show status like "Qcache_inserts"; |
1436 | -+Variable_name Value |
1437 | -+Qcache_inserts 21 |
1438 | -+show status like "Qcache_hits"; |
1439 | -+Variable_name Value |
1440 | -+Qcache_hits 26 |
1441 | -+select *# a comment \ |
1442 | -+from t1; |
1443 | -+a |
1444 | -+1 |
1445 | -+2 |
1446 | -+3 |
1447 | -+select *# a comment \ |
1448 | -+from t1; |
1449 | -+a |
1450 | -+1 |
1451 | -+2 |
1452 | -+3 |
1453 | -+show status like "Qcache_queries_in_cache"; |
1454 | -+Variable_name Value |
1455 | -+Qcache_queries_in_cache 22 |
1456 | -+show status like "Qcache_inserts"; |
1457 | -+Variable_name Value |
1458 | -+Qcache_inserts 22 |
1459 | -+show status like "Qcache_hits"; |
1460 | -+Variable_name Value |
1461 | -+Qcache_hits 27 |
1462 | -+----------------------------------------------------- |
1463 | -+select *-- a comment \ |
1464 | -+from t1 |
1465 | -+----------------------------------------------------- |
1466 | -+show status like "Qcache_queries_in_cache"; |
1467 | -+Variable_name Value |
1468 | -+Qcache_queries_in_cache 22 |
1469 | -+show status like "Qcache_inserts"; |
1470 | -+Variable_name Value |
1471 | -+Qcache_inserts 22 |
1472 | -+show status like "Qcache_hits"; |
1473 | -+Variable_name Value |
1474 | -+Qcache_hits 27 |
1475 | -+select *-- a comment \ |
1476 | -+from t1; |
1477 | -+a |
1478 | -+1 |
1479 | -+2 |
1480 | -+3 |
1481 | -+select *-- a comment \ |
1482 | -+from t1; |
1483 | -+a |
1484 | -+1 |
1485 | -+2 |
1486 | -+3 |
1487 | -+show status like "Qcache_queries_in_cache"; |
1488 | -+Variable_name Value |
1489 | -+Qcache_queries_in_cache 23 |
1490 | -+show status like "Qcache_inserts"; |
1491 | -+Variable_name Value |
1492 | -+Qcache_inserts 23 |
1493 | -+show status like "Qcache_hits"; |
1494 | -+Variable_name Value |
1495 | -+Qcache_hits 28 |
1496 | -+----------------------------------------------------- |
1497 | -+select "\\"" /* not a comment */" from t1 |
1498 | -+----------------------------------------------------- |
1499 | -+show status like "Qcache_queries_in_cache"; |
1500 | -+Variable_name Value |
1501 | -+Qcache_queries_in_cache 23 |
1502 | -+show status like "Qcache_inserts"; |
1503 | -+Variable_name Value |
1504 | -+Qcache_inserts 23 |
1505 | -+show status like "Qcache_hits"; |
1506 | -+Variable_name Value |
1507 | -+Qcache_hits 28 |
1508 | -+select "\\"" /* not a comment */" from t1; |
1509 | -+\" /* not a comment */ |
1510 | -+\" /* not a comment */ |
1511 | -+\" /* not a comment */ |
1512 | -+\" /* not a comment */ |
1513 | -+select "\\"" /* not a comment */" from t1; |
1514 | -+\" /* not a comment */ |
1515 | -+\" /* not a comment */ |
1516 | -+\" /* not a comment */ |
1517 | -+\" /* not a comment */ |
1518 | -+show status like "Qcache_queries_in_cache"; |
1519 | -+Variable_name Value |
1520 | -+Qcache_queries_in_cache 24 |
1521 | -+show status like "Qcache_inserts"; |
1522 | -+Variable_name Value |
1523 | -+Qcache_inserts 24 |
1524 | -+show status like "Qcache_hits"; |
1525 | -+Variable_name Value |
1526 | -+Qcache_hits 29 |
1527 | -+----------------------------------------------------- |
1528 | -+select "\\"" /*! not a comment */" from t1 |
1529 | -+----------------------------------------------------- |
1530 | -+show status like "Qcache_queries_in_cache"; |
1531 | -+Variable_name Value |
1532 | -+Qcache_queries_in_cache 24 |
1533 | -+show status like "Qcache_inserts"; |
1534 | -+Variable_name Value |
1535 | -+Qcache_inserts 24 |
1536 | -+show status like "Qcache_hits"; |
1537 | -+Variable_name Value |
1538 | -+Qcache_hits 29 |
1539 | -+select "\\"" /*! not a comment */" from t1; |
1540 | -+\" /*! not a comment */ |
1541 | -+\" /*! not a comment */ |
1542 | -+\" /*! not a comment */ |
1543 | -+\" /*! not a comment */ |
1544 | -+select "\\"" /*! not a comment */" from t1; |
1545 | -+\" /*! not a comment */ |
1546 | -+\" /*! not a comment */ |
1547 | -+\" /*! not a comment */ |
1548 | -+\" /*! not a comment */ |
1549 | -+show status like "Qcache_queries_in_cache"; |
1550 | -+Variable_name Value |
1551 | -+Qcache_queries_in_cache 25 |
1552 | -+show status like "Qcache_inserts"; |
1553 | -+Variable_name Value |
1554 | -+Qcache_inserts 25 |
1555 | -+show status like "Qcache_hits"; |
1556 | -+Variable_name Value |
1557 | -+Qcache_hits 30 |
1558 | -+----------------------------------------------------- |
1559 | +select ' \' ' from t1 |
1560 | +----------------------------------------------------- |
1561 | +show status like "Qcache_queries_in_cache"; |
1562 | +Variable_name Value |
1563 | -+Qcache_queries_in_cache 25 |
1564 | -+show status like "Qcache_inserts"; |
1565 | -+Variable_name Value |
1566 | -+Qcache_inserts 25 |
1567 | -+show status like "Qcache_hits"; |
1568 | -+Variable_name Value |
1569 | -+Qcache_hits 30 |
1570 | -+select ' \' ' from t1; |
1571 | -+' |
1572 | -+ ' |
1573 | -+ ' |
1574 | -+ ' |
1575 | -+select ' \' ' from t1; |
1576 | -+' |
1577 | -+ ' |
1578 | -+ ' |
1579 | -+ ' |
1580 | -+show status like "Qcache_queries_in_cache"; |
1581 | -+Variable_name Value |
1582 | -+Qcache_queries_in_cache 26 |
1583 | -+show status like "Qcache_inserts"; |
1584 | -+Variable_name Value |
1585 | -+Qcache_inserts 26 |
1586 | -+show status like "Qcache_hits"; |
1587 | -+Variable_name Value |
1588 | -+Qcache_hits 31 |
1589 | -+----------------------------------------------------- |
1590 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1 |
1591 | -+----------------------------------------------------- |
1592 | -+show status like "Qcache_queries_in_cache"; |
1593 | -+Variable_name Value |
1594 | -+Qcache_queries_in_cache 26 |
1595 | -+show status like "Qcache_inserts"; |
1596 | -+Variable_name Value |
1597 | -+Qcache_inserts 26 |
1598 | -+show status like "Qcache_hits"; |
1599 | -+Variable_name Value |
1600 | -+Qcache_hits 31 |
1601 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1; |
1602 | -+' /* comment inside quotes with internal backslash quote */ |
1603 | -+ ' /* comment inside quotes with internal backslash quote */ |
1604 | -+ ' /* comment inside quotes with internal backslash quote */ |
1605 | -+ ' /* comment inside quotes with internal backslash quote */ |
1606 | -+select ' \' /* comment inside quotes with internal backslash quote */' from t1; |
1607 | -+' /* comment inside quotes with internal backslash quote */ |
1608 | -+ ' /* comment inside quotes with internal backslash quote */ |
1609 | -+ ' /* comment inside quotes with internal backslash quote */ |
1610 | -+ ' /* comment inside quotes with internal backslash quote */ |
1611 | -+show status like "Qcache_queries_in_cache"; |
1612 | -+Variable_name Value |
1613 | -+Qcache_queries_in_cache 27 |
1614 | -+show status like "Qcache_inserts"; |
1615 | -+Variable_name Value |
1616 | -+Qcache_inserts 27 |
1617 | -+show status like "Qcache_hits"; |
1618 | -+Variable_name Value |
1619 | -+Qcache_hits 32 |
1620 | ++Qcache_queries_in_cache 20 |
1621 | ++show status like "Qcache_inserts"; |
1622 | ++Variable_name Value |
1623 | ++Qcache_inserts 20 |
1624 | ++show status like "Qcache_hits"; |
1625 | ++Variable_name Value |
1626 | ++Qcache_hits 25 |
1627 | ++select ' \' ' from t1; |
1628 | ++' |
1629 | ++ ' |
1630 | ++ ' |
1631 | ++ ' |
1632 | ++select ' \' ' from t1; |
1633 | ++' |
1634 | ++ ' |
1635 | ++ ' |
1636 | ++ ' |
1637 | ++show status like "Qcache_queries_in_cache"; |
1638 | ++Variable_name Value |
1639 | ++Qcache_queries_in_cache 21 |
1640 | ++show status like "Qcache_inserts"; |
1641 | ++Variable_name Value |
1642 | ++Qcache_inserts 21 |
1643 | ++show status like "Qcache_hits"; |
1644 | ++Variable_name Value |
1645 | ++Qcache_hits 26 |
1646 | +DROP TABLE t1; |
1647 | +SET GLOBAL query_cache_size=default; |
1648 | +set global query_cache_strip_comments=OFF; |
1649 | @@ -3735,7 +3091,7 @@ |
1650 | +SET GLOBAL query_cache_size=0; |
1651 | --- a/mysql-test/r/mysqld--help-notwin.result |
1652 | +++ b/mysql-test/r/mysqld--help-notwin.result |
1653 | -@@ -493,6 +493,10 @@ |
1654 | +@@ -500,6 +500,10 @@ |
1655 | The minimum size for blocks allocated by the query cache |
1656 | --query-cache-size=# |
1657 | The memory allocated to store results from old queries |
1658 | @@ -3746,7 +3102,7 @@ |
1659 | --query-cache-type=name |
1660 | OFF = Don't cache or retrieve results. ON = Cache all |
1661 | results except SELECT SQL_NO_CACHE ... queries. DEMAND = |
1662 | -@@ -931,6 +935,7 @@ |
1663 | +@@ -942,6 +946,7 @@ |
1664 | query-cache-limit 1048576 |
1665 | query-cache-min-res-unit 4096 |
1666 | query-cache-size 0 |
1667 | @@ -3778,7 +3134,7 @@ |
1668 | +try_lock_mutex_query |
1669 | +SET GLOBAL query_cache_size=0; |
1670 | --- /dev/null |
1671 | -+++ b/mysql-test/r/percona_query_cache_with_comments_crash_2.result |
1672 | ++++ b/mysql-test/r/percona_bug856404.result |
1673 | @@ -0,0 +1,8 @@ |
1674 | +DROP TABLE IF EXISTS table17_int; |
1675 | +DROP TABLE IF EXISTS table30_int; |
1676 | @@ -3789,120 +3145,24 @@ |
1677 | +DROP TABLE table17_int; |
1678 | +DROP TABLE table30_int; |
1679 | --- /dev/null |
1680 | -+++ b/mysql-test/t/percona_query_cache_with_comments_crash_2-master.opt |
1681 | ++++ b/mysql-test/t/percona_bug856404-master.opt |
1682 | @@ -0,0 +1 @@ |
1683 | +--query-cache-size=10M --query-cache-strip-comments |
1684 | --- /dev/null |
1685 | -+++ b/mysql-test/t/percona_query_cache_with_comments_crash_2.test |
1686 | -@@ -0,0 +1,9 @@ |
1687 | ++++ b/mysql-test/t/percona_bug856404.test |
1688 | +@@ -0,0 +1,15 @@ |
1689 | ++######################################################################## |
1690 | ++# Bug #856404: Crash when query_cache_strip_comments enabled |
1691 | ++######################################################################## |
1692 | ++ |
1693 | +--disable_warnings |
1694 | +DROP TABLE IF EXISTS table17_int; |
1695 | +DROP TABLE IF EXISTS table30_int; |
1696 | +--enable_warnings |
1697 | ++ |
1698 | +CREATE TABLE `table17_int` (pk integer auto_increment primary key, `col_char_10_not_null_key` char(10), `col_enum_not_null_key` int); |
1699 | +CREATE TABLE `table30_int` (pk integer auto_increment primary key, `col_enum_not_null_key` int); |
1700 | +SELECT X . `pk` FROM `table17_int` AS X LEFT JOIN `table30_int` AS Y USING ( `col_enum_not_null_key` ) WHERE X . `col_char_10_not_null_key` != ' you need to translate Views labels into other languages, consider installing the <a href=\" !path\">Internationalization</a> package\'s Views translation module.' LIMIT 7 /*Generated by THREAD_ID 1*/; |
1701 | ++ |
1702 | +DROP TABLE table17_int; |
1703 | +DROP TABLE table30_int; |
1704 | ---- a/sql/sql_class.cc |
1705 | -+++ b/sql/sql_class.cc |
1706 | -@@ -807,6 +807,99 @@ |
1707 | - sql_errno == ER_TRG_NO_DEFINER); |
1708 | - } |
1709 | - |
1710 | -+#ifdef HAVE_QUERY_CACHE |
1711 | -+ |
1712 | -+ |
1713 | -+Query_Without_Comments::Query_Without_Comments() : |
1714 | -+ buffer(0), |
1715 | -+ q_length(0), |
1716 | -+ b_length(0) |
1717 | -+{ |
1718 | -+} |
1719 | -+ |
1720 | -+ |
1721 | -+Query_Without_Comments::~Query_Without_Comments() |
1722 | -+{ |
1723 | -+ if(buffer) |
1724 | -+ { |
1725 | -+ my_free(buffer); |
1726 | -+ } |
1727 | -+} |
1728 | -+ |
1729 | -+ |
1730 | -+bool Query_Without_Comments::allocate(size_t query_length, size_t db_length) |
1731 | -+{ |
1732 | -+ DBUG_ENTER("Query_Without_Comments::allocate"); |
1733 | -+ DBUG_PRINT("info", ("old buffer: %p " |
1734 | -+ "old query: '%-.4096s' " |
1735 | -+ "old buffer length: %u " |
1736 | -+ "old query length: %u", |
1737 | -+ buffer, |
1738 | -+ buffer, |
1739 | -+ (uint) b_length, |
1740 | -+ (uint) q_length)); |
1741 | -+ /* save maximum query length for check in the set_length */ |
1742 | -+ q_length= query_length; |
1743 | -+ /* according to sql_parse.cc memory allocation */ |
1744 | -+ size_t new_b_length= (query_length + 1) + sizeof(size_t) + db_length + |
1745 | -+ QUERY_CACHE_FLAGS_SIZE; |
1746 | -+ if (b_length < new_b_length) |
1747 | -+ { |
1748 | -+ b_length= new_b_length; |
1749 | -+ if (buffer) |
1750 | -+ { |
1751 | -+ buffer= (char*) my_realloc(buffer, b_length, MYF(0)); |
1752 | -+ } |
1753 | -+ else |
1754 | -+ { |
1755 | -+ buffer= (char *) my_malloc(b_length, MYF(0)); |
1756 | -+ } |
1757 | -+ } |
1758 | -+ buffer[0]= 0; |
1759 | -+ DBUG_PRINT("info", ("buffer: %p " |
1760 | -+ "buffer length: %u " |
1761 | -+ "query maximum length: %u", |
1762 | -+ buffer, |
1763 | -+ (uint) b_length, |
1764 | -+ (uint) q_length)); |
1765 | -+ DBUG_RETURN(buffer); |
1766 | -+} |
1767 | -+ |
1768 | -+ |
1769 | -+void Query_Without_Comments::set_length(size_t query_length) |
1770 | -+{ |
1771 | -+ DBUG_ENTER("Query_Without_Comments::set_length"); |
1772 | -+ DBUG_ASSERT(query_length <= q_length); |
1773 | -+ buffer[query_length]= 0; |
1774 | -+ DBUG_PRINT("info", ("buffer: %p " |
1775 | -+ "query: '%-.4096s' " |
1776 | -+ "buffer length: %u " |
1777 | -+ "query maximum length: %u " |
1778 | -+ "query length: %u", |
1779 | -+ buffer, |
1780 | -+ buffer, |
1781 | -+ (uint) b_length, |
1782 | -+ (uint) q_length, |
1783 | -+ (uint) query_length)); |
1784 | -+ q_length= query_length; |
1785 | -+ DBUG_VOID_RETURN; |
1786 | -+} |
1787 | -+ |
1788 | -+ |
1789 | -+char* Query_Without_Comments::query() |
1790 | -+{ |
1791 | -+ return buffer; |
1792 | -+} |
1793 | -+ |
1794 | -+ |
1795 | -+size_t Query_Without_Comments::length() |
1796 | -+{ |
1797 | -+ return q_length; |
1798 | -+} |
1799 | -+ |
1800 | -+ |
1801 | -+#endif // HAVE_QUERY_CACHE |
1802 | -+ |
1803 | - |
1804 | - THD::THD() |
1805 | - :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, |
http:// jenkins. percona. com/view/ Percona% 20Server% 205.5/job/ percona- server- 5.5-param/ 303/