00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <drizzled/statement/execute.h>
00024 #include <drizzled/session.h>
00025 #include <drizzled/execute.h>
00026 #include <drizzled/user_var_entry.h>
00027 #include <drizzled/plugin/listen.h>
00028 #include <drizzled/plugin/client.h>
00029 #include <drizzled/plugin/null_client.h>
00030 #include <drizzled/plugin/client/concurrent.h>
00031 #include <drizzled/sql_lex.h>
00032
00033 namespace drizzled {
00034
00035 void parse(drizzled::Session&, const char *inBuf, uint32_t length);
00036
00037 namespace statement {
00038
00039 Execute::Execute(Session *in_session,
00040 execute_string_t to_execute_arg,
00041 bool is_quiet_arg,
00042 bool is_concurrent_arg,
00043 bool should_wait_arg) :
00044 Statement(in_session),
00045 is_quiet(is_quiet_arg),
00046 is_concurrent(is_concurrent_arg),
00047 should_wait(should_wait_arg),
00048 to_execute(to_execute_arg)
00049 {
00050 }
00051
00052
00053 bool statement::Execute::parseVariable()
00054 {
00055 if (to_execute.isVariable())
00056 {
00057 user_var_entry *var= session().getVariable(to_execute, false);
00058
00059 if (var && var->length && var->value && var->type == STRING_RESULT)
00060 {
00061 lex_string_t tmp_for_var;
00062 tmp_for_var.assign(var->value, var->length);
00063 to_execute.set(tmp_for_var);
00064
00065 return true;
00066 }
00067 }
00068
00069 return false;
00070 }
00071
00072
00073 bool statement::Execute::runStatement(plugin::NullClient& client, const std::string &arg)
00074 {
00075 client.pushSQL(arg);
00076 if (not session().executeStatement())
00077 return true;
00078
00079 if (session().is_error())
00080 return true;
00081
00082 return false;
00083 }
00084
00085
00086 bool statement::Execute::execute()
00087 {
00088 bool ret= execute_shell();
00089
00090
00091 lex().statement= this;
00092
00093 return ret;
00094 }
00095
00096
00097 bool statement::Execute::execute_shell()
00098 {
00099 if (to_execute.size() == 0)
00100 {
00101 my_error(ER_WRONG_ARGUMENTS, MYF(0), "Invalid Variable");
00102 return false;
00103 }
00104
00105 if (to_execute.isVariable())
00106 {
00107 if (not parseVariable())
00108 {
00109 my_error(ER_WRONG_ARGUMENTS, MYF(0), "Invalid Variable");
00110 return false;
00111 }
00112 }
00113
00114 if (is_concurrent)
00115 {
00116 if (not session().isConcurrentExecuteAllowed())
00117 {
00118 my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
00119 return false;
00120 }
00121
00122 drizzled::Execute executer(session(), should_wait);
00123 executer.run(to_execute);
00124 }
00125 else
00126 {
00127 if (is_quiet)
00128 {
00129 plugin::Client *temp= session().getClient();
00130 boost::scoped_ptr<plugin::NullClient> null_client(new plugin::NullClient);
00131
00132 session().setClient(null_client.get());
00133
00134 bool error_occured= false;
00135 bool is_savepoint= false;
00136 {
00137 std::string start_sql;
00138 if (session().inTransaction())
00139 {
00140
00141 start_sql= "SAVEPOINT execute_internal_savepoint";
00142 is_savepoint= true;
00143 }
00144 else
00145 {
00146 start_sql= "START TRANSACTION";
00147 }
00148
00149 error_occured= runStatement(*null_client, start_sql);
00150 }
00151
00152
00153
00154 if (not error_occured)
00155 {
00156 typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
00157 std::string full_string(to_execute.data(), to_execute.size());
00158 Tokenizer tok(full_string, boost::escaped_list_separator<char>("\\", ";", "\""));
00159
00160 for (Tokenizer::iterator iter= tok.begin(); iter != tok.end(); ++iter)
00161 {
00162 if (session().getKilled() == Session::KILL_CONNECTION)
00163 break;
00164 if (runStatement(*null_client, *iter))
00165 {
00166 error_occured= true;
00167 break;
00168 }
00169 }
00170
00171
00172 {
00173 std::string final_sql;
00174 if (is_savepoint)
00175 {
00176 final_sql= error_occured ?
00177 "ROLLBACK TO SAVEPOINT execute_internal_savepoint" :
00178 "RELEASE SAVEPOINT execute_internal_savepoint";
00179 }
00180 else
00181 {
00182 final_sql= error_occured ? "ROLLBACK" : "COMMIT";
00183 }
00184
00185
00186
00187 (void)runStatement(*null_client, final_sql);
00188 }
00189 }
00190
00191 session().setClient(temp);
00192 if (session().is_error())
00193 {
00194 session().clear_error(true);
00195 }
00196 else
00197 {
00198 session().clearDiagnostics();
00199 }
00200
00201 session().my_ok();
00202
00203 null_client->close();
00204 }
00205 else
00206 {
00207 parse(session(), to_execute.data(), to_execute.size());
00208 }
00209 }
00210
00211 return true;
00212 }
00213
00214 }
00215 }
00216