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
00029 #include <string>
00030
00031 using namespace std;
00032
00033 namespace drizzled
00034 {
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 TransactionServices &transaction_services= TransactionServices::singleton();
00069
00070
00071 if (savepoints.empty())
00072 {
00073 my_error(ER_SP_DOES_NOT_EXIST,
00074 MYF(0),
00075 "SAVEPOINT",
00076 lex().ident.str);
00077 return false;
00078 }
00079
00080 {
00081
00082 NamedSavepoint &first_savepoint= savepoints.front();
00083 const string &first_savepoint_name= first_savepoint.getName();
00084 if (my_strnncoll(system_charset_info,
00085 (unsigned char *) lex().ident.str,
00086 lex().ident.length,
00087 (unsigned char *) first_savepoint_name.c_str(),
00088 first_savepoint_name.size()) == 0)
00089 {
00090
00091 (void) transaction_services.rollbackToSavepoint(session(), first_savepoint);
00092
00093 if (transaction().all.hasModifiedNonTransData())
00094 {
00095 push_warning(&session(),
00096 DRIZZLE_ERROR::WARN_LEVEL_WARN,
00097 ER_WARNING_NOT_COMPLETE_ROLLBACK,
00098 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
00099 }
00100 session().my_ok();
00101 return false;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 bool found= false;
00113 deque<NamedSavepoint> copy_savepoints(savepoints);
00114 deque<NamedSavepoint> new_savepoints;
00115 while (savepoints.empty() == false)
00116 {
00117 NamedSavepoint &sv= savepoints.front();
00118 const string &sv_name= sv.getName();
00119 if (! found &&
00120 my_strnncoll(system_charset_info,
00121 (unsigned char *) lex().ident.str,
00122 lex().ident.length,
00123 (unsigned char *) sv_name.c_str(),
00124 sv_name.size()) == 0)
00125 {
00126
00127 found= true;
00128
00129 (void) transaction_services.rollbackToSavepoint(session(), sv);
00130 }
00131 if (found)
00132 {
00133
00134
00135
00136
00137
00138 new_savepoints.push_back(sv);
00139 }
00140 savepoints.pop_front();
00141 }
00142 if (found)
00143 {
00144 if (transaction().all.hasModifiedNonTransData())
00145 {
00146 push_warning(&session(),
00147 DRIZZLE_ERROR::WARN_LEVEL_WARN,
00148 ER_WARNING_NOT_COMPLETE_ROLLBACK,
00149 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
00150 }
00151
00152 transaction().savepoints= new_savepoints;
00153 session().my_ok();
00154 }
00155 else
00156 {
00157
00158 transaction().savepoints= copy_savepoints;
00159 my_error(ER_SP_DOES_NOT_EXIST,
00160 MYF(0),
00161 "SAVEPOINT",
00162 lex().ident.str);
00163 }
00164 return false;
00165 }
00166
00167 }