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