Merge lp:~dedzone/drizzle/query-cache-hook into lp:~drizzle-trunk/drizzle/development

Proposed by Djellel E. Difallah
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
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.

To post a comment you must log in.
Revision history for this message
Monty Taylor (mordred) wrote : Posted in a previous version of this proposal

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?

review: Needs Fixing
Revision history for this message
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://code.launchpad.net/~dedzone/drizzle/query-cache-hook/+merge/29359
> You are subscribed to branch lp:drizzle.
>

--
Toru Maesaka <email address hidden>

Revision history for this message
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

Revision history for this message
Monty Taylor (mordred) wrote :

For those following along at home, the wiki page is:

http://drizzle.org/wiki/Query_cache

lp:~dedzone/drizzle/query-cache-hook updated
1647. By Djellel E. Difallah <ded@ubuntu>

merge with trunk

Revision history for this message
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://drizzle.org/wiki/Query_cache
> --
> https://code.launchpad.net/~dedzone/drizzle/query-cache-hook/+merge/29729
> You are subscribed to branch lp:drizzle.
>

--
Toru Maesaka <email address hidden>

Revision history for this message
Brian Aker (brianaker) wrote :

It would be good to see some test cases. How is the invalidation work within a transaction?

Cheers,
  -Brian

review: Needs Information
Revision history for this message
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

Revision history for this message
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://code.launchpad.net/~dedzone/drizzle/query-cache-hook/+merge/29729
> You are subscribed to branch lp:drizzle.
>

--
Toru Maesaka <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'drizzled/plugin/query_cache.cc'
--- drizzled/plugin/query_cache.cc 2010-05-15 18:23:34 +0000
+++ drizzled/plugin/query_cache.cc 2010-07-12 19:31:41 +0000
@@ -2,6 +2,7 @@
2 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:2 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3 *3 *
4 * Copyright (C) 2008 Sun Microsystems4 * Copyright (C) 2008 Sun Microsystems
5 * Copyright (C) 2010 Djellel Eddine Difallah
5 *6 *
6 * This program is free software; you can redistribute it and/or modify7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by8 * it under the terms of the GNU General Public License as published by
@@ -37,122 +38,144 @@
3738
38/* Namespaces are here to prevent global symbol clashes with these classes */39/* Namespaces are here to prevent global symbol clashes with these classes */
3940
40class TryFetchAndSendIterate41class IsCachedIterate
41 : public unary_function<plugin::QueryCache *, bool>42 : public unary_function<plugin::QueryCache *, bool>
42{43{
43 Session *session;44 Session *session;
44 bool is_transactional;45public:
45public:46 IsCachedIterate(Session* session_arg) :
46 TryFetchAndSendIterate(Session *session_arg, bool is_transactional_arg) :47 unary_function<plugin::QueryCache *, bool>(),
47 unary_function<plugin::QueryCache *, bool>(),48 session(session_arg) { }
48 session(session_arg), is_transactional(is_transactional_arg) { }49
4950 inline result_type operator()(argument_type handler)
50 inline result_type operator()(argument_type handler)51 {
51 {52 return handler->doIsCached(session);
52 if (handler->tryFetchAndSend(session, is_transactional))53 }
53 {54};
54 errmsg_printf(ERRMSG_LVL_ERROR,55
55 _("qcache plugin '%s' try_fetch_and_send() failed"),56bool plugin::QueryCache::isCached(Session *session)
56 handler->getName().c_str());57{
57 return true;58 vector<plugin::QueryCache *>::iterator iter=
58 }59 find_if(all_query_cache.begin(), all_query_cache.end(),
59 return false;60 IsCachedIterate(session));
60 }61 /* If iter is == end() here, that means that all of the plugins returned
61};62 * false, which in this case means they all succeeded. Since we want to
6263 * return false on success, we return the value of the two being !=
63class SetIterate64 */
64 : public unary_function<plugin::QueryCache *, bool>65 return iter != all_query_cache.end();
65{66}
66 Session *session;67
67 bool is_transactional;68
68public:69class SendCachedResultsetIterate
69 SetIterate(Session *session_arg, bool is_transactional_arg) :70 : public unary_function<plugin::QueryCache *, bool>
70 unary_function<plugin::QueryCache *, bool>(),71{
71 session(session_arg), is_transactional(is_transactional_arg) { }72 Session *session;
7273public:
73 inline result_type operator()(argument_type handler)74 SendCachedResultsetIterate(Session *session_arg) :
74 {75 unary_function<plugin::QueryCache *, bool>(),
7576 session(session_arg) { }
76 if (handler->set(session, is_transactional))77
77 {78 inline result_type operator()(argument_type handler)
78 errmsg_printf(ERRMSG_LVL_ERROR, _("qcache plugin '%s' set() failed"),79 {
79 handler->getName().c_str());80 if (handler->doSendCachedResultset(session))
80 return true;81 return false;
81 }82 return true;
82 return false;83 }
83 }84};
84};85bool plugin::QueryCache::sendCachedResultset(Session *session)
8586{
86class InvalidateTableIterate87 vector<plugin::QueryCache *>::iterator iter=
87 : public unary_function<plugin::QueryCache *, bool>88 find_if(all_query_cache.begin(), all_query_cache.end(),
88{89 SendCachedResultsetIterate(session));
89 Session *session;90 /* If iter is == end() here, that means that all of the plugins returned
90 bool is_transactional;91 * false, which in this case means they all succeeded. Since we want to
91public:92 * return false on success, we return the value of the two being !=
92 InvalidateTableIterate(Session *session_arg, bool is_transactional_arg) :93 */
93 unary_function<plugin::QueryCache *, bool>(),94 return iter != all_query_cache.end();
94 session(session_arg), is_transactional(is_transactional_arg) { }95}
9596
96 inline result_type operator()(argument_type handler)97class PrepareResultsetIterate
97 {98 : public unary_function<plugin::QueryCache *, bool>
9899{
99 if (handler->invalidateTable(session, is_transactional))100 Session *session;
100 {101public:
101 errmsg_printf(ERRMSG_LVL_ERROR,102 PrepareResultsetIterate(Session *session_arg) :
102 _("qcache plugin '%s' invalidateTable() failed"),
103 handler->getName().c_str());
104 return true;
105 }
106 return false;
107 }
108};
109
110
111class InvalidateDbIterate
112 : public unary_function<plugin::QueryCache *, bool>
113{
114 Session *session;
115 const char *dbname;
116 bool is_transactional;
117public:
118 InvalidateDbIterate(Session *session_arg, const char *dbname_arg,
119 bool is_transactional_arg) :
120 unary_function<plugin::QueryCache *, bool>(),
121 session(session_arg), dbname(dbname_arg),
122 is_transactional(is_transactional_arg) { }
123
124 inline result_type operator()(argument_type handler)
125 {
126 if (handler->invalidateDb(session, dbname, is_transactional))
127 {
128 errmsg_printf(ERRMSG_LVL_ERROR,
129 _("qcache plugin '%s' invalidateDb() failed"),
130 handler->getName().c_str());
131 return true;
132 }
133 return false;
134 }
135};
136
137class FlushIterate
138 : public unary_function<plugin::QueryCache *, bool>
139{
140 Session *session;
141public:
142 FlushIterate(Session *session_arg) :
143 unary_function<plugin::QueryCache *, bool>(), session(session_arg) { }103 unary_function<plugin::QueryCache *, bool>(), session(session_arg) { }
144104
145 inline result_type operator()(argument_type handler)105 inline result_type operator()(argument_type handler)
146 {106 {
147 if (handler->flush(session))107 return handler->doPrepareResultset(session);
148 {108 }
149 errmsg_printf(ERRMSG_LVL_ERROR, _("qcache plugin '%s' flush() failed"),109};
150 handler->getName().c_str());110bool plugin::QueryCache::prepareResultset(Session *session)
151 return true;111{
152 }112 vector<plugin::QueryCache *>::iterator iter=
153 return false;113 find_if(all_query_cache.begin(), all_query_cache.end(),
154 }114 PrepareResultsetIterate(session));
155};115 /* If iter is == end() here, that means that all of the plugins returned
116 * false, which in this case means they all succeeded. Since we want to
117 * return false on success, we return the value of the two being !=
118 */
119 return iter != all_query_cache.end();
120}
121
122class SetResultsetIterate
123 : public unary_function<plugin::QueryCache *, bool>
124{
125 Session *session;
126public:
127 SetResultsetIterate(Session *session_arg) :
128 unary_function<plugin::QueryCache *, bool>(),
129 session(session_arg) { }
130
131 inline result_type operator()(argument_type handler)
132 {
133 return handler->doSetResultset(session);
134 }
135};
136
137bool plugin::QueryCache::setResultset(Session *session)
138{
139 /* Use find_if instead of foreach so that we can collect return codes */
140 vector<plugin::QueryCache *>::iterator iter=
141 find_if(all_query_cache.begin(), all_query_cache.end(),
142 SetResultsetIterate(session));
143 /* If iter is == end() here, that means that all of the plugins returned
144 * false, which in this case means they all succeeded. Since we want to
145 * return false on success, we return the value of the two being !=
146 */
147 return iter != all_query_cache.end();
148}
149
150class InsertRecordIterate
151 : public unary_function<plugin::QueryCache *, bool>
152{
153 Session *session;
154 List<Item> &item;
155public:
156 InsertRecordIterate(Session *session_arg, List<Item> &item_arg) :
157 unary_function<plugin::QueryCache *, bool>(),
158 session(session_arg), item(item_arg) { }
159
160 inline result_type operator()(argument_type handler)
161 {
162 return handler->doInsertRecord(session, item);
163 }
164};
165bool plugin::QueryCache::insertRecord(Session *session, List<Item> &items)
166{
167 /* Use find_if instead of foreach so that we can collect return codes */
168 vector<plugin::QueryCache *>::iterator iter=
169 find_if(all_query_cache.begin(), all_query_cache.end(),
170 InsertRecordIterate(session, items));
171 /* If iter is == end() here, that means that all of the plugins returned
172 * false, which in this case means they all succeeded. Since we want to
173 * return false on success, we return the value of the two being !=
174 */
175 return iter != all_query_cache.end();
176}
177
178
156179
157bool plugin::QueryCache::addPlugin(plugin::QueryCache *handler)180bool plugin::QueryCache::addPlugin(plugin::QueryCache *handler)
158{181{
@@ -166,73 +189,4 @@
166 handler));189 handler));
167}190}
168191
169
170bool plugin::QueryCache::tryFetchAndSendDo(Session *session,
171 bool transactional)
172{
173 /* Use find_if instead of foreach so that we can collect return codes */
174 vector<plugin::QueryCache *>::iterator iter=
175 find_if(all_query_cache.begin(), all_query_cache.end(),
176 TryFetchAndSendIterate(session, transactional));
177 /* If iter is == end() here, that means that all of the plugins returned
178 * false, which in this case means they all succeeded. Since we want to
179 * return false on success, we return the value of the two being !=
180 */
181 return iter != all_query_cache.end();
182}
183
184bool plugin::QueryCache::setDo(Session *session, bool transactional)
185{
186 /* Use find_if instead of foreach so that we can collect return codes */
187 vector<plugin::QueryCache *>::iterator iter=
188 find_if(all_query_cache.begin(), all_query_cache.end(),
189 SetIterate(session, transactional));
190 /* If iter is == end() here, that means that all of the plugins returned
191 * false, which in this case means they all succeeded. Since we want to
192 * return false on success, we return the value of the two being !=
193 */
194 return iter != all_query_cache.end();
195}
196
197bool plugin::QueryCache::invalidateTableDo(Session *session,
198 bool transactional)
199{
200 /* Use find_if instead of foreach so that we can collect return codes */
201 vector<plugin::QueryCache *>::iterator iter=
202 find_if(all_query_cache.begin(), all_query_cache.end(),
203 InvalidateTableIterate(session, transactional));
204 /* If iter is == end() here, that means that all of the plugins returned
205 * false, which in this case means they all succeeded. Since we want to
206 * return false on success, we return the value of the two being !=
207 */
208 return iter != all_query_cache.end();
209}
210
211bool plugin::QueryCache::invalidateDbDo(Session *session, const char *dbname,
212 bool transactional)
213{
214 /* Use find_if instead of foreach so that we can collect return codes */
215 vector<plugin::QueryCache *>::iterator iter=
216 find_if(all_query_cache.begin(), all_query_cache.end(),
217 InvalidateDbIterate(session, dbname, transactional));
218 /* If iter is == end() here, that means that all of the plugins returned
219 * false, which in this case means they all succeeded. Since we want to
220 * return false on success, we return the value of the two being !=
221 */
222 return iter != all_query_cache.end();
223}
224
225bool plugin::QueryCache::flushDo(Session *session)
226{
227 /* Use find_if instead of foreach so that we can collect return codes */
228 vector<plugin::QueryCache *>::iterator iter=
229 find_if(all_query_cache.begin(), all_query_cache.end(),
230 FlushIterate(session));
231 /* If iter is == end() here, that means that all of the plugins returned
232 * false, which in this case means they all succeeded. Since we want to
233 * return false on success, we return the value of the two being !=
234 */
235 return iter != all_query_cache.end();
236}
237
238} /* namespace drizzled */192} /* namespace drizzled */
239193
=== modified file 'drizzled/plugin/query_cache.h'
--- drizzled/plugin/query_cache.h 2010-03-06 02:08:13 +0000
+++ drizzled/plugin/query_cache.h 2010-07-12 19:31:41 +0000
@@ -4,6 +4,7 @@
4 * Definitions required for Query Cache plugin4 * Definitions required for Query Cache plugin
5 *5 *
6 * Copyright (C) 2008 Sun Microsystems, Toru Maesaka6 * Copyright (C) 2008 Sun Microsystems, Toru Maesaka
7 * Copyright (C) 2010 Djellel Eddine Difallah
7 *8 *
8 * This program is free software; you can redistribute it and/or modify9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by10 * it under the terms of the GNU General Public License as published by
@@ -22,55 +23,60 @@
22#ifndef DRIZZLED_PLUGIN_QUERY_CACHE_H23#ifndef DRIZZLED_PLUGIN_QUERY_CACHE_H
23#define DRIZZLED_PLUGIN_QUERY_CACHE_H24#define DRIZZLED_PLUGIN_QUERY_CACHE_H
2425
26#include "drizzled/plugin.h"
25#include "drizzled/plugin/plugin.h"27#include "drizzled/plugin/plugin.h"
28#include <drizzled/sql_list.h>
2629
27namespace drizzled30namespace drizzled
28{31{
29class Session;32class Session;
33class select_result;
3034
31namespace plugin35namespace plugin
32{36{
3337
34/* 38/*
35 This is the API that a qcache plugin must implement.39 This is the API that a qcache plugin must implement.
36 it should implement each of these function pointers.
37 if a function pointer is NULL (not loaded), that's ok.
38
39 Return:
40 false = success
41 true = failure
42*/40*/
41
43class QueryCache : public Plugin42class QueryCache : public Plugin
44{43{
44private:
45
45 QueryCache();46 QueryCache();
46 QueryCache(const QueryCache &);47 QueryCache(const QueryCache &);
47 QueryCache& operator=(const QueryCache &);48 QueryCache& operator=(const QueryCache &);
48public:49
50public:
51
49 explicit QueryCache(std::string name_arg)52 explicit QueryCache(std::string name_arg)
50 : Plugin(name_arg, "QueryCache")53 : Plugin(name_arg, "QueryCache")
51 {}54 {}
5255
53 virtual ~QueryCache() {}56 virtual ~QueryCache() {}
54 /* Lookup the cache and transmit the data back to the client */57
55 virtual bool tryFetchAndSend(Session *session,58 /* these are the Query Cache interface functions */
56 bool is_transactional)= 0;59
5760 /* Lookup the cache and transmit the data back to the client */
58 virtual bool set(Session *session, bool is_transactional)= 0;61 virtual bool doIsCached(Session* session)= 0;
59 virtual bool invalidateTable(Session *session, bool is_transactional)= 0;62 /* Lookup the cache and transmit the data back to the client */
60 virtual bool invalidateDb(Session *session, const char *db_name,63 virtual bool doSendCachedResultset(Session *session)= 0;
61 bool transactional)= 0;64 /* Send the current Resultset to the cache */
62 virtual bool flush(Session *session)= 0;65 virtual bool doSetResultset(Session *session)= 0;
66 /* initiate a new Resultset (header) */
67 virtual bool doPrepareResultset(Session *session)= 0;
68 /* push a record to the current Resultset */
69 virtual bool doInsertRecord(Session *session, List<Item> &item)= 0;
6370
64 static bool addPlugin(QueryCache *handler);71 static bool addPlugin(QueryCache *handler);
65 static void removePlugin(QueryCache *handler);72 static void removePlugin(QueryCache *handler);
6673
67 /* These are the functions called by the rest of the Drizzle server */74 /* These are the functions called by the rest of the Drizzle server */
68 static bool tryFetchAndSendDo(Session *session, bool transactional);75 static bool isCached(Session *session);
69 static bool setDo(Session *session, bool transactional);76 static bool sendCachedResultset(Session *session);
70 static bool invalidateTableDo(Session *session, bool transactional);77 static bool prepareResultset(Session *session);
71 static bool invalidateDbDo(Session *session, const char *db_name,78 static bool setResultset(Session *session);
72 bool transactional);79 static bool insertRecord(Session *session, List<Item> &item);
73 static bool flushDo(Session *session);
74};80};
7581
76} /* namespace plugin */82} /* namespace plugin */
7783
=== modified file 'drizzled/select_send.h'
--- drizzled/select_send.h 2010-02-14 19:27:57 +0000
+++ drizzled/select_send.h 2010-07-12 19:31:41 +0000
@@ -22,6 +22,7 @@
22#define DRIZZLED_SELECT_SEND_H22#define DRIZZLED_SELECT_SEND_H
2323
24#include <drizzled/plugin/client.h>24#include <drizzled/plugin/client.h>
25#include <drizzled/plugin/query_cache.h>
25#include <drizzled/plugin/transactional_storage_engine.h>26#include <drizzled/plugin/transactional_storage_engine.h>
2627
27namespace drizzled28namespace drizzled
@@ -111,6 +112,10 @@
111 break;112 break;
112 }113 }
113 }114 }
115 /* Insert this record to the Resultset into the cache */
116 if (session->query_cache_key != "" && session->getResultsetMessage() != NULL)
117 plugin::QueryCache::insertRecord(session, items);
118
114 session->sent_row_count++;119 session->sent_row_count++;
115 if (session->is_error())120 if (session->is_error())
116 return true;121 return true;
117122
=== modified file 'drizzled/session.cc'
--- drizzled/session.cc 2010-07-07 17:51:44 +0000
+++ drizzled/session.cc 2010-07-12 19:31:41 +0000
@@ -229,6 +229,9 @@
229 cleanup_done= abort_on_warning= no_warnings_for_error= false;229 cleanup_done= abort_on_warning= no_warnings_for_error= false;
230 pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);230 pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
231231
232 /* query_cache init */
233 query_cache_key= "";
234 resultset= NULL;
232 /* Variables with default values */235 /* Variables with default values */
233 proc_info="login";236 proc_info="login";
234 where= Session::DEFAULT_WHERE;237 where= Session::DEFAULT_WHERE;
@@ -1464,6 +1467,8 @@
1464{1467{
1465 /* Cleanup SQL processing state to reuse this statement in next query. */1468 /* Cleanup SQL processing state to reuse this statement in next query. */
1466 lex_end(lex);1469 lex_end(lex);
1470 query_cache_key= ""; // reset the cache key
1471 resultset= NULL;
1467}1472}
14681473
1469bool Session::copy_db_to(char **p_db, size_t *p_db_length)1474bool Session::copy_db_to(char **p_db, size_t *p_db_length)
14701475
=== modified file 'drizzled/session.h'
--- drizzled/session.h 2010-07-07 17:51:44 +0000
+++ drizzled/session.h 2010-07-12 19:31:41 +0000
@@ -67,6 +67,7 @@
67{67{
68class Transaction;68class Transaction;
69class Statement;69class Statement;
70class Resultset;
70}71}
71namespace internal72namespace internal
72{73{
@@ -368,6 +369,8 @@
368 */369 */
369 std::string db;370 std::string db;
370371
372 /* current cache key */
373 std::string query_cache_key;
371 /**374 /**
372 Constant for Session::where initialization in the beginning of every query.375 Constant for Session::where initialization in the beginning of every query.
373376
@@ -1175,7 +1178,15 @@
1175 {1178 {
1176 return statement_message;1179 return statement_message;
1177 }1180 }
11781181
1182 /**
1183 * Returns a pointer to the current Resulset message for this
1184 * Session, or NULL if no active message.
1185 */
1186 message::Resultset *getResultsetMessage() const
1187 {
1188 return resultset;
1189 }
1179 /**1190 /**
1180 * Sets the active transaction message used by the ReplicationServices1191 * Sets the active transaction message used by the ReplicationServices
1181 * component.1192 * component.
@@ -1197,10 +1208,24 @@
1197 {1208 {
1198 statement_message= in_message;1209 statement_message= in_message;
1199 }1210 }
1211
1212 /**
1213 * Sets the active Resultset message used by the Query Cache
1214 * plugin.
1215 *
1216 * @param[in] Pointer to the message
1217 */
1218 void setResultsetMessage(message::Resultset *in_message)
1219 {
1220 resultset= in_message;
1221 }
1222
1200private:1223private:
1201 /** Pointers to memory managed by the ReplicationServices component */1224 /** Pointers to memory managed by the ReplicationServices component */
1202 message::Transaction *transaction_message;1225 message::Transaction *transaction_message;
1203 message::Statement *statement_message;1226 message::Statement *statement_message;
1227 /* Pointer to the current resultset of Select query */
1228 message::Resultset *resultset;
1204 plugin::EventObserverList *session_event_observers;1229 plugin::EventObserverList *session_event_observers;
1205 1230
1206 /* Schema observers are mapped to databases. */1231 /* Schema observers are mapped to databases. */
12071232
=== modified file 'drizzled/sql_parse.cc'
--- drizzled/sql_parse.cc 2010-07-07 17:51:44 +0000
+++ drizzled/sql_parse.cc 2010-07-12 19:31:41 +0000
@@ -44,6 +44,7 @@
4444
45#include "drizzled/plugin/logging.h"45#include "drizzled/plugin/logging.h"
46#include "drizzled/plugin/query_rewrite.h"46#include "drizzled/plugin/query_rewrite.h"
47#include "drizzled/plugin/query_cache.h"
47#include "drizzled/plugin/authorization.h"48#include "drizzled/plugin/authorization.h"
48#include "drizzled/optimizer/explain_plan.h"49#include "drizzled/optimizer/explain_plan.h"
49#include "drizzled/pthread_globals.h"50#include "drizzled/pthread_globals.h"
@@ -476,9 +477,7 @@
476477
477 /* now we are ready to execute the statement */478 /* now we are ready to execute the statement */
478 res= lex->statement->execute();479 res= lex->statement->execute();
479
480 session->set_proc_info("query end");480 session->set_proc_info("query end");
481
482 /*481 /*
483 The return value for ROW_COUNT() is "implementation dependent" if the482 The return value for ROW_COUNT() is "implementation dependent" if the
484 statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC483 statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
@@ -492,7 +491,6 @@
492491
493 return (res || session->is_error());492 return (res || session->is_error());
494}493}
495
496bool execute_sqlcom_select(Session *session, TableList *all_tables)494bool execute_sqlcom_select(Session *session, TableList *all_tables)
497{495{
498 LEX *lex= session->lex;496 LEX *lex= session->lex;
@@ -540,7 +538,13 @@
540 {538 {
541 if (!result && !(result= new select_send()))539 if (!result && !(result= new select_send()))
542 return true;540 return true;
541
542 /* Init the Query Cache plugin */
543 plugin::QueryCache::prepareResultset(session);
543 res= handle_select(session, lex, result, 0);544 res= handle_select(session, lex, result, 0);
545 /* Send the Resultset to the cache */
546 plugin::QueryCache::setResultset(session);
547
544 if (result != lex->result)548 if (result != lex->result)
545 delete result;549 delete result;
546 }550 }
@@ -715,13 +719,25 @@
715 uint64_t start_time= my_getsystime();719 uint64_t start_time= my_getsystime();
716 lex_start(session);720 lex_start(session);
717 session->reset_for_next_command();721 session->reset_for_next_command();
718722 /* Check if the Query is Cached if and return true if yes
723 * TODO the plugin has to make sure that the query is cacheble
724 * by setting the query_safe_cache param to TRUE
725 */
726 bool res= true;
727 if (plugin::QueryCache::isCached(session))
728 {
729 res= plugin::QueryCache::sendCachedResultset(session);
730 }
731 if (not res)
732 {
733#if defined(DEBUG)
734 errmsg_printf(ERRMSG_LVL_DBUG,_("Results retrieved from cache"));
735#endif /* DEBUG */
736 return;
737 }
719 LEX *lex= session->lex;738 LEX *lex= session->lex;
720
721 Lex_input_stream lip(session, inBuf, length);739 Lex_input_stream lip(session, inBuf, length);
722
723 bool err= parse_sql(session, &lip);740 bool err= parse_sql(session, &lip);
724
725 if (!err)741 if (!err)
726 {742 {
727 {743 {
@@ -731,9 +747,9 @@
731 session->thread_id,747 session->thread_id,
732 const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));748 const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
733 // Implement Views here --Brian749 // Implement Views here --Brian
734
735 /* Actually execute the query */750 /* Actually execute the query */
736 try {751 try
752 {
737 mysql_execute_command(session);753 mysql_execute_command(session);
738 }754 }
739 catch (...)755 catch (...)
@@ -749,7 +765,6 @@
749 {765 {
750 assert(session->is_error());766 assert(session->is_error());
751 }767 }
752
753 lex->unit.cleanup();768 lex->unit.cleanup();
754 session->set_proc_info("freeing items");769 session->set_proc_info("freeing items");
755 session->end_statement();770 session->end_statement();