32
36
namespace statement
35
Execute::Execute(Session *in_session) :
39
Execute::Execute(Session *in_session,
40
drizzled::execute_string_t to_execute_arg,
42
bool is_concurrent_arg) :
36
43
Statement(in_session),
44
is_quiet(is_quiet_arg),
45
is_concurrent(is_concurrent_arg),
46
to_execute(to_execute_arg)
42
51
bool statement::Execute::parseVariable()
53
if (to_execute.isVariable())
46
55
user_var_entry *var= getSession()->getVariable(to_execute, false);
77
mysql_parse(getSession(), to_execute.str, to_execute.length);
79
// We have to restore ourselves at the top for delete[] to work.
103
if (getSession()->isConcurrentExecuteAllowed())
105
plugin::client::Concurrent *client= new plugin::client::Concurrent;
106
std::string execution_string(to_execute.str, to_execute.length);
107
client->pushSQL(execution_string);
108
Session *new_session= new Session(client);
110
// We set the current schema. @todo do the same with catalog
111
if (not getSession()->getSchema().empty())
112
new_session->set_db(getSession()->getSchema());
114
new_session->setConcurrentExecute(false);
116
// Overwrite the context in the next session, with what we have in our
117
// session. Eventually we will allow someone to change the effective
119
new_session->getSecurityContext()= getSession()->getSecurityContext();
121
if (new_session->schedule())
122
Session::unlink(new_session);
126
my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
134
plugin::Client *temp= getSession()->getClient();
135
plugin::NullClient *null_client= new plugin::NullClient;
137
getSession()->setClient(null_client);
139
bool error_occured= false;
140
bool is_savepoint= false;
142
std::string start_sql;
143
if (getSession()->inTransaction())
145
// @todo Figure out something a bit more solid then this.
146
start_sql.append("SAVEPOINT execute_internal_savepoint");
151
start_sql.append("START TRANSACTION");
154
error_occured= runStatement(null_client, start_sql);
157
// @note this is copied from code in NULL client, all of this belongs
158
// in the pluggable parser pieces.
159
if (not error_occured)
161
typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
162
std::string full_string(to_execute.str, to_execute.length);
163
Tokenizer tok(full_string, boost::escaped_list_separator<char>("\\", ";", "\""));
165
for (Tokenizer::iterator iter= tok.begin();
166
iter != tok.end() and getSession()->getKilled() != Session::KILL_CONNECTION;
169
if (runStatement(null_client, *iter))
176
// @todo Encapsulate logic later to method
178
std::string final_sql;
183
final_sql.append("ROLLBACK TO SAVEPOINT execute_internal_savepoint");
187
final_sql.append("RELEASE SAVEPOINT execute_internal_savepoint");
194
final_sql.append("ROLLBACK");
198
final_sql.append("COMMIT");
202
// Run the cleanup command, we currently ignore if an error occurs
204
(void)runStatement(null_client, final_sql);
208
getSession()->setClient(temp);
209
if (getSession()->is_error())
211
getSession()->clear_error(true);
215
getSession()->clearDiagnostics();
218
getSession()->my_ok();
220
null_client->close();
225
mysql_parse(getSession(), to_execute.str, to_execute.length);
230
// We have to restore ourselves at the top for delete() to work.
80
231
getSession()->getLex()->statement= this;