23
23
#include "drizzled/statement/execute.h"
24
24
#include "drizzled/session.h"
25
#include "drizzled/execute.h"
26
25
#include "drizzled/user_var_entry.h"
27
#include "drizzled/plugin/listen.h"
28
#include "drizzled/plugin/client.h"
29
#include "drizzled/plugin/null_client.h"
30
#include "drizzled/plugin/client/concurrent.h"
35
void parse(drizzled::Session *session, const char *inBuf, uint32_t length);
30
void mysql_parse(drizzled::Session *session, const char *inBuf, uint32_t length);
37
32
namespace statement
40
Execute::Execute(Session *in_session,
41
drizzled::execute_string_t to_execute_arg,
43
bool is_concurrent_arg,
44
bool should_wait_arg) :
35
Execute::Execute(Session *in_session) :
45
36
Statement(in_session),
46
is_quiet(is_quiet_arg),
47
is_concurrent(is_concurrent_arg),
48
should_wait(should_wait_arg),
49
to_execute(to_execute_arg)
54
42
bool statement::Execute::parseVariable()
56
if (to_execute.isVariable())
58
46
user_var_entry *var= getSession()->getVariable(to_execute, false);
75
bool statement::Execute::runStatement(plugin::NullClient *client, const std::string &arg)
78
if (not getSession()->executeStatement())
81
if (getSession()->is_error())
88
61
bool statement::Execute::execute()
90
bool ret= execute_shell();
92
// We have to restore ourselves at the top for delete() to work.
93
getSession()->getLex()->statement= this;
99
bool statement::Execute::execute_shell()
101
63
if (to_execute.length == 0)
103
65
my_error(ER_WRONG_ARGUMENTS, MYF(0), "Invalid Variable");
107
if (to_execute.isVariable())
109
70
if (not parseVariable())
118
if (not getSession()->isConcurrentExecuteAllowed())
120
my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
124
drizzled::Execute executer(*getSession(), should_wait);
125
executer.run(to_execute.str, to_execute.length);
127
else // Non-concurrent run.
131
plugin::Client *temp= getSession()->getClient();
132
plugin::NullClient *null_client= new plugin::NullClient;
134
getSession()->setClient(null_client);
136
bool error_occured= false;
137
bool is_savepoint= false;
139
std::string start_sql;
140
if (getSession()->inTransaction())
142
// @todo Figure out something a bit more solid then this.
143
start_sql.append("SAVEPOINT execute_internal_savepoint");
148
start_sql.append("START TRANSACTION");
151
error_occured= runStatement(null_client, start_sql);
154
// @note this is copied from code in NULL client, all of this belongs
155
// in the pluggable parser pieces.
156
if (not error_occured)
158
typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
159
std::string full_string(to_execute.str, to_execute.length);
160
Tokenizer tok(full_string, boost::escaped_list_separator<char>("\\", ";", "\""));
162
for (Tokenizer::iterator iter= tok.begin();
163
iter != tok.end() and getSession()->getKilled() != Session::KILL_CONNECTION;
166
if (runStatement(null_client, *iter))
173
// @todo Encapsulate logic later to method
175
std::string final_sql;
180
final_sql.append("ROLLBACK TO SAVEPOINT execute_internal_savepoint");
184
final_sql.append("RELEASE SAVEPOINT execute_internal_savepoint");
191
final_sql.append("ROLLBACK");
195
final_sql.append("COMMIT");
199
// Run the cleanup command, we currently ignore if an error occurs
201
(void)runStatement(null_client, final_sql);
205
getSession()->setClient(temp);
206
if (getSession()->is_error())
208
getSession()->clear_error(true);
212
getSession()->clearDiagnostics();
215
getSession()->my_ok();
217
null_client->close();
222
parse(getSession(), to_execute.str, to_execute.length);
77
mysql_parse(getSession(), to_execute.str, to_execute.length);
79
// We have to restore ourselves at the top for delete[] to work.
80
getSession()->getLex()->statement= this;