~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/transaction_services.cc

  • Committer: David Shrewsbury
  • Date: 2010-12-06 17:17:49 UTC
  • mto: (1991.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1992.
  • Revision ID: shrewsbury.dave@gmail.com-20101206171749-lwrkbh3p2qsbk23s
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.

Show diffs side-by-side

added added

removed removed

Lines of Context:
690
690
     */
691
691
    if (normal_transaction)
692
692
      rollbackTransactionMessage(session);
 
693
    else
 
694
      rollbackStatementMessage(session);
693
695
 
694
696
    if (is_real_trans)
695
697
      session->transaction.xid_state.xid.null();
730
732
*/
731
733
int TransactionServices::autocommitOrRollback(Session *session, int error)
732
734
{
 
735
  /* One GPB Statement message per SQL statement */
 
736
  message::Statement *statement= session->getStatementMessage();
 
737
  if ((statement != NULL) && (! error))
 
738
    finalizeStatementMessage(*statement, session);
733
739
 
734
740
  if (session->transaction.stmt.getResourceContexts().empty() == false)
735
741
  {
1050
1056
  /* If there is an active statement message, finalize it */
1051
1057
  message::Statement *statement= in_session->getStatementMessage();
1052
1058
 
1053
 
  if (statement != NULL)
1054
 
  {
1055
 
    finalizeStatementMessage(*statement, in_session);
1056
 
  }
1057
 
  else
1058
 
    return 0; /* No data modification occurred inside the transaction */
 
1059
  /*
 
1060
   * Statement should always be NULL since we finalize each message
 
1061
   * in autocommitOrRollback()
 
1062
   */
 
1063
  assert(statement == NULL);
 
1064
 
 
1065
  /*
 
1066
   * If no Transaction message was ever created, then no data modification
 
1067
   * occurred inside the transaction, so nothing to do.
 
1068
   */
 
1069
  if (in_session->getTransactionMessage() == NULL)
 
1070
    return 0;
1059
1071
  
1060
1072
  message::Transaction* transaction= getActiveTransactionMessage(in_session);
1061
1073
 
1138
1150
  cleanupTransactionMessage(transaction, in_session);
1139
1151
}
1140
1152
 
 
1153
void TransactionServices::rollbackStatementMessage(Session *in_session)
 
1154
{
 
1155
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
1156
  if (! replication_services.isActive())
 
1157
    return;
 
1158
 
 
1159
  /* If we never added a Statement message, nothing to undo. */
 
1160
  if (in_session->getStatementMessage() == NULL)
 
1161
    return;
 
1162
 
 
1163
  message::Transaction *transaction= getActiveTransactionMessage(in_session);
 
1164
 
 
1165
  google::protobuf::RepeatedPtrField<message::Statement> *statements_in_txn;
 
1166
  statements_in_txn= transaction->mutable_statement();
 
1167
  /*
 
1168
   TODO: Fix for segmented statements
 
1169
   message::Statement *statement= in_session->getStatementMessage();
 
1170
 
 
1171
   if (statement->
 
1172
   */
 
1173
  statements_in_txn->RemoveLast();
 
1174
 
 
1175
  in_session->setStatementMessage(NULL);
 
1176
}
 
1177
  
1141
1178
message::Statement &TransactionServices::getInsertStatement(Session *in_session,
1142
1179
                                                            Table *in_table,
1143
1180
                                                            uint32_t *next_segment_id)
1927
1964
  }
1928
1965
}
1929
1966
 
1930
 
 
1931
 
/**
1932
 
 * Template for removing Statement records of different types.
1933
 
 *
1934
 
 * The code for removing records from different Statement message types
1935
 
 * is identical except for the class types that are embedded within the
1936
 
 * Statement.
1937
 
 *
1938
 
 * There are 3 scenarios we need to look for:
1939
 
 *   - We've been asked to remove more records than exist in the Statement
1940
 
 *   - We've been asked to remove less records than exist in the Statement
1941
 
 *   - We've been asked to remove ALL records that exist in the Statement
1942
 
 *
1943
 
 * If we are removing ALL records, then effectively we would be left with
1944
 
 * an empty Statement message, so we should just remove it and clean up
1945
 
 * message pointers in the Session object.
1946
 
 */
1947
 
template <class DataType, class RecordType>
1948
 
static bool removeStatementRecordsWithType(Session *session,
1949
 
                                           DataType *data,
1950
 
                                           uint32_t count)
1951
 
{
1952
 
  uint32_t num_avail_recs= static_cast<uint32_t>(data->record_size());
1953
 
 
1954
 
  /* If there aren't enough records to remove 'count' of them, error. */
1955
 
  if (num_avail_recs < count)
1956
 
    return false;
1957
 
 
1958
 
  /*
1959
 
   * If we are removing all of the data records, we'll just remove this
1960
 
   * entire Statement message.
1961
 
   */
1962
 
  if (num_avail_recs == count)
1963
 
  {
1964
 
    message::Transaction *transaction= session->getTransactionMessage();
1965
 
    protobuf::RepeatedPtrField<message::Statement> *statements= transaction->mutable_statement();
1966
 
    statements->RemoveLast();
1967
 
 
1968
 
    /*
1969
 
     * Now need to set the Session Statement pointer to either the previous
1970
 
     * Statement, or NULL if there isn't one.
1971
 
     */
1972
 
    if (statements->size() == 0)
1973
 
    {
1974
 
      session->setStatementMessage(NULL);
1975
 
    }
1976
 
    else
1977
 
    {
1978
 
      /*
1979
 
       * There isn't a great way to get a pointer to the previous Statement
1980
 
       * message using the RepeatedPtrField object, so we'll just get to it
1981
 
       * using the Transaction message.
1982
 
       */
1983
 
      int last_stmt_idx= transaction->statement_size() - 1;
1984
 
      session->setStatementMessage(transaction->mutable_statement(last_stmt_idx));
1985
 
    }
1986
 
  }
1987
 
  /* We only need to remove 'count' records */
1988
 
  else if (num_avail_recs > count)
1989
 
  {
1990
 
    protobuf::RepeatedPtrField<RecordType> *records= data->mutable_record();
1991
 
    while (count--)
1992
 
      records->RemoveLast();
1993
 
  }
1994
 
 
1995
 
  return true;
1996
 
}
1997
 
 
1998
 
 
1999
 
bool TransactionServices::removeStatementRecords(Session *session,
2000
 
                                                 uint32_t count)
2001
 
{
2002
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
2003
 
  if (! replication_services.isActive())
2004
 
    return false;
2005
 
 
2006
 
  /* Get the most current Statement */
2007
 
  message::Statement *statement= session->getStatementMessage();
2008
 
 
2009
 
  /* Make sure we have work to do */
2010
 
  if (statement == NULL)
2011
 
    return false;
2012
 
 
2013
 
  bool retval= false;
2014
 
 
2015
 
  switch (statement->type())
2016
 
  {
2017
 
    case message::Statement::INSERT:
2018
 
    {
2019
 
      message::InsertData *data= statement->mutable_insert_data();
2020
 
      retval= removeStatementRecordsWithType<message::InsertData, message::InsertRecord>(session, data, count);
2021
 
      break;
2022
 
    }
2023
 
 
2024
 
    case message::Statement::UPDATE:
2025
 
    {
2026
 
      message::UpdateData *data= statement->mutable_update_data();
2027
 
      retval= removeStatementRecordsWithType<message::UpdateData, message::UpdateRecord>(session, data, count);
2028
 
      break;
2029
 
    }
2030
 
 
2031
 
    case message::Statement::DELETE:  /* not sure if this one is possible... */
2032
 
    {
2033
 
      message::DeleteData *data= statement->mutable_delete_data();
2034
 
      retval= removeStatementRecordsWithType<message::DeleteData, message::DeleteRecord>(session, data, count);
2035
 
      break;
2036
 
    }
2037
 
 
2038
 
    default:
2039
 
      retval= false;
2040
 
      break;
2041
 
  }
2042
 
 
2043
 
  return retval;
2044
 
}
2045
 
 
2046
 
 
2047
1967
void TransactionServices::createTable(Session *in_session,
2048
1968
                                      const message::Table &table)
2049
1969
{