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 #include <drizzled/show.h>
00023 #include <drizzled/session.h>
00024 #include <drizzled/statement/rollback_to_savepoint.h>
00025 #include <drizzled/transaction_services.h>
00026 #include <drizzled/named_savepoint.h>
00027 #include <drizzled/util/functors.h>
00028 #include <drizzled/session/transactions.h>
00029
00030 #include <string>
00031
00032 using namespace std;
00033
00034 namespace drizzled {
00035
00036 bool statement::RollbackToSavepoint::execute()
00037 {
00038
00039
00040
00041
00042
00043
00044 if ( (session().options & OPTION_NOT_AUTOCOMMIT) &&
00045 (transaction().all.getResourceContexts().empty() == true) )
00046 {
00047 if (session().startTransaction() == false)
00048 {
00049 return false;
00050 }
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 deque<NamedSavepoint> &savepoints= transaction().savepoints;
00068
00069
00070 if (savepoints.empty())
00071 {
00072 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex().ident.data());
00073 return false;
00074 }
00075
00076 {
00077
00078 NamedSavepoint &first_savepoint= savepoints.front();
00079 const string &first_savepoint_name= first_savepoint.getName();
00080 if (my_strnncoll(system_charset_info,
00081 (unsigned char *) lex().ident.data(),
00082 lex().ident.size(),
00083 (unsigned char *) first_savepoint_name.c_str(),
00084 first_savepoint_name.size()) == 0)
00085 {
00086
00087 (void) TransactionServices::rollbackToSavepoint(session(), first_savepoint);
00088
00089 if (transaction().all.hasModifiedNonTransData())
00090 {
00091 push_warning(&session(),
00092 DRIZZLE_ERROR::WARN_LEVEL_WARN,
00093 ER_WARNING_NOT_COMPLETE_ROLLBACK,
00094 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
00095 }
00096 session().my_ok();
00097 return false;
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 bool found= false;
00109 deque<NamedSavepoint> copy_savepoints(savepoints);
00110 deque<NamedSavepoint> new_savepoints;
00111 while (savepoints.empty() == false)
00112 {
00113 NamedSavepoint &sv= savepoints.front();
00114 const string &sv_name= sv.getName();
00115 if (! found &&
00116 my_strnncoll(system_charset_info,
00117 (unsigned char *) lex().ident.data(),
00118 lex().ident.size(),
00119 (unsigned char *) sv_name.c_str(),
00120 sv_name.size()) == 0)
00121 {
00122
00123 found= true;
00124
00125 (void) TransactionServices::rollbackToSavepoint(session(), sv);
00126 }
00127 if (found)
00128 {
00129
00130
00131
00132
00133
00134 new_savepoints.push_back(sv);
00135 }
00136 savepoints.pop_front();
00137 }
00138 if (found)
00139 {
00140 if (transaction().all.hasModifiedNonTransData())
00141 {
00142 push_warning(&session(),
00143 DRIZZLE_ERROR::WARN_LEVEL_WARN,
00144 ER_WARNING_NOT_COMPLETE_ROLLBACK,
00145 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
00146 }
00147
00148 transaction().savepoints= new_savepoints;
00149 session().my_ok();
00150 }
00151 else
00152 {
00153
00154 transaction().savepoints= copy_savepoints;
00155 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex().ident.data());
00156 }
00157 return false;
00158 }
00159
00160 }