Merge lp:~dedzone/drizzle/query-cache-hook into lp:~drizzle-trunk/drizzle/development
- query-cache-hook
- Merge into development
Status: | Merged |
---|---|
Merge reported by: | Monty Taylor |
Merged at revision: | not available |
Proposed branch: | lp:~dedzone/drizzle/query-cache-hook |
Merge into: | lp:~drizzle-trunk/drizzle/development |
Diff against target: |
640 lines (+224/-214) 6 files modified
drizzled/plugin/query_cache.cc (+135/-181) drizzled/plugin/query_cache.h (+28/-22) drizzled/select_send.h (+5/-0) drizzled/session.cc (+5/-0) drizzled/session.h (+26/-1) drizzled/sql_parse.cc (+25/-10) |
To merge this branch: | bzr merge lp:~dedzone/drizzle/query-cache-hook |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brian Aker | Needs Information | ||
Monty Taylor | Pending | ||
Review via email: mp+29729@code.launchpad.net |
This proposal supersedes a proposal from 2010-07-07.
Commit message
Description of the change
Monty Taylor (mordred) wrote : Posted in a previous version of this proposal | # |
Toru Maesaka (tmaesaka) wrote : Posted in a previous version of this proposal | # |
Agreed. It looks fine from first glimpse but I'm also not 100% sure
whether the hook points are placed in appropriate places in terms of
code flow.
I think it would be awesome if Djelle could provide us with arguments
on why the hooks are placed where they are atm.
Cheers,
Toru
On Thu, Jul 8, 2010 at 1:41 PM, Monty Taylor <email address hidden> wrote:
> Review: Needs Fixing
> One little thing:
>
> cout << "Results are cached" << endl;
>
> Looks like a debugging statement. Could you please remove this?
>
> In general looks fine to me, although I have not examined codeflow through the runtime - Brian?
> --
> https:/
> You are subscribed to branch lp:drizzle.
>
--
Toru Maesaka <email address hidden>
Djellel E. Difallah (dedzone) wrote : | # |
Hello,
I have added a wiki page explaining the Query Cache interface and the hooks into the code base.
Can you please review it.
Thanks!
~Djellel
Monty Taylor (mordred) wrote : | # |
For those following along at home, the wiki page is:
- 1647. By Djellel E. Difallah <ded@ubuntu>
-
merge with trunk
Toru Maesaka (tmaesaka) wrote : | # |
Fantastic!
This is exactly what I wanted to see. From engineering perspective, I
wanted to see this much earlier in the project but I'm happy to see
progress regardless :)
-Toru
On Tuesday, July 13, 2010, Monty Taylor <email address hidden> wrote:
> For those following along at home, the wiki page is:
>
> http://
> --
> https:/
> You are subscribed to branch lp:drizzle.
>
--
Toru Maesaka <email address hidden>
Brian Aker (brianaker) wrote : | # |
It would be good to see some test cases. How is the invalidation work within a transaction?
Cheers,
-Brian
Padraig O'Sullivan (posulliv) wrote : | # |
Hey Brian,
We were planning on doing invalidation using the replication API for this project. Would you mind expanding on what you mean here?
Thanks,
Padraig
Toru Maesaka (tmaesaka) wrote : | # |
Hi Brian,
Regarding test cases for Djellel's code, his changeset only includes
hooks and no real implementation of the plugin. So, I'm wondering how
we could write tests for it at this point. Would a "dummy" plugin
work? for example a module called "query-cache-test" or something
along that line.
As for invalidation in transactions, it shouldn't be a problem if we
use the Replication API since the transaction should have succeeded
when the query cache invalidator is called.
Cheers,
Toru
On Tue, Jul 20, 2010 at 10:17 AM, Brian Aker <email address hidden> wrote:
> Review: Needs Information
> It would be good to see some test cases. How is the invalidation work within a transaction?
>
> Cheers,
> -Brian
>
>
> --
> https:/
> You are subscribed to branch lp:drizzle.
>
--
Toru Maesaka <email address hidden>
Preview Diff
1 | === modified file 'drizzled/plugin/query_cache.cc' |
2 | --- drizzled/plugin/query_cache.cc 2010-05-15 18:23:34 +0000 |
3 | +++ drizzled/plugin/query_cache.cc 2010-07-12 19:31:41 +0000 |
4 | @@ -2,6 +2,7 @@ |
5 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
6 | * |
7 | * Copyright (C) 2008 Sun Microsystems |
8 | + * Copyright (C) 2010 Djellel Eddine Difallah |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | @@ -37,122 +38,144 @@ |
13 | |
14 | /* Namespaces are here to prevent global symbol clashes with these classes */ |
15 | |
16 | -class TryFetchAndSendIterate |
17 | - : public unary_function<plugin::QueryCache *, bool> |
18 | -{ |
19 | - Session *session; |
20 | - bool is_transactional; |
21 | -public: |
22 | - TryFetchAndSendIterate(Session *session_arg, bool is_transactional_arg) : |
23 | - unary_function<plugin::QueryCache *, bool>(), |
24 | - session(session_arg), is_transactional(is_transactional_arg) { } |
25 | - |
26 | - inline result_type operator()(argument_type handler) |
27 | - { |
28 | - if (handler->tryFetchAndSend(session, is_transactional)) |
29 | - { |
30 | - errmsg_printf(ERRMSG_LVL_ERROR, |
31 | - _("qcache plugin '%s' try_fetch_and_send() failed"), |
32 | - handler->getName().c_str()); |
33 | - return true; |
34 | - } |
35 | - return false; |
36 | - } |
37 | -}; |
38 | - |
39 | -class SetIterate |
40 | - : public unary_function<plugin::QueryCache *, bool> |
41 | -{ |
42 | - Session *session; |
43 | - bool is_transactional; |
44 | -public: |
45 | - SetIterate(Session *session_arg, bool is_transactional_arg) : |
46 | - unary_function<plugin::QueryCache *, bool>(), |
47 | - session(session_arg), is_transactional(is_transactional_arg) { } |
48 | - |
49 | - inline result_type operator()(argument_type handler) |
50 | - { |
51 | - |
52 | - if (handler->set(session, is_transactional)) |
53 | - { |
54 | - errmsg_printf(ERRMSG_LVL_ERROR, _("qcache plugin '%s' set() failed"), |
55 | - handler->getName().c_str()); |
56 | - return true; |
57 | - } |
58 | - return false; |
59 | - } |
60 | -}; |
61 | - |
62 | -class InvalidateTableIterate |
63 | - : public unary_function<plugin::QueryCache *, bool> |
64 | -{ |
65 | - Session *session; |
66 | - bool is_transactional; |
67 | -public: |
68 | - InvalidateTableIterate(Session *session_arg, bool is_transactional_arg) : |
69 | - unary_function<plugin::QueryCache *, bool>(), |
70 | - session(session_arg), is_transactional(is_transactional_arg) { } |
71 | - |
72 | - inline result_type operator()(argument_type handler) |
73 | - { |
74 | - |
75 | - if (handler->invalidateTable(session, is_transactional)) |
76 | - { |
77 | - errmsg_printf(ERRMSG_LVL_ERROR, |
78 | - _("qcache plugin '%s' invalidateTable() failed"), |
79 | - handler->getName().c_str()); |
80 | - return true; |
81 | - } |
82 | - return false; |
83 | - } |
84 | -}; |
85 | - |
86 | - |
87 | -class InvalidateDbIterate |
88 | - : public unary_function<plugin::QueryCache *, bool> |
89 | -{ |
90 | - Session *session; |
91 | - const char *dbname; |
92 | - bool is_transactional; |
93 | -public: |
94 | - InvalidateDbIterate(Session *session_arg, const char *dbname_arg, |
95 | - bool is_transactional_arg) : |
96 | - unary_function<plugin::QueryCache *, bool>(), |
97 | - session(session_arg), dbname(dbname_arg), |
98 | - is_transactional(is_transactional_arg) { } |
99 | - |
100 | - inline result_type operator()(argument_type handler) |
101 | - { |
102 | - if (handler->invalidateDb(session, dbname, is_transactional)) |
103 | - { |
104 | - errmsg_printf(ERRMSG_LVL_ERROR, |
105 | - _("qcache plugin '%s' invalidateDb() failed"), |
106 | - handler->getName().c_str()); |
107 | - return true; |
108 | - } |
109 | - return false; |
110 | - } |
111 | -}; |
112 | - |
113 | -class FlushIterate |
114 | - : public unary_function<plugin::QueryCache *, bool> |
115 | -{ |
116 | - Session *session; |
117 | -public: |
118 | - FlushIterate(Session *session_arg) : |
119 | +class IsCachedIterate |
120 | + : public unary_function<plugin::QueryCache *, bool> |
121 | +{ |
122 | + Session *session; |
123 | +public: |
124 | + IsCachedIterate(Session* session_arg) : |
125 | + unary_function<plugin::QueryCache *, bool>(), |
126 | + session(session_arg) { } |
127 | + |
128 | + inline result_type operator()(argument_type handler) |
129 | + { |
130 | + return handler->doIsCached(session); |
131 | + } |
132 | +}; |
133 | + |
134 | +bool plugin::QueryCache::isCached(Session *session) |
135 | +{ |
136 | + vector<plugin::QueryCache *>::iterator iter= |
137 | + find_if(all_query_cache.begin(), all_query_cache.end(), |
138 | + IsCachedIterate(session)); |
139 | + /* If iter is == end() here, that means that all of the plugins returned |
140 | + * false, which in this case means they all succeeded. Since we want to |
141 | + * return false on success, we return the value of the two being != |
142 | + */ |
143 | + return iter != all_query_cache.end(); |
144 | +} |
145 | + |
146 | + |
147 | +class SendCachedResultsetIterate |
148 | + : public unary_function<plugin::QueryCache *, bool> |
149 | +{ |
150 | + Session *session; |
151 | +public: |
152 | + SendCachedResultsetIterate(Session *session_arg) : |
153 | + unary_function<plugin::QueryCache *, bool>(), |
154 | + session(session_arg) { } |
155 | + |
156 | + inline result_type operator()(argument_type handler) |
157 | + { |
158 | + if (handler->doSendCachedResultset(session)) |
159 | + return false; |
160 | + return true; |
161 | + } |
162 | +}; |
163 | +bool plugin::QueryCache::sendCachedResultset(Session *session) |
164 | +{ |
165 | + vector<plugin::QueryCache *>::iterator iter= |
166 | + find_if(all_query_cache.begin(), all_query_cache.end(), |
167 | + SendCachedResultsetIterate(session)); |
168 | + /* If iter is == end() here, that means that all of the plugins returned |
169 | + * false, which in this case means they all succeeded. Since we want to |
170 | + * return false on success, we return the value of the two being != |
171 | + */ |
172 | + return iter != all_query_cache.end(); |
173 | +} |
174 | + |
175 | +class PrepareResultsetIterate |
176 | + : public unary_function<plugin::QueryCache *, bool> |
177 | +{ |
178 | + Session *session; |
179 | +public: |
180 | + PrepareResultsetIterate(Session *session_arg) : |
181 | unary_function<plugin::QueryCache *, bool>(), session(session_arg) { } |
182 | |
183 | inline result_type operator()(argument_type handler) |
184 | { |
185 | - if (handler->flush(session)) |
186 | - { |
187 | - errmsg_printf(ERRMSG_LVL_ERROR, _("qcache plugin '%s' flush() failed"), |
188 | - handler->getName().c_str()); |
189 | - return true; |
190 | - } |
191 | - return false; |
192 | - } |
193 | -}; |
194 | + return handler->doPrepareResultset(session); |
195 | + } |
196 | +}; |
197 | +bool plugin::QueryCache::prepareResultset(Session *session) |
198 | +{ |
199 | + vector<plugin::QueryCache *>::iterator iter= |
200 | + find_if(all_query_cache.begin(), all_query_cache.end(), |
201 | + PrepareResultsetIterate(session)); |
202 | + /* If iter is == end() here, that means that all of the plugins returned |
203 | + * false, which in this case means they all succeeded. Since we want to |
204 | + * return false on success, we return the value of the two being != |
205 | + */ |
206 | + return iter != all_query_cache.end(); |
207 | +} |
208 | + |
209 | +class SetResultsetIterate |
210 | + : public unary_function<plugin::QueryCache *, bool> |
211 | +{ |
212 | + Session *session; |
213 | +public: |
214 | + SetResultsetIterate(Session *session_arg) : |
215 | + unary_function<plugin::QueryCache *, bool>(), |
216 | + session(session_arg) { } |
217 | + |
218 | + inline result_type operator()(argument_type handler) |
219 | + { |
220 | + return handler->doSetResultset(session); |
221 | + } |
222 | +}; |
223 | + |
224 | +bool plugin::QueryCache::setResultset(Session *session) |
225 | +{ |
226 | + /* Use find_if instead of foreach so that we can collect return codes */ |
227 | + vector<plugin::QueryCache *>::iterator iter= |
228 | + find_if(all_query_cache.begin(), all_query_cache.end(), |
229 | + SetResultsetIterate(session)); |
230 | + /* If iter is == end() here, that means that all of the plugins returned |
231 | + * false, which in this case means they all succeeded. Since we want to |
232 | + * return false on success, we return the value of the two being != |
233 | + */ |
234 | + return iter != all_query_cache.end(); |
235 | +} |
236 | + |
237 | +class InsertRecordIterate |
238 | + : public unary_function<plugin::QueryCache *, bool> |
239 | +{ |
240 | + Session *session; |
241 | + List<Item> &item; |
242 | +public: |
243 | + InsertRecordIterate(Session *session_arg, List<Item> &item_arg) : |
244 | + unary_function<plugin::QueryCache *, bool>(), |
245 | + session(session_arg), item(item_arg) { } |
246 | + |
247 | + inline result_type operator()(argument_type handler) |
248 | + { |
249 | + return handler->doInsertRecord(session, item); |
250 | + } |
251 | +}; |
252 | +bool plugin::QueryCache::insertRecord(Session *session, List<Item> &items) |
253 | +{ |
254 | + /* Use find_if instead of foreach so that we can collect return codes */ |
255 | + vector<plugin::QueryCache *>::iterator iter= |
256 | + find_if(all_query_cache.begin(), all_query_cache.end(), |
257 | + InsertRecordIterate(session, items)); |
258 | + /* If iter is == end() here, that means that all of the plugins returned |
259 | + * false, which in this case means they all succeeded. Since we want to |
260 | + * return false on success, we return the value of the two being != |
261 | + */ |
262 | + return iter != all_query_cache.end(); |
263 | +} |
264 | + |
265 | + |
266 | |
267 | bool plugin::QueryCache::addPlugin(plugin::QueryCache *handler) |
268 | { |
269 | @@ -166,73 +189,4 @@ |
270 | handler)); |
271 | } |
272 | |
273 | - |
274 | -bool plugin::QueryCache::tryFetchAndSendDo(Session *session, |
275 | - bool transactional) |
276 | -{ |
277 | - /* Use find_if instead of foreach so that we can collect return codes */ |
278 | - vector<plugin::QueryCache *>::iterator iter= |
279 | - find_if(all_query_cache.begin(), all_query_cache.end(), |
280 | - TryFetchAndSendIterate(session, transactional)); |
281 | - /* If iter is == end() here, that means that all of the plugins returned |
282 | - * false, which in this case means they all succeeded. Since we want to |
283 | - * return false on success, we return the value of the two being != |
284 | - */ |
285 | - return iter != all_query_cache.end(); |
286 | -} |
287 | - |
288 | -bool plugin::QueryCache::setDo(Session *session, bool transactional) |
289 | -{ |
290 | - /* Use find_if instead of foreach so that we can collect return codes */ |
291 | - vector<plugin::QueryCache *>::iterator iter= |
292 | - find_if(all_query_cache.begin(), all_query_cache.end(), |
293 | - SetIterate(session, transactional)); |
294 | - /* If iter is == end() here, that means that all of the plugins returned |
295 | - * false, which in this case means they all succeeded. Since we want to |
296 | - * return false on success, we return the value of the two being != |
297 | - */ |
298 | - return iter != all_query_cache.end(); |
299 | -} |
300 | - |
301 | -bool plugin::QueryCache::invalidateTableDo(Session *session, |
302 | - bool transactional) |
303 | -{ |
304 | - /* Use find_if instead of foreach so that we can collect return codes */ |
305 | - vector<plugin::QueryCache *>::iterator iter= |
306 | - find_if(all_query_cache.begin(), all_query_cache.end(), |
307 | - InvalidateTableIterate(session, transactional)); |
308 | - /* If iter is == end() here, that means that all of the plugins returned |
309 | - * false, which in this case means they all succeeded. Since we want to |
310 | - * return false on success, we return the value of the two being != |
311 | - */ |
312 | - return iter != all_query_cache.end(); |
313 | -} |
314 | - |
315 | -bool plugin::QueryCache::invalidateDbDo(Session *session, const char *dbname, |
316 | - bool transactional) |
317 | -{ |
318 | - /* Use find_if instead of foreach so that we can collect return codes */ |
319 | - vector<plugin::QueryCache *>::iterator iter= |
320 | - find_if(all_query_cache.begin(), all_query_cache.end(), |
321 | - InvalidateDbIterate(session, dbname, transactional)); |
322 | - /* If iter is == end() here, that means that all of the plugins returned |
323 | - * false, which in this case means they all succeeded. Since we want to |
324 | - * return false on success, we return the value of the two being != |
325 | - */ |
326 | - return iter != all_query_cache.end(); |
327 | -} |
328 | - |
329 | -bool plugin::QueryCache::flushDo(Session *session) |
330 | -{ |
331 | - /* Use find_if instead of foreach so that we can collect return codes */ |
332 | - vector<plugin::QueryCache *>::iterator iter= |
333 | - find_if(all_query_cache.begin(), all_query_cache.end(), |
334 | - FlushIterate(session)); |
335 | - /* If iter is == end() here, that means that all of the plugins returned |
336 | - * false, which in this case means they all succeeded. Since we want to |
337 | - * return false on success, we return the value of the two being != |
338 | - */ |
339 | - return iter != all_query_cache.end(); |
340 | -} |
341 | - |
342 | } /* namespace drizzled */ |
343 | |
344 | === modified file 'drizzled/plugin/query_cache.h' |
345 | --- drizzled/plugin/query_cache.h 2010-03-06 02:08:13 +0000 |
346 | +++ drizzled/plugin/query_cache.h 2010-07-12 19:31:41 +0000 |
347 | @@ -4,6 +4,7 @@ |
348 | * Definitions required for Query Cache plugin |
349 | * |
350 | * Copyright (C) 2008 Sun Microsystems, Toru Maesaka |
351 | + * Copyright (C) 2010 Djellel Eddine Difallah |
352 | * |
353 | * This program is free software; you can redistribute it and/or modify |
354 | * it under the terms of the GNU General Public License as published by |
355 | @@ -22,55 +23,60 @@ |
356 | #ifndef DRIZZLED_PLUGIN_QUERY_CACHE_H |
357 | #define DRIZZLED_PLUGIN_QUERY_CACHE_H |
358 | |
359 | +#include "drizzled/plugin.h" |
360 | #include "drizzled/plugin/plugin.h" |
361 | +#include <drizzled/sql_list.h> |
362 | |
363 | namespace drizzled |
364 | { |
365 | class Session; |
366 | +class select_result; |
367 | |
368 | namespace plugin |
369 | { |
370 | |
371 | /* |
372 | This is the API that a qcache plugin must implement. |
373 | - it should implement each of these function pointers. |
374 | - if a function pointer is NULL (not loaded), that's ok. |
375 | - |
376 | - Return: |
377 | - false = success |
378 | - true = failure |
379 | */ |
380 | + |
381 | class QueryCache : public Plugin |
382 | { |
383 | +private: |
384 | + |
385 | QueryCache(); |
386 | QueryCache(const QueryCache &); |
387 | QueryCache& operator=(const QueryCache &); |
388 | -public: |
389 | + |
390 | +public: |
391 | + |
392 | explicit QueryCache(std::string name_arg) |
393 | : Plugin(name_arg, "QueryCache") |
394 | {} |
395 | |
396 | virtual ~QueryCache() {} |
397 | - /* Lookup the cache and transmit the data back to the client */ |
398 | - virtual bool tryFetchAndSend(Session *session, |
399 | - bool is_transactional)= 0; |
400 | - |
401 | - virtual bool set(Session *session, bool is_transactional)= 0; |
402 | - virtual bool invalidateTable(Session *session, bool is_transactional)= 0; |
403 | - virtual bool invalidateDb(Session *session, const char *db_name, |
404 | - bool transactional)= 0; |
405 | - virtual bool flush(Session *session)= 0; |
406 | + |
407 | + /* these are the Query Cache interface functions */ |
408 | + |
409 | + /* Lookup the cache and transmit the data back to the client */ |
410 | + virtual bool doIsCached(Session* session)= 0; |
411 | + /* Lookup the cache and transmit the data back to the client */ |
412 | + virtual bool doSendCachedResultset(Session *session)= 0; |
413 | + /* Send the current Resultset to the cache */ |
414 | + virtual bool doSetResultset(Session *session)= 0; |
415 | + /* initiate a new Resultset (header) */ |
416 | + virtual bool doPrepareResultset(Session *session)= 0; |
417 | + /* push a record to the current Resultset */ |
418 | + virtual bool doInsertRecord(Session *session, List<Item> &item)= 0; |
419 | |
420 | static bool addPlugin(QueryCache *handler); |
421 | static void removePlugin(QueryCache *handler); |
422 | |
423 | /* These are the functions called by the rest of the Drizzle server */ |
424 | - static bool tryFetchAndSendDo(Session *session, bool transactional); |
425 | - static bool setDo(Session *session, bool transactional); |
426 | - static bool invalidateTableDo(Session *session, bool transactional); |
427 | - static bool invalidateDbDo(Session *session, const char *db_name, |
428 | - bool transactional); |
429 | - static bool flushDo(Session *session); |
430 | + static bool isCached(Session *session); |
431 | + static bool sendCachedResultset(Session *session); |
432 | + static bool prepareResultset(Session *session); |
433 | + static bool setResultset(Session *session); |
434 | + static bool insertRecord(Session *session, List<Item> &item); |
435 | }; |
436 | |
437 | } /* namespace plugin */ |
438 | |
439 | === modified file 'drizzled/select_send.h' |
440 | --- drizzled/select_send.h 2010-02-14 19:27:57 +0000 |
441 | +++ drizzled/select_send.h 2010-07-12 19:31:41 +0000 |
442 | @@ -22,6 +22,7 @@ |
443 | #define DRIZZLED_SELECT_SEND_H |
444 | |
445 | #include <drizzled/plugin/client.h> |
446 | +#include <drizzled/plugin/query_cache.h> |
447 | #include <drizzled/plugin/transactional_storage_engine.h> |
448 | |
449 | namespace drizzled |
450 | @@ -111,6 +112,10 @@ |
451 | break; |
452 | } |
453 | } |
454 | + /* Insert this record to the Resultset into the cache */ |
455 | + if (session->query_cache_key != "" && session->getResultsetMessage() != NULL) |
456 | + plugin::QueryCache::insertRecord(session, items); |
457 | + |
458 | session->sent_row_count++; |
459 | if (session->is_error()) |
460 | return true; |
461 | |
462 | === modified file 'drizzled/session.cc' |
463 | --- drizzled/session.cc 2010-07-07 17:51:44 +0000 |
464 | +++ drizzled/session.cc 2010-07-12 19:31:41 +0000 |
465 | @@ -229,6 +229,9 @@ |
466 | cleanup_done= abort_on_warning= no_warnings_for_error= false; |
467 | pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST); |
468 | |
469 | + /* query_cache init */ |
470 | + query_cache_key= ""; |
471 | + resultset= NULL; |
472 | /* Variables with default values */ |
473 | proc_info="login"; |
474 | where= Session::DEFAULT_WHERE; |
475 | @@ -1464,6 +1467,8 @@ |
476 | { |
477 | /* Cleanup SQL processing state to reuse this statement in next query. */ |
478 | lex_end(lex); |
479 | + query_cache_key= ""; // reset the cache key |
480 | + resultset= NULL; |
481 | } |
482 | |
483 | bool Session::copy_db_to(char **p_db, size_t *p_db_length) |
484 | |
485 | === modified file 'drizzled/session.h' |
486 | --- drizzled/session.h 2010-07-07 17:51:44 +0000 |
487 | +++ drizzled/session.h 2010-07-12 19:31:41 +0000 |
488 | @@ -67,6 +67,7 @@ |
489 | { |
490 | class Transaction; |
491 | class Statement; |
492 | +class Resultset; |
493 | } |
494 | namespace internal |
495 | { |
496 | @@ -368,6 +369,8 @@ |
497 | */ |
498 | std::string db; |
499 | |
500 | + /* current cache key */ |
501 | + std::string query_cache_key; |
502 | /** |
503 | Constant for Session::where initialization in the beginning of every query. |
504 | |
505 | @@ -1175,7 +1178,15 @@ |
506 | { |
507 | return statement_message; |
508 | } |
509 | - |
510 | + |
511 | + /** |
512 | + * Returns a pointer to the current Resulset message for this |
513 | + * Session, or NULL if no active message. |
514 | + */ |
515 | + message::Resultset *getResultsetMessage() const |
516 | + { |
517 | + return resultset; |
518 | + } |
519 | /** |
520 | * Sets the active transaction message used by the ReplicationServices |
521 | * component. |
522 | @@ -1197,10 +1208,24 @@ |
523 | { |
524 | statement_message= in_message; |
525 | } |
526 | + |
527 | + /** |
528 | + * Sets the active Resultset message used by the Query Cache |
529 | + * plugin. |
530 | + * |
531 | + * @param[in] Pointer to the message |
532 | + */ |
533 | + void setResultsetMessage(message::Resultset *in_message) |
534 | + { |
535 | + resultset= in_message; |
536 | + } |
537 | + |
538 | private: |
539 | /** Pointers to memory managed by the ReplicationServices component */ |
540 | message::Transaction *transaction_message; |
541 | message::Statement *statement_message; |
542 | + /* Pointer to the current resultset of Select query */ |
543 | + message::Resultset *resultset; |
544 | plugin::EventObserverList *session_event_observers; |
545 | |
546 | /* Schema observers are mapped to databases. */ |
547 | |
548 | === modified file 'drizzled/sql_parse.cc' |
549 | --- drizzled/sql_parse.cc 2010-07-07 17:51:44 +0000 |
550 | +++ drizzled/sql_parse.cc 2010-07-12 19:31:41 +0000 |
551 | @@ -44,6 +44,7 @@ |
552 | |
553 | #include "drizzled/plugin/logging.h" |
554 | #include "drizzled/plugin/query_rewrite.h" |
555 | +#include "drizzled/plugin/query_cache.h" |
556 | #include "drizzled/plugin/authorization.h" |
557 | #include "drizzled/optimizer/explain_plan.h" |
558 | #include "drizzled/pthread_globals.h" |
559 | @@ -476,9 +477,7 @@ |
560 | |
561 | /* now we are ready to execute the statement */ |
562 | res= lex->statement->execute(); |
563 | - |
564 | session->set_proc_info("query end"); |
565 | - |
566 | /* |
567 | The return value for ROW_COUNT() is "implementation dependent" if the |
568 | statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC |
569 | @@ -492,7 +491,6 @@ |
570 | |
571 | return (res || session->is_error()); |
572 | } |
573 | - |
574 | bool execute_sqlcom_select(Session *session, TableList *all_tables) |
575 | { |
576 | LEX *lex= session->lex; |
577 | @@ -540,7 +538,13 @@ |
578 | { |
579 | if (!result && !(result= new select_send())) |
580 | return true; |
581 | + |
582 | + /* Init the Query Cache plugin */ |
583 | + plugin::QueryCache::prepareResultset(session); |
584 | res= handle_select(session, lex, result, 0); |
585 | + /* Send the Resultset to the cache */ |
586 | + plugin::QueryCache::setResultset(session); |
587 | + |
588 | if (result != lex->result) |
589 | delete result; |
590 | } |
591 | @@ -715,13 +719,25 @@ |
592 | uint64_t start_time= my_getsystime(); |
593 | lex_start(session); |
594 | session->reset_for_next_command(); |
595 | - |
596 | + /* Check if the Query is Cached if and return true if yes |
597 | + * TODO the plugin has to make sure that the query is cacheble |
598 | + * by setting the query_safe_cache param to TRUE |
599 | + */ |
600 | + bool res= true; |
601 | + if (plugin::QueryCache::isCached(session)) |
602 | + { |
603 | + res= plugin::QueryCache::sendCachedResultset(session); |
604 | + } |
605 | + if (not res) |
606 | + { |
607 | +#if defined(DEBUG) |
608 | + errmsg_printf(ERRMSG_LVL_DBUG,_("Results retrieved from cache")); |
609 | +#endif /* DEBUG */ |
610 | + return; |
611 | + } |
612 | LEX *lex= session->lex; |
613 | - |
614 | Lex_input_stream lip(session, inBuf, length); |
615 | - |
616 | bool err= parse_sql(session, &lip); |
617 | - |
618 | if (!err) |
619 | { |
620 | { |
621 | @@ -731,9 +747,9 @@ |
622 | session->thread_id, |
623 | const_cast<const char *>(session->db.empty() ? "" : session->db.c_str())); |
624 | // Implement Views here --Brian |
625 | - |
626 | /* Actually execute the query */ |
627 | - try { |
628 | + try |
629 | + { |
630 | mysql_execute_command(session); |
631 | } |
632 | catch (...) |
633 | @@ -749,7 +765,6 @@ |
634 | { |
635 | assert(session->is_error()); |
636 | } |
637 | - |
638 | lex->unit.cleanup(); |
639 | session->set_proc_info("freeing items"); |
640 | session->end_statement(); |
One little thing:
cout << "Results are cached" << endl;
Looks like a debugging statement. Could you please remove this?
In general looks fine to me, although I have not examined codeflow through the runtime - Brian?